diff options
-rw-r--r-- | rtl/modexpng_io_manager.v | 364 | ||||
-rw-r--r-- | rtl/modexpng_io_manager_debug.vh | 41 |
2 files changed, 266 insertions, 139 deletions
diff --git a/rtl/modexpng_io_manager.v b/rtl/modexpng_io_manager.v index a5cd1db..466f1ea 100644 --- a/rtl/modexpng_io_manager.v +++ b/rtl/modexpng_io_manager.v @@ -173,19 +173,26 @@ module modexpng_io_manager // // FSM Declaration // - localparam [2:0] IO_FSM_STATE_IDLE = 3'b000; - localparam [2:0] IO_FSM_STATE_LATENCY_PRE1 = 3'b001; - localparam [2:0] IO_FSM_STATE_LATENCY_PRE2 = 3'b010; - localparam [2:0] IO_FSM_STATE_BUSY = 3'b011; - localparam [2:0] IO_FSM_STATE_EXTRA = 3'b100; - localparam [2:0] IO_FSM_STATE_LATENCY_POST1 = 3'b101; - localparam [2:0] IO_FSM_STATE_LATENCY_POST2 = 3'b110; - localparam [2:0] IO_FSM_STATE_STOP = 3'b111; - - reg [2:0] io_fsm_state = IO_FSM_STATE_IDLE; - reg [2:0] io_fsm_state_next; - + localparam [3:0] IO_FSM_STATE_IDLE_X = 4'h0; + localparam [3:0] IO_FSM_STATE_LATENCY_PRE1_X = 4'h1; + localparam [3:0] IO_FSM_STATE_LATENCY_PRE2_X = 4'h2; + localparam [3:0] IO_FSM_STATE_LATENCY_PRE3_X = 4'h3; + localparam [3:0] IO_FSM_STATE_LATENCY_PRE4_X = 4'h4; + localparam [3:0] IO_FSM_STATE_BUSY1_X = 4'hA; + localparam [3:0] IO_FSM_STATE_BUSY2_X = 4'hB; + localparam [3:0] IO_FSM_STATE_EXTRA1_X = 4'hC; + localparam [3:0] IO_FSM_STATE_EXTRA2_X = 4'hD; + localparam [3:0] IO_FSM_STATE_LATENCY_POST1_X = 4'h5; + localparam [3:0] IO_FSM_STATE_LATENCY_POST2_X = 4'h6; + localparam [3:0] IO_FSM_STATE_LATENCY_POST3_X = 4'h7; + localparam [3:0] IO_FSM_STATE_LATENCY_POST4_X = 4'h8; + localparam [3:0] IO_FSM_STATE_STOP_X = 4'hF; + + reg [3:0] io_fsm_state = IO_FSM_STATE_IDLE_X; + reg [3:0] io_fsm_state_next; + wire [3:0] io_fsm_state_after_busy; + // // Control Signals // @@ -280,17 +287,32 @@ module modexpng_io_manager // Delays // reg [OP_ADDR_W -1:0] in_1_addr_op_dly1; - reg [OP_ADDR_W -1:0] in_1_addr_op_dly2; reg [OP_ADDR_W -1:0] in_2_addr_op_dly1; - reg [OP_ADDR_W -1:0] in_2_addr_op_dly2; - reg [OP_ADDR_W -1:0] dummy_addr_op_dly1; - reg [OP_ADDR_W -1:0] dummy_addr_op_dly2; + reg [OP_ADDR_W -1:0] dummy_addr_op_dly1; + + reg [WORD_W -1:0] io_in_1_din_dly1; + reg [WORD_W -1:0] io_in_2_din_dly1; + + reg [WORD_W -1:0] wrk_narrow_x_din_x_lsb_dly1; + reg [WORD_W -1:0] wrk_narrow_y_din_x_lsb_dly1; + reg [WORD_W -1:0] wrk_narrow_x_din_y_lsb_dly1; + reg [WORD_W -1:0] wrk_narrow_y_din_y_lsb_dly1; + always @(posedge clk) begin // - {in_1_addr_op_dly2, in_1_addr_op_dly1} <= {in_1_addr_op_dly1, in_1_addr_op}; - {in_2_addr_op_dly2, in_2_addr_op_dly1} <= {in_2_addr_op_dly1, in_2_addr_op}; - {dummy_addr_op_dly2, dummy_addr_op_dly1} <= {dummy_addr_op_dly1, dummy_addr_op}; + {in_1_addr_op_dly1} <= {in_1_addr_op}; + {in_2_addr_op_dly1} <= {in_2_addr_op}; + // + {io_in_1_din_dly1} <= {io_in_1_din}; + {io_in_2_din_dly1} <= {io_in_2_din}; + // + {dummy_addr_op_dly1} <= {dummy_addr_op}; + // + {wrk_narrow_x_din_x_lsb_dly1} <= {wrk_narrow_x_din_x_lsb}; + {wrk_narrow_y_din_x_lsb_dly1} <= {wrk_narrow_y_din_x_lsb}; + {wrk_narrow_x_din_y_lsb_dly1} <= {wrk_narrow_x_din_y_lsb}; + {wrk_narrow_y_din_y_lsb_dly1} <= {wrk_narrow_y_din_y_lsb}; // end @@ -318,12 +340,7 @@ module modexpng_io_manager wire sel_aux_is_1 = sel_aux == UOP_AUX_1; wire sel_aux_is_2 = sel_aux == UOP_AUX_2; - - wire in_1_addr_op_next_is_last; - wire in_2_addr_op_next_is_last; - wire in_2_addr_op_next_is_one; - wire dummy_addr_op_next_is_last; - + // // Ladder Init/Step Logic @@ -346,7 +363,7 @@ module modexpng_io_manager always @(posedge clk) // - if (io_fsm_state_next == IO_FSM_STATE_LATENCY_PRE1) begin + if (io_fsm_state_next == IO_FSM_STATE_LATENCY_PRE1_X) begin // if (opcode_is_ladder_init) begin ladder_index <= ladder_steps; @@ -366,40 +383,46 @@ module modexpng_io_manager // // Ladder Mux // - reg ladder_dpq_mux; + reg ladder_dpq_mux_dly1; + reg ladder_dpq_mux_dly2; + wire ladder_dpq_mux = ladder_dpq_mux_dly2; - always @(io_in_2_din, ladder_index_lsb) + always @(io_in_2_din_dly1, ladder_index_lsb) // case(ladder_index_lsb) - 4'b0000: ladder_dpq_mux = io_in_2_din[ 0]; - 4'b0001: ladder_dpq_mux = io_in_2_din[ 1]; - 4'b0010: ladder_dpq_mux = io_in_2_din[ 2]; - 4'b0011: ladder_dpq_mux = io_in_2_din[ 3]; - 4'b0100: ladder_dpq_mux = io_in_2_din[ 4]; - 4'b0101: ladder_dpq_mux = io_in_2_din[ 5]; - 4'b0110: ladder_dpq_mux = io_in_2_din[ 6]; - 4'b0111: ladder_dpq_mux = io_in_2_din[ 7]; - 4'b1000: ladder_dpq_mux = io_in_2_din[ 8]; - 4'b1001: ladder_dpq_mux = io_in_2_din[ 9]; - 4'b1010: ladder_dpq_mux = io_in_2_din[10]; - 4'b1011: ladder_dpq_mux = io_in_2_din[11]; - 4'b1100: ladder_dpq_mux = io_in_2_din[12]; - 4'b1101: ladder_dpq_mux = io_in_2_din[13]; - 4'b1110: ladder_dpq_mux = io_in_2_din[14]; - 4'b1111: ladder_dpq_mux = io_in_2_din[15]; + 4'b0000: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 0]; + 4'b0001: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 1]; + 4'b0010: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 2]; + 4'b0011: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 3]; + 4'b0100: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 4]; + 4'b0101: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 5]; + 4'b0110: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 6]; + 4'b0111: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 7]; + 4'b1000: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 8]; + 4'b1001: ladder_dpq_mux_dly1 = io_in_2_din_dly1[ 9]; + 4'b1010: ladder_dpq_mux_dly1 = io_in_2_din_dly1[10]; + 4'b1011: ladder_dpq_mux_dly1 = io_in_2_din_dly1[11]; + 4'b1100: ladder_dpq_mux_dly1 = io_in_2_din_dly1[12]; + 4'b1101: ladder_dpq_mux_dly1 = io_in_2_din_dly1[13]; + 4'b1110: ladder_dpq_mux_dly1 = io_in_2_din_dly1[14]; + 4'b1111: ladder_dpq_mux_dly1 = io_in_2_din_dly1[15]; endcase - + + always @(posedge clk) + // + ladder_dpq_mux_dly2 <= ladder_dpq_mux_dly1; + always @(posedge clk) // case (io_fsm_state) // - IO_FSM_STATE_BUSY: + IO_FSM_STATE_BUSY1_X: if (opcode_is_ladder) ladder_d_r <= ladder_dpq_mux; // - IO_FSM_STATE_LATENCY_POST1: + IO_FSM_STATE_LATENCY_POST1_X: if (opcode_is_ladder) ladder_p_r <= ladder_dpq_mux; // - IO_FSM_STATE_LATENCY_POST2: + IO_FSM_STATE_LATENCY_POST3_X: if (opcode_is_ladder) ladder_q_r <= ladder_dpq_mux; // endcase @@ -415,14 +438,14 @@ module modexpng_io_manager in_2_en <= 1'b0; end else case (io_fsm_state_next) // - IO_FSM_STATE_LATENCY_PRE1, - IO_FSM_STATE_LATENCY_PRE2, - IO_FSM_STATE_BUSY: begin + IO_FSM_STATE_LATENCY_PRE1_X, + IO_FSM_STATE_LATENCY_PRE3_X, + IO_FSM_STATE_BUSY1_X: begin in_1_en <= opcode_is_input && sel_aux_is_1; in_2_en <= (opcode_is_input && sel_aux_is_2) || opcode_is_ladder; end // - IO_FSM_STATE_EXTRA: begin + IO_FSM_STATE_EXTRA1_X: begin in_1_en <= opcode_is_input && sel_aux_is_1 && sel_in_needs_extra; in_2_en <= opcode_is_input && sel_aux_is_2 && sel_in_needs_extra; end @@ -434,6 +457,7 @@ module modexpng_io_manager // endcase + // // Destination Enable Logic // @@ -450,9 +474,9 @@ module modexpng_io_manager // end else case (io_fsm_state) // - IO_FSM_STATE_BUSY, - IO_FSM_STATE_EXTRA, - IO_FSM_STATE_LATENCY_POST1: begin + IO_FSM_STATE_BUSY1_X, + IO_FSM_STATE_EXTRA1_X, + IO_FSM_STATE_LATENCY_POST1_X: begin // wide_xy_ena_x <= opcode_is_input_wide && sel_crt_is_x; wide_xy_ena_y <= opcode_is_input_wide && sel_crt_is_y; @@ -463,7 +487,7 @@ module modexpng_io_manager // end // - IO_FSM_STATE_LATENCY_POST2: begin + IO_FSM_STATE_LATENCY_POST3_X: begin // wide_xy_ena_x <= 1'b0; wide_xy_ena_y <= 1'b0; @@ -491,10 +515,23 @@ module modexpng_io_manager // // Output Data Logic // - wire [WORD_EXT_W -1:0] io_in_dout_mux = {{(WORD_EXT_W-WORD_W){1'b0}}, sel_aux_is_1 ? io_in_1_din : io_in_2_din}; + reg [ WORD_W -1:0] io_in_dout_mux_dly2; + wire [WORD_EXT_W -1:0] io_in_dout_mux = {{(WORD_EXT_W-WORD_W){1'b0}}, io_in_dout_mux_dly2}; - wire [WORD_W -1:0] wrk_narrow_xy_din_x_mux_lsb = sel_aux == UOP_AUX_1 ? wrk_narrow_x_din_x_lsb : wrk_narrow_y_din_x_lsb; - wire [WORD_W -1:0] wrk_narrow_xy_din_y_mux_lsb = sel_aux == UOP_AUX_1 ? wrk_narrow_x_din_y_lsb : wrk_narrow_y_din_y_lsb; + reg [WORD_W -1:0] wrk_narrow_din_x_lsb_mux_dly2; + reg [WORD_W -1:0] wrk_narrow_din_y_lsb_mux_dly2; + + wire [WORD_W -1:0] wrk_narrow_din_x_lsb_mux = wrk_narrow_din_x_lsb_mux_dly2; + wire [WORD_W -1:0] wrk_narrow_din_y_lsb_mux = wrk_narrow_din_y_lsb_mux_dly2; + + always @(posedge clk) begin + // + io_in_dout_mux_dly2 <= sel_aux_is_1 ? io_in_1_din_dly1 : io_in_2_din_dly1; + // + wrk_narrow_din_x_lsb_mux_dly2 = sel_aux == UOP_AUX_1 ? wrk_narrow_x_din_x_lsb_dly1 : wrk_narrow_y_din_x_lsb_dly1; + wrk_narrow_din_y_lsb_mux_dly2 = sel_aux == UOP_AUX_1 ? wrk_narrow_x_din_y_lsb_dly1 : wrk_narrow_y_din_y_lsb_dly1; + // + end always @(posedge clk) begin // @@ -511,25 +548,25 @@ module modexpng_io_manager // case (io_fsm_state) // - IO_FSM_STATE_BUSY, - IO_FSM_STATE_EXTRA, - IO_FSM_STATE_LATENCY_POST1: begin + IO_FSM_STATE_BUSY1_X, + IO_FSM_STATE_EXTRA1_X, + IO_FSM_STATE_LATENCY_POST1_X: begin // if (opcode_is_input_wide && sel_crt_is_x) {wide_x_din_x, wide_y_din_x} <= {2{io_in_dout_mux}}; if (opcode_is_input_wide && sel_crt_is_y) {wide_x_din_y, wide_y_din_y} <= {2{io_in_dout_mux}}; if (opcode_is_input_narrow && sel_crt_is_x) {narrow_x_din_x, narrow_y_din_x} <= {2{io_in_dout_mux}}; if (opcode_is_input_narrow && sel_crt_is_y) {narrow_x_din_y, narrow_y_din_y} <= {2{io_in_dout_mux}}; // - if (opcode_is_output) out_dout <= sel_crt_is_x ? wrk_narrow_xy_din_x_mux_lsb : wrk_narrow_xy_din_y_mux_lsb; + if (opcode_is_output) out_dout <= sel_crt_is_x ? wrk_narrow_din_x_lsb_mux : wrk_narrow_din_y_lsb_mux; // end // - IO_FSM_STATE_LATENCY_POST2: begin + IO_FSM_STATE_LATENCY_POST3_X: begin // if (opcode_is_input_narrow && sel_crt_is_x && sel_in_needs_extra) {narrow_x_din_x, narrow_y_din_x} <= {2{io_in_dout_mux}}; if (opcode_is_input_narrow && sel_crt_is_y && sel_in_needs_extra) {narrow_x_din_y, narrow_y_din_y} <= {2{io_in_dout_mux}}; // - if (opcode_is_output) out_dout <= sel_crt_is_x ? wrk_narrow_xy_din_x_mux_lsb : wrk_narrow_xy_din_y_mux_lsb; + if (opcode_is_output) out_dout <= sel_crt_is_x ? wrk_narrow_din_x_lsb_mux : wrk_narrow_din_y_lsb_mux; // end // @@ -541,8 +578,26 @@ module modexpng_io_manager // // Destination Address Logic // - wire [OP_ADDR_W -1:0] in_addr_op_dly2_mux = - sel_aux_is_1 ? in_1_addr_op_dly2 : in_2_addr_op_dly2; + reg [OP_ADDR_W -1:0] in_addr_op_dly2_mux; + reg [OP_ADDR_W -1:0] in_addr_op_dly3_mux; + reg [OP_ADDR_W -1:0] in_addr_op_dly4_mux; + wire [OP_ADDR_W -1:0] in_addr_op_mux = in_addr_op_dly4_mux; + + reg [OP_ADDR_W -1:0] dummy_addr_op_dly2; + reg [OP_ADDR_W -1:0] dummy_addr_op_dly3; + reg [OP_ADDR_W -1:0] dummy_addr_op_dly4; + + always @(posedge clk) begin + // + in_addr_op_dly2_mux <= sel_aux_is_1 ? in_1_addr_op_dly1 : in_2_addr_op_dly1; + in_addr_op_dly3_mux <= in_addr_op_dly2_mux; + in_addr_op_dly4_mux <= in_addr_op_dly3_mux; + // + dummy_addr_op_dly2 <= dummy_addr_op_dly1; + dummy_addr_op_dly3 <= dummy_addr_op_dly2; + dummy_addr_op_dly4 <= dummy_addr_op_dly3; + // + end always @(posedge clk) begin // @@ -554,27 +609,27 @@ module modexpng_io_manager // case (io_fsm_state) // - IO_FSM_STATE_BUSY, - IO_FSM_STATE_EXTRA, - IO_FSM_STATE_LATENCY_POST1: begin - if (opcode_is_input_wide && sel_crt_is_x) {wide_xy_bank_x, wide_xy_addr_x } <= {sel_out, in_addr_op_dly2_mux}; - if (opcode_is_input_wide && sel_crt_is_y) {wide_xy_bank_y, wide_xy_addr_y } <= {sel_out, in_addr_op_dly2_mux}; - if (opcode_is_input_narrow && sel_crt_is_x) {narrow_xy_bank_x, narrow_xy_addr_x} <= {sel_out, in_addr_op_dly2_mux}; - if (opcode_is_input_narrow && sel_crt_is_y) {narrow_xy_bank_y, narrow_xy_addr_y} <= {sel_out, in_addr_op_dly2_mux}; - if (opcode_is_output ) {out_addr_bank, out_addr_op} <= {sel_out, dummy_addr_op_dly2}; + IO_FSM_STATE_BUSY1_X, + IO_FSM_STATE_EXTRA1_X, + IO_FSM_STATE_LATENCY_POST1_X: begin + if (opcode_is_input_wide && sel_crt_is_x) {wide_xy_bank_x, wide_xy_addr_x } <= {sel_out, in_addr_op_mux }; + if (opcode_is_input_wide && sel_crt_is_y) {wide_xy_bank_y, wide_xy_addr_y } <= {sel_out, in_addr_op_mux }; + if (opcode_is_input_narrow && sel_crt_is_x) {narrow_xy_bank_x, narrow_xy_addr_x} <= {sel_out, in_addr_op_mux }; + if (opcode_is_input_narrow && sel_crt_is_y) {narrow_xy_bank_y, narrow_xy_addr_y} <= {sel_out, in_addr_op_mux }; + if (opcode_is_output ) {out_addr_bank, out_addr_op} <= {sel_out, dummy_addr_op_dly4}; end // - IO_FSM_STATE_LATENCY_POST2: begin + IO_FSM_STATE_LATENCY_POST3_X: begin if (opcode_is_input_narrow && sel_crt_is_x && sel_in_needs_extra) {narrow_xy_bank_x, narrow_xy_addr_x} <= {BANK_NARROW_EXT, OP_ADDR_EXT_COEFF }; if (opcode_is_input_narrow && sel_crt_is_y && sel_in_needs_extra) {narrow_xy_bank_y, narrow_xy_addr_y} <= {BANK_NARROW_EXT, OP_ADDR_EXT_COEFF }; - if (opcode_is_output ) {out_addr_bank, out_addr_op } <= {sel_out, dummy_addr_op_dly2}; + if (opcode_is_output ) {out_addr_bank, out_addr_op } <= {sel_out, dummy_addr_op_dly4}; end // endcase // end - + // // Source Address Logic // @@ -586,43 +641,71 @@ module modexpng_io_manager wire [OP_ADDR_W -1:0] in_2_addr_op_next = in_2_addr_next[OP_ADDR_W -1:0]; wire [OP_ADDR_W -1:0] dummy_addr_op_next = dummy_addr_next; - assign in_1_addr_op_next_is_last = in_1_addr_op_next == word_index_last; - assign in_2_addr_op_next_is_last = in_2_addr_op_next == word_index_last; -// assign in_2_addr_op_next_is_one = in_2_addr_op_next == OP_ADDR_ONE; - assign dummy_addr_op_next_is_last = dummy_addr_op_next == word_index_last; - + reg in_1_addr_op_is_last = 1'b0; + reg in_2_addr_op_is_last = 1'b0; + reg dummy_addr_op_is_last = 1'b0; + always @(posedge clk) begin // {in_1_addr_bank, in_1_addr_op } <= {BANK_DNC, OP_ADDR_DNC}; {in_2_addr_bank, in_2_addr_op } <= {BANK_DNC, OP_ADDR_DNC}; { dummy_addr_op} <= { OP_ADDR_DNC}; // - in_1_addr_next <= {BANK_DNC, OP_ADDR_DNC}; - in_2_addr_next <= {BANK_DNC, OP_ADDR_DNC}; - dummy_addr_next <= { OP_ADDR_DNC}; - // case (io_fsm_state_next) // - IO_FSM_STATE_LATENCY_PRE1: begin + IO_FSM_STATE_LATENCY_PRE1_X: begin // {in_1_addr_bank, in_1_addr_op } <= {sel_in, OP_ADDR_ZERO}; if (!opcode_is_ladder) {in_2_addr_bank, in_2_addr_op } <= {sel_in, OP_ADDR_ZERO}; - else {in_2_addr_bank, in_2_addr_op } <= {BANK_DNC, OP_ADDR_DNC}; + else {in_2_addr_bank, in_2_addr_op } <= {BANK_DNC, OP_ADDR_DNC }; { dummy_addr_op} <= { OP_ADDR_ZERO}; - // - in_1_addr_next <= {sel_in, OP_ADDR_ONE}; - in_2_addr_next <= {sel_in, OP_ADDR_ONE}; - dummy_addr_next <= { OP_ADDR_ONE}; - // + // end // - IO_FSM_STATE_LATENCY_PRE2: begin + IO_FSM_STATE_LATENCY_PRE3_X: begin // {in_1_addr_bank, in_1_addr_op } <= in_1_addr_next; if (!opcode_is_ladder) {in_2_addr_bank, in_2_addr_op } <= in_2_addr_next; else {in_2_addr_bank, in_2_addr_op } <= {BANK_IN_2_D, ladder_index_msb}; { dummy_addr_op} <= dummy_addr_next; // + end + // + IO_FSM_STATE_BUSY1_X: begin + // + {in_1_addr_bank, in_1_addr_op } <= in_1_addr_next; + {in_2_addr_bank, in_2_addr_op } <= in_2_addr_next; + { dummy_addr_op} <= dummy_addr_next; + // + end + // + IO_FSM_STATE_EXTRA1_X: + // + if (opcode_is_input && sel_in_needs_extra) begin + // + if (sel_aux_is_1) {in_1_addr_bank, in_1_addr_op} <= in_1_addr_next; + if (sel_aux_is_2) {in_2_addr_bank, in_2_addr_op} <= in_2_addr_next; + // + end + // + endcase + // + end + + always @(posedge clk) + // + case (io_fsm_state_next) + // + IO_FSM_STATE_LATENCY_PRE1_X: begin + // + in_1_addr_next <= {sel_in, OP_ADDR_ONE}; + in_2_addr_next <= {sel_in, OP_ADDR_ONE}; + dummy_addr_next <= { OP_ADDR_ONE}; + // + end + // + IO_FSM_STATE_LATENCY_PRE3_X: begin + // in_1_addr_next <= in_1_addr_next + 1'b1; if (!opcode_is_ladder) in_2_addr_next <= in_2_addr_next + 1'b1; else in_2_addr_next <= {BANK_IN_2_P, 1'b1, ladder_index_msb[OP_ADDR_W-2:0]}; @@ -630,11 +713,7 @@ module modexpng_io_manager // end // - IO_FSM_STATE_BUSY: begin - // - {in_1_addr_bank, in_1_addr_op } <= in_1_addr_next; - {in_2_addr_bank, in_2_addr_op } <= in_2_addr_next; - { dummy_addr_op} <= dummy_addr_next; + IO_FSM_STATE_BUSY1_X: begin // in_1_addr_next <= in_1_addr_next + 1'b1; if (!opcode_is_ladder) in_2_addr_next <= in_2_addr_next + 1'b1; @@ -643,33 +722,42 @@ module modexpng_io_manager // end // - IO_FSM_STATE_EXTRA: + IO_FSM_STATE_EXTRA1_X: // if (opcode_is_input && sel_in_needs_extra) begin // - if (sel_aux_is_1) begin - {in_1_addr_bank, in_1_addr_op} <= in_1_addr_next; - in_1_addr_next <= in_1_addr_next + 1'b1; - end - // - if (sel_aux_is_2) begin - {in_2_addr_bank, in_2_addr_op} <= in_2_addr_next; - in_2_addr_next <= in_2_addr_next + 1'b1; - end + if (sel_aux_is_1) in_1_addr_next <= in_1_addr_next + 1'b1; + if (sel_aux_is_2) in_2_addr_next <= in_2_addr_next + 1'b1; // - end + end + // + endcase + + always @(posedge clk) begin + // + in_1_addr_op_is_last <= 1'b0; + in_2_addr_op_is_last <= 1'b0; + dummy_addr_op_is_last <= 1'b0; + // + case (io_fsm_state_next) + // + IO_FSM_STATE_BUSY1_X: begin + in_1_addr_op_is_last <= in_1_addr_op_next == word_index_last; + in_2_addr_op_is_last <= in_2_addr_op_next == word_index_last; + dummy_addr_op_is_last <= dummy_addr_op_next == word_index_last; + end // endcase // end - + // // FSM Process // always @(posedge clk or negedge rst_n) // - if (!rst_n) io_fsm_state <= IO_FSM_STATE_IDLE; + if (!rst_n) io_fsm_state <= IO_FSM_STATE_IDLE_X; else io_fsm_state <= io_fsm_state_next; @@ -682,13 +770,13 @@ module modexpng_io_manager // io_fsm_done <= 1'b0; // - if (io_fsm_state == IO_FSM_STATE_BUSY) begin + if (io_fsm_state == IO_FSM_STATE_BUSY1_X) begin // if (opcode_is_input) begin - if (sel_aux_is_1 && in_1_addr_op_next_is_last) io_fsm_done <= 1'b1; - if (sel_aux_is_2 && in_2_addr_op_next_is_last) io_fsm_done <= 1'b1; + if (sel_aux_is_1 && in_1_addr_op_is_last) io_fsm_done <= 1'b1; + if (sel_aux_is_2 && in_2_addr_op_is_last) io_fsm_done <= 1'b1; end else if (opcode_is_output || opcode_is_ladder) begin - if (dummy_addr_op_next_is_last) io_fsm_done <= 1'b1; + if (dummy_addr_op_is_last) io_fsm_done <= 1'b1; end // end @@ -699,19 +787,26 @@ module modexpng_io_manager // // FSM Transition Logic // - wire [2:0] io_fsm_state_after_busy = opcode_is_input ? IO_FSM_STATE_EXTRA : IO_FSM_STATE_LATENCY_POST1; + assign io_fsm_state_after_busy = opcode_is_input ? IO_FSM_STATE_EXTRA1_X : IO_FSM_STATE_LATENCY_POST1_X; always @* begin // case (io_fsm_state) - IO_FSM_STATE_IDLE: io_fsm_state_next = ena ? IO_FSM_STATE_LATENCY_PRE1 : IO_FSM_STATE_IDLE ; - IO_FSM_STATE_LATENCY_PRE1: io_fsm_state_next = IO_FSM_STATE_LATENCY_PRE2 ; - IO_FSM_STATE_LATENCY_PRE2: io_fsm_state_next = IO_FSM_STATE_BUSY ; - IO_FSM_STATE_BUSY: io_fsm_state_next = io_fsm_done ? io_fsm_state_after_busy : IO_FSM_STATE_BUSY ; - IO_FSM_STATE_EXTRA: io_fsm_state_next = IO_FSM_STATE_LATENCY_POST1 ; - IO_FSM_STATE_LATENCY_POST1: io_fsm_state_next = IO_FSM_STATE_LATENCY_POST2 ; - IO_FSM_STATE_LATENCY_POST2: io_fsm_state_next = IO_FSM_STATE_STOP ; - IO_FSM_STATE_STOP: io_fsm_state_next = IO_FSM_STATE_IDLE ; + IO_FSM_STATE_IDLE_X: io_fsm_state_next = ena ? IO_FSM_STATE_LATENCY_PRE1_X : IO_FSM_STATE_IDLE_X ; + IO_FSM_STATE_LATENCY_PRE1_X: io_fsm_state_next = IO_FSM_STATE_LATENCY_PRE2_X ; + IO_FSM_STATE_LATENCY_PRE2_X: io_fsm_state_next = IO_FSM_STATE_LATENCY_PRE3_X ; + IO_FSM_STATE_LATENCY_PRE3_X: io_fsm_state_next = IO_FSM_STATE_LATENCY_PRE4_X ; + IO_FSM_STATE_LATENCY_PRE4_X: io_fsm_state_next = IO_FSM_STATE_BUSY1_X ; + IO_FSM_STATE_BUSY1_X: io_fsm_state_next = IO_FSM_STATE_BUSY2_X ; + IO_FSM_STATE_BUSY2_X: io_fsm_state_next = io_fsm_done ? io_fsm_state_after_busy : IO_FSM_STATE_BUSY1_X; + IO_FSM_STATE_EXTRA1_X: io_fsm_state_next = IO_FSM_STATE_EXTRA2_X ; + IO_FSM_STATE_EXTRA2_X: io_fsm_state_next = IO_FSM_STATE_LATENCY_POST1_X ; + IO_FSM_STATE_LATENCY_POST1_X: io_fsm_state_next = IO_FSM_STATE_LATENCY_POST2_X ; + IO_FSM_STATE_LATENCY_POST2_X: io_fsm_state_next = IO_FSM_STATE_LATENCY_POST3_X ; + IO_FSM_STATE_LATENCY_POST3_X: io_fsm_state_next = IO_FSM_STATE_LATENCY_POST4_X ; + IO_FSM_STATE_LATENCY_POST4_X: io_fsm_state_next = IO_FSM_STATE_STOP_X ; + IO_FSM_STATE_STOP_X: io_fsm_state_next = IO_FSM_STATE_IDLE_X ; + default: io_fsm_state_next = IO_FSM_STATE_IDLE_X ; endcase // end @@ -728,25 +823,16 @@ module modexpng_io_manager // if (!rst_n) rdy_reg <= 1'b1; else case (io_fsm_state) - IO_FSM_STATE_IDLE: rdy_reg <= ~ena; - IO_FSM_STATE_STOP: rdy_reg <= 1'b1; + IO_FSM_STATE_IDLE_X: rdy_reg <= ~ena; + IO_FSM_STATE_STOP_X: rdy_reg <= 1'b1; endcase // - // BEGIN DEBUG + // Optional Debug Facility // `ifdef MODEXPNG_ENABLE_DEBUG - always @(posedge clk) - // - if (io_fsm_state == IO_FSM_STATE_STOP) begin - if (opcode_is_ladder_init) begin - $display("[step] | D | P | Q"); - $display("-------+---+---+---"); - end else if (opcode_is_ladder_step) - $display("[%4d] | %d | %d | %d", ladder_index, ladder_d_r, ladder_p_r, ladder_q_r); - end - // + `include "modexpng_io_manager_debug.vh" `endif diff --git a/rtl/modexpng_io_manager_debug.vh b/rtl/modexpng_io_manager_debug.vh new file mode 100644 index 0000000..593005b --- /dev/null +++ b/rtl/modexpng_io_manager_debug.vh @@ -0,0 +1,41 @@ +//====================================================================== +// +// Copyright (c) 2019, NORDUnet A/S All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// - Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// - Neither the name of the NORDUnet nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//====================================================================== + +always @(posedge clk) + // + if (io_fsm_state == IO_FSM_STATE_STOP_X) begin + if (opcode_is_ladder_init) begin + $display("[step] | D | P | Q"); + $display("-------+---+---+---"); + end else if (opcode_is_ladder_step) + $display("[%4d] | %d | %d | %d", ladder_index, ladder_d_r, ladder_p_r, ladder_q_r); + end |