[otbn] Small decode fixes and struct rearrangement

This places far more of the decoder signals into the specific
base/bignum structs. Those signals that are moved into the specific
structs may have had a shared meaning but are unrelated in terms of
logic (e.g. operand select for the ALUs, different decode logic for
bignum and base ISAs and different ALU muxes they control).

There are some small clean-ups around removing unused types and enums
that relate to decode.

Signed-off-by: Greg Chadwick <gac@lowrisc.org>
diff --git a/hw/ip/otbn/rtl/otbn_controller.sv b/hw/ip/otbn/rtl/otbn_controller.sv
index 9adc7e4..d962c2e 100644
--- a/hw/ip/otbn/rtl/otbn_controller.sv
+++ b/hw/ip/otbn/rtl/otbn_controller.sv
@@ -207,7 +207,7 @@
 
   // Base ALU Operand A MUX
   always_comb begin
-    unique case (insn_dec_shared_i.op_a_sel)
+    unique case (insn_dec_base_i.op_a_sel)
       OpASelRegister:
         alu_base_operation_o.operand_a = rf_base_rd_data_a_i;
       OpASelZero:
@@ -221,7 +221,7 @@
 
   // Base ALU Operand B MUX
   always_comb begin
-    unique case (insn_dec_shared_i.op_b_sel)
+    unique case (insn_dec_base_i.op_b_sel)
       OpBSelRegister:
         alu_base_operation_o.operand_b = rf_base_rd_data_b_i;
       OpBSelImmediate:
@@ -240,15 +240,13 @@
   // Register file write MUX
   // Suppress write for loads when controller isn't in stall state as load data for writeback is
   // only available in the stall state.
-  assign rf_base_wr_en_o =
-   insn_dec_shared_i.rf_we                                    &
-   ~(insn_dec_shared_i.ld_insn & (state_q != OtbnStateStall)) &
-   (insn_dec_shared_i.subset == InsnSubsetBase);
+  assign rf_base_wr_en_o = insn_dec_base_i.rf_we &
+    ~(insn_dec_shared_i.ld_insn & (state_q != OtbnStateStall));
 
   assign rf_base_wr_addr_o = insn_dec_base_i.d;
 
   always_comb begin
-    unique case (insn_dec_shared_i.rf_wdata_sel)
+    unique case (insn_dec_base_i.rf_wdata_sel)
       RfWdSelEx:
         rf_base_wr_data_o = alu_base_operation_result_i;
       RfWdSelLsu:
@@ -269,7 +267,7 @@
 
   // Base ALU Operand B MUX
   always_comb begin
-    unique case (insn_dec_shared_i.op_b_sel)
+    unique case (insn_dec_bignum_i.op_b_sel)
       OpBSelRegister:
         alu_bignum_operation_o.operand_b = rf_bignum_rd_data_b_i;
       OpBSelImmediate:
@@ -288,15 +286,12 @@
   // Suppress write for loads when controller isn't in stall state as load data for writeback is
   // only available in the stall state.
   assign rf_bignum_wr_en_o =
-    {2{insn_dec_shared_i.rf_we                                    &
-       ~(insn_dec_shared_i.ld_insn & (state_q != OtbnStateStall)) &
-       (insn_dec_shared_i.subset == InsnSubsetBignum)
-    }};
+    {2{insn_dec_bignum_i.rf_we & ~(insn_dec_shared_i.ld_insn & (state_q != OtbnStateStall))}};
 
   assign rf_bignum_wr_addr_o = insn_dec_bignum_i.d;
 
   always_comb begin
-    unique case (insn_dec_shared_i.rf_wdata_sel)
+    unique case (insn_dec_bignum_i.rf_wdata_sel)
       RfWdSelEx:
         rf_bignum_wr_data_o = alu_bignum_operation_result_i;
       RfWdSelLsu:
diff --git a/hw/ip/otbn/rtl/otbn_decoder.sv b/hw/ip/otbn/rtl/otbn_decoder.sv
index 69c1a61..46e2dcb 100644
--- a/hw/ip/otbn/rtl/otbn_decoder.sv
+++ b/hw/ip/otbn/rtl/otbn_decoder.sv
@@ -28,7 +28,8 @@
 );
 
   logic        illegal_insn;
-  logic        rf_we;
+  logic        rf_we_base;
+  logic        rf_we_bignum;
 
   logic [31:0] insn;
   logic [31:0] insn_alu;
@@ -51,7 +52,6 @@
   //////////////////////////////////////
   // Register and immediate selection //
   //////////////////////////////////////
-  imm_a_sel_base_e   imm_a_mux_sel_base; // immediate selection for operand a in base ISA
   imm_b_sel_base_e   imm_b_mux_sel_base; // immediate selection for operand b in base ISA
   shamt_sel_bignum_e shift_amt_mux_sel_bignum; // shift amount selection in bignum ISA
 
@@ -63,8 +63,11 @@
 
   alu_op_base_e   alu_operator_base;   // ALU operation selection for base ISA
   alu_op_bignum_e alu_operator_bignum; // ALU operation selection for bignum ISA
-  op_a_sel_e      alu_op_a_mux_sel;    // operand a selection: reg value, PC, immediate or zero
-  op_b_sel_e      alu_op_b_mux_sel;    // operand b selection: reg value or immediate
+
+  op_a_sel_e alu_op_a_mux_sel_base; // operand a selection for base ISA: reg value, PC or zero
+  op_b_sel_e alu_op_b_mux_sel_base; // operand b selection for base ISA: reg value or immediate
+
+  op_b_sel_e alu_op_b_mux_sel_bignum; // operand b selection for bignum ISA: reg value or immediate
 
   comparison_op_base_e comparison_operator_base;
 
@@ -106,7 +109,8 @@
   assign insn_rd = insn[11:7];
 
   insn_subset_e insn_subset;
-  rf_wd_sel_e rf_wdata_sel;
+  rf_wd_sel_e rf_wdata_sel_base;
+  rf_wd_sel_e rf_wdata_sel_bignum;
 
   logic ecall_insn;
   logic ld_insn;
@@ -147,26 +151,29 @@
     d:             insn_rd,
     i:             imm_b_base,
     alu_op:        alu_operator_base,
-    comparison_op: comparison_operator_base
+    comparison_op: comparison_operator_base,
+    op_a_sel:      alu_op_a_mux_sel_base,
+    op_b_sel:      alu_op_b_mux_sel_base,
+    rf_we:         rf_we_base,
+    rf_wdata_sel:  rf_wdata_sel_base
   };
 
   assign insn_dec_bignum_o = '{
-    a:           insn_rs1,
-    b:           insn_rs2,
-    d:           insn_rd,
-    i:           imm_i_type_bignum,
-    shift_amt:   shift_amt_bignum,
-    shift_right: shift_right_bignum,
-    flag_group:  flag_group_bignum,
-    alu_op:      alu_operator_bignum
+    a:            insn_rs1,
+    b:            insn_rs2,
+    d:            insn_rd,
+    i:            imm_i_type_bignum,
+    shift_amt:    shift_amt_bignum,
+    shift_right:  shift_right_bignum,
+    flag_group:   flag_group_bignum,
+    alu_op:       alu_operator_bignum,
+    op_b_sel:     alu_op_b_mux_sel_bignum,
+    rf_we:        rf_we_bignum,
+    rf_wdata_sel: rf_wdata_sel_bignum
   };
 
   assign insn_dec_shared_o = '{
     subset:        insn_subset,
-    op_a_sel:      alu_op_a_mux_sel,
-    op_b_sel:      alu_op_b_mux_sel,
-    rf_we:         rf_we,
-    rf_wdata_sel:  rf_wdata_sel,
     ecall_insn:    ecall_insn,
     ld_insn:       ld_insn,
     st_insn:       st_insn,
@@ -181,8 +188,12 @@
   /////////////
 
   always_comb begin
-    rf_wdata_sel          = RfWdSelEx;
-    rf_we                 = 1'b0;
+    rf_wdata_sel_base     = RfWdSelEx;
+    rf_we_base            = 1'b0;
+
+    rf_wdata_sel_bignum   = RfWdSelEx;
+    rf_we_bignum          = 1'b0;
+
     rf_ren_a              = 1'b0;
     rf_ren_b              = 1'b0;
 
@@ -204,13 +215,13 @@
 
       InsnOpcodeBaseLui: begin  // Load Upper Immediate
         insn_subset      = InsnSubsetBase;
-        rf_we            = 1'b1;
+        rf_we_base       = 1'b1;
       end
 
       InsnOpcodeBaseOpImm: begin // Register-Immediate ALU Operations
         insn_subset      = InsnSubsetBase;
         rf_ren_a         = 1'b1;
-        rf_we            = 1'b1;
+        rf_we_base       = 1'b1;
 
         unique case (insn[14:12])
           3'b000,
@@ -246,7 +257,7 @@
         insn_subset     = InsnSubsetBase;
         rf_ren_a        = 1'b1;
         rf_ren_b        = 1'b1;
-        rf_we           = 1'b1;
+        rf_we_base      = 1'b1;
         if ({insn[26], insn[13:12]} != {1'b1, 2'b01}) begin
           unique case ({insn[31:25], insn[14:12]})
             // RV32I ALU operations
@@ -272,11 +283,11 @@
       ///////////////////////
 
       InsnOpcodeBaseLoad: begin
-        insn_subset  = InsnSubsetBase;
-        ld_insn      = 1'b1;
-        rf_ren_a     = 1'b1;
-        rf_we        = 1'b1;
-        rf_wdata_sel = RfWdSelLsu;
+        insn_subset       = InsnSubsetBase;
+        ld_insn           = 1'b1;
+        rf_ren_a          = 1'b1;
+        rf_we_base        = 1'b1;
+        rf_wdata_sel_base = RfWdSelLsu;
 
         if (insn[14:12] != 3'b010) begin
           illegal_insn = 1'b1;
@@ -311,18 +322,18 @@
       end
 
       InsnOpcodeBaseJal: begin
-        insn_subset  = InsnSubsetBase;
-        jump_insn    = 1'b1;
-        rf_we        = 1'b1;
-        rf_wdata_sel = RfWdSelNextPc;
+        insn_subset       = InsnSubsetBase;
+        jump_insn         = 1'b1;
+        rf_we_base        = 1'b1;
+        rf_wdata_sel_base = RfWdSelNextPc;
       end
 
       InsnOpcodeBaseJalr: begin
-        insn_subset  = InsnSubsetBase;
-        jump_insn    = 1'b1;
-        rf_ren_a     = 1'b1;
-        rf_we        = 1'b1;
-        rf_wdata_sel = RfWdSelNextPc;
+        insn_subset       = InsnSubsetBase;
+        jump_insn         = 1'b1;
+        rf_ren_a          = 1'b1;
+        rf_we_base        = 1'b1;
+        rf_wdata_sel_base = RfWdSelNextPc;
 
         if (insn[14:12] != 3'b000) begin
           illegal_insn = 1'b1;
@@ -350,9 +361,9 @@
             illegal_insn = 1'b1;
           end
         end else begin
-          rf_we        = 1'b1;
-          rf_wdata_sel = RfWdSelIspr;
-          rf_ren_a     = 1'b1;
+          rf_we_base        = 1'b1;
+          rf_wdata_sel_base = RfWdSelIspr;
+          rf_ren_a          = 1'b1;
 
           if (insn[14:12] == 3'b001) begin
             ispr_rw_insn = 1'b1;
@@ -369,9 +380,9 @@
       ////////////////
 
       InsnOpcodeBignumArith: begin
-        insn_subset = InsnSubsetBignum;
-        rf_we       = 1'b1;
-        rf_ren_a    = 1'b1;
+        insn_subset  = InsnSubsetBignum;
+        rf_we_bignum = 1'b1;
+        rf_ren_a     = 1'b1;
 
         if (insn[14:12] != 3'b100) begin
           // All Alu instructions other than BN.ADDI/BN.SUBI
@@ -390,9 +401,9 @@
       ////////////////////////
 
       InsnOpcodeBignumShiftLogical: begin
-        insn_subset = InsnSubsetBignum;
-        rf_we       = 1'b1;
-        rf_ren_a    = 1'b1;
+        insn_subset  = InsnSubsetBignum;
+        rf_we_bignum = 1'b1;
+        rf_ren_a     = 1'b1;
 
         // BN.NOT doesn't read register B
         if (insn[14:12] != 3'b101) begin
@@ -414,9 +425,9 @@
         insn_subset = InsnSubsetBignum;
 
         if (insn[14:12] == 3'b111) begin //BN.WSRRS/BN.WSRRW
-          rf_we         = 1'b1;
-          rf_ren_a      = 1'b1;
-          rf_wdata_sel  = RfWdSelIspr;
+          rf_we_bignum        = 1'b1;
+          rf_ren_a            = 1'b1;
+          rf_wdata_sel_bignum = RfWdSelIspr;
 
           if (insn[31]) begin
             ispr_rw_insn = 1'b1;
@@ -436,7 +447,8 @@
     // NOTE: instructions can also be detected to be illegal inside the CSRs (upon accesses with
     // insufficient privileges). These cases are not handled here.
     if (illegal_insn) begin
-      rf_we           = 1'b0;
+      rf_we_base   = 1'b0;
+      rf_we_bignum = 1'b0;
     end
   end
 
@@ -446,13 +458,16 @@
 
   always_comb begin
     alu_operator_base        = AluOpBaseAdd;
-    alu_operator_bignum      = AluOpBignumAdd;
     comparison_operator_base = ComparisonOpBaseEq;
-    alu_op_a_mux_sel         = OpASelRegister;
-    alu_op_b_mux_sel         = OpBSelImmediate;
 
-    imm_a_mux_sel_base       = ImmBaseAZero;
+    alu_op_a_mux_sel_base    = OpASelRegister;
+    alu_op_b_mux_sel_base    = OpBSelImmediate;
+
     imm_b_mux_sel_base       = ImmBaseBI;
+
+    alu_operator_bignum      = AluOpBignumAdd;
+    alu_op_b_mux_sel_bignum  = OpBSelImmediate;
+
     shift_amt_mux_sel_bignum = ShamtSelBignumA;
 
     opcode_alu               = insn_opcode_e'(insn_alu[6:0]);
@@ -463,24 +478,23 @@
       //////////////
 
       InsnOpcodeBaseLui: begin  // Load Upper Immediate
-        alu_op_a_mux_sel   = OpASelZero;
-        alu_op_b_mux_sel   = OpBSelImmediate;
-        imm_a_mux_sel_base = ImmBaseAZero;
-        imm_b_mux_sel_base = ImmBaseBU;
-        alu_operator_base  = AluOpBaseAdd;
+        alu_op_a_mux_sel_base = OpASelZero;
+        alu_op_b_mux_sel_base = OpBSelImmediate;
+        imm_b_mux_sel_base    = ImmBaseBU;
+        alu_operator_base     = AluOpBaseAdd;
       end
 
       InsnOpcodeBaseAuipc: begin  // Add Upper Immediate to PC
-        alu_op_a_mux_sel   = OpASelCurrPc;
-        alu_op_b_mux_sel   = OpBSelImmediate;
-        imm_b_mux_sel_base = ImmBaseBU;
-        alu_operator_base  = AluOpBaseAdd;
+        alu_op_a_mux_sel_base = OpASelCurrPc;
+        alu_op_b_mux_sel_base = OpBSelImmediate;
+        imm_b_mux_sel_base    = ImmBaseBU;
+        alu_operator_base     = AluOpBaseAdd;
       end
 
       InsnOpcodeBaseOpImm: begin // Register-Immediate ALU Operations
-        alu_op_a_mux_sel   = OpASelRegister;
-        alu_op_b_mux_sel   = OpBSelImmediate;
-        imm_b_mux_sel_base = ImmBaseBI;
+        alu_op_a_mux_sel_base = OpASelRegister;
+        alu_op_b_mux_sel_base = OpBSelImmediate;
+        imm_b_mux_sel_base    = ImmBaseBI;
 
         unique case (insn_alu[14:12])
           3'b000: alu_operator_base = AluOpBaseAdd;  // Add Immediate
@@ -505,8 +519,8 @@
       end
 
       InsnOpcodeBaseOp: begin  // Register-Register ALU operation
-        alu_op_a_mux_sel = OpASelRegister;
-        alu_op_b_mux_sel = OpBSelRegister;
+        alu_op_a_mux_sel_base = OpASelRegister;
+        alu_op_b_mux_sel_base = OpBSelRegister;
 
         if (!insn_alu[26]) begin
           unique case ({insn_alu[31:25], insn_alu[14:12]})
@@ -529,17 +543,17 @@
       ///////////////////////
 
       InsnOpcodeBaseLoad: begin
-        alu_op_a_mux_sel   = OpASelRegister;
-        alu_op_b_mux_sel   = OpBSelImmediate;
-        alu_operator_base  = AluOpBaseAdd;
-        imm_b_mux_sel_base = ImmBaseBI;
+        alu_op_a_mux_sel_base = OpASelRegister;
+        alu_op_b_mux_sel_base = OpBSelImmediate;
+        alu_operator_base     = AluOpBaseAdd;
+        imm_b_mux_sel_base    = ImmBaseBI;
       end
 
       InsnOpcodeBaseStore: begin
-        alu_op_a_mux_sel   = OpASelRegister;
-        alu_op_b_mux_sel   = OpBSelImmediate;
-        alu_operator_base  = AluOpBaseAdd;
-        imm_b_mux_sel_base = ImmBaseBS;
+        alu_op_a_mux_sel_base = OpASelRegister;
+        alu_op_b_mux_sel_base = OpBSelImmediate;
+        alu_operator_base     = AluOpBaseAdd;
+        imm_b_mux_sel_base    = ImmBaseBS;
       end
 
       //////////////////////
@@ -547,25 +561,25 @@
       //////////////////////
 
       InsnOpcodeBaseBranch: begin
-        alu_op_a_mux_sel         = OpASelCurrPc;
-        alu_op_b_mux_sel         = OpBSelImmediate;
+        alu_op_a_mux_sel_base    = OpASelCurrPc;
+        alu_op_b_mux_sel_base    = OpBSelImmediate;
         alu_operator_base        = AluOpBaseAdd;
         imm_b_mux_sel_base       = ImmBaseBB;
         comparison_operator_base = insn_alu[12] ? ComparisonOpBaseNeq : ComparisonOpBaseEq;
       end
 
       InsnOpcodeBaseJal: begin
-        alu_op_a_mux_sel   = OpASelCurrPc;
-        alu_op_b_mux_sel   = OpBSelImmediate;
-        alu_operator_base  = AluOpBaseAdd;
-        imm_b_mux_sel_base = ImmBaseBJ;
+        alu_op_a_mux_sel_base = OpASelCurrPc;
+        alu_op_b_mux_sel_base = OpBSelImmediate;
+        alu_operator_base     = AluOpBaseAdd;
+        imm_b_mux_sel_base    = ImmBaseBJ;
       end
 
       InsnOpcodeBaseJalr: begin
-        alu_op_a_mux_sel   = OpASelRegister;
-        alu_op_b_mux_sel   = OpBSelImmediate;
-        alu_operator_base  = AluOpBaseAdd;
-        imm_b_mux_sel_base = ImmBaseBI;
+        alu_op_a_mux_sel_base = OpASelRegister;
+        alu_op_b_mux_sel_base = OpBSelImmediate;
+        alu_operator_base     = AluOpBaseAdd;
+        imm_b_mux_sel_base    = ImmBaseBI;
       end
 
       //////////////////
@@ -574,8 +588,8 @@
 
       InsnOpcodeBaseSystem: begin
         // The only instructions with System opcode that care about operands are CSR access
-        alu_op_a_mux_sel   = OpASelRegister;
-        imm_b_mux_sel_base = ImmBaseBI;
+        alu_op_a_mux_sel_base = OpASelRegister;
+        imm_b_mux_sel_base    = ImmBaseBI;
       end
       default: ;
 
@@ -584,7 +598,6 @@
       ////////////////
 
       InsnOpcodeBignumArith: begin
-        alu_op_a_mux_sel         = OpASelRegister;
         shift_amt_mux_sel_bignum = ShamtSelBignumA;
 
         unique case(insn_alu[14:12])
@@ -610,9 +623,9 @@
         endcase
 
         if (insn_alu[14:12] != 3'b100) begin
-          alu_op_b_mux_sel = OpBSelRegister;
+          alu_op_b_mux_sel_bignum = OpBSelRegister;
         end else begin
-          alu_op_b_mux_sel = OpBSelImmediate;
+          alu_op_b_mux_sel_bignum = OpBSelImmediate;
         end
       end
 
@@ -621,8 +634,7 @@
       /////////////////
 
       InsnOpcodeBignumShiftLogical: begin
-        alu_op_a_mux_sel = OpASelRegister;
-        alu_op_b_mux_sel = OpBSelRegister;
+        alu_op_b_mux_sel_bignum = OpBSelRegister;
 
         unique case(insn_alu[14:12])
           3'b010: begin
diff --git a/hw/ip/otbn/rtl/otbn_pkg.sv b/hw/ip/otbn/rtl/otbn_pkg.sv
index 45c43cb..db1cab7 100644
--- a/hw/ip/otbn/rtl/otbn_pkg.sv
+++ b/hw/ip/otbn/rtl/otbn_pkg.sv
@@ -116,8 +116,7 @@
   typedef enum logic [1:0] {
     OpASelRegister  = 'd0,
     OpASelZero = 'd1,
-    OpASelFwd = 'd2,
-    OpASelCurrPc = 'd3
+    OpASelCurrPc = 'd2
   } op_a_sel_e;
 
   // Operand b source selection
@@ -126,11 +125,6 @@
     OpBSelImmediate = 1'b1
   } op_b_sel_e;
 
-  // Immediate a selection for base ISA
-  typedef enum logic {
-    ImmBaseAZero
-  } imm_a_sel_base_e;
-
   // Immediate b selection for base ISA
   typedef enum logic [2:0] {
     ImmBaseBI,
@@ -206,21 +200,14 @@
   //`ASSERT_INIT(WsrESizeMatchesParameter_A, $bits(wsr_e) == WsrNumWidth)
 
   // Structures for decoded instructions, grouped into three:
-  // - insn_dec_shared_t - Anything that applies to both bignum and base ISAs, all fields valid when
-  // instruction is valid.
-  // - insn_dec_base_t - Anything that only applies to base ISA, fields only valid when `subset` in
-  // `insn_dec_shared_t` indicates a base ISA instruction.
-  // - insn_dec_bignum_t - Anything that only applies to bignum ISA, fields only valid when `subset` in
-  // `insn_dec_shared_t` indicates a bignum ISA instruction.
+  // - insn_dec_shared_t - Anything that applies to both bignum and base microarchitecture
+  // - insn_dec_base_t - Anything that only applies to the base side microarchitecture
+  // - insn_dec_bignum_t - Anything that only applies to bignum side microarchitecture
   //
   // TODO: The variable names are rather short, especially "i" is confusing. Think about renaming.
   //
   typedef struct packed {
     insn_subset_e   subset;
-    op_a_sel_e      op_a_sel;
-    op_b_sel_e      op_b_sel;
-    logic           rf_we;
-    rf_wd_sel_e     rf_wdata_sel;
     logic           ecall_insn;
     logic           ld_insn;
     logic           st_insn;
@@ -237,6 +224,10 @@
     logic [31:0]         i;             // Immediate
     alu_op_base_e        alu_op;
     comparison_op_base_e comparison_op;
+    op_a_sel_e           op_a_sel;
+    op_b_sel_e           op_b_sel;
+    logic                rf_we;
+    rf_wd_sel_e          rf_wdata_sel;
   } insn_dec_base_t;
 
   typedef struct packed {
@@ -251,6 +242,9 @@
 
     flag_group_t             flag_group;
     alu_op_bignum_e          alu_op;
+    op_b_sel_e               op_b_sel;
+    logic                    rf_we;
+    rf_wd_sel_e              rf_wdata_sel;
   } insn_dec_bignum_t;
 
   typedef struct packed {