[Cryptech-Commits] [core/math/modexpng] 72/92: The I/O manager has to work in sync with the general worker module. Made the necessary changes to make it work after the general worker update. Also moved debug simulation-time code into a separate file.

git at cryptech.is git at cryptech.is
Sat Mar 14 18:19:51 UTC 2020


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository core/math/modexpng.

commit 76f89d63c8f06bb61ea7db42eddecc3498c5c73e
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Tue Jan 21 00:07:36 2020 +0300

    The I/O manager has to work in sync with the general worker module. Made the
    necessary changes to make it work after the general worker update. Also moved
    debug simulation-time code into a separate file.
---
 rtl/modexpng_io_manager.v        | 364 ++++++++++++++++++++++++---------------
 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,42 +641,70 @@ 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;
@@ -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



More information about the Commits mailing list