[keymgr] Add edn support

- Not yet fully connected to edn in top level

Signed-off-by: Timothy Chen <timothytim@google.com>

[keymgr] port rename

Signed-off-by: Timothy Chen <timothytim@google.com>

[keymgr] Update to use prim_reqack

Does not assume keymgr is in the same clock domain as prim_reqack.

Signed-off-by: Timothy Chen <timothytim@google.com>

[keymgr] capture reqack data

Signed-off-by: Timothy Chen <timothytim@google.com>

[keymgr] re-arrange core files

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/keymgr/data/keymgr.hjson b/hw/ip/keymgr/data/keymgr.hjson
index 2c576ba..71e569e 100644
--- a/hw/ip/keymgr/data/keymgr.hjson
+++ b/hw/ip/keymgr/data/keymgr.hjson
@@ -3,6 +3,9 @@
 // SPDX-License-Identifier: Apache-2.0
 { name: "KEYMGR",
   clock_primary: "clk_i",
+  other_clock_list: [ "clk_edn_i" ]
+  reset_primary: "rst_ni",
+  other_reset_list: [ "rst_edn_ni" ]
   bus_device: "tlul",
   interrupt_list: [
     { name: "op_done",   desc: "Operation complete" },
@@ -21,6 +24,12 @@
 
   // Define keymgr <-> kmac / aes / hmac struct packages
   inter_signal_list: [
+    { struct:  "edn",
+      type:    "req_rsp",
+      name:    "edn",
+      act:     "req",
+      package: "edn_pkg",
+    },
     { struct:  "hw_key_req",  // aes_key_req_t
       type:    "uni",
       name:    "aes_key",     // aes_key_o (req)
@@ -302,6 +311,21 @@
       ],
     },
 
+    { name: "RESEED_INTERVAL",
+      desc: "reseed internval for key manager entropy reseed",
+      swaccess: "rw",
+      hwaccess: "hro",
+      fields: [
+        { bits: "15:0",
+          name: "VAL",
+          resval: "0x100"
+          desc: '''
+            Number of key manager cycles before the entropy is reseeded
+          '''
+        },
+      ]
+    },
+
     { name: "ROM_EXT_DESC_EN",
       desc: "Register write enable for ROM_EXT_DESC",
       swaccess: "rw0c",
@@ -582,7 +606,7 @@
       swaccess: "ro",
       hwaccess: "hwo",
       fields: [
-        { bits: "2:0",
+        { bits: "3:0",
           name: "STATE",
           resval: "0x0"
           desc: "Key manager control state",
diff --git a/hw/ip/keymgr/dv/env/keymgr_if.sv b/hw/ip/keymgr/dv/env/keymgr_if.sv
index 803fa9a..504e41c 100644
--- a/hw/ip/keymgr/dv/env/keymgr_if.sv
+++ b/hw/ip/keymgr/dv/env/keymgr_if.sv
@@ -11,6 +11,7 @@
   otp_data_t otp;
   otp_ctrl_pkg::otp_keymgr_key_t otp_key;
   flash_ctrl_pkg::keymgr_flash_t flash;
+  edn_pkg::edn_rsp_t edn_rsp;
 
   hw_key_req_t kmac_key;
   hw_key_req_t hmac_key;
@@ -21,7 +22,11 @@
     otp     = OTP_DATA_DEFAULT;
     otp_key = otp_ctrl_pkg::OTP_KEYMGR_KEY_DEFAULT;
     flash   = flash_ctrl_pkg::KEYMGR_FLASH_DEFAULT;
-
+    edn_rsp = '{
+      edn_ack: 1'b1,
+      edn_fips: 1'b0,
+      edn_bus: 32'hFBA6E5DA
+    };
 
   endtask
 endinterface
diff --git a/hw/ip/keymgr/dv/tb.sv b/hw/ip/keymgr/dv/tb.sv
index 01d8de4..14e44af 100644
--- a/hw/ip/keymgr/dv/tb.sv
+++ b/hw/ip/keymgr/dv/tb.sv
@@ -39,6 +39,7 @@
     .lc_i                 (keymgr_if.lc),
     .otp_key_i            (keymgr_if.otp_key),
     .otp_i                (keymgr_if.otp),
+    .edn_i                (keymgr_if.edn_rsp),
     .flash_i              (keymgr_if.flash),
     .intr_op_done_o       (interrupts[IntrOpDone]),
     .intr_err_o           (interrupts[IntrErr]),
diff --git a/hw/ip/keymgr/keymgr.core b/hw/ip/keymgr/keymgr.core
index 85c5cee..11b3cf0 100644
--- a/hw/ip/keymgr/keymgr.core
+++ b/hw/ip/keymgr/keymgr.core
@@ -11,7 +11,6 @@
       - lowrisc:ip:tlul
       - lowrisc:prim:all
       - lowrisc:prim:lfsr
-      - lowrisc:ip:otp_ctrl_pkg
       - lowrisc:ip:keymgr_pkg
     files:
       - rtl/keymgr_reg_pkg.sv
@@ -22,6 +21,7 @@
       - rtl/keymgr_cfg_en.sv
       - rtl/keymgr_kmac_if.sv
       - rtl/keymgr_input_checks.sv
+      - rtl/keymgr_reseed_ctrl.sv
       - rtl/keymgr.sv
     file_type: systemVerilogSource
 
diff --git a/hw/ip/keymgr/keymgr_pkg.core b/hw/ip/keymgr/keymgr_pkg.core
index bb1118f..2a4ddef 100644
--- a/hw/ip/keymgr/keymgr_pkg.core
+++ b/hw/ip/keymgr/keymgr_pkg.core
@@ -9,6 +9,8 @@
   files_rtl:
     depend:
       - lowrisc:constants:top_pkg
+      - lowrisc:ip:edn_pkg
+      - lowrisc:ip:otp_ctrl_pkg
       - lowrisc:ip:flash_ctrl_pkg
     files:
       - rtl/keymgr_pkg.sv
diff --git a/hw/ip/keymgr/rtl/keymgr.sv b/hw/ip/keymgr/rtl/keymgr.sv
index 5983b43..198f3a9 100644
--- a/hw/ip/keymgr/rtl/keymgr.sv
+++ b/hw/ip/keymgr/rtl/keymgr.sv
@@ -20,6 +20,8 @@
 ) (
   input clk_i,
   input rst_ni,
+  input clk_edn_i,
+  input rst_edn_ni,
 
   // Bus Interface
   input  tlul_pkg::tl_h2d_t tl_i,
@@ -40,6 +42,10 @@
   input otp_data_t otp_i,
   input flash_ctrl_pkg::keymgr_flash_t flash_i,
 
+  // connection to edn
+  output edn_pkg::edn_req_t edn_o,
+  input edn_pkg::edn_rsp_t edn_i,
+
   // interrupts and alerts
   output logic intr_op_done_o,
   output logic intr_err_o,
@@ -82,6 +88,25 @@
   // The second case is less sensitive and is applied directly.  If the inputs
   // have more bits than the lfsr output, the lfsr value is simply replicated
 
+  logic seed_en;
+  logic [LfsrWidth-1:0] seed;
+  logic reseed_req;
+  logic reseed_ack;
+
+  keymgr_reseed_ctrl u_reseed_ctrl (
+    .clk_i,
+    .rst_ni,
+    .clk_edn_i,
+    .rst_edn_ni,
+    .reseed_req_i(reseed_req),
+    .reseed_ack_o(reseed_ack),
+    .reseed_interval_i(reg2hw.reseed_interval.q),
+    .edn_o,
+    .edn_i,
+    .seed_en_o(seed_en),
+    .seed_o(seed)
+  );
+
   logic [63:0] lfsr;
   logic ctrl_lfsr_en, data_lfsr_en, sideload_lfsr_en;
 
@@ -95,9 +120,14 @@
     .clk_i,
     .rst_ni,
     .lfsr_en_i(ctrl_lfsr_en | data_lfsr_en | sideload_lfsr_en),
-    .seed_en_i(1'b0),
-    .seed_i('0),
-    .entropy_i('0), // TBD, this should be hooked up to an entropy distribution pkg
+    // The seed update is skipped if there is an ongoing keymgr transaction.
+    // This is not really done for any functional purpose but more to simplify
+    // DV. When an invalid operation is selected, the keymgr just starts transmitting
+    // whatever is at the prng output, however, this may cause a dv protocol violation
+    // if a reseed happens to coincide.
+    .seed_en_i(seed_en & ~reg2hw.control.start.q),
+    .seed_i(seed),
+    .entropy_i('0),
     .state_o(lfsr)
   );
 
@@ -126,8 +156,10 @@
     .clk_i,
     .rst_ni,
     .en_i(lc_i.keymgr_en),
+    .prng_reseed_req_o(reseed_req),
+    .prng_reseed_ack_i(reseed_ack),
     .prng_en_o(ctrl_lfsr_en),
-    .entropy_i(lfsr[63:32]),  // TBD, recommend directly interfacing with DRBG for keymgr_ctrl
+    .entropy_i(lfsr[63:32]),
     .init_i(reg2hw.control.init.q),
     .init_done_o(init_done),
     .op_i(keymgr_ops_e'(reg2hw.control.operation.q)),
diff --git a/hw/ip/keymgr/rtl/keymgr_ctrl.sv b/hw/ip/keymgr/rtl/keymgr_ctrl.sv
index fe25fc7..d1bb539 100644
--- a/hw/ip/keymgr/rtl/keymgr_ctrl.sv
+++ b/hw/ip/keymgr/rtl/keymgr_ctrl.sv
@@ -14,10 +14,6 @@
   // lifecycle enforcement
   input en_i,
 
-  // entropy input
-  input [(LfsrWidth/2)-1:0] entropy_i,
-  output logic prng_en_o,
-
   // Software interface
   input init_i,
   output logic init_done_o,
@@ -46,8 +42,15 @@
   input kmac_fsm_err_i, // asserted when kmac fsm reaches unexpected state
   input kmac_op_err_i,  // asserted when kmac itself reports an error
   input kmac_cmd_err_i, // asserted when more than one command given to kmac
-  input [Shares-1:0][KeyWidth-1:0] kmac_data_i
+  input [Shares-1:0][KeyWidth-1:0] kmac_data_i,
+
+  // prng control interface
+  input [(LfsrWidth/2)-1:0] entropy_i,
+  input prng_reseed_ack_i,
+  output logic prng_reseed_req_o,
+  output logic prng_en_o
 );
+
   localparam int EntropyWidth = LfsrWidth / 2;
   localparam int EntropyRounds = KeyWidth / EntropyWidth;
   localparam int CntWidth = $clog2(EntropyRounds + 1);
@@ -159,6 +162,7 @@
     stage_sel_o = Disable;
 
     // enable prng toggling
+    prng_reseed_req_o = 1'b0;
     prng_en_o = 1'b0;
 
     op_done_o = 1'b0;
@@ -180,13 +184,21 @@
         // Note, if init is called at the same time as start, it is considered
         // an invalid command sequence.
         if (init_i && !invalid_op && en_i) begin
-          state_d = StRandom;
+          state_d = StEntropyReseed;
         end else begin
           state_d = StReset;
           init_done_o = init_i & invalid_op;
         end
       end
 
+      // reseed entropy
+      StEntropyReseed: begin
+        prng_reseed_req_o = 1'b1;
+        if (prng_reseed_ack_i) begin
+          state_d = StRandom;
+        end
+      end
+
       // This state does not accept any command.
       StRandom: begin
         init_done_o = 1'b0;
diff --git a/hw/ip/keymgr/rtl/keymgr_pkg.sv b/hw/ip/keymgr/rtl/keymgr_pkg.sv
index f0274d4..53a32d5 100644
--- a/hw/ip/keymgr/rtl/keymgr_pkg.sv
+++ b/hw/ip/keymgr/rtl/keymgr_pkg.sv
@@ -13,6 +13,7 @@
   parameter int KeyMgrStages = 3;      // Number of key manager stages (creator, ownerInt, owner)
   parameter int RomExtDescWidth = 128; // Size of rom_ext hash, truncated
   parameter int Shares = 2; // number of key shares
+  parameter int EdnWidth = edn_pkg::ENDPOINT_BUS_WIDTH;
 
   // These should be defined in another module's package
   parameter int HealthStateWidth = 128;
@@ -91,15 +92,16 @@
   } keymgr_ops_e;
 
   // Enumeration for working state
-  typedef enum logic [2:0] {
+  typedef enum logic [3:0] {
     StReset = 0,
-    StRandom = 1,
-    StInit = 2,
-    StCreatorRootKey = 3,
-    StOwnerIntKey = 4,
-    StOwnerKey = 5,
-    StWipe = 6,
-    StDisabled = 7
+    StEntropyReseed = 1,
+    StRandom = 2,
+    StInit = 3,
+    StCreatorRootKey = 4,
+    StOwnerIntKey = 5,
+    StOwnerKey = 6,
+    StWipe = 7,
+    StDisabled = 8
   } keymgr_working_state_e;
 
   // Enumeration for operation status
diff --git a/hw/ip/keymgr/rtl/keymgr_reg_pkg.sv b/hw/ip/keymgr/rtl/keymgr_reg_pkg.sv
index 5700ab6..d0f9cd9 100644
--- a/hw/ip/keymgr/rtl/keymgr_reg_pkg.sv
+++ b/hw/ip/keymgr/rtl/keymgr_reg_pkg.sv
@@ -72,6 +72,10 @@
   } keymgr_reg2hw_control_reg_t;
 
   typedef struct packed {
+    logic [15:0] q;
+  } keymgr_reg2hw_reseed_interval_reg_t;
+
+  typedef struct packed {
     logic [31:0] q;
   } keymgr_reg2hw_rom_ext_desc_mreg_t;
 
@@ -152,7 +156,7 @@
   } keymgr_hw2reg_sw_share1_output_mreg_t;
 
   typedef struct packed {
-    logic [2:0]  d;
+    logic [3:0]  d;
     logic        de;
   } keymgr_hw2reg_working_state_reg_t;
 
@@ -185,11 +189,12 @@
   // Register to internal design logic //
   ///////////////////////////////////////
   typedef struct packed {
-    keymgr_reg2hw_intr_state_reg_t intr_state; // [534:533]
-    keymgr_reg2hw_intr_enable_reg_t intr_enable; // [532:531]
-    keymgr_reg2hw_intr_test_reg_t intr_test; // [530:527]
-    keymgr_reg2hw_alert_test_reg_t alert_test; // [526:523]
-    keymgr_reg2hw_control_reg_t control; // [522:516]
+    keymgr_reg2hw_intr_state_reg_t intr_state; // [550:549]
+    keymgr_reg2hw_intr_enable_reg_t intr_enable; // [548:547]
+    keymgr_reg2hw_intr_test_reg_t intr_test; // [546:543]
+    keymgr_reg2hw_alert_test_reg_t alert_test; // [542:539]
+    keymgr_reg2hw_control_reg_t control; // [538:532]
+    keymgr_reg2hw_reseed_interval_reg_t reseed_interval; // [531:516]
     keymgr_reg2hw_rom_ext_desc_mreg_t [3:0] rom_ext_desc; // [515:388]
     keymgr_reg2hw_software_binding_mreg_t [3:0] software_binding; // [387:260]
     keymgr_reg2hw_salt_mreg_t [3:0] salt; // [259:132]
@@ -204,12 +209,12 @@
   // Internal design logic to register //
   ///////////////////////////////////////
   typedef struct packed {
-    keymgr_hw2reg_intr_state_reg_t intr_state; // [551:548]
-    keymgr_hw2reg_cfgen_reg_t cfgen; // [547:547]
-    keymgr_hw2reg_control_reg_t control; // [546:543]
-    keymgr_hw2reg_sw_share0_output_mreg_t [7:0] sw_share0_output; // [542:279]
-    keymgr_hw2reg_sw_share1_output_mreg_t [7:0] sw_share1_output; // [278:15]
-    keymgr_hw2reg_working_state_reg_t working_state; // [14:11]
+    keymgr_hw2reg_intr_state_reg_t intr_state; // [552:549]
+    keymgr_hw2reg_cfgen_reg_t cfgen; // [548:548]
+    keymgr_hw2reg_control_reg_t control; // [547:544]
+    keymgr_hw2reg_sw_share0_output_mreg_t [7:0] sw_share0_output; // [543:280]
+    keymgr_hw2reg_sw_share1_output_mreg_t [7:0] sw_share1_output; // [279:16]
+    keymgr_hw2reg_working_state_reg_t working_state; // [15:11]
     keymgr_hw2reg_op_status_reg_t op_status; // [10:8]
     keymgr_hw2reg_err_code_reg_t err_code; // [7:0]
   } keymgr_hw2reg_t;
@@ -221,45 +226,46 @@
   parameter logic [7:0] KEYMGR_ALERT_TEST_OFFSET = 8'h c;
   parameter logic [7:0] KEYMGR_CFGEN_OFFSET = 8'h 10;
   parameter logic [7:0] KEYMGR_CONTROL_OFFSET = 8'h 14;
-  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_EN_OFFSET = 8'h 18;
-  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_0_OFFSET = 8'h 1c;
-  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_1_OFFSET = 8'h 20;
-  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_2_OFFSET = 8'h 24;
-  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_3_OFFSET = 8'h 28;
-  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_0_OFFSET = 8'h 2c;
-  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_1_OFFSET = 8'h 30;
-  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_2_OFFSET = 8'h 34;
-  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_3_OFFSET = 8'h 38;
-  parameter logic [7:0] KEYMGR_SALT_0_OFFSET = 8'h 3c;
-  parameter logic [7:0] KEYMGR_SALT_1_OFFSET = 8'h 40;
-  parameter logic [7:0] KEYMGR_SALT_2_OFFSET = 8'h 44;
-  parameter logic [7:0] KEYMGR_SALT_3_OFFSET = 8'h 48;
-  parameter logic [7:0] KEYMGR_KEY_VERSION_OFFSET = 8'h 4c;
-  parameter logic [7:0] KEYMGR_MAX_CREATOR_KEY_VER_EN_OFFSET = 8'h 50;
-  parameter logic [7:0] KEYMGR_MAX_CREATOR_KEY_VER_OFFSET = 8'h 54;
-  parameter logic [7:0] KEYMGR_MAX_OWNER_INT_KEY_VER_EN_OFFSET = 8'h 58;
-  parameter logic [7:0] KEYMGR_MAX_OWNER_INT_KEY_VER_OFFSET = 8'h 5c;
-  parameter logic [7:0] KEYMGR_MAX_OWNER_KEY_VER_EN_OFFSET = 8'h 60;
-  parameter logic [7:0] KEYMGR_MAX_OWNER_KEY_VER_OFFSET = 8'h 64;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_0_OFFSET = 8'h 68;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_1_OFFSET = 8'h 6c;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_2_OFFSET = 8'h 70;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_3_OFFSET = 8'h 74;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_4_OFFSET = 8'h 78;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_5_OFFSET = 8'h 7c;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_6_OFFSET = 8'h 80;
-  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_7_OFFSET = 8'h 84;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_0_OFFSET = 8'h 88;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_1_OFFSET = 8'h 8c;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_2_OFFSET = 8'h 90;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_3_OFFSET = 8'h 94;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_4_OFFSET = 8'h 98;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_5_OFFSET = 8'h 9c;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_6_OFFSET = 8'h a0;
-  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_7_OFFSET = 8'h a4;
-  parameter logic [7:0] KEYMGR_WORKING_STATE_OFFSET = 8'h a8;
-  parameter logic [7:0] KEYMGR_OP_STATUS_OFFSET = 8'h ac;
-  parameter logic [7:0] KEYMGR_ERR_CODE_OFFSET = 8'h b0;
+  parameter logic [7:0] KEYMGR_RESEED_INTERVAL_OFFSET = 8'h 18;
+  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_EN_OFFSET = 8'h 1c;
+  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_0_OFFSET = 8'h 20;
+  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_1_OFFSET = 8'h 24;
+  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_2_OFFSET = 8'h 28;
+  parameter logic [7:0] KEYMGR_ROM_EXT_DESC_3_OFFSET = 8'h 2c;
+  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_0_OFFSET = 8'h 30;
+  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_1_OFFSET = 8'h 34;
+  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_2_OFFSET = 8'h 38;
+  parameter logic [7:0] KEYMGR_SOFTWARE_BINDING_3_OFFSET = 8'h 3c;
+  parameter logic [7:0] KEYMGR_SALT_0_OFFSET = 8'h 40;
+  parameter logic [7:0] KEYMGR_SALT_1_OFFSET = 8'h 44;
+  parameter logic [7:0] KEYMGR_SALT_2_OFFSET = 8'h 48;
+  parameter logic [7:0] KEYMGR_SALT_3_OFFSET = 8'h 4c;
+  parameter logic [7:0] KEYMGR_KEY_VERSION_OFFSET = 8'h 50;
+  parameter logic [7:0] KEYMGR_MAX_CREATOR_KEY_VER_EN_OFFSET = 8'h 54;
+  parameter logic [7:0] KEYMGR_MAX_CREATOR_KEY_VER_OFFSET = 8'h 58;
+  parameter logic [7:0] KEYMGR_MAX_OWNER_INT_KEY_VER_EN_OFFSET = 8'h 5c;
+  parameter logic [7:0] KEYMGR_MAX_OWNER_INT_KEY_VER_OFFSET = 8'h 60;
+  parameter logic [7:0] KEYMGR_MAX_OWNER_KEY_VER_EN_OFFSET = 8'h 64;
+  parameter logic [7:0] KEYMGR_MAX_OWNER_KEY_VER_OFFSET = 8'h 68;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_0_OFFSET = 8'h 6c;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_1_OFFSET = 8'h 70;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_2_OFFSET = 8'h 74;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_3_OFFSET = 8'h 78;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_4_OFFSET = 8'h 7c;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_5_OFFSET = 8'h 80;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_6_OFFSET = 8'h 84;
+  parameter logic [7:0] KEYMGR_SW_SHARE0_OUTPUT_7_OFFSET = 8'h 88;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_0_OFFSET = 8'h 8c;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_1_OFFSET = 8'h 90;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_2_OFFSET = 8'h 94;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_3_OFFSET = 8'h 98;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_4_OFFSET = 8'h 9c;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_5_OFFSET = 8'h a0;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_6_OFFSET = 8'h a4;
+  parameter logic [7:0] KEYMGR_SW_SHARE1_OUTPUT_7_OFFSET = 8'h a8;
+  parameter logic [7:0] KEYMGR_WORKING_STATE_OFFSET = 8'h ac;
+  parameter logic [7:0] KEYMGR_OP_STATUS_OFFSET = 8'h b0;
+  parameter logic [7:0] KEYMGR_ERR_CODE_OFFSET = 8'h b4;
 
 
   // Register Index
@@ -270,6 +276,7 @@
     KEYMGR_ALERT_TEST,
     KEYMGR_CFGEN,
     KEYMGR_CONTROL,
+    KEYMGR_RESEED_INTERVAL,
     KEYMGR_ROM_EXT_DESC_EN,
     KEYMGR_ROM_EXT_DESC_0,
     KEYMGR_ROM_EXT_DESC_1,
@@ -312,52 +319,53 @@
   } keymgr_id_e;
 
   // Register width information to check illegal writes
-  parameter logic [3:0] KEYMGR_PERMIT [45] = '{
+  parameter logic [3:0] KEYMGR_PERMIT [46] = '{
     4'b 0001, // index[ 0] KEYMGR_INTR_STATE
     4'b 0001, // index[ 1] KEYMGR_INTR_ENABLE
     4'b 0001, // index[ 2] KEYMGR_INTR_TEST
     4'b 0001, // index[ 3] KEYMGR_ALERT_TEST
     4'b 0001, // index[ 4] KEYMGR_CFGEN
     4'b 0011, // index[ 5] KEYMGR_CONTROL
-    4'b 0001, // index[ 6] KEYMGR_ROM_EXT_DESC_EN
-    4'b 1111, // index[ 7] KEYMGR_ROM_EXT_DESC_0
-    4'b 1111, // index[ 8] KEYMGR_ROM_EXT_DESC_1
-    4'b 1111, // index[ 9] KEYMGR_ROM_EXT_DESC_2
-    4'b 1111, // index[10] KEYMGR_ROM_EXT_DESC_3
-    4'b 1111, // index[11] KEYMGR_SOFTWARE_BINDING_0
-    4'b 1111, // index[12] KEYMGR_SOFTWARE_BINDING_1
-    4'b 1111, // index[13] KEYMGR_SOFTWARE_BINDING_2
-    4'b 1111, // index[14] KEYMGR_SOFTWARE_BINDING_3
-    4'b 1111, // index[15] KEYMGR_SALT_0
-    4'b 1111, // index[16] KEYMGR_SALT_1
-    4'b 1111, // index[17] KEYMGR_SALT_2
-    4'b 1111, // index[18] KEYMGR_SALT_3
-    4'b 1111, // index[19] KEYMGR_KEY_VERSION
-    4'b 0001, // index[20] KEYMGR_MAX_CREATOR_KEY_VER_EN
-    4'b 1111, // index[21] KEYMGR_MAX_CREATOR_KEY_VER
-    4'b 0001, // index[22] KEYMGR_MAX_OWNER_INT_KEY_VER_EN
-    4'b 1111, // index[23] KEYMGR_MAX_OWNER_INT_KEY_VER
-    4'b 0001, // index[24] KEYMGR_MAX_OWNER_KEY_VER_EN
-    4'b 1111, // index[25] KEYMGR_MAX_OWNER_KEY_VER
-    4'b 1111, // index[26] KEYMGR_SW_SHARE0_OUTPUT_0
-    4'b 1111, // index[27] KEYMGR_SW_SHARE0_OUTPUT_1
-    4'b 1111, // index[28] KEYMGR_SW_SHARE0_OUTPUT_2
-    4'b 1111, // index[29] KEYMGR_SW_SHARE0_OUTPUT_3
-    4'b 1111, // index[30] KEYMGR_SW_SHARE0_OUTPUT_4
-    4'b 1111, // index[31] KEYMGR_SW_SHARE0_OUTPUT_5
-    4'b 1111, // index[32] KEYMGR_SW_SHARE0_OUTPUT_6
-    4'b 1111, // index[33] KEYMGR_SW_SHARE0_OUTPUT_7
-    4'b 1111, // index[34] KEYMGR_SW_SHARE1_OUTPUT_0
-    4'b 1111, // index[35] KEYMGR_SW_SHARE1_OUTPUT_1
-    4'b 1111, // index[36] KEYMGR_SW_SHARE1_OUTPUT_2
-    4'b 1111, // index[37] KEYMGR_SW_SHARE1_OUTPUT_3
-    4'b 1111, // index[38] KEYMGR_SW_SHARE1_OUTPUT_4
-    4'b 1111, // index[39] KEYMGR_SW_SHARE1_OUTPUT_5
-    4'b 1111, // index[40] KEYMGR_SW_SHARE1_OUTPUT_6
-    4'b 1111, // index[41] KEYMGR_SW_SHARE1_OUTPUT_7
-    4'b 0001, // index[42] KEYMGR_WORKING_STATE
-    4'b 0001, // index[43] KEYMGR_OP_STATUS
-    4'b 0001  // index[44] KEYMGR_ERR_CODE
+    4'b 0011, // index[ 6] KEYMGR_RESEED_INTERVAL
+    4'b 0001, // index[ 7] KEYMGR_ROM_EXT_DESC_EN
+    4'b 1111, // index[ 8] KEYMGR_ROM_EXT_DESC_0
+    4'b 1111, // index[ 9] KEYMGR_ROM_EXT_DESC_1
+    4'b 1111, // index[10] KEYMGR_ROM_EXT_DESC_2
+    4'b 1111, // index[11] KEYMGR_ROM_EXT_DESC_3
+    4'b 1111, // index[12] KEYMGR_SOFTWARE_BINDING_0
+    4'b 1111, // index[13] KEYMGR_SOFTWARE_BINDING_1
+    4'b 1111, // index[14] KEYMGR_SOFTWARE_BINDING_2
+    4'b 1111, // index[15] KEYMGR_SOFTWARE_BINDING_3
+    4'b 1111, // index[16] KEYMGR_SALT_0
+    4'b 1111, // index[17] KEYMGR_SALT_1
+    4'b 1111, // index[18] KEYMGR_SALT_2
+    4'b 1111, // index[19] KEYMGR_SALT_3
+    4'b 1111, // index[20] KEYMGR_KEY_VERSION
+    4'b 0001, // index[21] KEYMGR_MAX_CREATOR_KEY_VER_EN
+    4'b 1111, // index[22] KEYMGR_MAX_CREATOR_KEY_VER
+    4'b 0001, // index[23] KEYMGR_MAX_OWNER_INT_KEY_VER_EN
+    4'b 1111, // index[24] KEYMGR_MAX_OWNER_INT_KEY_VER
+    4'b 0001, // index[25] KEYMGR_MAX_OWNER_KEY_VER_EN
+    4'b 1111, // index[26] KEYMGR_MAX_OWNER_KEY_VER
+    4'b 1111, // index[27] KEYMGR_SW_SHARE0_OUTPUT_0
+    4'b 1111, // index[28] KEYMGR_SW_SHARE0_OUTPUT_1
+    4'b 1111, // index[29] KEYMGR_SW_SHARE0_OUTPUT_2
+    4'b 1111, // index[30] KEYMGR_SW_SHARE0_OUTPUT_3
+    4'b 1111, // index[31] KEYMGR_SW_SHARE0_OUTPUT_4
+    4'b 1111, // index[32] KEYMGR_SW_SHARE0_OUTPUT_5
+    4'b 1111, // index[33] KEYMGR_SW_SHARE0_OUTPUT_6
+    4'b 1111, // index[34] KEYMGR_SW_SHARE0_OUTPUT_7
+    4'b 1111, // index[35] KEYMGR_SW_SHARE1_OUTPUT_0
+    4'b 1111, // index[36] KEYMGR_SW_SHARE1_OUTPUT_1
+    4'b 1111, // index[37] KEYMGR_SW_SHARE1_OUTPUT_2
+    4'b 1111, // index[38] KEYMGR_SW_SHARE1_OUTPUT_3
+    4'b 1111, // index[39] KEYMGR_SW_SHARE1_OUTPUT_4
+    4'b 1111, // index[40] KEYMGR_SW_SHARE1_OUTPUT_5
+    4'b 1111, // index[41] KEYMGR_SW_SHARE1_OUTPUT_6
+    4'b 1111, // index[42] KEYMGR_SW_SHARE1_OUTPUT_7
+    4'b 0001, // index[43] KEYMGR_WORKING_STATE
+    4'b 0001, // index[44] KEYMGR_OP_STATUS
+    4'b 0001  // index[45] KEYMGR_ERR_CODE
   };
 endpackage
 
diff --git a/hw/ip/keymgr/rtl/keymgr_reg_top.sv b/hw/ip/keymgr/rtl/keymgr_reg_top.sv
index 260d191..4455f2e 100644
--- a/hw/ip/keymgr/rtl/keymgr_reg_top.sv
+++ b/hw/ip/keymgr/rtl/keymgr_reg_top.sv
@@ -105,6 +105,9 @@
   logic [1:0] control_dest_sel_qs;
   logic [1:0] control_dest_sel_wd;
   logic control_dest_sel_we;
+  logic [15:0] reseed_interval_qs;
+  logic [15:0] reseed_interval_wd;
+  logic reseed_interval_we;
   logic [1:0] rom_ext_desc_en_qs;
   logic [1:0] rom_ext_desc_en_wd;
   logic rom_ext_desc_en_we;
@@ -213,7 +216,7 @@
   logic [31:0] sw_share1_output_7_qs;
   logic [31:0] sw_share1_output_7_wd;
   logic sw_share1_output_7_we;
-  logic [2:0] working_state_qs;
+  logic [3:0] working_state_qs;
   logic [1:0] op_status_qs;
   logic [1:0] op_status_wd;
   logic op_status_we;
@@ -525,6 +528,33 @@
   );
 
 
+  // R[reseed_interval]: V(False)
+
+  prim_subreg #(
+    .DW      (16),
+    .SWACCESS("RW"),
+    .RESVAL  (16'h100)
+  ) u_reseed_interval (
+    .clk_i   (clk_i    ),
+    .rst_ni  (rst_ni  ),
+
+    // from register interface
+    .we     (reseed_interval_we),
+    .wd     (reseed_interval_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0  ),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.reseed_interval.q ),
+
+    // to register interface (read)
+    .qs     (reseed_interval_qs)
+  );
+
+
   // R[rom_ext_desc_en]: V(False)
 
   prim_subreg #(
@@ -1512,9 +1542,9 @@
   // R[working_state]: V(False)
 
   prim_subreg #(
-    .DW      (3),
+    .DW      (4),
     .SWACCESS("RO"),
-    .RESVAL  (3'h0)
+    .RESVAL  (4'h0)
   ) u_working_state (
     .clk_i   (clk_i    ),
     .rst_ni  (rst_ni  ),
@@ -1670,7 +1700,7 @@
 
 
 
-  logic [44:0] addr_hit;
+  logic [45:0] addr_hit;
   always_comb begin
     addr_hit = '0;
     addr_hit[ 0] = (reg_addr == KEYMGR_INTR_STATE_OFFSET);
@@ -1679,45 +1709,46 @@
     addr_hit[ 3] = (reg_addr == KEYMGR_ALERT_TEST_OFFSET);
     addr_hit[ 4] = (reg_addr == KEYMGR_CFGEN_OFFSET);
     addr_hit[ 5] = (reg_addr == KEYMGR_CONTROL_OFFSET);
-    addr_hit[ 6] = (reg_addr == KEYMGR_ROM_EXT_DESC_EN_OFFSET);
-    addr_hit[ 7] = (reg_addr == KEYMGR_ROM_EXT_DESC_0_OFFSET);
-    addr_hit[ 8] = (reg_addr == KEYMGR_ROM_EXT_DESC_1_OFFSET);
-    addr_hit[ 9] = (reg_addr == KEYMGR_ROM_EXT_DESC_2_OFFSET);
-    addr_hit[10] = (reg_addr == KEYMGR_ROM_EXT_DESC_3_OFFSET);
-    addr_hit[11] = (reg_addr == KEYMGR_SOFTWARE_BINDING_0_OFFSET);
-    addr_hit[12] = (reg_addr == KEYMGR_SOFTWARE_BINDING_1_OFFSET);
-    addr_hit[13] = (reg_addr == KEYMGR_SOFTWARE_BINDING_2_OFFSET);
-    addr_hit[14] = (reg_addr == KEYMGR_SOFTWARE_BINDING_3_OFFSET);
-    addr_hit[15] = (reg_addr == KEYMGR_SALT_0_OFFSET);
-    addr_hit[16] = (reg_addr == KEYMGR_SALT_1_OFFSET);
-    addr_hit[17] = (reg_addr == KEYMGR_SALT_2_OFFSET);
-    addr_hit[18] = (reg_addr == KEYMGR_SALT_3_OFFSET);
-    addr_hit[19] = (reg_addr == KEYMGR_KEY_VERSION_OFFSET);
-    addr_hit[20] = (reg_addr == KEYMGR_MAX_CREATOR_KEY_VER_EN_OFFSET);
-    addr_hit[21] = (reg_addr == KEYMGR_MAX_CREATOR_KEY_VER_OFFSET);
-    addr_hit[22] = (reg_addr == KEYMGR_MAX_OWNER_INT_KEY_VER_EN_OFFSET);
-    addr_hit[23] = (reg_addr == KEYMGR_MAX_OWNER_INT_KEY_VER_OFFSET);
-    addr_hit[24] = (reg_addr == KEYMGR_MAX_OWNER_KEY_VER_EN_OFFSET);
-    addr_hit[25] = (reg_addr == KEYMGR_MAX_OWNER_KEY_VER_OFFSET);
-    addr_hit[26] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_0_OFFSET);
-    addr_hit[27] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_1_OFFSET);
-    addr_hit[28] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_2_OFFSET);
-    addr_hit[29] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_3_OFFSET);
-    addr_hit[30] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_4_OFFSET);
-    addr_hit[31] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_5_OFFSET);
-    addr_hit[32] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_6_OFFSET);
-    addr_hit[33] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_7_OFFSET);
-    addr_hit[34] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_0_OFFSET);
-    addr_hit[35] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_1_OFFSET);
-    addr_hit[36] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_2_OFFSET);
-    addr_hit[37] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_3_OFFSET);
-    addr_hit[38] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_4_OFFSET);
-    addr_hit[39] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_5_OFFSET);
-    addr_hit[40] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_6_OFFSET);
-    addr_hit[41] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_7_OFFSET);
-    addr_hit[42] = (reg_addr == KEYMGR_WORKING_STATE_OFFSET);
-    addr_hit[43] = (reg_addr == KEYMGR_OP_STATUS_OFFSET);
-    addr_hit[44] = (reg_addr == KEYMGR_ERR_CODE_OFFSET);
+    addr_hit[ 6] = (reg_addr == KEYMGR_RESEED_INTERVAL_OFFSET);
+    addr_hit[ 7] = (reg_addr == KEYMGR_ROM_EXT_DESC_EN_OFFSET);
+    addr_hit[ 8] = (reg_addr == KEYMGR_ROM_EXT_DESC_0_OFFSET);
+    addr_hit[ 9] = (reg_addr == KEYMGR_ROM_EXT_DESC_1_OFFSET);
+    addr_hit[10] = (reg_addr == KEYMGR_ROM_EXT_DESC_2_OFFSET);
+    addr_hit[11] = (reg_addr == KEYMGR_ROM_EXT_DESC_3_OFFSET);
+    addr_hit[12] = (reg_addr == KEYMGR_SOFTWARE_BINDING_0_OFFSET);
+    addr_hit[13] = (reg_addr == KEYMGR_SOFTWARE_BINDING_1_OFFSET);
+    addr_hit[14] = (reg_addr == KEYMGR_SOFTWARE_BINDING_2_OFFSET);
+    addr_hit[15] = (reg_addr == KEYMGR_SOFTWARE_BINDING_3_OFFSET);
+    addr_hit[16] = (reg_addr == KEYMGR_SALT_0_OFFSET);
+    addr_hit[17] = (reg_addr == KEYMGR_SALT_1_OFFSET);
+    addr_hit[18] = (reg_addr == KEYMGR_SALT_2_OFFSET);
+    addr_hit[19] = (reg_addr == KEYMGR_SALT_3_OFFSET);
+    addr_hit[20] = (reg_addr == KEYMGR_KEY_VERSION_OFFSET);
+    addr_hit[21] = (reg_addr == KEYMGR_MAX_CREATOR_KEY_VER_EN_OFFSET);
+    addr_hit[22] = (reg_addr == KEYMGR_MAX_CREATOR_KEY_VER_OFFSET);
+    addr_hit[23] = (reg_addr == KEYMGR_MAX_OWNER_INT_KEY_VER_EN_OFFSET);
+    addr_hit[24] = (reg_addr == KEYMGR_MAX_OWNER_INT_KEY_VER_OFFSET);
+    addr_hit[25] = (reg_addr == KEYMGR_MAX_OWNER_KEY_VER_EN_OFFSET);
+    addr_hit[26] = (reg_addr == KEYMGR_MAX_OWNER_KEY_VER_OFFSET);
+    addr_hit[27] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_0_OFFSET);
+    addr_hit[28] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_1_OFFSET);
+    addr_hit[29] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_2_OFFSET);
+    addr_hit[30] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_3_OFFSET);
+    addr_hit[31] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_4_OFFSET);
+    addr_hit[32] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_5_OFFSET);
+    addr_hit[33] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_6_OFFSET);
+    addr_hit[34] = (reg_addr == KEYMGR_SW_SHARE0_OUTPUT_7_OFFSET);
+    addr_hit[35] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_0_OFFSET);
+    addr_hit[36] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_1_OFFSET);
+    addr_hit[37] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_2_OFFSET);
+    addr_hit[38] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_3_OFFSET);
+    addr_hit[39] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_4_OFFSET);
+    addr_hit[40] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_5_OFFSET);
+    addr_hit[41] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_6_OFFSET);
+    addr_hit[42] = (reg_addr == KEYMGR_SW_SHARE1_OUTPUT_7_OFFSET);
+    addr_hit[43] = (reg_addr == KEYMGR_WORKING_STATE_OFFSET);
+    addr_hit[44] = (reg_addr == KEYMGR_OP_STATUS_OFFSET);
+    addr_hit[45] = (reg_addr == KEYMGR_ERR_CODE_OFFSET);
   end
 
   assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
@@ -1770,6 +1801,7 @@
     if (addr_hit[42] && reg_we && (KEYMGR_PERMIT[42] != (KEYMGR_PERMIT[42] & reg_be))) wr_err = 1'b1 ;
     if (addr_hit[43] && reg_we && (KEYMGR_PERMIT[43] != (KEYMGR_PERMIT[43] & reg_be))) wr_err = 1'b1 ;
     if (addr_hit[44] && reg_we && (KEYMGR_PERMIT[44] != (KEYMGR_PERMIT[44] & reg_be))) wr_err = 1'b1 ;
+    if (addr_hit[45] && reg_we && (KEYMGR_PERMIT[45] != (KEYMGR_PERMIT[45] & reg_be))) wr_err = 1'b1 ;
   end
 
   assign intr_state_op_done_we = addr_hit[0] & reg_we & ~wr_err;
@@ -1810,128 +1842,131 @@
   assign control_dest_sel_we = addr_hit[5] & reg_we & ~wr_err;
   assign control_dest_sel_wd = reg_wdata[13:12];
 
-  assign rom_ext_desc_en_we = addr_hit[6] & reg_we & ~wr_err;
+  assign reseed_interval_we = addr_hit[6] & reg_we & ~wr_err;
+  assign reseed_interval_wd = reg_wdata[15:0];
+
+  assign rom_ext_desc_en_we = addr_hit[7] & reg_we & ~wr_err;
   assign rom_ext_desc_en_wd = reg_wdata[1:0];
 
-  assign rom_ext_desc_0_we = addr_hit[7] & reg_we & ~wr_err;
+  assign rom_ext_desc_0_we = addr_hit[8] & reg_we & ~wr_err;
   assign rom_ext_desc_0_wd = reg_wdata[31:0];
 
-  assign rom_ext_desc_1_we = addr_hit[8] & reg_we & ~wr_err;
+  assign rom_ext_desc_1_we = addr_hit[9] & reg_we & ~wr_err;
   assign rom_ext_desc_1_wd = reg_wdata[31:0];
 
-  assign rom_ext_desc_2_we = addr_hit[9] & reg_we & ~wr_err;
+  assign rom_ext_desc_2_we = addr_hit[10] & reg_we & ~wr_err;
   assign rom_ext_desc_2_wd = reg_wdata[31:0];
 
-  assign rom_ext_desc_3_we = addr_hit[10] & reg_we & ~wr_err;
+  assign rom_ext_desc_3_we = addr_hit[11] & reg_we & ~wr_err;
   assign rom_ext_desc_3_wd = reg_wdata[31:0];
 
-  assign software_binding_0_we = addr_hit[11] & reg_we & ~wr_err;
+  assign software_binding_0_we = addr_hit[12] & reg_we & ~wr_err;
   assign software_binding_0_wd = reg_wdata[31:0];
 
-  assign software_binding_1_we = addr_hit[12] & reg_we & ~wr_err;
+  assign software_binding_1_we = addr_hit[13] & reg_we & ~wr_err;
   assign software_binding_1_wd = reg_wdata[31:0];
 
-  assign software_binding_2_we = addr_hit[13] & reg_we & ~wr_err;
+  assign software_binding_2_we = addr_hit[14] & reg_we & ~wr_err;
   assign software_binding_2_wd = reg_wdata[31:0];
 
-  assign software_binding_3_we = addr_hit[14] & reg_we & ~wr_err;
+  assign software_binding_3_we = addr_hit[15] & reg_we & ~wr_err;
   assign software_binding_3_wd = reg_wdata[31:0];
 
-  assign salt_0_we = addr_hit[15] & reg_we & ~wr_err;
+  assign salt_0_we = addr_hit[16] & reg_we & ~wr_err;
   assign salt_0_wd = reg_wdata[31:0];
 
-  assign salt_1_we = addr_hit[16] & reg_we & ~wr_err;
+  assign salt_1_we = addr_hit[17] & reg_we & ~wr_err;
   assign salt_1_wd = reg_wdata[31:0];
 
-  assign salt_2_we = addr_hit[17] & reg_we & ~wr_err;
+  assign salt_2_we = addr_hit[18] & reg_we & ~wr_err;
   assign salt_2_wd = reg_wdata[31:0];
 
-  assign salt_3_we = addr_hit[18] & reg_we & ~wr_err;
+  assign salt_3_we = addr_hit[19] & reg_we & ~wr_err;
   assign salt_3_wd = reg_wdata[31:0];
 
-  assign key_version_we = addr_hit[19] & reg_we & ~wr_err;
+  assign key_version_we = addr_hit[20] & reg_we & ~wr_err;
   assign key_version_wd = reg_wdata[31:0];
 
-  assign max_creator_key_ver_en_we = addr_hit[20] & reg_we & ~wr_err;
+  assign max_creator_key_ver_en_we = addr_hit[21] & reg_we & ~wr_err;
   assign max_creator_key_ver_en_wd = reg_wdata[0];
 
-  assign max_creator_key_ver_we = addr_hit[21] & reg_we & ~wr_err;
+  assign max_creator_key_ver_we = addr_hit[22] & reg_we & ~wr_err;
   assign max_creator_key_ver_wd = reg_wdata[31:0];
 
-  assign max_owner_int_key_ver_en_we = addr_hit[22] & reg_we & ~wr_err;
+  assign max_owner_int_key_ver_en_we = addr_hit[23] & reg_we & ~wr_err;
   assign max_owner_int_key_ver_en_wd = reg_wdata[0];
 
-  assign max_owner_int_key_ver_we = addr_hit[23] & reg_we & ~wr_err;
+  assign max_owner_int_key_ver_we = addr_hit[24] & reg_we & ~wr_err;
   assign max_owner_int_key_ver_wd = reg_wdata[31:0];
 
-  assign max_owner_key_ver_en_we = addr_hit[24] & reg_we & ~wr_err;
+  assign max_owner_key_ver_en_we = addr_hit[25] & reg_we & ~wr_err;
   assign max_owner_key_ver_en_wd = reg_wdata[0];
 
-  assign max_owner_key_ver_we = addr_hit[25] & reg_we & ~wr_err;
+  assign max_owner_key_ver_we = addr_hit[26] & reg_we & ~wr_err;
   assign max_owner_key_ver_wd = reg_wdata[31:0];
 
-  assign sw_share0_output_0_we = addr_hit[26] & reg_re;
+  assign sw_share0_output_0_we = addr_hit[27] & reg_re;
   assign sw_share0_output_0_wd = '1;
 
-  assign sw_share0_output_1_we = addr_hit[27] & reg_re;
+  assign sw_share0_output_1_we = addr_hit[28] & reg_re;
   assign sw_share0_output_1_wd = '1;
 
-  assign sw_share0_output_2_we = addr_hit[28] & reg_re;
+  assign sw_share0_output_2_we = addr_hit[29] & reg_re;
   assign sw_share0_output_2_wd = '1;
 
-  assign sw_share0_output_3_we = addr_hit[29] & reg_re;
+  assign sw_share0_output_3_we = addr_hit[30] & reg_re;
   assign sw_share0_output_3_wd = '1;
 
-  assign sw_share0_output_4_we = addr_hit[30] & reg_re;
+  assign sw_share0_output_4_we = addr_hit[31] & reg_re;
   assign sw_share0_output_4_wd = '1;
 
-  assign sw_share0_output_5_we = addr_hit[31] & reg_re;
+  assign sw_share0_output_5_we = addr_hit[32] & reg_re;
   assign sw_share0_output_5_wd = '1;
 
-  assign sw_share0_output_6_we = addr_hit[32] & reg_re;
+  assign sw_share0_output_6_we = addr_hit[33] & reg_re;
   assign sw_share0_output_6_wd = '1;
 
-  assign sw_share0_output_7_we = addr_hit[33] & reg_re;
+  assign sw_share0_output_7_we = addr_hit[34] & reg_re;
   assign sw_share0_output_7_wd = '1;
 
-  assign sw_share1_output_0_we = addr_hit[34] & reg_re;
+  assign sw_share1_output_0_we = addr_hit[35] & reg_re;
   assign sw_share1_output_0_wd = '1;
 
-  assign sw_share1_output_1_we = addr_hit[35] & reg_re;
+  assign sw_share1_output_1_we = addr_hit[36] & reg_re;
   assign sw_share1_output_1_wd = '1;
 
-  assign sw_share1_output_2_we = addr_hit[36] & reg_re;
+  assign sw_share1_output_2_we = addr_hit[37] & reg_re;
   assign sw_share1_output_2_wd = '1;
 
-  assign sw_share1_output_3_we = addr_hit[37] & reg_re;
+  assign sw_share1_output_3_we = addr_hit[38] & reg_re;
   assign sw_share1_output_3_wd = '1;
 
-  assign sw_share1_output_4_we = addr_hit[38] & reg_re;
+  assign sw_share1_output_4_we = addr_hit[39] & reg_re;
   assign sw_share1_output_4_wd = '1;
 
-  assign sw_share1_output_5_we = addr_hit[39] & reg_re;
+  assign sw_share1_output_5_we = addr_hit[40] & reg_re;
   assign sw_share1_output_5_wd = '1;
 
-  assign sw_share1_output_6_we = addr_hit[40] & reg_re;
+  assign sw_share1_output_6_we = addr_hit[41] & reg_re;
   assign sw_share1_output_6_wd = '1;
 
-  assign sw_share1_output_7_we = addr_hit[41] & reg_re;
+  assign sw_share1_output_7_we = addr_hit[42] & reg_re;
   assign sw_share1_output_7_wd = '1;
 
 
-  assign op_status_we = addr_hit[43] & reg_we & ~wr_err;
+  assign op_status_we = addr_hit[44] & reg_we & ~wr_err;
   assign op_status_wd = reg_wdata[1:0];
 
-  assign err_code_invalid_op_we = addr_hit[44] & reg_we & ~wr_err;
+  assign err_code_invalid_op_we = addr_hit[45] & reg_we & ~wr_err;
   assign err_code_invalid_op_wd = reg_wdata[0];
 
-  assign err_code_invalid_cmd_we = addr_hit[44] & reg_we & ~wr_err;
+  assign err_code_invalid_cmd_we = addr_hit[45] & reg_we & ~wr_err;
   assign err_code_invalid_cmd_wd = reg_wdata[1];
 
-  assign err_code_invalid_kmac_input_we = addr_hit[44] & reg_we & ~wr_err;
+  assign err_code_invalid_kmac_input_we = addr_hit[45] & reg_we & ~wr_err;
   assign err_code_invalid_kmac_input_wd = reg_wdata[2];
 
-  assign err_code_invalid_kmac_data_we = addr_hit[44] & reg_we & ~wr_err;
+  assign err_code_invalid_kmac_data_we = addr_hit[45] & reg_we & ~wr_err;
   assign err_code_invalid_kmac_data_wd = reg_wdata[3];
 
   // Read data return
@@ -1970,158 +2005,162 @@
       end
 
       addr_hit[6]: begin
-        reg_rdata_next[1:0] = rom_ext_desc_en_qs;
+        reg_rdata_next[15:0] = reseed_interval_qs;
       end
 
       addr_hit[7]: begin
-        reg_rdata_next[31:0] = rom_ext_desc_0_qs;
+        reg_rdata_next[1:0] = rom_ext_desc_en_qs;
       end
 
       addr_hit[8]: begin
-        reg_rdata_next[31:0] = rom_ext_desc_1_qs;
+        reg_rdata_next[31:0] = rom_ext_desc_0_qs;
       end
 
       addr_hit[9]: begin
-        reg_rdata_next[31:0] = rom_ext_desc_2_qs;
+        reg_rdata_next[31:0] = rom_ext_desc_1_qs;
       end
 
       addr_hit[10]: begin
-        reg_rdata_next[31:0] = rom_ext_desc_3_qs;
+        reg_rdata_next[31:0] = rom_ext_desc_2_qs;
       end
 
       addr_hit[11]: begin
-        reg_rdata_next[31:0] = software_binding_0_qs;
+        reg_rdata_next[31:0] = rom_ext_desc_3_qs;
       end
 
       addr_hit[12]: begin
-        reg_rdata_next[31:0] = software_binding_1_qs;
+        reg_rdata_next[31:0] = software_binding_0_qs;
       end
 
       addr_hit[13]: begin
-        reg_rdata_next[31:0] = software_binding_2_qs;
+        reg_rdata_next[31:0] = software_binding_1_qs;
       end
 
       addr_hit[14]: begin
-        reg_rdata_next[31:0] = software_binding_3_qs;
+        reg_rdata_next[31:0] = software_binding_2_qs;
       end
 
       addr_hit[15]: begin
-        reg_rdata_next[31:0] = salt_0_qs;
+        reg_rdata_next[31:0] = software_binding_3_qs;
       end
 
       addr_hit[16]: begin
-        reg_rdata_next[31:0] = salt_1_qs;
+        reg_rdata_next[31:0] = salt_0_qs;
       end
 
       addr_hit[17]: begin
-        reg_rdata_next[31:0] = salt_2_qs;
+        reg_rdata_next[31:0] = salt_1_qs;
       end
 
       addr_hit[18]: begin
-        reg_rdata_next[31:0] = salt_3_qs;
+        reg_rdata_next[31:0] = salt_2_qs;
       end
 
       addr_hit[19]: begin
-        reg_rdata_next[31:0] = key_version_qs;
+        reg_rdata_next[31:0] = salt_3_qs;
       end
 
       addr_hit[20]: begin
-        reg_rdata_next[0] = max_creator_key_ver_en_qs;
+        reg_rdata_next[31:0] = key_version_qs;
       end
 
       addr_hit[21]: begin
-        reg_rdata_next[31:0] = max_creator_key_ver_qs;
+        reg_rdata_next[0] = max_creator_key_ver_en_qs;
       end
 
       addr_hit[22]: begin
-        reg_rdata_next[0] = max_owner_int_key_ver_en_qs;
+        reg_rdata_next[31:0] = max_creator_key_ver_qs;
       end
 
       addr_hit[23]: begin
-        reg_rdata_next[31:0] = max_owner_int_key_ver_qs;
+        reg_rdata_next[0] = max_owner_int_key_ver_en_qs;
       end
 
       addr_hit[24]: begin
-        reg_rdata_next[0] = max_owner_key_ver_en_qs;
+        reg_rdata_next[31:0] = max_owner_int_key_ver_qs;
       end
 
       addr_hit[25]: begin
-        reg_rdata_next[31:0] = max_owner_key_ver_qs;
+        reg_rdata_next[0] = max_owner_key_ver_en_qs;
       end
 
       addr_hit[26]: begin
-        reg_rdata_next[31:0] = sw_share0_output_0_qs;
+        reg_rdata_next[31:0] = max_owner_key_ver_qs;
       end
 
       addr_hit[27]: begin
-        reg_rdata_next[31:0] = sw_share0_output_1_qs;
+        reg_rdata_next[31:0] = sw_share0_output_0_qs;
       end
 
       addr_hit[28]: begin
-        reg_rdata_next[31:0] = sw_share0_output_2_qs;
+        reg_rdata_next[31:0] = sw_share0_output_1_qs;
       end
 
       addr_hit[29]: begin
-        reg_rdata_next[31:0] = sw_share0_output_3_qs;
+        reg_rdata_next[31:0] = sw_share0_output_2_qs;
       end
 
       addr_hit[30]: begin
-        reg_rdata_next[31:0] = sw_share0_output_4_qs;
+        reg_rdata_next[31:0] = sw_share0_output_3_qs;
       end
 
       addr_hit[31]: begin
-        reg_rdata_next[31:0] = sw_share0_output_5_qs;
+        reg_rdata_next[31:0] = sw_share0_output_4_qs;
       end
 
       addr_hit[32]: begin
-        reg_rdata_next[31:0] = sw_share0_output_6_qs;
+        reg_rdata_next[31:0] = sw_share0_output_5_qs;
       end
 
       addr_hit[33]: begin
-        reg_rdata_next[31:0] = sw_share0_output_7_qs;
+        reg_rdata_next[31:0] = sw_share0_output_6_qs;
       end
 
       addr_hit[34]: begin
-        reg_rdata_next[31:0] = sw_share1_output_0_qs;
+        reg_rdata_next[31:0] = sw_share0_output_7_qs;
       end
 
       addr_hit[35]: begin
-        reg_rdata_next[31:0] = sw_share1_output_1_qs;
+        reg_rdata_next[31:0] = sw_share1_output_0_qs;
       end
 
       addr_hit[36]: begin
-        reg_rdata_next[31:0] = sw_share1_output_2_qs;
+        reg_rdata_next[31:0] = sw_share1_output_1_qs;
       end
 
       addr_hit[37]: begin
-        reg_rdata_next[31:0] = sw_share1_output_3_qs;
+        reg_rdata_next[31:0] = sw_share1_output_2_qs;
       end
 
       addr_hit[38]: begin
-        reg_rdata_next[31:0] = sw_share1_output_4_qs;
+        reg_rdata_next[31:0] = sw_share1_output_3_qs;
       end
 
       addr_hit[39]: begin
-        reg_rdata_next[31:0] = sw_share1_output_5_qs;
+        reg_rdata_next[31:0] = sw_share1_output_4_qs;
       end
 
       addr_hit[40]: begin
-        reg_rdata_next[31:0] = sw_share1_output_6_qs;
+        reg_rdata_next[31:0] = sw_share1_output_5_qs;
       end
 
       addr_hit[41]: begin
-        reg_rdata_next[31:0] = sw_share1_output_7_qs;
+        reg_rdata_next[31:0] = sw_share1_output_6_qs;
       end
 
       addr_hit[42]: begin
-        reg_rdata_next[2:0] = working_state_qs;
+        reg_rdata_next[31:0] = sw_share1_output_7_qs;
       end
 
       addr_hit[43]: begin
-        reg_rdata_next[1:0] = op_status_qs;
+        reg_rdata_next[3:0] = working_state_qs;
       end
 
       addr_hit[44]: begin
+        reg_rdata_next[1:0] = op_status_qs;
+      end
+
+      addr_hit[45]: begin
         reg_rdata_next[0] = err_code_invalid_op_qs;
         reg_rdata_next[1] = err_code_invalid_cmd_qs;
         reg_rdata_next[2] = err_code_invalid_kmac_input_qs;
diff --git a/hw/ip/keymgr/rtl/keymgr_reseed_ctrl.sv b/hw/ip/keymgr/rtl/keymgr_reseed_ctrl.sv
new file mode 100644
index 0000000..a4cf2c1
--- /dev/null
+++ b/hw/ip/keymgr/rtl/keymgr_reseed_ctrl.sv
@@ -0,0 +1,132 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Key manager entropy reseed controls
+//
+
+`include "prim_assert.sv"
+
+module keymgr_reseed_ctrl import keymgr_pkg::*; (
+  input clk_i,
+  input rst_ni,
+  input clk_edn_i,
+  input rst_edn_ni,
+
+  // interface to keymgr_ctrl
+  input reseed_req_i,
+  output logic reseed_ack_o,
+
+  // interface to software
+  input [15:0] reseed_interval_i,
+
+  // interface to edn
+  output edn_pkg::edn_req_t edn_o,
+  input edn_pkg::edn_rsp_t edn_i,
+
+  // interface to lfsr
+  output logic seed_en_o,
+  output logic [LfsrWidth-1:0] seed_o
+);
+
+  localparam int EdnRounds = LfsrWidth / EdnWidth;
+  localparam int EdnCntWidth = prim_util_pkg::vbits(EdnRounds);
+
+  // counter to track number of edn rounds
+  logic [EdnCntWidth-1:0] edn_cnt;
+  logic edn_txn_done;
+  logic edn_done;
+  logic edn_req, edn_ack;
+  logic [EdnWidth-1:0] edn_data;
+
+  // This tracks how many edn rounds are required to fill up
+  // one required entry.
+  assign edn_txn_done = edn_req & edn_ack;
+  assign edn_done = (edn_cnt == EdnRounds - 1) & edn_txn_done;
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      edn_cnt <= '0;
+    end else if (edn_done) begin
+      edn_cnt <= '0;
+    end else if (edn_txn_done) begin
+      edn_cnt <= edn_cnt - 1'b1;
+    end
+  end
+
+  // first activation of edn counter
+  logic first_use;
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      first_use <= 1'b1;
+    end else if (edn_done) begin
+      first_use <= 1'b0;
+    end
+  end
+
+  // whenever reseed count drops to 0, issue a request and wait for ack
+  logic [15:0] reseed_cnt;
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      reseed_cnt <= '{default: 1};
+    end else if(edn_done) begin
+      reseed_cnt <= reseed_interval_i;
+    end else if(reseed_req_i) begin
+      reseed_cnt <= '0;
+    end else if(|reseed_cnt && !first_use) begin
+      reseed_cnt <= reseed_cnt - 1'b1;
+    end
+  end
+
+  assign edn_req = (reseed_cnt == '0);
+  assign reseed_ack_o = reseed_req_i & edn_done;
+  assign seed_en_o = edn_done;
+
+  if (EdnRounds == 1) begin : gen_same_width
+    assign seed_o = edn_data;
+  end else begin : gen_mult_width
+    // hold one less transaction in storage
+    localparam int DeltaWidth = LfsrWidth-EdnWidth;
+    logic [DeltaWidth-1:0] seed_q;
+
+    if (DeltaWidth > EdnWidth) begin : gen_greater_width
+      always_ff @(posedge clk_i) begin
+        if (edn_txn_done) begin
+          seed_q <= {seed_q[0 +: DeltaWidth-EdnWidth], edn_data};
+        end
+      end
+    end begin : gen_double_width
+      always_ff @(posedge clk_i) begin
+        if (edn_txn_done) begin
+          seed_q <= edn_data;
+        end
+      end
+    end
+
+    assign seed_o = {seed_q, edn_data};
+  end
+
+  //req/ack interface to edn
+  prim_sync_reqack u_reqack (
+    .clk_src_i(clk_i),
+    .rst_src_ni(rst_ni),
+    .clk_dst_i(clk_edn_i),
+    .rst_dst_ni(rst_edn_ni),
+    .src_req_i(edn_req),
+    .src_ack_o(edn_ack),
+    .dst_req_o(edn_o.edn_req),
+    .dst_ack_i(edn_i.edn_ack)
+  );
+
+  // capture the data on edn domain since the ack interface
+  // finishes before the source domain is able to see it
+  always_ff @(posedge clk_edn_i) begin
+    if (edn_o.edn_req && edn_i.edn_ack) begin
+      edn_data <= edn_i.edn_bus;
+    end
+  end
+
+
+  logic unused_fips;
+  assign unused_fips = edn_i.edn_fips;
+
+endmodule // keymgr_reseed_ctrl
diff --git a/hw/ip/prim/rtl/prim_sync_reqack.sv b/hw/ip/prim/rtl/prim_sync_reqack.sv
index 2481c71..808630b 100644
--- a/hw/ip/prim/rtl/prim_sync_reqack.sv
+++ b/hw/ip/prim/rtl/prim_sync_reqack.sv
@@ -150,9 +150,9 @@
   end
 
   // Source domain cannot de-assert REQ while waiting for ACK.
-  `ASSERT(ReqAckSyncHoldReq, $fell(src_req_i) |-> (src_fsm_cs != HANDSHAKE), clk_src_i, rst_src_ni)
+  `ASSERT(ReqAckSyncHoldReq, $fell(src_req_i) |-> (src_fsm_cs != HANDSHAKE), clk_src_i, !rst_src_ni)
 
   // Destination domain cannot assert ACK without REQ.
-  `ASSERT(ReqAckSyncAckNeedsReq, dst_ack_i |-> dst_req_o, clk_dst_i, rst_dst_ni)
+  `ASSERT(ReqAckSyncAckNeedsReq, dst_ack_i |-> dst_req_o, clk_dst_i, !rst_dst_ni)
 
 endmodule
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index 119383d..b3a51e8 100755
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -322,9 +322,9 @@
     },
     { name: "keymgr",
       type: "keymgr",
-      clock_srcs: {clk_i: "main"},
+      clock_srcs: {clk_i: "main", clk_edn_i: "main"},
       clock_group: "secure",
-      reset_connections: {rst_ni: "sys"},
+      reset_connections: {rst_ni: "sys", rst_edn_ni: "sys"},
       base_addr: "0x41130000",
     },
     { name: "csrng",
@@ -507,6 +507,9 @@
       'flash_ctrl.keymgr': ['keymgr.flash'],
       'alert_handler.crashdump': ['rstmgr.alert_dump'],
       'csrng.entropy_src_hw_if' : ['entropy_src.entropy_src_hw_if'],
+      // TODO see #4447
+      //'edn0.edn' : ['keymgr.edn'],
+
 
       // KeyMgr Sideload & KDF function
       'otp_ctrl.otp_keymgr_key': ['keymgr.otp_key'],