[Cryptech-Commits] [core/pkey/ed25519] 04/04: Incorporated latest microcode from the C model. Passes all the test vectors from the RFC. Needs minor cleanup.

git at cryptech.is git at cryptech.is
Mon Oct 15 13:18:11 UTC 2018


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

meisterpaul1 at yandex.ru pushed a commit to branch master
in repository core/pkey/ed25519.

commit 7cbc1fec6f39e377a8d945c3aad183b4cffeadd3
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Mon Oct 15 15:54:47 2018 +0300

    Incorporated latest microcode from the C model. Passes all the test vectors
    from the RFC. Needs minor cleanup.
---
 bench/tb_base_point_multiplier.v |  71 +++++--
 rtl/ed25519_microcode.v          | 422 +++++++++++++++++++++++++++++++++++----
 rtl/ed25519_multiplier.v         | 121 +++++++++--
 rtl/ed25519_uop.v                |  17 +-
 4 files changed, 544 insertions(+), 87 deletions(-)

diff --git a/bench/tb_base_point_multiplier.v b/bench/tb_base_point_multiplier.v
index 7d8de3b..f4a60ae 100644
--- a/bench/tb_base_point_multiplier.v
+++ b/bench/tb_base_point_multiplier.v
@@ -152,6 +152,18 @@ module tb_base_point_multiplier;
         $display("1. Q = d * G...");
         test_base_point_multiplier(ED25519_D_HASHED_LSB_1, ED25519_Q_Y_1);
         
+        $display("2. Q = d * G...");
+        test_base_point_multiplier(ED25519_D_HASHED_LSB_2, ED25519_Q_Y_2);
+        
+        $display("3. Q = d * G...");
+        test_base_point_multiplier(ED25519_D_HASHED_LSB_3, ED25519_Q_Y_3);
+        
+        $display("4. Q = d * G...");
+        test_base_point_multiplier(ED25519_D_HASHED_LSB_4, ED25519_Q_Y_4);
+        
+        $display("5. Q = d * G...");
+        test_base_point_multiplier(ED25519_D_HASHED_LSB_5, ED25519_Q_Y_5);
+        
             /* print result */
         if (ok) $display("tb_base_point_multiplier: SUCCESS");
         else    $display("tb_base_point_multiplier: FAILURE");
@@ -174,6 +186,7 @@ module tb_base_point_multiplier;
         reg     [255:0] k_shreg;
         reg     [255:0] qy_shreg;
         reg             qy_ok;
+        reg     [255:0] qy_shreg_rev;
         
         integer         w;
 
@@ -223,28 +236,46 @@ module tb_base_point_multiplier;
                 /* wait for operation to complete */
             while (!rdy) #`CLOCK_PERIOD;
             
-//                /* read result */
-//            for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin
-//                
-//                    /* set address */
-//                tb_qxy_addr = w[WORD_COUNTER_WIDTH-1:0];
-//                
-//                    /* wait for 1 clock tick */
-//                #10;
-//                
-//                    /* store data word */
-//                qx_shreg = {tb_qx_data, qx_shreg[255:32]};
-//                qy_shreg = {tb_qy_data, qy_shreg[255:32]};
-//
-//            end
-//            
-//                /* compare */
-//            q_ok =  (qx_shreg == qx) &&
-//                        (qy_shreg == qy);
-//
+                /* read result */
+            for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin
+                
+                    /* set address */
+                tb_qy_addr = w[WORD_COUNTER_WIDTH-1:0];
+                
+                    /* wait for 1 clock tick */
+                #`CLOCK_PERIOD
+                
+                    /* store data word */
+                qy_shreg = {tb_qy_data, qy_shreg[255:32]};
+
+            end
+            
+                /* for some reason reference values in the RFC have different
+                 * byte order, thus we need to reverse our result */
+                 
+            #`CLOCK_PERIOD;
+                 
+            for (w=0; w<4*OPERAND_NUM_WORDS; w=w+1) begin
+                
+                /* shift right by 8 bits */
+                qy_shreg     = {qy_shreg[7:0], qy_shreg[255:8]};
+                
+                /* shift left by 8 bits */
+                qy_shreg_rev = {qy_shreg_rev[255-8:0], qy_shreg[255-:8]};
+            end
+            
+            
+                /* compare */
+            qy_ok = (qy_shreg_rev == qy);
+
                 /* display results */
             if (qy_ok)  $display("test_base_point_multiplier(): CORRECT RESULT");
-            else        $display("test_base_point_multiplier(): WRONG RESULT");
+            else begin
+                $display("test_base_point_multiplier(): WRONG RESULT");
+                $display("REF: %x", qy);
+                $display("OUT: %x", qy_shreg_rev);
+                $display("XOR: %x", qy_shreg_rev ^ qy);
+            end
             
                 /* update global flag */
             ok = ok & qy_ok;
diff --git a/rtl/ed25519_microcode.v b/rtl/ed25519_microcode.v
index 95f8fec..ec36e3f 100644
--- a/rtl/ed25519_microcode.v
+++ b/rtl/ed25519_microcode.v
@@ -28,8 +28,7 @@
 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 //
-//======================================================================`timescale 1ns  1ps
-
+//======================================================================
 
 module ed25519_microcode
 (
@@ -43,46 +42,385 @@ module ed25519_microcode
     always @(posedge clk)
         //
         case (addr)
-    
-            // Initialization
-            6'd00:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_X};
-            6'd01:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE,  UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Y};
-            6'd02:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE,  UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Z};
-            6'd03:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_T};
-            
-            6'd04:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_G_X,  UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_X};
-            6'd05:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_G_Y,  UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_Y};
-            6'd06:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE,  UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_Z};
-            6'd07:  data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_G_T,  UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_T};
-            
-            6'd08:  data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE,   UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
-            
-            // Before Round when k = 1
-            6'd09:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_X};
-            6'd10:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Y};
-            6'd11:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Z};
-            6'd12:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_T};
-            
-            6'd13:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_X};
-            6'd14:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Y};
-            6'd15:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Z};
-            6'd16:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_T};
-            
-            6'd17:  data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE,   UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
-			
-            // Before Round when k = 0
-            6'd18:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_X};
-            6'd19:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Y};
-            6'd20:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Z};
-            6'd21:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_T};
-            
-            6'd22:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_X};
-            6'd23:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Y};
-            6'd24:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Z};
-            6'd25:  data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_T};
-            
-            6'd26:  data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE,   UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};			
 
-        endcase
+            // PREPARE
+            9'd000: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_X};
+            9'd001: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Y};
+            9'd002: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Z};
+            9'd003: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_T};
+            9'd004: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_G_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_X};
+            9'd005: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_G_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_Y};
+            9'd006: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_Z};
+            9'd007: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_G_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_T};
+            9'd008: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // BEFORE_ROUND_K0
+            9'd009: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_X};
+            9'd010: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Y};
+            9'd011: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Z};
+            9'd012: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_T};
+            9'd013: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_X};
+            9'd014: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Y};
+            9'd015: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Z};
+            9'd016: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_T};
+            9'd017: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // BEFORE_ROUND_K1
+            9'd018: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_X};
+            9'd019: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Y};
+            9'd020: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_Z};
+            9'd021: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_U_T};
+            9'd022: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_X};
+            9'd023: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Y};
+            9'd024: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_Z};
+            9'd025: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R1_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_V_T};
+            9'd026: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // DURING_ROUND
+            9'd027: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_U_X, UOP_OPERAND_CYCLE_U_X, UOP_OPERAND_PROC_A};
+            9'd028: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_U_Y, UOP_OPERAND_CYCLE_U_Y, UOP_OPERAND_PROC_B};
+            9'd029: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_U_Z, UOP_OPERAND_CYCLE_U_Z, UOP_OPERAND_PROC_I};
+            9'd030: data <= {UOP_OPCODE_ADD, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_C};
+            9'd031: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_U_X, UOP_OPERAND_CYCLE_U_Y, UOP_OPERAND_PROC_I};
+            9'd032: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_D};
+            9'd033: data <= {UOP_OPCODE_ADD, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_A, UOP_OPERAND_PROC_B, UOP_OPERAND_PROC_H};
+            9'd034: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_H, UOP_OPERAND_PROC_D, UOP_OPERAND_PROC_E};
+            9'd035: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_A, UOP_OPERAND_PROC_B, UOP_OPERAND_PROC_G};
+            9'd036: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_C, UOP_OPERAND_PROC_G, UOP_OPERAND_PROC_F};
+            9'd037: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_G, UOP_OPERAND_DONTCARE, UOP_OPERAND_PROC_G};
+            9'd038: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_H, UOP_OPERAND_DONTCARE, UOP_OPERAND_PROC_H};
+            9'd039: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_E, UOP_OPERAND_PROC_F, UOP_OPERAND_CYCLE_S_X};
+            9'd040: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_G, UOP_OPERAND_PROC_H, UOP_OPERAND_CYCLE_S_Y};
+            9'd041: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_E, UOP_OPERAND_PROC_H, UOP_OPERAND_CYCLE_S_T};
+            9'd042: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_F, UOP_OPERAND_PROC_G, UOP_OPERAND_CYCLE_S_Z};
+            9'd043: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_S_Y, UOP_OPERAND_CYCLE_S_X, UOP_OPERAND_PROC_I};
+            9'd044: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_V_Y, UOP_OPERAND_CYCLE_V_X, UOP_OPERAND_PROC_J};
+            9'd045: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_J, UOP_OPERAND_PROC_A};
+            9'd046: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_S_Y, UOP_OPERAND_CYCLE_S_X, UOP_OPERAND_PROC_I};
+            9'd047: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_V_Y, UOP_OPERAND_CYCLE_V_X, UOP_OPERAND_PROC_J};
+            9'd048: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_J, UOP_OPERAND_PROC_B};
+            9'd049: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_S_Z, UOP_OPERAND_CYCLE_V_T, UOP_OPERAND_PROC_I};
+            9'd050: data <= {UOP_OPCODE_ADD, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_C};
+            9'd051: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_S_T, UOP_OPERAND_CYCLE_V_Z, UOP_OPERAND_PROC_I};
+            9'd052: data <= {UOP_OPCODE_ADD, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_I, UOP_OPERAND_PROC_D};
+            9'd053: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_C, UOP_OPERAND_PROC_D, UOP_OPERAND_PROC_E};
+            9'd054: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_B, UOP_OPERAND_PROC_A, UOP_OPERAND_PROC_F};
+            9'd055: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_B, UOP_OPERAND_PROC_A, UOP_OPERAND_PROC_G};
+            9'd056: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_PROC_D, UOP_OPERAND_PROC_C, UOP_OPERAND_PROC_H};
+            9'd057: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_E, UOP_OPERAND_PROC_F, UOP_OPERAND_CYCLE_T_X};
+            9'd058: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_G, UOP_OPERAND_PROC_H, UOP_OPERAND_CYCLE_T_Y};
+            9'd059: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_E, UOP_OPERAND_PROC_H, UOP_OPERAND_CYCLE_T_T};
+            9'd060: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_PROC_F, UOP_OPERAND_PROC_G, UOP_OPERAND_CYCLE_T_Z};
+            9'd061: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // AFTER_ROUND_K0
+            9'd062: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_X};
+            9'd063: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_Y};
+            9'd064: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_Z};
+            9'd065: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R1_T};
+            9'd066: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // AFTER_ROUND_K1
+            9'd067: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_X};
+            9'd068: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Y};
+            9'd069: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Z};
+            9'd070: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T_T, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_T};
+            9'd071: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // BEFORE_INVERSION
+            9'd072: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Z};
+            9'd073: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_R0_Z, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_1};
+            9'd074: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // DURING_INVERSION
+            9'd075: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_1, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_1};
+            9'd076: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_1, UOP_OPERAND_INVERT_T_1, UOP_OPERAND_INVERT_T_10};
+            9'd077: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_T_10, UOP_OPERAND_INVERT_T_10, UOP_OPERAND_INVERT_R1};
+            9'd078: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd079: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_T_1, UOP_OPERAND_INVERT_T_1001};
+            9'd080: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_T_10, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_10};
+            9'd081: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_1001, UOP_OPERAND_INVERT_T_10, UOP_OPERAND_INVERT_T_1011};
+            9'd082: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_T_1011, UOP_OPERAND_INVERT_T_1011, UOP_OPERAND_INVERT_R1};
+            9'd083: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_T_1001, UOP_OPERAND_INVERT_T_X5};
+            9'd084: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_T_X5, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_R1};
+            9'd085: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd086: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd087: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd088: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd089: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd090: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_T_X5, UOP_OPERAND_INVERT_T_X10};
+            9'd091: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X10, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_R1};
+            9'd092: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X10, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_X10};
+            9'd093: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd094: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd095: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd096: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd097: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd098: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd099: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd100: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd101: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd102: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd103: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_T_X10, UOP_OPERAND_INVERT_T_X20};
+            9'd104: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X20, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_R1};
+            9'd105: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X20, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_X20};
+            9'd106: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd107: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd108: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd109: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd110: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd111: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd112: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd113: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd114: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd115: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd116: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd117: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd118: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd119: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd120: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd121: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd122: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd123: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd124: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd125: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd126: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_T_X20, UOP_OPERAND_INVERT_T_X40};
+            9'd127: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X40, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_R1};
+            9'd128: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd129: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd130: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd131: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd132: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd133: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd134: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd135: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd136: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd137: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd138: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_T_X10, UOP_OPERAND_INVERT_T_X50};
+            9'd139: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X50, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_R1};
+            9'd140: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X50, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_X50};
+            9'd141: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd142: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd143: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd144: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd145: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd146: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd147: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd148: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd149: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd150: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd151: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd152: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd153: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd154: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd155: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd156: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd157: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd158: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd159: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd160: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd161: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd162: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd163: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd164: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd165: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd166: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd167: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd168: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd169: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd170: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd171: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd172: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd173: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd174: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd175: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd176: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd177: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd178: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd179: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd180: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd181: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd182: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd183: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd184: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd185: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd186: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd187: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd188: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd189: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd190: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd191: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_T_X50, UOP_OPERAND_INVERT_T_X100};
+            9'd192: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X100, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_R1};
+            9'd193: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_T_X100, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_X100};
+            9'd194: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd195: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd196: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd197: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd198: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd199: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd200: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd201: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd202: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd203: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd204: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd205: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd206: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd207: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd208: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd209: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd210: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd211: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd212: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd213: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd214: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd215: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd216: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd217: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd218: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd219: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd220: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd221: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd222: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd223: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd224: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd225: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd226: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd227: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd228: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd229: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd230: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd231: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd232: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd233: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd234: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd235: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd236: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd237: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd238: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd239: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd240: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd241: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd242: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd243: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd244: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd245: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd246: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd247: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd248: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd249: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd250: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd251: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd252: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd253: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd254: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd255: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd256: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd257: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd258: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd259: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd260: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd261: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd262: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd263: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd264: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd265: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd266: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd267: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd268: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd269: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd270: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd271: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd272: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd273: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd274: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd275: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd276: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd277: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd278: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd279: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd280: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd281: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd282: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd283: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd284: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd285: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd286: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd287: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd288: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd289: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd290: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd291: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd292: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd293: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd294: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_T_X100, UOP_OPERAND_INVERT_R2};
+            9'd295: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd296: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd297: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd298: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd299: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd300: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd301: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd302: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd303: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd304: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd305: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd306: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd307: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd308: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd309: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd310: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd311: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd312: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd313: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd314: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd315: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd316: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd317: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd318: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd319: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd320: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd321: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd322: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd323: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd324: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd325: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd326: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd327: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd328: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd329: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd330: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd331: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd332: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd333: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd334: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd335: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd336: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd337: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd338: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd339: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd340: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd341: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd342: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd343: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd344: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd345: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_T_X50, UOP_OPERAND_INVERT_R1};
+            9'd346: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd347: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd348: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd349: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+            9'd350: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+            9'd351: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_T_1011, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_T_1011};
+            9'd352: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_T_1011, UOP_OPERAND_INVERT_R1};
+            9'd353: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // AFTER_INVERSION
+            9'd354: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_R1};
+            9'd355: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_CYCLE_R0_X, UOP_OPERAND_CYCLE_R0_X};
+            9'd356: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_CYCLE_R0_Y, UOP_OPERAND_CYCLE_R0_Y};
+            9'd357: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // FINAL_REDUCTION
+            9'd358: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_R0_X, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_CYCLE_R0_X};
+            9'd359: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_R0_Y, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_CYCLE_R0_Y};
+            9'd360: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // HANDLE_SIGN
+            9'd361: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_X, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_X};
+            9'd362: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+            // OUTPUT
+            9'd363: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_R0_Y, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_R0_Y};
+            9'd364: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+
+    endcase
 
 endmodule
diff --git a/rtl/ed25519_multiplier.v b/rtl/ed25519_multiplier.v
index d6960ec..31a4b18 100644
--- a/rtl/ed25519_multiplier.v
+++ b/rtl/ed25519_multiplier.v
@@ -72,19 +72,31 @@ module ed25519_multiplier
     //
     // FSM
     //
-    localparam [3:0] FSM_STATE_IDLE                 = 4'd00;
-    localparam [3:0] FSM_STATE_PREPARE_TRIG         = 4'd01;
-    localparam [3:0] FSM_STATE_PREPARE_WAIT         = 4'd02;
-    localparam [3:0] FSM_STATE_BEFORE_ROUND_TRIG    = 4'd03;
-    localparam [3:0] FSM_STATE_BEFORE_ROUND_WAIT    = 4'd04;
-    localparam [3:0] FSM_STATE_DURING_ROUND_TRIG    = 4'd05;
-    localparam [3:0] FSM_STATE_DURING_ROUND_WAIT    = 4'd06;
-    localparam [3:0] FSM_STATE_AFTER_ROUND_TRIG     = 4'd07;
-    localparam [3:0] FSM_STATE_AFTER_ROUND_WAIT     = 4'd08;
-    localparam [3:0] FSM_STATE_DONE                 = 4'd15;
-
-    reg [3:0] fsm_state = FSM_STATE_IDLE;
-    reg [3:0] fsm_state_next;
+    localparam [4:0] FSM_STATE_IDLE                 = 5'd00;
+    localparam [4:0] FSM_STATE_PREPARE_TRIG         = 5'd01;
+    localparam [4:0] FSM_STATE_PREPARE_WAIT         = 5'd02;
+    localparam [4:0] FSM_STATE_BEFORE_ROUND_TRIG    = 5'd03;
+    localparam [4:0] FSM_STATE_BEFORE_ROUND_WAIT    = 5'd04;
+    localparam [4:0] FSM_STATE_DURING_ROUND_TRIG    = 5'd05;
+    localparam [4:0] FSM_STATE_DURING_ROUND_WAIT    = 5'd06;
+    localparam [4:0] FSM_STATE_AFTER_ROUND_TRIG     = 5'd07;
+    localparam [4:0] FSM_STATE_AFTER_ROUND_WAIT     = 5'd08;
+    localparam [4:0] FSM_STATE_BEFORE_INVERT_TRIG   = 5'd09;
+    localparam [4:0] FSM_STATE_BEFORE_INVERT_WAIT   = 5'd10;
+    localparam [4:0] FSM_STATE_DURING_INVERT_TRIG   = 5'd11;
+    localparam [4:0] FSM_STATE_DURING_INVERT_WAIT   = 5'd12;
+    localparam [4:0] FSM_STATE_AFTER_INVERT_TRIG    = 5'd13;
+    localparam [4:0] FSM_STATE_AFTER_INVERT_WAIT    = 5'd14;
+    localparam [4:0] FSM_STATE_FINAL_REDUCE_TRIG    = 5'd15;
+    localparam [4:0] FSM_STATE_FINAL_REDUCE_WAIT    = 5'd16;
+    localparam [4:0] FSM_STATE_HANDLE_SIGN_TRIG     = 5'd17;
+    localparam [4:0] FSM_STATE_HANDLE_SIGN_WAIT     = 5'd18;
+    localparam [4:0] FSM_STATE_OUTPUT_TRIG          = 5'd19;
+    localparam [4:0] FSM_STATE_OUTPUT_WAIT          = 5'd20;
+    localparam [4:0] FSM_STATE_DONE                 = 5'd31;
+
+    reg [4:0] fsm_state = FSM_STATE_IDLE;
+    reg [4:0] fsm_state_next;
 
 
     //
@@ -114,7 +126,13 @@ module ed25519_multiplier
             FSM_STATE_PREPARE_TRIG,
             FSM_STATE_BEFORE_ROUND_TRIG,
             FSM_STATE_DURING_ROUND_TRIG,
-            FSM_STATE_AFTER_ROUND_TRIG:     worker_trig <= 1'b1;
+            FSM_STATE_AFTER_ROUND_TRIG,
+            FSM_STATE_BEFORE_INVERT_TRIG,
+            FSM_STATE_DURING_INVERT_TRIG,
+            FSM_STATE_AFTER_INVERT_TRIG,
+            FSM_STATE_FINAL_REDUCE_TRIG,
+            FSM_STATE_HANDLE_SIGN_TRIG,
+            FSM_STATE_OUTPUT_TRIG:          worker_trig <= 1'b1;
             default:                        worker_trig <= 1'b0;
         endcase
         
@@ -134,10 +152,8 @@ module ed25519_multiplier
     // Final Round Detection Logic
     //
     wire [ 3: 0] fsm_state_after_round = (bit_counter != bit_counter_zero) ?
-        FSM_STATE_BEFORE_ROUND_TRIG : FSM_STATE_DONE;
-
-
-  
+        FSM_STATE_BEFORE_ROUND_TRIG : FSM_STATE_BEFORE_INVERT_TRIG;
+        
 
     //
     // K Latch
@@ -171,6 +187,14 @@ module ed25519_multiplier
         case (fsm_state)
             FSM_STATE_PREPARE_TRIG:         worker_offset <= UOP_OFFSET_PREPARE;
             FSM_STATE_BEFORE_ROUND_TRIG:    worker_offset <= k_din_shreg[0] ? UOP_OFFSET_BEFORE_ROUND_K1 : UOP_OFFSET_BEFORE_ROUND_K0;
+            FSM_STATE_DURING_ROUND_TRIG:    worker_offset <= UOP_OFFSET_DURING_ROUND;
+            FSM_STATE_AFTER_ROUND_TRIG:     worker_offset <= k_din_shreg[0] ? UOP_OFFSET_AFTER_ROUND_K1 : UOP_OFFSET_AFTER_ROUND_K0;
+            FSM_STATE_BEFORE_INVERT_TRIG:   worker_offset <= UOP_OFFSET_BEFORE_INVERSION;
+            FSM_STATE_DURING_INVERT_TRIG:   worker_offset <= UOP_OFFSET_DURING_INVERSION;
+            FSM_STATE_AFTER_INVERT_TRIG:    worker_offset <= UOP_OFFSET_AFTER_INVERSION;
+            FSM_STATE_FINAL_REDUCE_TRIG:    worker_offset <= UOP_OFFSET_FINAL_REDUCTION;
+            FSM_STATE_HANDLE_SIGN_TRIG:     worker_offset <= UOP_OFFSET_HANDLE_SIGN;
+            FSM_STATE_OUTPUT_TRIG:          worker_offset <= UOP_OFFSET_OUTPUT;
             default:                        worker_offset <= {UOP_ADDR_WIDTH{1'bX}};
         endcase
         
@@ -207,6 +231,24 @@ module ed25519_multiplier
             FSM_STATE_AFTER_ROUND_TRIG:     fsm_state_next = FSM_STATE_AFTER_ROUND_WAIT;
             FSM_STATE_AFTER_ROUND_WAIT:     fsm_state_next = fsm_wait_done ? fsm_state_after_round : FSM_STATE_AFTER_ROUND_WAIT;
 
+            FSM_STATE_BEFORE_INVERT_TRIG:   fsm_state_next = FSM_STATE_BEFORE_INVERT_WAIT;
+            FSM_STATE_BEFORE_INVERT_WAIT:   fsm_state_next = fsm_wait_done ? FSM_STATE_DURING_INVERT_TRIG : FSM_STATE_BEFORE_INVERT_WAIT;
+            
+            FSM_STATE_DURING_INVERT_TRIG:   fsm_state_next = FSM_STATE_DURING_INVERT_WAIT;
+            FSM_STATE_DURING_INVERT_WAIT:   fsm_state_next = fsm_wait_done ? FSM_STATE_AFTER_INVERT_TRIG : FSM_STATE_DURING_INVERT_WAIT;
+            
+            FSM_STATE_AFTER_INVERT_TRIG:    fsm_state_next = FSM_STATE_AFTER_INVERT_WAIT;
+            FSM_STATE_AFTER_INVERT_WAIT:    fsm_state_next = fsm_wait_done ? FSM_STATE_FINAL_REDUCE_TRIG : FSM_STATE_AFTER_INVERT_WAIT;
+            
+            FSM_STATE_FINAL_REDUCE_TRIG:    fsm_state_next = FSM_STATE_FINAL_REDUCE_WAIT;
+            FSM_STATE_FINAL_REDUCE_WAIT:    fsm_state_next = fsm_wait_done ? FSM_STATE_HANDLE_SIGN_TRIG : FSM_STATE_FINAL_REDUCE_WAIT;
+            
+            FSM_STATE_HANDLE_SIGN_TRIG:     fsm_state_next = FSM_STATE_HANDLE_SIGN_WAIT;
+            FSM_STATE_HANDLE_SIGN_WAIT:     fsm_state_next = fsm_wait_done ? FSM_STATE_OUTPUT_TRIG : FSM_STATE_HANDLE_SIGN_WAIT;
+
+            FSM_STATE_OUTPUT_TRIG:          fsm_state_next = FSM_STATE_OUTPUT_WAIT;
+            FSM_STATE_OUTPUT_WAIT:          fsm_state_next = fsm_wait_done ? FSM_STATE_DONE : FSM_STATE_OUTPUT_WAIT;
+
             FSM_STATE_DONE:                 fsm_state_next = FSM_STATE_IDLE;
 
         endcase
@@ -214,16 +256,53 @@ module ed25519_multiplier
     end
 
 
+	//
+	// Debug
+	//
+    wire debug_dump_now = fsm_state == FSM_STATE_OUTPUT_TRIG;
+	
+	reg [6:0] debug_dump_addr1 = {1'bX, UOP_OPERAND_INVERT_R1};
+	reg [6:0] debug_dump_addr2 = {1'b0, UOP_OPERAND_CYCLE_R0_X};
+	reg [6:0] debug_dump_addr3 = {1'b0, UOP_OPERAND_CYCLE_R0_Y};
+	reg [6:0] debug_dump_addr4 = {1'bX, UOP_OPERAND_CYCLE_R0_T};
+	reg [6:0] debug_dump_addr5 = {1'bX, UOP_OPERAND_CYCLE_R1_X};
+	reg [6:0] debug_dump_addr6 = {1'bX, UOP_OPERAND_CYCLE_R1_Y};
+	reg [6:0] debug_dump_addr7 = {1'bX, UOP_OPERAND_CYCLE_R1_Z};
+	reg [6:0] debug_dump_addr8 = {1'bX, UOP_OPERAND_CYCLE_R1_T};
+
     //
     // Worker
     //
+    
+    wire worker_final_reduce = fsm_state == FSM_STATE_FINAL_REDUCE_WAIT;
+    wire worker_handle_sign  = fsm_state == FSM_STATE_HANDLE_SIGN_WAIT;
+    wire worker_output_now   = fsm_state == FSM_STATE_OUTPUT_WAIT;
+    
     ed25519_worker uop_worker
     (
         .clk        (clk),
         .rst_n      (rst_n),
-        .ena        (worker_trig),
-        .rdy        (worker_done),
-        .uop_offset (worker_offset)
+        .debug_dump_now		(debug_dump_now),
+
+        .debug_dump_addr1	(debug_dump_addr1),
+        .debug_dump_addr2	(debug_dump_addr2),
+        .debug_dump_addr3	(debug_dump_addr3),
+        .debug_dump_addr4	(debug_dump_addr4),
+        .debug_dump_addr5	(debug_dump_addr5),
+        .debug_dump_addr6	(debug_dump_addr6),
+        .debug_dump_addr7	(debug_dump_addr7),
+        .debug_dump_addr8	(debug_dump_addr8),
+		  
+        .ena            (worker_trig),
+        .rdy            (worker_done),
+        .uop_offset     (worker_offset),
+        .final_reduce   (worker_final_reduce),
+        .handle_sign    (worker_handle_sign),
+        .output_now     (worker_output_now),
+        
+        .y_addr         (qy_addr),
+        .y_dout         (qy_dout),
+        .y_wren         (qy_wren)
     );
 
 
diff --git a/rtl/ed25519_uop.v b/rtl/ed25519_uop.v
index 4b744c6..12b9e10 100644
--- a/rtl/ed25519_uop.v
+++ b/rtl/ed25519_uop.v
@@ -30,13 +30,22 @@
 //
 //======================================================================
 
-localparam integer UOP_ADDR_WIDTH    = 6;    // 2 ^ 6 = 64 instructions
+localparam integer UOP_ADDR_WIDTH    = 9;    // 2 ^ 9 = max 512 instructions
 
 localparam integer UOP_DATA_WIDTH = 5 + 1 + 3 * 6;  // opcode + banks + 3 * operand (2 * src + dst)
 
-localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_PREPARE          = 6'd00;
-localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_BEFORE_ROUND_K1  = 6'd09;
-localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_BEFORE_ROUND_K0  = 6'd18;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_PREPARE          = 9'd000;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_BEFORE_ROUND_K0  = 9'd009;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_BEFORE_ROUND_K1  = 9'd018;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_DURING_ROUND     = 9'd027;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_AFTER_ROUND_K0   = 9'd062;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_AFTER_ROUND_K1   = 9'd067;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_BEFORE_INVERSION = 9'd072;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_DURING_INVERSION = 9'd075;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_AFTER_INVERSION  = 9'd354;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_FINAL_REDUCTION  = 9'd358;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_HANDLE_SIGN      = 9'd361;
+localparam [UOP_ADDR_WIDTH-1:0] UOP_OFFSET_OUTPUT           = 9'd363;
 
 localparam [4:0] UOP_OPCODE_COPY    = 5'b00001;
 localparam [4:0] UOP_OPCODE_ADD     = 5'b00010;



More information about the Commits mailing list