aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_mmm_transporter.v
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/modexpng_mmm_transporter.v')
-rw-r--r--rtl/modexpng_mmm_transporter.v157
1 files changed, 157 insertions, 0 deletions
diff --git a/rtl/modexpng_mmm_transporter.v b/rtl/modexpng_mmm_transporter.v
new file mode 100644
index 0000000..a8f309a
--- /dev/null
+++ b/rtl/modexpng_mmm_transporter.v
@@ -0,0 +1,157 @@
+module modexpng_mmm_transporter
+(
+ clk,
+ ena,
+ index_last,
+ fsm_state,
+ fsm_state_next,
+ load_phase,
+ load_xy_addr,
+ load_xy_addr_vld,
+ load_xy_req,
+ load_addr_zero,
+ load_t1t2_addr_done,
+ load_nn_coeff_addr_done
+);
+
+
+ //
+ // Includes
+ //
+ //`include "modexpng_parameters.vh"
+ //`include "modexpng_parameters_x8.vh"
+ `include "modexpng_mmm_fsm.vh"
+
+
+ //
+ // Parameters
+ //
+ parameter INDEX_WIDTH = 6;
+
+
+ //
+ // Ports
+ //
+ input clk;
+ input ena;
+ input [ INDEX_WIDTH-1:0] index_last;
+ input [FSM_STATE_WIDTH-1:0] fsm_state;
+ input [FSM_STATE_WIDTH-1:0] fsm_state_next;
+ output load_phase;
+ output [ INDEX_WIDTH:0] load_xy_addr;
+ output load_xy_addr_vld;
+ output load_xy_req;
+ output load_addr_zero;
+ output load_t1t2_addr_done;
+ output load_nn_coeff_addr_done;
+
+
+ //
+ // Load Address Generator
+ //
+ reg load_phase_reg;
+ reg [INDEX_WIDTH:0] load_xy_addr_reg;
+ reg load_xy_addr_vld_reg;
+ reg load_xy_req_reg;
+
+
+ //
+ // Mapping
+ //
+ assign load_phase = load_phase_reg;
+ assign load_xy_addr = load_xy_addr_reg;
+ assign load_xy_addr_vld = load_xy_addr_vld_reg;
+ assign load_xy_req = load_xy_req_reg;
+
+
+ //
+ // Handy Quantities
+ //
+ wire [INDEX_WIDTH:0] load_xy_addr_zero = {{INDEX_WIDTH{1'b0}}, 1'b0};
+ wire [INDEX_WIDTH:0] load_xy_addr_next = load_xy_addr_reg + 1'b1;
+ wire [INDEX_WIDTH:0] load_xy_addr_xxx = {{INDEX_WIDTH{1'bX}}, 1'bX};
+
+
+ //
+ // More Handy Quantities
+ //
+ reg [INDEX_WIDTH:0] load_t1t2_addr_last;
+ reg [INDEX_WIDTH:0] load_nn_coeff_addr_last;
+
+
+ //
+ // Flags
+ //
+ assign load_addr_zero = load_xy_addr_reg == load_xy_addr_zero;
+ assign load_t1t2_addr_done = load_xy_addr_reg == load_t1t2_addr_last;
+ assign load_nn_coeff_addr_done = load_xy_addr_reg == load_nn_coeff_addr_last;
+
+
+ //
+ // Last Index Latch
+ //
+ always @(posedge clk)
+ //
+ if (ena && (fsm_state == FSM_STATE_IDLE)) begin
+ load_t1t2_addr_last <= {1'b0, index_last};
+ load_nn_coeff_addr_last <= {1'b0, index_last} + 1'b1;
+ end
+
+
+ //
+ // Update Load Phase
+ //
+ always @(posedge clk)
+ //
+ case (fsm_state_next)
+ FSM_STATE_LOAD_T1T2_1,
+ FSM_STATE_LOAD_T1T2_2,
+ FSM_STATE_LOAD_T1T2_3: load_phase_reg <= 1'b0;
+ FSM_STATE_LOAD_NN_COEFF_1,
+ FSM_STATE_LOAD_NN_COEFF_2,
+ FSM_STATE_LOAD_NN_COEFF_3: load_phase_reg <= 1'b1;
+ default: load_phase_reg <= 1'bX;
+ endcase
+
+
+ //
+ // Update Load Address
+ //
+ always @(posedge clk)
+ //
+ case (fsm_state_next)
+ FSM_STATE_LOAD_T1T2_1: load_xy_addr_reg <= (fsm_state == FSM_STATE_LOAD_T1T2_3) ? load_xy_addr_next : load_xy_addr_zero;
+ FSM_STATE_LOAD_T1T2_2,
+ FSM_STATE_LOAD_T1T2_3: load_xy_addr_reg <= load_xy_addr_reg;
+ FSM_STATE_LOAD_NN_COEFF_1: load_xy_addr_reg <= (fsm_state == FSM_STATE_LOAD_NN_COEFF_3) ? load_xy_addr_next : load_xy_addr_zero;
+ FSM_STATE_LOAD_NN_COEFF_2,
+ FSM_STATE_LOAD_NN_COEFF_3: load_xy_addr_reg <= load_xy_addr_reg;
+ default load_xy_addr_reg <= load_xy_addr_xxx;
+ endcase
+
+
+ //
+ // Update Address Valid Flag
+ //
+ always @(posedge clk)
+ //
+ case (fsm_state_next)
+ FSM_STATE_LOAD_T1T2_1,
+ FSM_STATE_LOAD_NN_COEFF_1: load_xy_addr_vld_reg <= 1'b1;
+ default load_xy_addr_vld_reg <= 1'b0;
+ endcase
+
+
+ //
+ // Update Load Request Flag
+ //
+ always @(posedge clk)
+ //
+ case (fsm_state_next)
+ FSM_STATE_LOAD_T1T2_2,
+ FSM_STATE_LOAD_NN_COEFF_2: load_xy_req_reg <= 1'b1;
+ default load_xy_req_reg <= 1'b0;
+ endcase
+
+
+endmodule