[csrng/rtl] only two values for field enable

For a 4 bit field, only values of 0xa and 0x5 will take effect.
Added a recoverable alert signal for other field enable values, and a status register.

Signed-off-by: Mark Branstad <mark.branstad@wdc.com>
diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson
index 85e8755..a5af229 100644
--- a/hw/ip/csrng/data/csrng.hjson
+++ b/hw/ip/csrng/data/csrng.hjson
@@ -40,6 +40,9 @@
       desc: "Asserted when a FIFO error or a fatal alert occurs. Check the !!ERR_CODE register to get more information."}
   ],
   alert_list: [
+    { name: "recov_alert",
+      desc: "This alert is triggered when a recoverable alert occurs.  Check the !!RECOV_ALERT_STS register to get more information."
+    }
     { name: "fatal_alert",
       desc: '''
             This alert triggers (i) if an illegal state machine state is reached, or
@@ -103,6 +106,8 @@
       swaccess: "rw",
       hwaccess: "hro",
       regwen: "REGWEN",
+      tags: [// Internal HW can modify status register
+                 "excl:CsrAllTests:CsrExclWrite"]
       fields: [
         {
             bits: "3:0",
@@ -279,6 +284,38 @@
       ]
     },
     {
+      name: "RECOV_ALERT_STS",
+      desc: "Recoverable alert status register",
+      swaccess: "rw0c",
+      hwaccess: "hwo",
+      fields: [
+        { bits: "0",
+          name: "ENABLE_FIELD_ALERT",
+          desc: '''
+                This bit is set when the ENABLE field in the !!CTRL register is set to
+                a value other than 0x5 or 0xA.
+                Writing a zero to this register resets the status bits.
+                '''
+        }
+        { bits: "1",
+          name: "SW_APP_ENABLE_FIELD_ALERT",
+          desc: '''
+                This bit is set when the SW_APP_ENABLE field in the !!CTRL register is set to
+                a value other than 0x5 or 0xA.
+                Writing a zero to this register resets the status bits.
+                '''
+        }
+        { bits: "2",
+          name: "READ_INT_STATE_FIELD_ALERT",
+          desc: '''
+                This bit is set when the READ_INT_STATE field in the !!CTRL register is set to
+                a value other than 0x5 or 0xA.
+                Writing a zero to this register resets the status bits.
+                '''
+        }
+      ]
+    },
+    {
       name: "ERR_CODE",
       desc: "Hardware detection of error conditions status register",
       swaccess: "ro",
diff --git a/hw/ip/csrng/dv/env/csrng_env_pkg.sv b/hw/ip/csrng/dv/env/csrng_env_pkg.sv
index 6a65fdf..5ad90d4 100644
--- a/hw/ip/csrng/dv/env/csrng_env_pkg.sv
+++ b/hw/ip/csrng/dv/env/csrng_env_pkg.sv
@@ -22,8 +22,8 @@
 
   // parameters
   parameter uint     NUM_HW_APPS      = 2;
-  parameter string   LIST_OF_ALERTS[] = {"fatal_alert"};
-  parameter uint     NUM_ALERTS       = 1;
+  parameter string   LIST_OF_ALERTS[] = {"recov_alert","fatal_alert"};
+  parameter uint     NUM_ALERTS       = 2;
   parameter uint     KEY_LEN          = 256;
   parameter uint     BLOCK_LEN        = 128;
   parameter uint     CTR_LEN          = 32;
diff --git a/hw/ip/csrng/rtl/csrng.sv b/hw/ip/csrng/rtl/csrng.sv
index 3e4b049..806b96b 100644
--- a/hw/ip/csrng/rtl/csrng.sv
+++ b/hw/ip/csrng/rtl/csrng.sv
@@ -61,9 +61,11 @@
   csrng_reg2hw_t reg2hw;
   csrng_hw2reg_t hw2reg;
 
-  logic  alert;
-  logic  alert_test;
-  logic  intg_err_alert;
+  logic [NumAlerts-1:0] alert_test;
+  logic [NumAlerts-1:0] alert;
+
+  logic [NumAlerts-1:0] intg_err_alert;
+  assign intg_err_alert[0] = 1'b0;
 
   csrng_reg_top u_reg (
     .clk_i,
@@ -72,7 +74,7 @@
     .tl_o,
     .reg2hw,
     .hw2reg,
-    .intg_err_o(intg_err_alert),
+    .intg_err_o(intg_err_alert[1]),
     .devmode_i(1'b1)
   );
 
@@ -104,8 +106,10 @@
     .csrng_cmd_o,
 
     // Alerts
-    .alert_test_o(alert_test),
-    .fatal_alert_o(alert),
+    .recov_alert_test_o(alert_test[0]),
+    .fatal_alert_test_o(alert_test[1]),
+    .recov_alert_o(alert[0]),
+    .fatal_alert_o(alert[1]),
 
     .intr_cs_cmd_req_done_o,
     .intr_cs_entropy_req_o,
@@ -114,19 +118,24 @@
   );
 
 
-  prim_alert_sender #(
-    .AsyncOn(AlertAsyncOn[0]),
-    .IsFatal(1)
-  ) u_prim_alert_sender (
-    .clk_i,
-    .rst_ni,
-    .alert_test_i  ( alert_test              ),
-    .alert_req_i   ( alert || intg_err_alert ),
-    .alert_ack_o   (                         ),
-    .alert_state_o (                         ),
-    .alert_rx_i    ( alert_rx_i[0]           ),
-    .alert_tx_o    ( alert_tx_o[0]           )
-  );
+  ///////////////////////////
+  // Alert generation
+  ///////////////////////////
+  for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx
+    prim_alert_sender #(
+      .AsyncOn(AlertAsyncOn[i]),
+      .IsFatal(i)
+    ) u_prim_alert_sender (
+      .clk_i,
+      .rst_ni,
+      .alert_test_i  ( alert_test[i]                 ),
+      .alert_req_i   ( alert[i] || intg_err_alert[i] ),
+      .alert_ack_o   (                               ),
+      .alert_state_o (                               ),
+      .alert_rx_i    ( alert_rx_i[i]                 ),
+      .alert_tx_o    ( alert_tx_o[i]                 )
+    );
+  end
 
 
   // Assertions
diff --git a/hw/ip/csrng/rtl/csrng_core.sv b/hw/ip/csrng/rtl/csrng_core.sv
index 58af24f..0065eb2 100644
--- a/hw/ip/csrng/rtl/csrng_core.sv
+++ b/hw/ip/csrng/rtl/csrng_core.sv
@@ -37,7 +37,10 @@
   output csrng_rsp_t  [NHwApps-1:0] csrng_cmd_o,
 
   // Alerts
-  output logic           alert_test_o,
+
+  output logic           recov_alert_test_o,
+  output logic           fatal_alert_test_o,
+  output logic           recov_alert_o,
   output logic           fatal_alert_o,
 
   output logic           intr_cs_cmd_req_done_o,
@@ -73,8 +76,18 @@
   logic       event_cs_hw_inst_exc;
   logic       event_cs_fatal_err;
   logic       cs_enable;
+  logic       cs_enable_pfe;
+  logic       cs_enable_pfd;
+  logic       cs_enable_pfa;
   logic       sw_app_enable;
+  logic       sw_app_enable_pfe;
+  logic       sw_app_enable_pfd;
+  logic       sw_app_enable_pfa;
   logic       read_int_state;
+  logic       read_int_state_pfe;
+  logic       read_int_state_pfd;
+  logic       read_int_state_pfa;
+  logic       recov_alert_event;
   logic       acmd_avail;
   logic       acmd_sop;
   logic       acmd_mop;
@@ -649,15 +662,47 @@
   assign fatal_alert_o = event_cs_fatal_err;
 
   // alert test
-  assign alert_test_o = {
-    reg2hw.alert_test.q &
-    reg2hw.alert_test.qe
+  assign recov_alert_test_o = {
+    reg2hw.alert_test.recov_alert.q &&
+    reg2hw.alert_test.recov_alert.qe
+  };
+  assign fatal_alert_test_o = {
+    reg2hw.alert_test.fatal_alert.q &&
+    reg2hw.alert_test.fatal_alert.qe
   };
 
+
+  assign recov_alert_event = cs_enable_pfa || sw_app_enable_pfa || read_int_state_pfa;
+
+  assign recov_alert_o = recov_alert_event;
+
+
+
+  // check for illegal enable field states, and set alert if detected
+
+  assign cs_enable_pfe = (cs_enb_e'(reg2hw.ctrl.enable.q) == CS_FIELD_ON);
+  assign cs_enable_pfd = (cs_enb_e'(reg2hw.ctrl.enable.q) == ~CS_FIELD_ON);
+  assign cs_enable_pfa = !(cs_enable_pfe || cs_enable_pfd);
+  assign hw2reg.recov_alert_sts.enable_field_alert.de = cs_enable_pfa;
+  assign hw2reg.recov_alert_sts.enable_field_alert.d  = cs_enable_pfa;
+
+  assign sw_app_enable_pfe = (cs_enb_e'(reg2hw.ctrl.sw_app_enable.q) == CS_FIELD_ON);
+  assign sw_app_enable_pfd = (cs_enb_e'(reg2hw.ctrl.sw_app_enable.q) == ~CS_FIELD_ON);
+  assign sw_app_enable_pfa = !(sw_app_enable_pfe || sw_app_enable_pfd);
+  assign hw2reg.recov_alert_sts.sw_app_enable_field_alert.de = sw_app_enable_pfa;
+  assign hw2reg.recov_alert_sts.sw_app_enable_field_alert.d  = sw_app_enable_pfa;
+
+  assign read_int_state_pfe = (cs_enb_e'(reg2hw.ctrl.read_int_state.q) == CS_FIELD_ON);
+  assign read_int_state_pfd = (cs_enb_e'(reg2hw.ctrl.read_int_state.q) == ~CS_FIELD_ON);
+  assign read_int_state_pfa = !(read_int_state_pfe || read_int_state_pfd);
+  assign hw2reg.recov_alert_sts.read_int_state_field_alert.de = read_int_state_pfa;
+  assign hw2reg.recov_alert_sts.read_int_state_field_alert.d  = read_int_state_pfa;
+
+
   // master module enable
-  assign cs_enable = (cs_enb_e'(reg2hw.ctrl.enable.q) == CS_FIELD_ON);
-  assign sw_app_enable = (cs_enb_e'(reg2hw.ctrl.sw_app_enable.q) == CS_FIELD_ON);
-  assign read_int_state = (cs_enb_e'(reg2hw.ctrl.read_int_state.q) == CS_FIELD_ON);
+  assign cs_enable = cs_enable_pfe;
+  assign sw_app_enable = sw_app_enable_pfe;
+  assign read_int_state = read_int_state_pfe;
 
   //------------------------------------------
   // application interface
diff --git a/hw/ip/csrng/rtl/csrng_reg_pkg.sv b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
index 68c0621..228d0ed 100644
--- a/hw/ip/csrng/rtl/csrng_reg_pkg.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_pkg.sv
@@ -7,7 +7,7 @@
 package csrng_reg_pkg;
 
   // Param list
-  parameter int NumAlerts = 1;
+  parameter int NumAlerts = 2;
 
   // Address widths within the block
   parameter int BlockAw = 7;
@@ -66,8 +66,14 @@
   } csrng_reg2hw_intr_test_reg_t;
 
   typedef struct packed {
-    logic        q;
-    logic        qe;
+    struct packed {
+      logic        q;
+      logic        qe;
+    } recov_alert;
+    struct packed {
+      logic        q;
+      logic        qe;
+    } fatal_alert;
   } csrng_reg2hw_alert_test_reg_t;
 
   typedef struct packed {
@@ -167,6 +173,21 @@
     struct packed {
       logic        d;
       logic        de;
+    } enable_field_alert;
+    struct packed {
+      logic        d;
+      logic        de;
+    } sw_app_enable_field_alert;
+    struct packed {
+      logic        d;
+      logic        de;
+    } read_int_state_field_alert;
+  } csrng_hw2reg_recov_alert_sts_reg_t;
+
+  typedef struct packed {
+    struct packed {
+      logic        d;
+      logic        de;
     } sfifo_cmd_err;
     struct packed {
       logic        d;
@@ -287,10 +308,10 @@
 
   // Register -> HW type
   typedef struct packed {
-    csrng_reg2hw_intr_state_reg_t intr_state; // [141:138]
-    csrng_reg2hw_intr_enable_reg_t intr_enable; // [137:134]
-    csrng_reg2hw_intr_test_reg_t intr_test; // [133:126]
-    csrng_reg2hw_alert_test_reg_t alert_test; // [125:124]
+    csrng_reg2hw_intr_state_reg_t intr_state; // [143:140]
+    csrng_reg2hw_intr_enable_reg_t intr_enable; // [139:136]
+    csrng_reg2hw_intr_test_reg_t intr_test; // [135:128]
+    csrng_reg2hw_alert_test_reg_t alert_test; // [127:124]
     csrng_reg2hw_ctrl_reg_t ctrl; // [123:112]
     csrng_reg2hw_cmd_req_reg_t cmd_req; // [111:79]
     csrng_reg2hw_genbits_reg_t genbits; // [78:46]
@@ -302,12 +323,13 @@
 
   // HW -> register type
   typedef struct packed {
-    csrng_hw2reg_intr_state_reg_t intr_state; // [179:172]
-    csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [171:168]
-    csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [167:166]
-    csrng_hw2reg_genbits_reg_t genbits; // [165:134]
-    csrng_hw2reg_int_state_val_reg_t int_state_val; // [133:102]
-    csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [101:86]
+    csrng_hw2reg_intr_state_reg_t intr_state; // [185:178]
+    csrng_hw2reg_sw_cmd_sts_reg_t sw_cmd_sts; // [177:174]
+    csrng_hw2reg_genbits_vld_reg_t genbits_vld; // [173:172]
+    csrng_hw2reg_genbits_reg_t genbits; // [171:140]
+    csrng_hw2reg_int_state_val_reg_t int_state_val; // [139:108]
+    csrng_hw2reg_hw_exc_sts_reg_t hw_exc_sts; // [107:92]
+    csrng_hw2reg_recov_alert_sts_reg_t recov_alert_sts; // [91:86]
     csrng_hw2reg_err_code_reg_t err_code; // [85:36]
     csrng_hw2reg_tracking_sm_obs_reg_t tracking_sm_obs; // [35:0]
   } csrng_hw2reg_t;
@@ -326,10 +348,11 @@
   parameter logic [BlockAw-1:0] CSRNG_INT_STATE_NUM_OFFSET = 7'h 28;
   parameter logic [BlockAw-1:0] CSRNG_INT_STATE_VAL_OFFSET = 7'h 2c;
   parameter logic [BlockAw-1:0] CSRNG_HW_EXC_STS_OFFSET = 7'h 30;
-  parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 34;
-  parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 38;
-  parameter logic [BlockAw-1:0] CSRNG_SEL_TRACKING_SM_OFFSET = 7'h 3c;
-  parameter logic [BlockAw-1:0] CSRNG_TRACKING_SM_OBS_OFFSET = 7'h 40;
+  parameter logic [BlockAw-1:0] CSRNG_RECOV_ALERT_STS_OFFSET = 7'h 34;
+  parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_OFFSET = 7'h 38;
+  parameter logic [BlockAw-1:0] CSRNG_ERR_CODE_TEST_OFFSET = 7'h 3c;
+  parameter logic [BlockAw-1:0] CSRNG_SEL_TRACKING_SM_OFFSET = 7'h 40;
+  parameter logic [BlockAw-1:0] CSRNG_TRACKING_SM_OBS_OFFSET = 7'h 44;
 
   // Reset values for hwext registers and their fields
   parameter logic [3:0] CSRNG_INTR_TEST_RESVAL = 4'h 0;
@@ -337,7 +360,8 @@
   parameter logic [0:0] CSRNG_INTR_TEST_CS_ENTROPY_REQ_RESVAL = 1'h 0;
   parameter logic [0:0] CSRNG_INTR_TEST_CS_HW_INST_EXC_RESVAL = 1'h 0;
   parameter logic [0:0] CSRNG_INTR_TEST_CS_FATAL_ERR_RESVAL = 1'h 0;
-  parameter logic [0:0] CSRNG_ALERT_TEST_RESVAL = 1'h 0;
+  parameter logic [1:0] CSRNG_ALERT_TEST_RESVAL = 2'h 0;
+  parameter logic [0:0] CSRNG_ALERT_TEST_RECOV_ALERT_RESVAL = 1'h 0;
   parameter logic [0:0] CSRNG_ALERT_TEST_FATAL_ALERT_RESVAL = 1'h 0;
   parameter logic [1:0] CSRNG_GENBITS_VLD_RESVAL = 2'h 0;
   parameter logic [31:0] CSRNG_GENBITS_RESVAL = 32'h 0;
@@ -358,6 +382,7 @@
     CSRNG_INT_STATE_NUM,
     CSRNG_INT_STATE_VAL,
     CSRNG_HW_EXC_STS,
+    CSRNG_RECOV_ALERT_STS,
     CSRNG_ERR_CODE,
     CSRNG_ERR_CODE_TEST,
     CSRNG_SEL_TRACKING_SM,
@@ -365,7 +390,7 @@
   } csrng_id_e;
 
   // Register width information to check illegal writes
-  parameter logic [3:0] CSRNG_PERMIT [17] = '{
+  parameter logic [3:0] CSRNG_PERMIT [18] = '{
     4'b 0001, // index[ 0] CSRNG_INTR_STATE
     4'b 0001, // index[ 1] CSRNG_INTR_ENABLE
     4'b 0001, // index[ 2] CSRNG_INTR_TEST
@@ -379,10 +404,11 @@
     4'b 0001, // index[10] CSRNG_INT_STATE_NUM
     4'b 1111, // index[11] CSRNG_INT_STATE_VAL
     4'b 0011, // index[12] CSRNG_HW_EXC_STS
-    4'b 1111, // index[13] CSRNG_ERR_CODE
-    4'b 0001, // index[14] CSRNG_ERR_CODE_TEST
-    4'b 0001, // index[15] CSRNG_SEL_TRACKING_SM
-    4'b 1111  // index[16] CSRNG_TRACKING_SM_OBS
+    4'b 0001, // index[13] CSRNG_RECOV_ALERT_STS
+    4'b 1111, // index[14] CSRNG_ERR_CODE
+    4'b 0001, // index[15] CSRNG_ERR_CODE_TEST
+    4'b 0001, // index[16] CSRNG_SEL_TRACKING_SM
+    4'b 1111  // index[17] CSRNG_TRACKING_SM_OBS
   };
 
 endpackage
diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv
index d68fe67..75e365f 100644
--- a/hw/ip/csrng/rtl/csrng_reg_top.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_top.sv
@@ -132,7 +132,8 @@
   logic intr_test_cs_hw_inst_exc_wd;
   logic intr_test_cs_fatal_err_wd;
   logic alert_test_we;
-  logic alert_test_wd;
+  logic alert_test_recov_alert_wd;
+  logic alert_test_fatal_alert_wd;
   logic regwen_we;
   logic regwen_qs;
   logic regwen_wd;
@@ -160,6 +161,13 @@
   logic hw_exc_sts_we;
   logic [14:0] hw_exc_sts_qs;
   logic [14:0] hw_exc_sts_wd;
+  logic recov_alert_sts_we;
+  logic recov_alert_sts_enable_field_alert_qs;
+  logic recov_alert_sts_enable_field_alert_wd;
+  logic recov_alert_sts_sw_app_enable_field_alert_qs;
+  logic recov_alert_sts_sw_app_enable_field_alert_wd;
+  logic recov_alert_sts_read_int_state_field_alert_qs;
+  logic recov_alert_sts_read_int_state_field_alert_wd;
   logic err_code_sfifo_cmd_err_qs;
   logic err_code_sfifo_genbits_err_qs;
   logic err_code_sfifo_cmdreq_err_qs;
@@ -472,16 +480,32 @@
 
   // R[alert_test]: V(True)
 
+  //   F[recov_alert]: 0:0
   prim_subreg_ext #(
     .DW    (1)
-  ) u_alert_test (
+  ) u_alert_test_recov_alert (
     .re     (1'b0),
     .we     (alert_test_we),
-    .wd     (alert_test_wd),
+    .wd     (alert_test_recov_alert_wd),
     .d      ('0),
     .qre    (),
-    .qe     (reg2hw.alert_test.qe),
-    .q      (reg2hw.alert_test.q),
+    .qe     (reg2hw.alert_test.recov_alert.qe),
+    .q      (reg2hw.alert_test.recov_alert.q),
+    .qs     ()
+  );
+
+
+  //   F[fatal_alert]: 1:1
+  prim_subreg_ext #(
+    .DW    (1)
+  ) u_alert_test_fatal_alert (
+    .re     (1'b0),
+    .we     (alert_test_we),
+    .wd     (alert_test_fatal_alert_wd),
+    .d      ('0),
+    .qre    (),
+    .qe     (reg2hw.alert_test.fatal_alert.qe),
+    .q      (reg2hw.alert_test.fatal_alert.q),
     .qs     ()
   );
 
@@ -570,7 +594,7 @@
   //   F[read_int_state]: 11:8
   prim_subreg #(
     .DW      (4),
-    .SWACCESS("RW"),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (4'h5)
   ) u_ctrl_read_int_state (
     .clk_i   (clk_i),
@@ -792,6 +816,86 @@
   );
 
 
+  // R[recov_alert_sts]: V(False)
+
+  //   F[enable_field_alert]: 0:0
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessW0C),
+    .RESVAL  (1'h0)
+  ) u_recov_alert_sts_enable_field_alert (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (recov_alert_sts_we),
+    .wd     (recov_alert_sts_enable_field_alert_wd),
+
+    // from internal hardware
+    .de     (hw2reg.recov_alert_sts.enable_field_alert.de),
+    .d      (hw2reg.recov_alert_sts.enable_field_alert.d),
+
+    // to internal hardware
+    .qe     (),
+    .q      (),
+
+    // to register interface (read)
+    .qs     (recov_alert_sts_enable_field_alert_qs)
+  );
+
+
+  //   F[sw_app_enable_field_alert]: 1:1
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessW0C),
+    .RESVAL  (1'h0)
+  ) u_recov_alert_sts_sw_app_enable_field_alert (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (recov_alert_sts_we),
+    .wd     (recov_alert_sts_sw_app_enable_field_alert_wd),
+
+    // from internal hardware
+    .de     (hw2reg.recov_alert_sts.sw_app_enable_field_alert.de),
+    .d      (hw2reg.recov_alert_sts.sw_app_enable_field_alert.d),
+
+    // to internal hardware
+    .qe     (),
+    .q      (),
+
+    // to register interface (read)
+    .qs     (recov_alert_sts_sw_app_enable_field_alert_qs)
+  );
+
+
+  //   F[read_int_state_field_alert]: 2:2
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessW0C),
+    .RESVAL  (1'h0)
+  ) u_recov_alert_sts_read_int_state_field_alert (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (recov_alert_sts_we),
+    .wd     (recov_alert_sts_read_int_state_field_alert_wd),
+
+    // from internal hardware
+    .de     (hw2reg.recov_alert_sts.read_int_state_field_alert.de),
+    .d      (hw2reg.recov_alert_sts.read_int_state_field_alert.d),
+
+    // to internal hardware
+    .qe     (),
+    .q      (),
+
+    // to register interface (read)
+    .qs     (recov_alert_sts_read_int_state_field_alert_qs)
+  );
+
+
   // R[err_code]: V(False)
 
   //   F[sfifo_cmd_err]: 0:0
@@ -1606,7 +1710,7 @@
 
 
 
-  logic [16:0] addr_hit;
+  logic [17:0] addr_hit;
   always_comb begin
     addr_hit = '0;
     addr_hit[ 0] = (reg_addr == CSRNG_INTR_STATE_OFFSET);
@@ -1622,10 +1726,11 @@
     addr_hit[10] = (reg_addr == CSRNG_INT_STATE_NUM_OFFSET);
     addr_hit[11] = (reg_addr == CSRNG_INT_STATE_VAL_OFFSET);
     addr_hit[12] = (reg_addr == CSRNG_HW_EXC_STS_OFFSET);
-    addr_hit[13] = (reg_addr == CSRNG_ERR_CODE_OFFSET);
-    addr_hit[14] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET);
-    addr_hit[15] = (reg_addr == CSRNG_SEL_TRACKING_SM_OFFSET);
-    addr_hit[16] = (reg_addr == CSRNG_TRACKING_SM_OBS_OFFSET);
+    addr_hit[13] = (reg_addr == CSRNG_RECOV_ALERT_STS_OFFSET);
+    addr_hit[14] = (reg_addr == CSRNG_ERR_CODE_OFFSET);
+    addr_hit[15] = (reg_addr == CSRNG_ERR_CODE_TEST_OFFSET);
+    addr_hit[16] = (reg_addr == CSRNG_SEL_TRACKING_SM_OFFSET);
+    addr_hit[17] = (reg_addr == CSRNG_TRACKING_SM_OBS_OFFSET);
   end
 
   assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
@@ -1649,7 +1754,8 @@
                (addr_hit[13] & (|(CSRNG_PERMIT[13] & ~reg_be))) |
                (addr_hit[14] & (|(CSRNG_PERMIT[14] & ~reg_be))) |
                (addr_hit[15] & (|(CSRNG_PERMIT[15] & ~reg_be))) |
-               (addr_hit[16] & (|(CSRNG_PERMIT[16] & ~reg_be)))));
+               (addr_hit[16] & (|(CSRNG_PERMIT[16] & ~reg_be))) |
+               (addr_hit[17] & (|(CSRNG_PERMIT[17] & ~reg_be)))));
   end
   assign intr_state_we = addr_hit[0] & reg_we & !reg_error;
 
@@ -1680,7 +1786,9 @@
   assign intr_test_cs_fatal_err_wd = reg_wdata[3];
   assign alert_test_we = addr_hit[3] & reg_we & !reg_error;
 
-  assign alert_test_wd = reg_wdata[0];
+  assign alert_test_recov_alert_wd = reg_wdata[0];
+
+  assign alert_test_fatal_alert_wd = reg_wdata[1];
   assign regwen_we = addr_hit[4] & reg_we & !reg_error;
 
   assign regwen_wd = reg_wdata[0];
@@ -1703,10 +1811,17 @@
   assign hw_exc_sts_we = addr_hit[12] & reg_we & !reg_error;
 
   assign hw_exc_sts_wd = reg_wdata[14:0];
-  assign err_code_test_we = addr_hit[14] & reg_we & !reg_error;
+  assign recov_alert_sts_we = addr_hit[13] & reg_we & !reg_error;
+
+  assign recov_alert_sts_enable_field_alert_wd = reg_wdata[0];
+
+  assign recov_alert_sts_sw_app_enable_field_alert_wd = reg_wdata[1];
+
+  assign recov_alert_sts_read_int_state_field_alert_wd = reg_wdata[2];
+  assign err_code_test_we = addr_hit[15] & reg_we & !reg_error;
 
   assign err_code_test_wd = reg_wdata[4:0];
-  assign sel_tracking_sm_we = addr_hit[15] & reg_we & !reg_error;
+  assign sel_tracking_sm_we = addr_hit[16] & reg_we & !reg_error;
 
   assign sel_tracking_sm_wd = reg_wdata[1:0];
 
@@ -1737,6 +1852,7 @@
 
       addr_hit[3]: begin
         reg_rdata_next[0] = '0;
+        reg_rdata_next[1] = '0;
       end
 
       addr_hit[4]: begin
@@ -1780,6 +1896,12 @@
       end
 
       addr_hit[13]: begin
+        reg_rdata_next[0] = recov_alert_sts_enable_field_alert_qs;
+        reg_rdata_next[1] = recov_alert_sts_sw_app_enable_field_alert_qs;
+        reg_rdata_next[2] = recov_alert_sts_read_int_state_field_alert_qs;
+      end
+
+      addr_hit[14]: begin
         reg_rdata_next[0] = err_code_sfifo_cmd_err_qs;
         reg_rdata_next[1] = err_code_sfifo_genbits_err_qs;
         reg_rdata_next[2] = err_code_sfifo_cmdreq_err_qs;
@@ -1807,15 +1929,15 @@
         reg_rdata_next[30] = err_code_fifo_state_err_qs;
       end
 
-      addr_hit[14]: begin
+      addr_hit[15]: begin
         reg_rdata_next[4:0] = err_code_test_qs;
       end
 
-      addr_hit[15]: begin
+      addr_hit[16]: begin
         reg_rdata_next[1:0] = '0;
       end
 
-      addr_hit[16]: begin
+      addr_hit[17]: begin
         reg_rdata_next[7:0] = tracking_sm_obs_tracking_sm_obs0_qs;
         reg_rdata_next[15:8] = tracking_sm_obs_tracking_sm_obs1_qs;
         reg_rdata_next[23:16] = tracking_sm_obs_tracking_sm_obs2_qs;