[otp_ctrl] Update all FSMs to use prim_flop for the state

Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv
index cb56600..1405d5d 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_dai.sv
@@ -75,7 +75,7 @@
   // DAI Control FSM //
   /////////////////////
 
-  // Encoding generated with ./sparse-fsm-encode -d 5 -m 20 -n 12
+  // Encoding generated with ./sparse-fsm-encode.py -d 5 -m 20 -n 12 -s 3011551511
   // Hamming distance histogram:
   //
   // 0:  --
@@ -83,11 +83,11 @@
   // 2:  --
   // 3:  --
   // 4:  --
-  // 5:  ||||||||||||||| (30.53%)
-  // 6:  |||||||||||||||||||| (38.42%)
+  // 5:  |||||||||||||||||| (32.11%)
+  // 6:  |||||||||||||||||||| (35.26%)
   // 7:  |||||||| (15.79%)
-  // 8:  |||| (8.42%)
-  // 9:  | (3.68%)
+  // 8:  |||||| (11.58%)
+  // 9:  | (2.11%)
   // 10:  (1.05%)
   // 11: | (2.11%)
   // 12: --
@@ -95,27 +95,28 @@
   // Minimum Hamming distance: 5
   // Maximum Hamming distance: 11
   //
-  typedef enum logic [11:0] {
-    ResetSt       = 12'b000000011100,
-    InitOtpSt     = 12'b010011000101,
-    InitPartSt    = 12'b101011010111,
-    IdleSt        = 12'b000010001011,
-    ErrorSt       = 12'b010010110000,
-    ReadSt        = 12'b111110000001,
-    ReadWaitSt    = 12'b001111100011,
-    DescrSt       = 12'b100101000110,
-    DescrWaitSt   = 12'b011000000010,
-    WriteSt       = 12'b001100111010,
-    WriteWaitSt   = 12'b110111101111,
-    ScrSt         = 12'b101010101000,
-    ScrWaitSt     = 12'b111110011110,
-    DigClrSt      = 12'b011101110100,
-    DigReadSt     = 12'b001101001101,
-    DigReadWaitSt = 12'b111001111001,
-    DigSt         = 12'b100111011000,
-    DigPadSt      = 12'b100000100101,
-    DigFinSt      = 12'b010101010011,
-    DigWaitSt     = 12'b010100101001
+  parameter int StateWidth = 12;
+  typedef enum logic [StateWidth-1:0] {
+    ResetSt       = 12'b001000011011,
+    InitOtpSt     = 12'b101111001001,
+    InitPartSt    = 12'b101010100111,
+    IdleSt        = 12'b110100110101,
+    ErrorSt       = 12'b100011010000,
+    ReadSt        = 12'b111001010110,
+    ReadWaitSt    = 12'b000101100111,
+    DescrSt       = 12'b110001001101,
+    DescrWaitSt   = 12'b010000110010,
+    WriteSt       = 12'b101101111100,
+    WriteWaitSt   = 12'b100100101010,
+    ScrSt         = 12'b111110010011,
+    ScrWaitSt     = 12'b010110011000,
+    DigClrSt      = 12'b011100001110,
+    DigReadSt     = 12'b011001101000,
+    DigReadWaitSt = 12'b000011111110,
+    DigSt         = 12'b000010101001,
+    DigPadSt      = 12'b000000000100,
+    DigFinSt      = 12'b010011000011,
+    DigWaitSt     = 12'b011011110101
   } state_e;
 
   typedef enum logic [1:0] {
@@ -623,15 +624,25 @@
   // Registers //
   ///////////////
 
+  // This primitive is used to place a size-only constraint on the
+  // flops in order to prevent FSM state encoding optimizations.
+  prim_flop #(
+    .Width(StateWidth),
+    .ResetValue(StateWidth'(ResetSt))
+  ) u_state_regs (
+    .clk_i,
+    .rst_ni,
+    .d_i ( state_d ),
+    .q_o ( state_q )
+  );
+
   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
     if (!rst_ni) begin
-      state_q        <= ResetSt;
       error_q        <= NoErr;
-      cnt_q         <= '0;
+      cnt_q          <= '0;
       data_q         <= '0;
       base_sel_q     <= DaiOffset;
     end else begin
-      state_q        <= state_d;
       error_q        <= error_d;
       cnt_q          <= cnt_d;
       base_sel_q     <= base_sel_d;
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv
index 76fdb98..8947989 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_lci.sv
@@ -59,7 +59,7 @@
   // Controller FSM //
   ////////////////////
 
-  // Encoding generated with ./sparse-fsm-encode -d 5 -m 5 -n 9
+  // Encoding generated with ./sparse-fsm-encode.py -d 5 -m 5 -n 9 -s 558234734
   // Hamming distance histogram:
   //
   // 0: --
@@ -76,12 +76,13 @@
   // Minimum Hamming distance: 5
   // Maximum Hamming distance: 6
   //
-  typedef enum logic [8:0] {
-    ResetSt     = 9'b110111000,
-    IdleSt      = 9'b101010100,
-    WriteSt     = 9'b000101110,
-    WriteWaitSt = 9'b000010011,
-    ErrorSt     = 9'b011001101
+  localparam int StateWidth = 9;
+  typedef enum logic [StateWidth-1:0] {
+    ResetSt     = 9'b010110111,
+    IdleSt      = 9'b101010010,
+    WriteSt     = 9'b111101110,
+    WriteWaitSt = 9'b100011101,
+    ErrorSt     = 9'b010000000
   } state_e;
 
   logic cnt_clr, cnt_en;
@@ -124,7 +125,7 @@
         end
       end
       ///////////////////////////////////////////////////////////////////
-      // Wait for a request from the life cycle controllers
+      // Wait for a request from the life cycle controller
       IdleSt: begin
         if (lc_req_i) begin
           state_d = WriteSt;
@@ -232,13 +233,23 @@
   // Registers //
   ///////////////
 
+  // This primitive is used to place a size-only constraint on the
+  // flops in order to prevent FSM state encoding optimizations.
+  prim_flop #(
+    .Width(StateWidth),
+    .ResetValue(StateWidth'(ResetSt))
+  ) u_state_regs (
+    .clk_i,
+    .rst_ni,
+    .d_i ( state_d ),
+    .q_o ( state_q )
+  );
+
   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
     if (!rst_ni) begin
-      state_q <= ResetSt;
       error_q <= NoErr;
       cnt_q   <= '0;
     end else begin
-      state_q <= state_d;
       error_q <= error_d;
       cnt_q   <= cnt_d;
     end
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv
index 9d7d3d3..5809176 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_lfsr_timer.sv
@@ -150,7 +150,7 @@
   // Ping and Timeout Logic //
   ////////////////////////////
 
-  // Encoding generated with ./sparse-fsm-encode -d 5 -m 5 -n 9
+  // Encoding generated with ./sparse-fsm-encode.py -d 5 -m 5 -n 9 -s 628816752
   // Hamming distance histogram:
   //
   // 0: --
@@ -167,12 +167,13 @@
   // Minimum Hamming distance: 5
   // Maximum Hamming distance: 6
   //
-  typedef enum logic [8:0] {
-    ResetSt     = 9'b110010010,
-    IdleSt      = 9'b011011101,
-    IntegWaitSt = 9'b100111111,
-    CnstyWaitSt = 9'b001000110,
-    ErrorSt     = 9'b101101000
+  localparam int StateWidth = 9;
+  typedef enum logic [StateWidth-1:0] {
+    ResetSt     = 9'b011111011,
+    IdleSt      = 9'b000100000,
+    IntegWaitSt = 9'b110010101,
+    CnstyWaitSt = 9'b001010110,
+    ErrorSt     = 9'b100101111
   } state_e;
 
   state_e state_d, state_q;
@@ -283,9 +284,20 @@
   // Registers //
   ///////////////
 
+  // This primitive is used to place a size-only constraint on the
+  // flops in order to prevent FSM state encoding optimizations.
+  prim_flop #(
+    .Width(StateWidth),
+    .ResetValue(StateWidth'(ResetSt))
+  ) u_state_regs (
+    .clk_i,
+    .rst_ni,
+    .d_i ( state_d ),
+    .q_o ( state_q )
+  );
+
   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
     if (!rst_ni) begin
-      state_q     <= ResetSt;
       integ_cnt_q <= '0;
       cnsty_cnt_q <= '0;
       integ_chk_req_q <= '0;
@@ -293,7 +305,6 @@
       chk_timeout_q   <= 1'b0;
       reseed_timer_q  <= '0;
     end else begin
-      state_q     <= state_d;
       integ_cnt_q <= integ_cnt_d;
       cnsty_cnt_q <= cnsty_cnt_d;
       integ_chk_req_q <= integ_chk_req_d;
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv
index a83d8ff..88f6729 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_buf.sv
@@ -82,7 +82,7 @@
   // OTP Partition FSM //
   ///////////////////////
 
-  // Encoding generated with ./sparse-fsm-encode -d 5 -m 16 -n 12
+  // Encoding generated with ./sparse-fsm-encode.py -d 5 -m 16 -n 12 -s 3370657881
   // Hamming distance histogram:
   //
   // 0:  --
@@ -90,35 +90,36 @@
   // 2:  --
   // 3:  --
   // 4:  --
-  // 5:  |||||||||||||||| (29.17%)
-  // 6:  |||||||||||||||||||| (35.83%)
-  // 7:  ||||||||||| (20.83%)
-  // 8:  |||| (7.50%)
-  // 9:  | (2.50%)
-  // 10: | (3.33%)
-  // 11:  (0.83%)
+  // 5:  |||||||||||||||||| (30.00%)
+  // 6:  |||||||||||||||||||| (32.50%)
+  // 7:  ||||||||||| (19.17%)
+  // 8:  ||||||| (11.67%)
+  // 9:  || (4.17%)
+  // 10: | (2.50%)
+  // 11: --
   // 12: --
   //
   // Minimum Hamming distance: 5
-  // Maximum Hamming distance: 11
+  // Maximum Hamming distance: 10
   //
-  typedef enum logic [11:0] {
-    ResetSt         = 12'b110001101001,
-    InitSt          = 12'b000100100000,
-    InitWaitSt      = 12'b011101011010,
-    InitDescrSt     = 12'b111010110000,
-    InitDescrWaitSt = 12'b110111000011,
-    IdleSt          = 12'b000000011100,
-    IntegScrSt      = 12'b001111101011,
-    IntegScrWaitSt  = 12'b000001000111,
-    IntegDigClrSt   = 12'b100110001101,
-    IntegDigSt      = 12'b101000110111,
-    IntegDigPadSt   = 12'b110101010100,
-    IntegDigFinSt   = 12'b101011001000,
-    IntegDigWaitSt  = 12'b010010101111,
-    CnstyReadSt     = 12'b001110000110,
-    CnstyReadWaitSt = 12'b011011011101,
-    ErrorSt         = 12'b000111110101
+  localparam int StateWidth = 12;
+  typedef enum logic [StateWidth-1:0] {
+    ResetSt         = 12'b001001101010,
+    InitSt          = 12'b110100100111,
+    InitWaitSt      = 12'b001110110001,
+    InitDescrSt     = 12'b110010000100,
+    InitDescrWaitSt = 12'b101000011100,
+    IdleSt          = 12'b100110101000,
+    IntegScrSt      = 12'b010101001101,
+    IntegScrWaitSt  = 12'b110101011010,
+    IntegDigClrSt   = 12'b011000011011,
+    IntegDigSt      = 12'b101001000001,
+    IntegDigPadSt   = 12'b101111010111,
+    IntegDigFinSt   = 12'b011011100101,
+    IntegDigWaitSt  = 12'b100011110010,
+    CnstyReadSt     = 12'b111111101110,
+    CnstyReadWaitSt = 12'b001100000110,
+    ErrorSt         = 12'b000011011001
   } state_e;
 
   typedef enum logic {
@@ -603,14 +604,24 @@
   // Registers //
   ///////////////
 
+  // This primitive is used to place a size-only constraint on the
+  // flops in order to prevent FSM state encoding optimizations.
+  prim_flop #(
+    .Width(StateWidth),
+    .ResetValue(StateWidth'(ResetSt))
+  ) u_state_regs (
+    .clk_i,
+    .rst_ni,
+    .d_i ( state_d ),
+    .q_o ( state_q )
+  );
+
   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
     if (!rst_ni) begin
-      state_q     <= ResetSt;
       error_q     <= NoErr;
       cnt_q       <= '0;
       dout_gate_q <= Locked;
     end else begin
-      state_q     <= state_d;
       error_q     <= error_d;
       cnt_q       <= cnt_d;
       dout_gate_q <= dout_gate_d;
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv
index 709fe94..3661a1f 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_part_unbuf.sv
@@ -63,7 +63,7 @@
   // OTP Partition FSM //
   ///////////////////////
 
-  // Encoding generated with ./sparse-fsm-encode -d 5 -m 7 -n 10
+  // Encoding generated with ./sparse-fsm-encode.py -d 5 -m 7 -n 10 -s 4247417884
   // Hamming distance histogram:
   //
   // 0: --
@@ -71,24 +71,25 @@
   // 2: --
   // 3: --
   // 4: --
-  // 5: |||||||||||||||||||| (42.86%)
-  // 6: |||||||||||||||||||| (42.86%)
-  // 7: |||||| (14.29%)
-  // 8: --
+  // 5: |||||||||||||||||||| (52.38%)
+  // 6: |||||||||||||| (38.10%)
+  // 7: | (4.76%)
+  // 8: | (4.76%)
   // 9: --
   // 10: --
   //
   // Minimum Hamming distance: 5
-  // Maximum Hamming distance: 7
+  // Maximum Hamming distance: 8
   //
-  typedef enum logic [9:0] {
-    ResetSt    = 10'b1000011000,
-    InitSt     = 10'b1001110011,
-    InitWaitSt = 10'b0100000111,
-    IdleSt     = 10'b1101100100,
-    ReadSt     = 10'b1110101011,
-    ReadWaitSt = 10'b0011011101,
-    ErrorSt    = 10'b0111010010
+  localparam int StateWidth = 10;
+  typedef enum logic [StateWidth-1:0] {
+    ResetSt    = 10'b1000111001,
+    InitSt     = 10'b1010110110,
+    InitWaitSt = 10'b0100010011,
+    IdleSt     = 10'b0101011100,
+    ReadSt     = 10'b0011000010,
+    ReadWaitSt = 10'b1101100000,
+    ErrorSt    = 10'b0110100101
   } state_e;
 
   typedef enum logic {
@@ -350,13 +351,23 @@
   // Registers //
   ///////////////
 
+  // This primitive is used to place a size-only constraint on the
+  // flops in order to prevent FSM state encoding optimizations.
+  prim_flop #(
+    .Width(StateWidth),
+    .ResetValue(StateWidth'(ResetSt))
+  ) u_state_regs (
+    .clk_i,
+    .rst_ni,
+    .d_i ( state_d ),
+    .q_o ( state_q )
+  );
+
   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
     if (!rst_ni) begin
-      state_q       <= ResetSt;
       error_q       <= NoErr;
       tlul_addr_q   <= '0;
     end else begin
-      state_q       <= state_d;
       error_q       <= error_d;
       if (tlul_gnt) begin
         tlul_addr_q <= tlul_addr_d;
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv
index 977106d..8fba552 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_scrmbl.sv
@@ -181,7 +181,7 @@
   // FSM //
   /////////
 
-  // Encoding generated with ./sparse-fsm-encode -d 5 -m 5 -n 9
+  // Encoding generated with ./sparse-fsm-encode.py -d 5 -m 5 -n 9 -s 2193087944
   // Hamming distance histogram:
   //
   // 0: --
@@ -198,12 +198,13 @@
   // Minimum Hamming distance: 5
   // Maximum Hamming distance: 6
   //
-  typedef enum logic [8:0] {
-    IdleSt    = 9'b011110111,
-    DecryptSt = 9'b000010001,
-    EncryptSt = 9'b011101000,
-    DigestSt  = 9'b100111100,
-    ErrorSt   = 9'b101001111
+  localparam int StateWidth = 9;
+  typedef enum logic [StateWidth-1:0] {
+    IdleSt    = 9'b100010111,
+    DecryptSt = 9'b001010000,
+    EncryptSt = 9'b011001011,
+    DigestSt  = 9'b100101000,
+    ErrorSt   = 9'b010111101
   } state_e;
 
   localparam int CntWidth = $clog2(NumPresentRounds+1);
@@ -391,9 +392,20 @@
   // Registers //
   ///////////////
 
+  // This primitive is used to place a size-only constraint on the
+  // flops in order to prevent FSM state encoding optimizations.
+  prim_flop #(
+    .Width(StateWidth),
+    .ResetValue(StateWidth'(IdleSt))
+  ) u_state_regs (
+    .clk_i,
+    .rst_ni,
+    .d_i ( state_d ),
+    .q_o ( state_q )
+  );
+
   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
     if (!rst_ni) begin
-      state_q        <= IdleSt;
       cnt_q          <= '0;
       key_state_q    <= '0;
       data_state_q   <= '0;
@@ -404,7 +416,6 @@
       sel_q          <= '0;
       digest_mode_q  <= 1'b0;
     end else begin
-      state_q       <= state_d;
       cnt_q         <= cnt_d;
       valid_q       <= valid_d;
       is_first_q    <= is_first_d;
diff --git a/hw/ip/prim_generic/rtl/prim_generic_otp.sv b/hw/ip/prim_generic/rtl/prim_generic_otp.sv
index f0c8879..aef12db 100644
--- a/hw/ip/prim_generic/rtl/prim_generic_otp.sv
+++ b/hw/ip/prim_generic/rtl/prim_generic_otp.sv
@@ -46,7 +46,7 @@
   // Control logic //
   ///////////////////
 
-  // Encoding generated with ./sparse-fsm-encode -d 5 -m 8 -n 10
+  // Encoding generated with ./sparse-fsm-encode.py -d 5 -m 8 -n 10
   // Hamming distance histogram:
   //
   // 0: --
@@ -64,7 +64,8 @@
   // Minimum Hamming distance: 5
   // Maximum Hamming distance: 8
   //
-  typedef enum logic [9:0] {
+  localparam int StateWidth = 10;
+  typedef enum logic [StateWidth-1:0] {
     ResetSt      = 10'b1100000011,
     InitSt       = 10'b1100110100,
     IdleSt       = 10'b1010111010,
@@ -249,9 +250,20 @@
   // Regs //
   //////////
 
+  // This primitive is used to place a size-only constraint on the
+  // flops in order to prevent FSM state encoding optimizations.
+  prim_flop #(
+    .Width(StateWidth),
+    .ResetValue(StateWidth'(ResetSt))
+  ) u_state_regs (
+    .clk_i,
+    .rst_ni,
+    .d_i ( state_d ),
+    .q_o ( state_q )
+  );
+
   always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs
     if (!rst_ni) begin
-      state_q <= ResetSt;
       valid_q <= '0;
       err_q   <= '0;
       addr_q  <= '0;
@@ -260,7 +272,6 @@
       cnt_q   <= '0;
       size_q  <= '0;
     end else begin
-      state_q <= state_d;
       valid_q <= valid_d;
       err_q   <= err_d;
       cnt_q   <= cnt_d;