[rom_ctrl] Add initial RTL

This doesn't really do anything very interesting: it just replaces the
ROM instantiation that was in top_earlgrey.sv and generates a verbose
wrapper around it.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/hw/Makefile b/hw/Makefile
index c9fa919..3155b51 100644
--- a/hw/Makefile
+++ b/hw/Makefile
@@ -30,6 +30,7 @@
        pattgen       \
        pinmux        \
        pwrmgr        \
+       rom_ctrl      \
        rstmgr        \
        rv_plic       \
        rv_timer      \
diff --git a/hw/ip/rom_ctrl/data/rom_ctrl.hjson b/hw/ip/rom_ctrl/data/rom_ctrl.hjson
new file mode 100644
index 0000000..de973c9
--- /dev/null
+++ b/hw/ip/rom_ctrl/data/rom_ctrl.hjson
@@ -0,0 +1,75 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+{
+  name: "rom_ctrl"
+  clock_primary: "clk_i"
+  reset_primary: "rst_ni",
+  regwidth: "32"
+  bus_interfaces: [
+    { protocol: "tlul", direction: "device", name: "regs" }
+    { protocol: "tlul", direction: "device", name: "rom" },
+  ],
+  param_list: [
+    { name:    "BootRomInitFile",
+      type:    "",
+      default: '""',
+      desc:    "Contents of mask ROM"
+      local:   "false",
+      expose:  "true"
+    }
+  ]
+  alert_list: [
+    { name: "fatal"
+      desc: "A fatal error. Fatal alerts are non-recoverable and will be asserted until a hard reset."
+    }
+  ],
+  inter_signal_list: [
+    // Interface to memory configuration
+    { name:    "rom_cfg",
+      package: "prim_rom_pkg",
+      struct:  "rom_cfg",
+      act:     "rcv"
+      type:    "uni",
+    }
+  ],
+  registers: {
+    regs: [
+      { name: "FATAL_ALERT_CAUSE",
+        desc: '''
+          The cause of a fatal alert.
+
+          The bits of this register correspond to errors that can cause a fatal
+          alert. Software can read these bits to see what went wrong. Once set,
+          these bits cannot be cleared.
+        '''
+        swaccess: "ro",
+        hwaccess: "hwo",
+        fields: [
+          { bits: "0",
+            name: "integrity_error",
+            resval: 0,
+            desc: "Set on an integrity error from the register interface"
+          }
+
+          { bits: "1",
+            name: "dummy",
+            resval: 0,
+            desc: "Dummy index to prevent reggen from hiding the array."
+          }
+        ]
+      }
+    ],
+
+    rom: [
+      // ROM size (given as `items` below) must be a power of two.
+      { window: {
+          name: "ROM"
+          items: "4096" // 16 KiB
+          swaccess: "ro",
+          desc: '''ROM data'''
+        }
+      }
+    ]
+  }
+}
diff --git a/hw/ip/rom_ctrl/lint/rom_ctrl.vlt b/hw/ip/rom_ctrl/lint/rom_ctrl.vlt
new file mode 100644
index 0000000..affe750
--- /dev/null
+++ b/hw/ip/rom_ctrl/lint/rom_ctrl.vlt
@@ -0,0 +1,5 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`verilator_config
diff --git a/hw/ip/rom_ctrl/lint/rom_ctrl.waiver b/hw/ip/rom_ctrl/lint/rom_ctrl.waiver
new file mode 100644
index 0000000..fd60e61
--- /dev/null
+++ b/hw/ip/rom_ctrl/lint/rom_ctrl.waiver
@@ -0,0 +1,4 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
diff --git a/hw/ip/rom_ctrl/rom_ctrl.core b/hw/ip/rom_ctrl/rom_ctrl.core
new file mode 100644
index 0000000..f0aae3b
--- /dev/null
+++ b/hw/ip/rom_ctrl/rom_ctrl.core
@@ -0,0 +1,65 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:ip:rom_ctrl:0.1"
+description: "ROM controller"
+
+filesets:
+  files_rtl:
+    depend:
+      - lowrisc:prim:alert
+      - lowrisc:prim:assert
+      - lowrisc:prim:rom_adv
+      - lowrisc:prim:subreg
+      - lowrisc:prim:util
+      - lowrisc:ip:tlul
+    files:
+      - rtl/rom_ctrl_pkg.sv
+      - rtl/rom_ctrl_reg_pkg.sv
+      - rtl/rom_ctrl_regs_reg_top.sv
+      - rtl/rom_ctrl_rom_reg_top.sv
+      - rtl/rom_ctrl.sv
+    file_type: systemVerilogSource
+
+  files_verilator_waiver:
+    depend:
+      # common waivers
+      - lowrisc:lint:common
+      - lowrisc:lint:comportable
+    files:
+      - lint/rom_ctrl.vlt
+    file_type: vlt
+
+  files_ascentlint_waiver:
+    depend:
+      # common waivers
+      - lowrisc:lint:common
+      - lowrisc:lint:comportable
+    files:
+      - lint/rom_ctrl.waiver
+    file_type: waiver
+
+parameters:
+  SYNTHESIS:
+    datatype: bool
+    paramtype: vlogdefine
+
+targets:
+  default: &default_target
+    filesets:
+      - tool_verilator ? (files_verilator_waiver)
+      - tool_ascentlint ? (files_ascentlint_waiver)
+      - files_rtl
+    toplevel: rom_ctrl
+
+  lint:
+    <<: *default_target
+    default_tool: verilator
+    parameters:
+      - SYNTHESIS=true
+    tools:
+      verilator:
+        mode: lint-only
+        verilator_options:
+          - "-Wall"
diff --git a/hw/ip/rom_ctrl/rtl/rom_ctrl.sv b/hw/ip/rom_ctrl/rtl/rom_ctrl.sv
new file mode 100644
index 0000000..2bd197f
--- /dev/null
+++ b/hw/ip/rom_ctrl/rtl/rom_ctrl.sv
@@ -0,0 +1,173 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+
+module rom_ctrl
+  import rom_ctrl_reg_pkg::NumAlerts;
+  import prim_rom_pkg::rom_cfg_t;
+#(
+  parameter                       BootRomInitFile = "",
+  parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}
+) (
+  input  clk_i,
+  input  rst_ni,
+
+  // ROM configuration parameters
+  input  rom_cfg_t rom_cfg_i,
+
+  input  tlul_pkg::tl_h2d_t rom_tl_i,
+  output tlul_pkg::tl_d2h_t rom_tl_o,
+
+  input  tlul_pkg::tl_h2d_t regs_tl_i,
+  output tlul_pkg::tl_d2h_t regs_tl_o,
+
+  // Alerts
+  input  prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i,
+  output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o
+);
+
+  import rom_ctrl_pkg::*;
+  import rom_ctrl_reg_pkg::*;
+  import prim_util_pkg::vbits;
+
+  // TL interface ==============================================================
+
+  tlul_pkg::tl_h2d_t tl_rom_h2d [1];
+  tlul_pkg::tl_d2h_t tl_rom_d2h [1];
+
+  rom_ctrl_rom_reg_top u_rom_top (
+      .clk_i      (clk_i),
+      .rst_ni     (rst_ni),
+      .tl_i       (rom_tl_i),
+      .tl_o       (rom_tl_o),
+      .tl_win_o   (tl_rom_h2d),
+      .tl_win_i   (tl_rom_d2h),
+
+      // TODO
+      .intg_err_o (),
+
+      .devmode_i  (1'b1)
+    );
+
+  // The ROM ===================================================================
+
+  // ROM_CTRL_ROM_SIZE is auto-generated by regtool and comes from the bus window size, measured in
+  // bytes of content (i.e. 4 times the number of 32 bit words).
+  localparam int unsigned RomSizeByte = ROM_CTRL_ROM_SIZE;
+  localparam int unsigned RomSizeWords = RomSizeByte >> 2;
+  localparam int unsigned RomIndexWidth = vbits(RomSizeWords);
+
+  logic                     rom_req;
+  logic [RomIndexWidth-1:0] rom_index;
+  logic [39:0]              rom_rdata;
+  logic                     rom_rvalid;
+
+  tlul_adapter_sram #(
+    .SramAw(RomIndexWidth),
+    .SramDw(32),
+    .Outstanding(2),
+    .ByteAccess(0),
+    .ErrOnWrite(1),
+    .EnableRspIntgGen(1),
+    .EnableDataIntgGen(1) // TODO: Needs to be updated for integrity passthrough
+  ) u_tl_adapter_rom (
+    .clk_i        (clk_i),
+    .rst_ni       (rst_ni),
+
+    .tl_i         (tl_rom_h2d[0]),
+    .tl_o         (tl_rom_d2h[0]),
+    .en_ifetch_i  (tlul_pkg::InstrEn),
+    .req_o        (rom_req),
+    .gnt_i        (1'b1),
+    .we_o         (),
+    .addr_o       (rom_index),
+    .wdata_o      (),
+    .wmask_o      (),
+    .intg_error_o (),
+    .rdata_i      (rom_rdata[31:0]),
+    .rvalid_i     (rom_rvalid),
+    .rerror_i     (2'b00)
+  );
+
+  prim_rom_adv #(
+    .Width       (40),
+    .Depth       (RomSizeWords),
+    .MemInitFile (BootRomInitFile)
+  ) u_rom
+   (
+    .clk_i    (clk_i),
+    .rst_ni   (rst_ni),
+    .req_i    (rom_req),
+    .addr_i   (rom_index),
+    .rdata_o  (rom_rdata),
+    .rvalid_o (rom_rvalid),
+    .cfg_i    (rom_cfg_i)
+  );
+
+  // TODO: The ROM has been expanded to 40 bits wide to allow us to add 9 ECC check bits. At the
+  //       moment, however, we're actually generating the ECC data in u_tl_adapter_rom. That should
+  //       go away soonish but, until then, waive the fact that we're not looking at the top bits of
+  //       rom_rdata.
+  logic unused_rom_rdata_top;
+  assign unused_rom_rdata_top = &{1'b0, rom_rdata[39:32]};
+
+  // Registers =================================================================
+
+  rom_ctrl_regs_reg2hw_t reg2hw;
+  rom_ctrl_regs_hw2reg_t hw2reg;
+  logic                  reg_integrity_error;
+
+  rom_ctrl_regs_reg_top u_reg_top (
+    .clk_i      (clk_i),
+    .rst_ni     (rst_ni),
+    .tl_i       (regs_tl_i),
+    .tl_o       (regs_tl_o),
+    .reg2hw     (reg2hw),
+    .hw2reg     (hw2reg),
+    .intg_err_o (reg_integrity_error),
+    .devmode_i  (1'b1)
+   );
+
+  // FATAL_ALERT_CAUSE register
+  assign hw2reg.fatal_alert_cause.integrity_error.d  = reg_integrity_error;
+  assign hw2reg.fatal_alert_cause.integrity_error.de = reg_integrity_error;
+  assign hw2reg.fatal_alert_cause.dummy.d  = 1'b0;
+  assign hw2reg.fatal_alert_cause.dummy.de = 1'b0;
+
+  // Alert generation ==========================================================
+
+  logic [NumAlerts-1:0] alert_test;
+  assign alert_test[AlertFatal] = reg2hw.alert_test.q &
+                                  reg2hw.alert_test.qe;
+
+  logic [NumAlerts-1:0] alerts;
+  assign alerts[AlertFatal] = reg_integrity_error;
+
+  for (genvar i = 0; i < NumAlerts; i++) begin: gen_alert_tx
+    prim_alert_sender #(
+      .AsyncOn(AlertAsyncOn[i]),
+      .IsFatal(i == AlertFatal)
+    ) u_alert_sender (
+      .clk_i,
+      .rst_ni,
+      .alert_test_i  ( alert_test[i] ),
+      .alert_req_i   ( alerts[i]     ),
+      .alert_ack_o   (               ),
+      .alert_state_o (               ),
+      .alert_rx_i    ( alert_rx_i[i] ),
+      .alert_tx_o    ( alert_tx_o[i] )
+    );
+  end
+
+  // Asserts ===================================================================
+
+  // All outputs should be known value after reset
+  `ASSERT_KNOWN(RomTlODValidKnown_A, rom_tl_o.d_valid)
+  `ASSERT_KNOWN(RomTlOAReadyKnown_A, rom_tl_o.a_ready)
+  `ASSERT_KNOWN(RegTlODValidKnown_A, regs_tl_o.d_valid)
+  `ASSERT_KNOWN(RegTlOAReadyKnown_A, regs_tl_o.a_ready)
+  `ASSERT_KNOWN(AlertTxOKnown_A, alert_tx_o)
+
+endmodule
diff --git a/hw/ip/rom_ctrl/rtl/rom_ctrl_pkg.sv b/hw/ip/rom_ctrl/rtl/rom_ctrl_pkg.sv
new file mode 100644
index 0000000..05d3786
--- /dev/null
+++ b/hw/ip/rom_ctrl/rtl/rom_ctrl_pkg.sv
@@ -0,0 +1,11 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+
+package rom_ctrl_pkg;
+
+  parameter int AlertFatal = 0;
+
+endpackage
diff --git a/hw/ip/rom_ctrl/rtl/rom_ctrl_reg_pkg.sv b/hw/ip/rom_ctrl/rtl/rom_ctrl_reg_pkg.sv
new file mode 100644
index 0000000..0d95045
--- /dev/null
+++ b/hw/ip/rom_ctrl/rtl/rom_ctrl_reg_pkg.sv
@@ -0,0 +1,71 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Register Package auto-generated by `reggen` containing data structure
+
+package rom_ctrl_reg_pkg;
+
+  // Param list
+  parameter int NumAlerts = 1;
+
+  // Address widths within the block
+  parameter int RegsAw = 3;
+  parameter int RomAw = 14;
+
+  ///////////////////////////////////////////////
+  // Typedefs for registers for regs interface //
+  ///////////////////////////////////////////////
+
+  typedef struct packed {
+    logic        q;
+    logic        qe;
+  } rom_ctrl_reg2hw_alert_test_reg_t;
+
+  typedef struct packed {
+    struct packed {
+      logic        d;
+      logic        de;
+    } integrity_error;
+    struct packed {
+      logic        d;
+      logic        de;
+    } dummy;
+  } rom_ctrl_hw2reg_fatal_alert_cause_reg_t;
+
+  // Register -> HW type for regs interface
+  typedef struct packed {
+    rom_ctrl_reg2hw_alert_test_reg_t alert_test; // [1:0]
+  } rom_ctrl_regs_reg2hw_t;
+
+  // HW -> register type for regs interface
+  typedef struct packed {
+    rom_ctrl_hw2reg_fatal_alert_cause_reg_t fatal_alert_cause; // [3:0]
+  } rom_ctrl_regs_hw2reg_t;
+
+  // Register offsets for regs interface
+  parameter logic [RegsAw-1:0] ROM_CTRL_ALERT_TEST_OFFSET = 3'h 0;
+  parameter logic [RegsAw-1:0] ROM_CTRL_FATAL_ALERT_CAUSE_OFFSET = 3'h 4;
+
+  // Reset values for hwext registers and their fields for regs interface
+  parameter logic [0:0] ROM_CTRL_ALERT_TEST_RESVAL = 1'h 0;
+  parameter logic [0:0] ROM_CTRL_ALERT_TEST_FATAL_RESVAL = 1'h 0;
+
+  // Register index for regs interface
+  typedef enum int {
+    ROM_CTRL_ALERT_TEST,
+    ROM_CTRL_FATAL_ALERT_CAUSE
+  } rom_ctrl_regs_id_e;
+
+  // Register width information to check illegal writes for regs interface
+  parameter logic [3:0] ROM_CTRL_REGS_PERMIT [2] = '{
+    4'b 0001, // index[0] ROM_CTRL_ALERT_TEST
+    4'b 0001  // index[1] ROM_CTRL_FATAL_ALERT_CAUSE
+  };
+
+  // Window parameters for rom interface
+  parameter logic [RomAw-1:0] ROM_CTRL_ROM_OFFSET = 14'h 0;
+  parameter int unsigned      ROM_CTRL_ROM_SIZE   = 'h 4000;
+
+endpackage
+
diff --git a/hw/ip/rom_ctrl/rtl/rom_ctrl_regs_reg_top.sv b/hw/ip/rom_ctrl/rtl/rom_ctrl_regs_reg_top.sv
new file mode 100644
index 0000000..364be39
--- /dev/null
+++ b/hw/ip/rom_ctrl/rtl/rom_ctrl_regs_reg_top.sv
@@ -0,0 +1,238 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Register Top module auto-generated by `reggen`
+
+`include "prim_assert.sv"
+
+module rom_ctrl_regs_reg_top (
+  input clk_i,
+  input rst_ni,
+
+  input  tlul_pkg::tl_h2d_t tl_i,
+  output tlul_pkg::tl_d2h_t tl_o,
+  // To HW
+  output rom_ctrl_reg_pkg::rom_ctrl_regs_reg2hw_t reg2hw, // Write
+  input  rom_ctrl_reg_pkg::rom_ctrl_regs_hw2reg_t hw2reg, // Read
+
+  // Integrity check errors
+  output logic intg_err_o,
+
+  // Config
+  input devmode_i // If 1, explicit error return for unmapped register access
+);
+
+  import rom_ctrl_reg_pkg::* ;
+
+  localparam int AW = 3;
+  localparam int DW = 32;
+  localparam int DBW = DW/8;                    // Byte Width
+
+  // register signals
+  logic           reg_we;
+  logic           reg_re;
+  logic [AW-1:0]  reg_addr;
+  logic [DW-1:0]  reg_wdata;
+  logic [DBW-1:0] reg_be;
+  logic [DW-1:0]  reg_rdata;
+  logic           reg_error;
+
+  logic          addrmiss, wr_err;
+
+  logic [DW-1:0] reg_rdata_next;
+
+  tlul_pkg::tl_h2d_t tl_reg_h2d;
+  tlul_pkg::tl_d2h_t tl_reg_d2h;
+
+  // incoming payload check
+  logic intg_err;
+  tlul_cmd_intg_chk u_chk (
+    .tl_i,
+    .err_o(intg_err)
+  );
+
+  logic intg_err_q;
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      intg_err_q <= '0;
+    end else if (intg_err) begin
+      intg_err_q <= 1'b1;
+    end
+  end
+
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
+  // outgoing integrity generation
+  tlul_pkg::tl_d2h_t tl_o_pre;
+  tlul_rsp_intg_gen u_rsp_intg_gen (
+    .tl_i(tl_o_pre),
+    .tl_o
+  );
+
+  assign tl_reg_h2d = tl_i;
+  assign tl_o_pre   = tl_reg_d2h;
+
+  tlul_adapter_reg #(
+    .RegAw(AW),
+    .RegDw(DW)
+  ) u_reg_if (
+    .clk_i,
+    .rst_ni,
+
+    .tl_i (tl_reg_h2d),
+    .tl_o (tl_reg_d2h),
+
+    .we_o    (reg_we),
+    .re_o    (reg_re),
+    .addr_o  (reg_addr),
+    .wdata_o (reg_wdata),
+    .be_o    (reg_be),
+    .rdata_i (reg_rdata),
+    .error_i (reg_error)
+  );
+
+  assign reg_rdata = reg_rdata_next ;
+  assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
+
+  // Define SW related signals
+  // Format: <reg>_<field>_{wd|we|qs}
+  //        or <reg>_{wd|we|qs} if field == 1 or 0
+  logic alert_test_wd;
+  logic alert_test_we;
+  logic fatal_alert_cause_integrity_error_qs;
+  logic fatal_alert_cause_dummy_qs;
+
+  // Register instances
+  // R[alert_test]: V(True)
+
+  prim_subreg_ext #(
+    .DW    (1)
+  ) u_alert_test (
+    .re     (1'b0),
+    .we     (alert_test_we),
+    .wd     (alert_test_wd),
+    .d      ('0),
+    .qre    (),
+    .qe     (reg2hw.alert_test.qe),
+    .q      (reg2hw.alert_test.q ),
+    .qs     ()
+  );
+
+
+  // R[fatal_alert_cause]: V(False)
+
+  //   F[integrity_error]: 0:0
+  prim_subreg #(
+    .DW      (1),
+    .SWACCESS("RO"),
+    .RESVAL  (1'h0)
+  ) u_fatal_alert_cause_integrity_error (
+    .clk_i   (clk_i    ),
+    .rst_ni  (rst_ni  ),
+
+    .we     (1'b0),
+    .wd     ('0  ),
+
+    // from internal hardware
+    .de     (hw2reg.fatal_alert_cause.integrity_error.de),
+    .d      (hw2reg.fatal_alert_cause.integrity_error.d ),
+
+    // to internal hardware
+    .qe     (),
+    .q      (),
+
+    // to register interface (read)
+    .qs     (fatal_alert_cause_integrity_error_qs)
+  );
+
+
+  //   F[dummy]: 1:1
+  prim_subreg #(
+    .DW      (1),
+    .SWACCESS("RO"),
+    .RESVAL  (1'h0)
+  ) u_fatal_alert_cause_dummy (
+    .clk_i   (clk_i    ),
+    .rst_ni  (rst_ni  ),
+
+    .we     (1'b0),
+    .wd     ('0  ),
+
+    // from internal hardware
+    .de     (hw2reg.fatal_alert_cause.dummy.de),
+    .d      (hw2reg.fatal_alert_cause.dummy.d ),
+
+    // to internal hardware
+    .qe     (),
+    .q      (),
+
+    // to register interface (read)
+    .qs     (fatal_alert_cause_dummy_qs)
+  );
+
+
+
+
+  logic [1:0] addr_hit;
+  always_comb begin
+    addr_hit = '0;
+    addr_hit[0] = (reg_addr == ROM_CTRL_ALERT_TEST_OFFSET);
+    addr_hit[1] = (reg_addr == ROM_CTRL_FATAL_ALERT_CAUSE_OFFSET);
+  end
+
+  assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
+
+  // Check sub-word write is permitted
+  always_comb begin
+    wr_err = 1'b0;
+    if (addr_hit[0] && reg_we && (ROM_CTRL_REGS_PERMIT[0] != (ROM_CTRL_REGS_PERMIT[0] & reg_be))) wr_err = 1'b1 ;
+    if (addr_hit[1] && reg_we && (ROM_CTRL_REGS_PERMIT[1] != (ROM_CTRL_REGS_PERMIT[1] & reg_be))) wr_err = 1'b1 ;
+  end
+
+  assign alert_test_we = addr_hit[0] & reg_we & !reg_error;
+  assign alert_test_wd = reg_wdata[0];
+
+  // Read data return
+  always_comb begin
+    reg_rdata_next = '0;
+    unique case (1'b1)
+      addr_hit[0]: begin
+        reg_rdata_next[0] = '0;
+      end
+
+      addr_hit[1]: begin
+        reg_rdata_next[0] = fatal_alert_cause_integrity_error_qs;
+        reg_rdata_next[1] = fatal_alert_cause_dummy_qs;
+      end
+
+      default: begin
+        reg_rdata_next = '1;
+      end
+    endcase
+  end
+
+  // Unused signal tieoff
+
+  // wdata / byte enable are not always fully used
+  // add a blanket unused statement to handle lint waivers
+  logic unused_wdata;
+  logic unused_be;
+  assign unused_wdata = ^reg_wdata;
+  assign unused_be = ^reg_be;
+
+  // Assertions for Register Interface
+  `ASSERT_PULSE(wePulse, reg_we)
+  `ASSERT_PULSE(rePulse, reg_re)
+
+  `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+
+  `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+
+  // this is formulated as an assumption such that the FPV testbenches do disprove this
+  // property by mistake
+  //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis)
+
+endmodule
diff --git a/hw/ip/rom_ctrl/rtl/rom_ctrl_rom_reg_top.sv b/hw/ip/rom_ctrl/rtl/rom_ctrl_rom_reg_top.sv
new file mode 100644
index 0000000..54e2507
--- /dev/null
+++ b/hw/ip/rom_ctrl/rtl/rom_ctrl_rom_reg_top.sv
@@ -0,0 +1,66 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Register Top module auto-generated by `reggen`
+
+`include "prim_assert.sv"
+
+module rom_ctrl_rom_reg_top (
+  input clk_i,
+  input rst_ni,
+
+  input  tlul_pkg::tl_h2d_t tl_i,
+  output tlul_pkg::tl_d2h_t tl_o,
+
+  // Output port for window
+  output tlul_pkg::tl_h2d_t tl_win_o  [1],
+  input  tlul_pkg::tl_d2h_t tl_win_i  [1],
+
+  // To HW
+
+  // Integrity check errors
+  output logic intg_err_o,
+
+  // Config
+  input devmode_i // If 1, explicit error return for unmapped register access
+);
+
+  import rom_ctrl_reg_pkg::* ;
+
+
+  // incoming payload check
+  logic intg_err;
+  tlul_cmd_intg_chk u_chk (
+    .tl_i,
+    .err_o(intg_err)
+  );
+
+  logic intg_err_q;
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      intg_err_q <= '0;
+    end else if (intg_err) begin
+      intg_err_q <= 1'b1;
+    end
+  end
+
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
+  // outgoing integrity generation
+  tlul_pkg::tl_d2h_t tl_o_pre;
+  tlul_rsp_intg_gen u_rsp_intg_gen (
+    .tl_i(tl_o_pre),
+    .tl_o
+  );
+
+  assign tl_win_o[0] = tl_i;
+  assign tl_o_pre    = tl_win_i[0];
+
+  // Unused signal tieoff
+  // devmode_i is not used if there are no registers
+  logic unused_devmode;
+  assign unused_devmode = ^devmode_i;
+endmodule
diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
index 3f2d820..716f0ed 100644
--- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
+++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
@@ -4827,11 +4827,9 @@
         null: 0x411D0000
       }
     }
-  ]
-  memory:
-  [
     {
-      name: rom
+      name: rom_ctrl
+      type: rom_ctrl
       clock_srcs:
       {
         clk_i: main
@@ -4841,45 +4839,72 @@
       {
         rst_ni: rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]
       }
-      type: rom
-      base_addr: 0x00008000
-      swaccess: ro
-      size: 0x4000
-      integ_width: 8
-      inter_signal_list:
-      [
-        {
-          struct: tl
-          package: tlul_pkg
-          type: req_rsp
-          act: rsp
-          name: tl
-          inst_name: rom
-          width: 1
-          default: ""
-          end_idx: -1
-          top_signame: rom_tl
-          index: -1
-        }
-        {
-          struct: rom_cfg
-          package: prim_rom_pkg
-          type: uni
-          name: cfg
-          act: rcv
-          inst_name: rom
-          width: 1
-          default: ""
-          top_signame: ast_rom_cfg
-          index: -1
-        }
-      ]
+      base_addrs:
+      {
+        rom: 0x00008000
+        regs: 0x411e0000
+      }
       clock_connections:
       {
         clk_i: clkmgr_aon_clocks.clk_main_infra
       }
       domain: "0"
+      param_list:
+      [
+        {
+          name: BootRomInitFile
+          desc: Contents of mask ROM
+          type: ""
+          default: '''""'''
+          expose: "true"
+          name_top: RomCtrlBootRomInitFile
+        }
+      ]
+      inter_signal_list:
+      [
+        {
+          name: rom_cfg
+          struct: rom_cfg
+          package: prim_rom_pkg
+          type: uni
+          act: rcv
+          width: 1
+          inst_name: rom_ctrl
+          default: ""
+          top_signame: ast_rom_cfg
+          index: -1
+        }
+        {
+          name: regs_tl
+          struct: tl
+          package: tlul_pkg
+          type: req_rsp
+          act: rsp
+          width: 1
+          inst_name: rom_ctrl
+          default: ""
+          end_idx: -1
+          top_signame: rom_ctrl_regs_tl
+          index: -1
+        }
+        {
+          name: rom_tl
+          struct: tl
+          package: tlul_pkg
+          type: req_rsp
+          act: rsp
+          width: 1
+          inst_name: rom_ctrl
+          default: ""
+          end_idx: -1
+          top_signame: rom_ctrl_rom_tl
+          index: -1
+        }
+      ]
     }
+  ]
+  memory:
+  [
     {
       name: ram_main
       clock_srcs:
@@ -5314,7 +5339,7 @@
       ]
       ast.rom_cfg:
       [
-        rom.cfg
+        rom_ctrl.rom_cfg
       ]
       alert_handler.crashdump:
       [
@@ -5594,9 +5619,13 @@
       [
         aon_timer_aon.aon_timer_rst_req
       ]
-      rom.tl:
+      rom_ctrl.rom_tl:
       [
-        main.tl_rom
+        main.tl_rom_ctrl__rom
+      ]
+      rom_ctrl.regs_tl:
+      [
+        main.tl_rom_ctrl__regs
       ]
       ram_main.tl:
       [
@@ -5835,14 +5864,15 @@
       {
         corei:
         [
-          rom
+          rom_ctrl.rom
           debug_mem
           ram_main
           eflash
         ]
         cored:
         [
-          rom
+          rom_ctrl.rom
+          rom_ctrl.regs
           debug_mem
           ram_main
           eflash
@@ -5862,7 +5892,8 @@
         ]
         dm_sba:
         [
-          rom
+          rom_ctrl.rom
+          rom_ctrl.regs
           ram_main
           eflash
           peri
@@ -5915,12 +5946,12 @@
           pipeline: "true"
         }
         {
-          name: rom
+          name: rom_ctrl.rom
           type: device
           clock: clk_main_i
           reset: rst_main_ni
           pipeline: "false"
-          inst_type: rom
+          inst_type: rom_ctrl
           addr_range:
           [
             {
@@ -5933,6 +5964,24 @@
           pipeline_byp: "true"
         }
         {
+          name: rom_ctrl.regs
+          type: device
+          clock: clk_main_i
+          reset: rst_main_ni
+          pipeline: "false"
+          inst_type: rom_ctrl
+          addr_range:
+          [
+            {
+              base_addr: 0x411e0000
+              size_byte: 0x1000
+            }
+          ]
+          xbar: false
+          stub: false
+          pipeline_byp: "true"
+        }
+        {
           name: debug_mem
           type: device
           clock: clk_main_i
@@ -6261,7 +6310,7 @@
           index: -1
         }
         {
-          name: tl_rom
+          name: tl_rom_ctrl__rom
           struct: tl
           package: tlul_pkg
           type: req_rsp
@@ -6269,7 +6318,19 @@
           width: 1
           inst_name: main
           default: ""
-          top_signame: rom_tl
+          top_signame: rom_ctrl_rom_tl
+          index: -1
+        }
+        {
+          name: tl_rom_ctrl__regs
+          struct: tl
+          package: tlul_pkg
+          type: req_rsp
+          act: req
+          width: 1
+          inst_name: main
+          default: ""
+          top_signame: rom_ctrl_regs_tl
           index: -1
         }
         {
@@ -8873,6 +8934,7 @@
     edn1
     sram_ctrl_main
     otbn
+    rom_ctrl
   ]
   alert:
   [
@@ -9079,6 +9141,13 @@
       async: "1"
       module_name: otbn
     }
+    {
+      name: rom_ctrl_fatal
+      width: 1
+      type: alert
+      async: "1"
+      module_name: rom_ctrl
+    }
   ]
   exported_rsts:
   {
@@ -11847,28 +11916,41 @@
         index: -1
       }
       {
+        name: rom_cfg
+        struct: rom_cfg
+        package: prim_rom_pkg
+        type: uni
+        act: rcv
+        width: 1
+        inst_name: rom_ctrl
+        default: ""
+        top_signame: ast_rom_cfg
+        index: -1
+      }
+      {
+        name: regs_tl
         struct: tl
         package: tlul_pkg
         type: req_rsp
         act: rsp
-        name: tl
-        inst_name: rom
         width: 1
+        inst_name: rom_ctrl
         default: ""
         end_idx: -1
-        top_signame: rom_tl
+        top_signame: rom_ctrl_regs_tl
         index: -1
       }
       {
-        struct: rom_cfg
-        package: prim_rom_pkg
-        type: uni
-        name: cfg
-        act: rcv
-        inst_name: rom
+        name: rom_tl
+        struct: tl
+        package: tlul_pkg
+        type: req_rsp
+        act: rsp
         width: 1
+        inst_name: rom_ctrl
         default: ""
-        top_signame: ast_rom_cfg
+        end_idx: -1
+        top_signame: rom_ctrl_rom_tl
         index: -1
       }
       {
@@ -12153,7 +12235,7 @@
         index: -1
       }
       {
-        name: tl_rom
+        name: tl_rom_ctrl__rom
         struct: tl
         package: tlul_pkg
         type: req_rsp
@@ -12161,7 +12243,19 @@
         width: 1
         inst_name: main
         default: ""
-        top_signame: rom_tl
+        top_signame: rom_ctrl_rom_tl
+        index: -1
+      }
+      {
+        name: tl_rom_ctrl__regs
+        struct: tl
+        package: tlul_pkg
+        type: req_rsp
+        act: req
+        width: 1
+        inst_name: main
+        default: ""
+        top_signame: rom_ctrl_regs_tl
         index: -1
       }
       {
@@ -14227,7 +14321,7 @@
       {
         package: tlul_pkg
         struct: tl_h2d
-        signame: rom_tl_req
+        signame: rom_ctrl_rom_tl_req
         width: 1
         type: req_rsp
         end_idx: -1
@@ -14238,7 +14332,29 @@
       {
         package: tlul_pkg
         struct: tl_d2h
-        signame: rom_tl_rsp
+        signame: rom_ctrl_rom_tl_rsp
+        width: 1
+        type: req_rsp
+        end_idx: -1
+        act: rsp
+        suffix: rsp
+        default: ""
+      }
+      {
+        package: tlul_pkg
+        struct: tl_h2d
+        signame: rom_ctrl_regs_tl_req
+        width: 1
+        type: req_rsp
+        end_idx: -1
+        act: rsp
+        suffix: req
+        default: ""
+      }
+      {
+        package: tlul_pkg
+        struct: tl_d2h
+        signame: rom_ctrl_regs_tl_rsp
         width: 1
         type: req_rsp
         end_idx: -1
diff --git a/hw/top_earlgrey/data/placement.xdc b/hw/top_earlgrey/data/placement.xdc
index 328c437..13b3d9f 100644
--- a/hw/top_earlgrey/data/placement.xdc
+++ b/hw/top_earlgrey/data/placement.xdc
@@ -1,7 +1,7 @@
 # Any change in ROM instances path should be updated in following two files
 # 1. hw/top_earlgrey/data/placement.xdc and
 # 2. hw/top_earlgrey/util/vivado_hook_opt_design_post.tcl
-set_property LOC RAMB36_X4Y18 [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_0" && PRIMITIVE_TYPE =~ BMEM.*.* }]
-set_property LOC RAMB36_X4Y19 [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_1" && PRIMITIVE_TYPE =~ BMEM.*.* }]
-set_property LOC RAMB36_X3Y14 [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_2" && PRIMITIVE_TYPE =~ BMEM.*.* }]
-set_property LOC RAMB36_X3Y15 [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_3" && PRIMITIVE_TYPE =~ BMEM.*.* }]
+set_property LOC RAMB36_X4Y18 [get_cells -hierarchical -filter { NAME =~  "*u_rom_ctrl*u_rom*rdata_o_reg_0" && PRIMITIVE_TYPE =~ BMEM.*.* }]
+set_property LOC RAMB36_X4Y19 [get_cells -hierarchical -filter { NAME =~  "*u_rom_ctrl*u_rom*rdata_o_reg_1" && PRIMITIVE_TYPE =~ BMEM.*.* }]
+set_property LOC RAMB36_X3Y14 [get_cells -hierarchical -filter { NAME =~  "*u_rom_ctrl*u_rom*rdata_o_reg_2" && PRIMITIVE_TYPE =~ BMEM.*.* }]
+set_property LOC RAMB36_X3Y15 [get_cells -hierarchical -filter { NAME =~  "*u_rom_ctrl*u_rom*rdata_o_reg_3" && PRIMITIVE_TYPE =~ BMEM.*.* }]
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index 5f29a7e..bb776f2 100755
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -574,37 +574,18 @@
       reset_connections: {rst_ni: "sys", rst_edn_ni: "sys"},
       base_addr: "0x411D0000",
     },
+    { name: "rom_ctrl",
+      type: "rom_ctrl",
+      clock_srcs: {clk_i: "main"},
+      clock_group: "infra",
+      reset_connections: {rst_ni: "sys"},
+      base_addrs: {rom: "0x00008000", regs: "0x411e0000"}
+    }
   ]
 
   // Memories (ROM, RAM, eFlash) are defined at the top.
   // It utilizes the primitive cells but configurable
   memory: [
-    { name: "rom",
-      clock_srcs: {clk_i: "main"},
-      clock_group: "infra",
-      reset_connections: {rst_ni: "sys"},
-      type: "rom",
-      base_addr: "0x00008000",
-      swaccess: "ro",
-      size: "0x4000",
-      // data integrity width
-      integ_width: 8,
-      inter_signal_list: [
-        { struct: "tl"
-          package: "tlul_pkg"
-          type: "req_rsp"
-          act: "rsp"
-          name: "tl"
-        },
-        // Interface to memory configuration
-        { struct:  "rom_cfg",
-          package: "prim_rom_pkg",
-          type:    "uni",
-          name:    "cfg",
-          act:     "rcv"
-        }
-      ]
-    },
     { name: "ram_main",
       clock_srcs: {clk_i: "main"},
       clock_group: "infra",
@@ -838,7 +819,7 @@
     'connect': {
       'ast.ram_1p_cfg'          : ['otbn.ram_cfg', 'ram_main.cfg', 'ram_ret_aon.cfg', 'rv_core_ibex.ram_cfg'],
       'ast.ram_2p_cfg'          : ['spi_device.ram_cfg', 'usbdev.ram_cfg'],
-      'ast.rom_cfg'             : ['rom.cfg'],
+      'ast.rom_cfg'             : ['rom_ctrl.rom_cfg'],
       'alert_handler.crashdump' : ['rstmgr_aon.alert_dump'],
       'alert_handler.esc_rx'    : ['rv_core_ibex.esc_nmi_rx',
                                    'lc_ctrl.esc_wipe_secrets_rx',
diff --git a/hw/top_earlgrey/data/xbar_main.hjson b/hw/top_earlgrey/data/xbar_main.hjson
index dcc5b80..87ddfd7 100644
--- a/hw/top_earlgrey/data/xbar_main.hjson
+++ b/hw/top_earlgrey/data/xbar_main.hjson
@@ -30,7 +30,13 @@
       pipeline_byp: "false"
 
     },
-    { name:      "rom",
+    { name:      "rom_ctrl.rom",
+      type:      "device",
+      clock:     "clk_main_i",
+      reset:     "rst_main_ni",
+      pipeline:  "false",
+    },
+    { name:      "rom_ctrl.regs",
       type:      "device",
       clock:     "clk_main_i",
       reset:     "rst_main_ni",
@@ -139,12 +145,17 @@
     },
   ],
   connections: {
-    corei:  ["rom", "debug_mem", "ram_main", "eflash"],
-    cored:  ["rom", "debug_mem", "ram_main", "eflash", "peri", "flash_ctrl",
-    "aes", "entropy_src", "csrng", "edn0", "edn1",
-    "hmac", "rv_plic", "otbn", "keymgr", "kmac", "sram_ctrl_main"],
-    dm_sba: ["rom",              "ram_main", "eflash", "peri", "flash_ctrl",
-    "aes", "entropy_src", "csrng", "edn0", "edn1",
-    "hmac", "rv_plic", "otbn", "kmac", "sram_ctrl_main"],
+    corei:  ["rom_ctrl.rom", "debug_mem", "ram_main", "eflash"],
+    cored:  [
+      "rom_ctrl.rom", "rom_ctrl.regs", "debug_mem", "ram_main",
+      "eflash", "peri", "flash_ctrl", "aes", "entropy_src", "csrng",
+      "edn0", "edn1", "hmac", "rv_plic", "otbn", "keymgr", "kmac",
+      "sram_ctrl_main"
+    ],
+    dm_sba: [
+      "rom_ctrl.rom", "rom_ctrl.regs", "ram_main", "eflash", "peri",
+      "flash_ctrl", "aes", "entropy_src", "csrng", "edn0", "edn1",
+      "hmac", "rv_plic", "otbn", "kmac", "sram_ctrl_main"
+    ],
   },
 }
diff --git a/hw/top_earlgrey/dv/autogen/tb__alert_handler_connect.sv b/hw/top_earlgrey/dv/autogen/tb__alert_handler_connect.sv
index 930538a..789e490 100644
--- a/hw/top_earlgrey/dv/autogen/tb__alert_handler_connect.sv
+++ b/hw/top_earlgrey/dv/autogen/tb__alert_handler_connect.sv
@@ -33,3 +33,4 @@
 assign alert_if[26].alert_tx = `CHIP_HIER.u_sram_ctrl_main.alert_tx_o[1];
 assign alert_if[27].alert_tx = `CHIP_HIER.u_otbn.alert_tx_o[0];
 assign alert_if[28].alert_tx = `CHIP_HIER.u_otbn.alert_tx_o[1];
+assign alert_if[29].alert_tx = `CHIP_HIER.u_rom_ctrl.alert_tx_o[0];
diff --git a/hw/top_earlgrey/dv/autogen/tb__xbar_connect.sv b/hw/top_earlgrey/dv/autogen/tb__xbar_connect.sv
index f8b7781..bbf24f1 100644
--- a/hw/top_earlgrey/dv/autogen/tb__xbar_connect.sv
+++ b/hw/top_earlgrey/dv/autogen/tb__xbar_connect.sv
@@ -33,7 +33,8 @@
 tl_if cored_tl_if(clk_main, rst_n);
 tl_if dm_sba_tl_if(clk_main, rst_n);
 
-tl_if rom_tl_if(clk_main, rst_n);
+tl_if rom_ctrl__rom_tl_if(clk_main, rst_n);
+tl_if rom_ctrl__regs_tl_if(clk_main, rst_n);
 tl_if debug_mem_tl_if(clk_main, rst_n);
 tl_if ram_main_tl_if(clk_main, rst_n);
 tl_if eflash_tl_if(clk_main, rst_n);
@@ -104,7 +105,8 @@
     `DRIVE_CHIP_TL_HOST_IF(corei, rv_core_ibex, tl_i)
     `DRIVE_CHIP_TL_HOST_IF(cored, rv_core_ibex, tl_d)
     `DRIVE_CHIP_TL_HOST_IF(dm_sba, dm_top, tl_h)
-    `DRIVE_CHIP_TL_DEVICE_IF(rom, tl_adapter_rom, tl)
+    `DRIVE_CHIP_TL_DEVICE_IF(rom_ctrl__rom, rom_ctrl, rom_tl)
+    `DRIVE_CHIP_TL_DEVICE_IF(rom_ctrl__regs, rom_ctrl, regs_tl)
     `DRIVE_CHIP_TL_DEVICE_IF(debug_mem, dm_top, tl_d)
     `DRIVE_CHIP_TL_DEVICE_IF(ram_main, tl_adapter_ram_main, tl)
     `DRIVE_CHIP_TL_DEVICE_IF(eflash, tl_adapter_eflash, tl)
diff --git a/hw/top_earlgrey/dv/autogen/xbar_env_pkg__params.sv b/hw/top_earlgrey/dv/autogen/xbar_env_pkg__params.sv
index 307264f..b7b61fa 100644
--- a/hw/top_earlgrey/dv/autogen/xbar_env_pkg__params.sv
+++ b/hw/top_earlgrey/dv/autogen/xbar_env_pkg__params.sv
@@ -7,9 +7,12 @@
 
 // List of Xbar device memory map
 tl_device_t xbar_devices[$] = '{
-    '{"rom", '{
+    '{"rom_ctrl__rom", '{
         '{32'h00008000, 32'h0000bfff}
     }},
+    '{"rom_ctrl__regs", '{
+        '{32'h411e0000, 32'h411e0fff}
+    }},
     '{"debug_mem", '{
         '{32'h1a110000, 32'h1a110fff}
     }},
@@ -140,13 +143,14 @@
   // List of Xbar hosts
 tl_host_t xbar_hosts[$] = '{
     '{"corei", 0, '{
-        "rom",
+        "rom_ctrl.rom",
         "debug_mem",
         "ram_main",
         "eflash"}}
     ,
     '{"cored", 1, '{
-        "rom",
+        "rom_ctrl.rom",
+        "rom_ctrl.regs",
         "debug_mem",
         "ram_main",
         "eflash",
@@ -191,7 +195,8 @@
         "sram_ctrl_main"}}
     ,
     '{"dm_sba", 2, '{
-        "rom",
+        "rom_ctrl.rom",
+        "rom_ctrl.regs",
         "ram_main",
         "eflash",
         "uart0",
diff --git a/hw/top_earlgrey/dv/env/autogen/chip_env_pkg__params.sv b/hw/top_earlgrey/dv/env/autogen/chip_env_pkg__params.sv
index a99f290..cb01a93 100644
--- a/hw/top_earlgrey/dv/env/autogen/chip_env_pkg__params.sv
+++ b/hw/top_earlgrey/dv/env/autogen/chip_env_pkg__params.sv
@@ -33,7 +33,8 @@
   "sram_ctrl_main_fatal_intg_error",
   "sram_ctrl_main_fatal_parity_error",
   "otbn_fatal",
-  "otbn_recov"
+  "otbn_recov",
+  "rom_ctrl_fatal"
 };
 
-parameter uint NUM_ALERTS = 29;
+parameter uint NUM_ALERTS = 30;
diff --git a/hw/top_earlgrey/dv/env/chip_env_pkg.sv b/hw/top_earlgrey/dv/env/chip_env_pkg.sv
index eeac51f..3b99f0d 100644
--- a/hw/top_earlgrey/dv/env/chip_env_pkg.sv
+++ b/hw/top_earlgrey/dv/env/chip_env_pkg.sv
@@ -75,7 +75,7 @@
   // functions
   function automatic bit [bus_params_pkg::BUS_AW-1:0] get_chip_mem_base_addr(chip_mem_e mem);
     case (mem)
-      Rom:    return top_earlgrey_pkg::TOP_EARLGREY_ROM_BASE_ADDR;
+      Rom:    return top_earlgrey_pkg::TOP_EARLGREY_ROM_CTRL_ROM_BASE_ADDR;
       RamMain:return top_earlgrey_pkg::TOP_EARLGREY_RAM_MAIN_BASE_ADDR;
       RamRet: return top_earlgrey_pkg::TOP_EARLGREY_RAM_RET_AON_BASE_ADDR;
       FlashBank0, FlashBank0Info: return top_earlgrey_pkg::TOP_EARLGREY_EFLASH_BASE_ADDR;
diff --git a/hw/top_earlgrey/dv/tb/chip_hier_macros.svh b/hw/top_earlgrey/dv/tb/chip_hier_macros.svh
index d98ad1f..d71592f 100644
--- a/hw/top_earlgrey/dv/tb/chip_hier_macros.svh
+++ b/hw/top_earlgrey/dv/tb/chip_hier_macros.svh
@@ -11,7 +11,7 @@
 `define CPU_HIER           `CHIP_HIER.u_rv_core_ibex
 `define RAM_MAIN_HIER      `CHIP_HIER.u_ram1p_ram_main.u_prim_ram_1p_adv.u_mem
 `define RAM_RET_HIER       `CHIP_HIER.u_ram1p_ram_ret_aon.u_prim_ram_1p_adv.u_mem
-`define ROM_HIER           `CHIP_HIER.u_rom_rom.u_prim_rom
+`define ROM_HIER           `CHIP_HIER.u_rom_ctrl.u_rom.u_prim_rom
 `define FLASH_HIER         `CHIP_HIER.u_flash_eflash.u_flash
 `define RSTMGR_HIER        `CHIP_HIER.u_rstmgr_aon
 `define CLKMGR_HIER        `CHIP_HIER.u_clkmgr_aon
diff --git a/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson b/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
index d52b32a..d1df40e 100644
--- a/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
+++ b/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
@@ -48,7 +48,7 @@
     { name: "NAlerts",
       desc: "Number of peripheral inputs",
       type: "int",
-      default: "29",
+      default: "30",
       local: "true"
     },
     { name: "EscCntDw",
@@ -66,7 +66,7 @@
     { name: "AsyncOn",
       desc: "Number of peripheral outputs",
       type: "logic [NAlerts-1:0]",
-      default: "29'b11111111111111110000000000000",
+      default: "30'b111111111111111110000000000000",
       local: "true"
     },
     { name: "N_CLASSES",
diff --git a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv
index cb53c8a..0df3e1a 100644
--- a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv
+++ b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv
@@ -7,10 +7,10 @@
 package alert_handler_reg_pkg;
 
   // Param list
-  parameter int NAlerts = 29;
+  parameter int NAlerts = 30;
   parameter int EscCntDw = 32;
   parameter int AccuCntDw = 16;
-  parameter logic [NAlerts-1:0] AsyncOn = 29'b11111111111111110000000000000;
+  parameter logic [NAlerts-1:0] AsyncOn = 30'b111111111111111110000000000000;
   parameter int N_CLASSES = 4;
   parameter int N_ESC_SEV = 4;
   parameter int N_PHASES = 4;
@@ -454,14 +454,14 @@
 
   // Register -> HW type
   typedef struct packed {
-    alert_handler_reg2hw_intr_state_reg_t intr_state; // [940:937]
-    alert_handler_reg2hw_intr_enable_reg_t intr_enable; // [936:933]
-    alert_handler_reg2hw_intr_test_reg_t intr_test; // [932:925]
-    alert_handler_reg2hw_regwen_reg_t regwen; // [924:924]
-    alert_handler_reg2hw_ping_timeout_cyc_reg_t ping_timeout_cyc; // [923:900]
-    alert_handler_reg2hw_alert_en_mreg_t [28:0] alert_en; // [899:871]
-    alert_handler_reg2hw_alert_class_mreg_t [28:0] alert_class; // [870:813]
-    alert_handler_reg2hw_alert_cause_mreg_t [28:0] alert_cause; // [812:784]
+    alert_handler_reg2hw_intr_state_reg_t intr_state; // [944:941]
+    alert_handler_reg2hw_intr_enable_reg_t intr_enable; // [940:937]
+    alert_handler_reg2hw_intr_test_reg_t intr_test; // [936:929]
+    alert_handler_reg2hw_regwen_reg_t regwen; // [928:928]
+    alert_handler_reg2hw_ping_timeout_cyc_reg_t ping_timeout_cyc; // [927:904]
+    alert_handler_reg2hw_alert_en_mreg_t [29:0] alert_en; // [903:874]
+    alert_handler_reg2hw_alert_class_mreg_t [29:0] alert_class; // [873:814]
+    alert_handler_reg2hw_alert_cause_mreg_t [29:0] alert_cause; // [813:784]
     alert_handler_reg2hw_loc_alert_en_mreg_t [3:0] loc_alert_en; // [783:780]
     alert_handler_reg2hw_loc_alert_class_mreg_t [3:0] loc_alert_class; // [779:772]
     alert_handler_reg2hw_loc_alert_cause_mreg_t [3:0] loc_alert_cause; // [771:768]
@@ -501,8 +501,8 @@
 
   // HW -> register type
   typedef struct packed {
-    alert_handler_hw2reg_intr_state_reg_t intr_state; // [285:278]
-    alert_handler_hw2reg_alert_cause_mreg_t [28:0] alert_cause; // [277:220]
+    alert_handler_hw2reg_intr_state_reg_t intr_state; // [287:280]
+    alert_handler_hw2reg_alert_cause_mreg_t [29:0] alert_cause; // [279:220]
     alert_handler_hw2reg_loc_alert_cause_mreg_t [3:0] loc_alert_cause; // [219:212]
     alert_handler_hw2reg_classa_regwen_reg_t classa_regwen; // [211:210]
     alert_handler_hw2reg_classa_accum_cnt_reg_t classa_accum_cnt; // [209:194]
diff --git a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv
index 46bfc42..93ed12f 100644
--- a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv
+++ b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv
@@ -225,6 +225,9 @@
   logic alert_en_en_a_28_qs;
   logic alert_en_en_a_28_wd;
   logic alert_en_en_a_28_we;
+  logic alert_en_en_a_29_qs;
+  logic alert_en_en_a_29_wd;
+  logic alert_en_en_a_29_we;
   logic [1:0] alert_class_0_class_a_0_qs;
   logic [1:0] alert_class_0_class_a_0_wd;
   logic alert_class_0_class_a_0_we;
@@ -312,6 +315,9 @@
   logic [1:0] alert_class_1_class_a_28_qs;
   logic [1:0] alert_class_1_class_a_28_wd;
   logic alert_class_1_class_a_28_we;
+  logic [1:0] alert_class_1_class_a_29_qs;
+  logic [1:0] alert_class_1_class_a_29_wd;
+  logic alert_class_1_class_a_29_we;
   logic alert_cause_a_0_qs;
   logic alert_cause_a_0_wd;
   logic alert_cause_a_0_we;
@@ -399,6 +405,9 @@
   logic alert_cause_a_28_qs;
   logic alert_cause_a_28_wd;
   logic alert_cause_a_28_we;
+  logic alert_cause_a_29_qs;
+  logic alert_cause_a_29_wd;
+  logic alert_cause_a_29_we;
   logic loc_alert_en_en_la_0_qs;
   logic loc_alert_en_en_la_0_wd;
   logic loc_alert_en_en_la_0_we;
@@ -1759,6 +1768,32 @@
   );
 
 
+  // F[en_a_29]: 29:29
+  prim_subreg #(
+    .DW      (1),
+    .SWACCESS("RW"),
+    .RESVAL  (1'h0)
+  ) u_alert_en_en_a_29 (
+    .clk_i   (clk_i    ),
+    .rst_ni  (rst_ni  ),
+
+    // from register interface (qualified with register enable)
+    .we     (alert_en_en_a_29_we & regwen_qs),
+    .wd     (alert_en_en_a_29_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0  ),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.alert_en[29].q ),
+
+    // to register interface (read)
+    .qs     (alert_en_en_a_29_qs)
+  );
+
+
 
 
   // Subregister 0 of Multireg alert_class
@@ -2521,6 +2556,32 @@
   );
 
 
+  // F[class_a_29]: 27:26
+  prim_subreg #(
+    .DW      (2),
+    .SWACCESS("RW"),
+    .RESVAL  (2'h0)
+  ) u_alert_class_1_class_a_29 (
+    .clk_i   (clk_i    ),
+    .rst_ni  (rst_ni  ),
+
+    // from register interface (qualified with register enable)
+    .we     (alert_class_1_class_a_29_we & regwen_qs),
+    .wd     (alert_class_1_class_a_29_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0  ),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.alert_class[29].q ),
+
+    // to register interface (read)
+    .qs     (alert_class_1_class_a_29_qs)
+  );
+
+
 
 
   // Subregister 0 of Multireg alert_cause
@@ -3280,6 +3341,32 @@
   );
 
 
+  // F[a_29]: 29:29
+  prim_subreg #(
+    .DW      (1),
+    .SWACCESS("W1C"),
+    .RESVAL  (1'h0)
+  ) u_alert_cause_a_29 (
+    .clk_i   (clk_i    ),
+    .rst_ni  (rst_ni  ),
+
+    // from register interface
+    .we     (alert_cause_a_29_we),
+    .wd     (alert_cause_a_29_wd),
+
+    // from internal hardware
+    .de     (hw2reg.alert_cause[29].de),
+    .d      (hw2reg.alert_cause[29].d ),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.alert_cause[29].q ),
+
+    // to register interface (read)
+    .qs     (alert_cause_a_29_qs)
+  );
+
+
 
 
   // Subregister 0 of Multireg loc_alert_en
@@ -5971,6 +6058,9 @@
   assign alert_en_en_a_28_we = addr_hit[5] & reg_we & !reg_error;
   assign alert_en_en_a_28_wd = reg_wdata[28];
 
+  assign alert_en_en_a_29_we = addr_hit[5] & reg_we & !reg_error;
+  assign alert_en_en_a_29_wd = reg_wdata[29];
+
   assign alert_class_0_class_a_0_we = addr_hit[6] & reg_we & !reg_error;
   assign alert_class_0_class_a_0_wd = reg_wdata[1:0];
 
@@ -6058,6 +6148,9 @@
   assign alert_class_1_class_a_28_we = addr_hit[7] & reg_we & !reg_error;
   assign alert_class_1_class_a_28_wd = reg_wdata[25:24];
 
+  assign alert_class_1_class_a_29_we = addr_hit[7] & reg_we & !reg_error;
+  assign alert_class_1_class_a_29_wd = reg_wdata[27:26];
+
   assign alert_cause_a_0_we = addr_hit[8] & reg_we & !reg_error;
   assign alert_cause_a_0_wd = reg_wdata[0];
 
@@ -6145,6 +6238,9 @@
   assign alert_cause_a_28_we = addr_hit[8] & reg_we & !reg_error;
   assign alert_cause_a_28_wd = reg_wdata[28];
 
+  assign alert_cause_a_29_we = addr_hit[8] & reg_we & !reg_error;
+  assign alert_cause_a_29_wd = reg_wdata[29];
+
   assign loc_alert_en_en_la_0_we = addr_hit[9] & reg_we & !reg_error;
   assign loc_alert_en_en_la_0_wd = reg_wdata[0];
 
@@ -6484,6 +6580,7 @@
         reg_rdata_next[26] = alert_en_en_a_26_qs;
         reg_rdata_next[27] = alert_en_en_a_27_qs;
         reg_rdata_next[28] = alert_en_en_a_28_qs;
+        reg_rdata_next[29] = alert_en_en_a_29_qs;
       end
 
       addr_hit[6]: begin
@@ -6519,6 +6616,7 @@
         reg_rdata_next[21:20] = alert_class_1_class_a_26_qs;
         reg_rdata_next[23:22] = alert_class_1_class_a_27_qs;
         reg_rdata_next[25:24] = alert_class_1_class_a_28_qs;
+        reg_rdata_next[27:26] = alert_class_1_class_a_29_qs;
       end
 
       addr_hit[8]: begin
@@ -6551,6 +6649,7 @@
         reg_rdata_next[26] = alert_cause_a_26_qs;
         reg_rdata_next[27] = alert_cause_a_27_qs;
         reg_rdata_next[28] = alert_cause_a_28_qs;
+        reg_rdata_next[29] = alert_cause_a_29_qs;
       end
 
       addr_hit[9]: begin
diff --git a/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson b/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson
index 468cc3f..a653bc2 100644
--- a/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson
+++ b/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson
@@ -30,14 +30,15 @@
   {
     corei:
     [
-      rom
+      rom_ctrl.rom
       debug_mem
       ram_main
       eflash
     ]
     cored:
     [
-      rom
+      rom_ctrl.rom
+      rom_ctrl.regs
       debug_mem
       ram_main
       eflash
@@ -57,7 +58,8 @@
     ]
     dm_sba:
     [
-      rom
+      rom_ctrl.rom
+      rom_ctrl.regs
       ram_main
       eflash
       peri
@@ -110,12 +112,12 @@
       pipeline: "true"
     }
     {
-      name: rom
+      name: rom_ctrl.rom
       type: device
       clock: clk_main_i
       reset: rst_main_ni
       pipeline: "false"
-      inst_type: rom
+      inst_type: rom_ctrl
       addr_range:
       [
         {
@@ -128,6 +130,24 @@
       pipeline_byp: "true"
     }
     {
+      name: rom_ctrl.regs
+      type: device
+      clock: clk_main_i
+      reset: rst_main_ni
+      pipeline: "false"
+      inst_type: rom_ctrl
+      addr_range:
+      [
+        {
+          base_addr: 0x411e0000
+          size_byte: 0x1000
+        }
+      ]
+      xbar: false
+      stub: false
+      pipeline_byp: "true"
+    }
+    {
       name: debug_mem
       type: device
       clock: clk_main_i
diff --git a/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.hjson b/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.hjson
index 73a77cb..a345523 100644
--- a/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.hjson
+++ b/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.hjson
@@ -33,7 +33,13 @@
     // device
     { struct: "tl"
       type:   "req_rsp"
-      name:   "tl_rom"
+      name:   "tl_rom_ctrl__rom"
+      act:    "req"
+      package: "tlul_pkg"
+    }
+    { struct: "tl"
+      type:   "req_rsp"
+      name:   "tl_rom_ctrl__regs"
       act:    "req"
       package: "tlul_pkg"
     }
diff --git a/hw/top_earlgrey/ip/xbar_main/dv/autogen/tb__xbar_connect.sv b/hw/top_earlgrey/ip/xbar_main/dv/autogen/tb__xbar_connect.sv
index 664569d..6c2f40f 100644
--- a/hw/top_earlgrey/ip/xbar_main/dv/autogen/tb__xbar_connect.sv
+++ b/hw/top_earlgrey/ip/xbar_main/dv/autogen/tb__xbar_connect.sv
@@ -22,7 +22,8 @@
 `CONNECT_TL_HOST_IF(dm_sba, dut, clk_main_i, rst_n)
 
 // Device TileLink interface connections
-`CONNECT_TL_DEVICE_IF(rom, dut, clk_main_i, rst_n)
+`CONNECT_TL_DEVICE_IF(rom_ctrl__rom, dut, clk_main_i, rst_n)
+`CONNECT_TL_DEVICE_IF(rom_ctrl__regs, dut, clk_main_i, rst_n)
 `CONNECT_TL_DEVICE_IF(debug_mem, dut, clk_main_i, rst_n)
 `CONNECT_TL_DEVICE_IF(ram_main, dut, clk_main_i, rst_n)
 `CONNECT_TL_DEVICE_IF(eflash, dut, clk_main_i, rst_n)
diff --git a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_cover.cfg b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_cover.cfg
index 2ab49e7..25bea19 100644
--- a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_cover.cfg
+++ b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_cover.cfg
@@ -16,8 +16,12 @@
 -node tb.dut tl_*.d_opcode[2:1]
 
 // [UNR] these device address bits are always 0
--node tb.dut tl_rom_o.a_address[14:14]
--node tb.dut tl_rom_o.a_address[31:16]
+-node tb.dut tl_rom_ctrl__rom_o.a_address[14:14]
+-node tb.dut tl_rom_ctrl__rom_o.a_address[31:16]
+-node tb.dut tl_rom_ctrl__regs_o.a_address[16:12]
+-node tb.dut tl_rom_ctrl__regs_o.a_address[23:21]
+-node tb.dut tl_rom_ctrl__regs_o.a_address[29:25]
+-node tb.dut tl_rom_ctrl__regs_o.a_address[31:31]
 -node tb.dut tl_debug_mem_o.a_address[15:12]
 -node tb.dut tl_debug_mem_o.a_address[19:17]
 -node tb.dut tl_debug_mem_o.a_address[24:21]
diff --git a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv
index a105e6e..9afa14d 100644
--- a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv
+++ b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv
@@ -7,9 +7,12 @@
 
 // List of Xbar device memory map
 tl_device_t xbar_devices[$] = '{
-    '{"rom", '{
+    '{"rom_ctrl__rom", '{
         '{32'h00008000, 32'h0000bfff}
     }},
+    '{"rom_ctrl__regs", '{
+        '{32'h411e0000, 32'h411e0fff}
+    }},
     '{"debug_mem", '{
         '{32'h1a110000, 32'h1a110fff}
     }},
@@ -62,13 +65,14 @@
   // List of Xbar hosts
 tl_host_t xbar_hosts[$] = '{
     '{"corei", 0, '{
-        "rom",
+        "rom_ctrl__rom",
         "debug_mem",
         "ram_main",
         "eflash"}}
     ,
     '{"cored", 1, '{
-        "rom",
+        "rom_ctrl__rom",
+        "rom_ctrl__regs",
         "debug_mem",
         "ram_main",
         "eflash",
@@ -87,7 +91,8 @@
         "sram_ctrl_main"}}
     ,
     '{"dm_sba", 2, '{
-        "rom",
+        "rom_ctrl__rom",
+        "rom_ctrl__regs",
         "ram_main",
         "eflash",
         "peri",
diff --git a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_bind.sv b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_bind.sv
index ded1cdd..7c4910a 100644
--- a/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_bind.sv
+++ b/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_bind.sv
@@ -26,11 +26,17 @@
   );
 
   // Device interfaces
-  bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_rom (
+  bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_rom_ctrl__rom (
     .clk_i  (clk_main_i),
     .rst_ni (rst_main_ni),
-    .h2d    (tl_rom_o),
-    .d2h    (tl_rom_i)
+    .h2d    (tl_rom_ctrl__rom_o),
+    .d2h    (tl_rom_ctrl__rom_i)
+  );
+  bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_rom_ctrl__regs (
+    .clk_i  (clk_main_i),
+    .rst_ni (rst_main_ni),
+    .h2d    (tl_rom_ctrl__regs_o),
+    .d2h    (tl_rom_ctrl__regs_i)
   );
   bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_debug_mem (
     .clk_i  (clk_main_i),
diff --git a/hw/top_earlgrey/ip/xbar_main/rtl/autogen/tl_main_pkg.sv b/hw/top_earlgrey/ip/xbar_main/rtl/autogen/tl_main_pkg.sv
index 0f81cff..f2b7a78 100644
--- a/hw/top_earlgrey/ip/xbar_main/rtl/autogen/tl_main_pkg.sv
+++ b/hw/top_earlgrey/ip/xbar_main/rtl/autogen/tl_main_pkg.sv
@@ -6,7 +6,8 @@
 
 package tl_main_pkg;
 
-  localparam logic [31:0] ADDR_SPACE_ROM            = 32'h 00008000;
+  localparam logic [31:0] ADDR_SPACE_ROM_CTRL__ROM  = 32'h 00008000;
+  localparam logic [31:0] ADDR_SPACE_ROM_CTRL__REGS = 32'h 411e0000;
   localparam logic [31:0] ADDR_SPACE_DEBUG_MEM      = 32'h 1a110000;
   localparam logic [31:0] ADDR_SPACE_RAM_MAIN       = 32'h 10000000;
   localparam logic [31:0] ADDR_SPACE_EFLASH         = 32'h 20000000;
@@ -26,7 +27,8 @@
   localparam logic [31:0] ADDR_SPACE_KEYMGR         = 32'h 41130000;
   localparam logic [31:0] ADDR_SPACE_SRAM_CTRL_MAIN = 32'h 411c0000;
 
-  localparam logic [31:0] ADDR_MASK_ROM            = 32'h 00003fff;
+  localparam logic [31:0] ADDR_MASK_ROM_CTRL__ROM  = 32'h 00003fff;
+  localparam logic [31:0] ADDR_MASK_ROM_CTRL__REGS = 32'h 00000fff;
   localparam logic [31:0] ADDR_MASK_DEBUG_MEM      = 32'h 00000fff;
   localparam logic [31:0] ADDR_MASK_RAM_MAIN       = 32'h 0001ffff;
   localparam logic [31:0] ADDR_MASK_EFLASH         = 32'h 000fffff;
@@ -47,26 +49,27 @@
   localparam logic [31:0] ADDR_MASK_SRAM_CTRL_MAIN = 32'h 00000fff;
 
   localparam int N_HOST   = 3;
-  localparam int N_DEVICE = 17;
+  localparam int N_DEVICE = 18;
 
   typedef enum int {
-    TlRom = 0,
-    TlDebugMem = 1,
-    TlRamMain = 2,
-    TlEflash = 3,
-    TlPeri = 4,
-    TlFlashCtrl = 5,
-    TlHmac = 6,
-    TlKmac = 7,
-    TlAes = 8,
-    TlEntropySrc = 9,
-    TlCsrng = 10,
-    TlEdn0 = 11,
-    TlEdn1 = 12,
-    TlRvPlic = 13,
-    TlOtbn = 14,
-    TlKeymgr = 15,
-    TlSramCtrlMain = 16
+    TlRomCtrlRom = 0,
+    TlRomCtrlRegs = 1,
+    TlDebugMem = 2,
+    TlRamMain = 3,
+    TlEflash = 4,
+    TlPeri = 5,
+    TlFlashCtrl = 6,
+    TlHmac = 7,
+    TlKmac = 8,
+    TlAes = 9,
+    TlEntropySrc = 10,
+    TlCsrng = 11,
+    TlEdn0 = 12,
+    TlEdn1 = 13,
+    TlRvPlic = 14,
+    TlOtbn = 15,
+    TlKeymgr = 16,
+    TlSramCtrlMain = 17
   } tl_device_e;
 
   typedef enum int {
diff --git a/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv b/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv
index d3af5c1..f0aa0b5 100644
--- a/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv
+++ b/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv
@@ -7,83 +7,87 @@
 //
 // Interconnect
 // corei
-//   -> s1n_20
-//     -> sm1_21
-//       -> rom
+//   -> s1n_21
 //     -> sm1_22
-//       -> debug_mem
+//       -> rom_ctrl.rom
 //     -> sm1_23
-//       -> ram_main
+//       -> debug_mem
 //     -> sm1_24
+//       -> ram_main
+//     -> sm1_25
 //       -> eflash
 // cored
-//   -> s1n_25
-//     -> sm1_21
-//       -> rom
+//   -> s1n_26
 //     -> sm1_22
-//       -> debug_mem
-//     -> sm1_23
-//       -> ram_main
-//     -> sm1_24
-//       -> eflash
+//       -> rom_ctrl.rom
 //     -> sm1_27
-//       -> asf_26
-//         -> peri
-//     -> sm1_28
-//       -> flash_ctrl
+//       -> rom_ctrl.regs
+//     -> sm1_23
+//       -> debug_mem
+//     -> sm1_24
+//       -> ram_main
+//     -> sm1_25
+//       -> eflash
 //     -> sm1_29
-//       -> aes
+//       -> asf_28
+//         -> peri
 //     -> sm1_30
-//       -> entropy_src
+//       -> flash_ctrl
 //     -> sm1_31
-//       -> csrng
+//       -> aes
 //     -> sm1_32
-//       -> edn0
+//       -> entropy_src
 //     -> sm1_33
-//       -> edn1
+//       -> csrng
 //     -> sm1_34
-//       -> hmac
+//       -> edn0
 //     -> sm1_35
-//       -> rv_plic
+//       -> edn1
 //     -> sm1_36
+//       -> hmac
+//     -> sm1_37
+//       -> rv_plic
+//     -> sm1_38
 //       -> otbn
 //     -> keymgr
-//     -> sm1_37
+//     -> sm1_39
 //       -> kmac
-//     -> sm1_38
+//     -> sm1_40
 //       -> sram_ctrl_main
 // dm_sba
-//   -> s1n_39
-//     -> sm1_21
-//       -> rom
-//     -> sm1_23
-//       -> ram_main
-//     -> sm1_24
-//       -> eflash
+//   -> s1n_41
+//     -> sm1_22
+//       -> rom_ctrl.rom
 //     -> sm1_27
-//       -> asf_26
-//         -> peri
-//     -> sm1_28
-//       -> flash_ctrl
+//       -> rom_ctrl.regs
+//     -> sm1_24
+//       -> ram_main
+//     -> sm1_25
+//       -> eflash
 //     -> sm1_29
-//       -> aes
+//       -> asf_28
+//         -> peri
 //     -> sm1_30
-//       -> entropy_src
+//       -> flash_ctrl
 //     -> sm1_31
-//       -> csrng
+//       -> aes
 //     -> sm1_32
-//       -> edn0
+//       -> entropy_src
 //     -> sm1_33
-//       -> edn1
+//       -> csrng
 //     -> sm1_34
-//       -> hmac
+//       -> edn0
 //     -> sm1_35
-//       -> rv_plic
+//       -> edn1
 //     -> sm1_36
-//       -> otbn
+//       -> hmac
 //     -> sm1_37
-//       -> kmac
+//       -> rv_plic
 //     -> sm1_38
+//       -> otbn
+//     -> sm1_39
+//       -> kmac
+//     -> sm1_40
 //       -> sram_ctrl_main
 
 module xbar_main (
@@ -101,8 +105,10 @@
   output tlul_pkg::tl_d2h_t tl_dm_sba_o,
 
   // Device interfaces
-  output tlul_pkg::tl_h2d_t tl_rom_o,
-  input  tlul_pkg::tl_d2h_t tl_rom_i,
+  output tlul_pkg::tl_h2d_t tl_rom_ctrl__rom_o,
+  input  tlul_pkg::tl_d2h_t tl_rom_ctrl__rom_i,
+  output tlul_pkg::tl_h2d_t tl_rom_ctrl__regs_o,
+  input  tlul_pkg::tl_d2h_t tl_rom_ctrl__regs_i,
   output tlul_pkg::tl_h2d_t tl_debug_mem_o,
   input  tlul_pkg::tl_d2h_t tl_debug_mem_i,
   output tlul_pkg::tl_h2d_t tl_ram_main_o,
@@ -147,33 +153,26 @@
   lc_ctrl_pkg::lc_tx_t unused_scanmode;
   assign unused_scanmode = scanmode_i;
 
-  tl_h2d_t tl_s1n_20_us_h2d ;
-  tl_d2h_t tl_s1n_20_us_d2h ;
+  tl_h2d_t tl_s1n_21_us_h2d ;
+  tl_d2h_t tl_s1n_21_us_d2h ;
 
 
-  tl_h2d_t tl_s1n_20_ds_h2d [4];
-  tl_d2h_t tl_s1n_20_ds_d2h [4];
+  tl_h2d_t tl_s1n_21_ds_h2d [4];
+  tl_d2h_t tl_s1n_21_ds_d2h [4];
 
   // Create steering signal
-  logic [2:0] dev_sel_s1n_20;
+  logic [2:0] dev_sel_s1n_21;
 
 
-  tl_h2d_t tl_sm1_21_us_h2d [3];
-  tl_d2h_t tl_sm1_21_us_d2h [3];
-
-  tl_h2d_t tl_sm1_21_ds_h2d ;
-  tl_d2h_t tl_sm1_21_ds_d2h ;
-
-
-  tl_h2d_t tl_sm1_22_us_h2d [2];
-  tl_d2h_t tl_sm1_22_us_d2h [2];
+  tl_h2d_t tl_sm1_22_us_h2d [3];
+  tl_d2h_t tl_sm1_22_us_d2h [3];
 
   tl_h2d_t tl_sm1_22_ds_h2d ;
   tl_d2h_t tl_sm1_22_ds_d2h ;
 
 
-  tl_h2d_t tl_sm1_23_us_h2d [3];
-  tl_d2h_t tl_sm1_23_us_d2h [3];
+  tl_h2d_t tl_sm1_23_us_h2d [2];
+  tl_d2h_t tl_sm1_23_us_d2h [2];
 
   tl_h2d_t tl_sm1_23_ds_h2d ;
   tl_d2h_t tl_sm1_23_ds_d2h ;
@@ -185,20 +184,22 @@
   tl_h2d_t tl_sm1_24_ds_h2d ;
   tl_d2h_t tl_sm1_24_ds_d2h ;
 
-  tl_h2d_t tl_s1n_25_us_h2d ;
-  tl_d2h_t tl_s1n_25_us_d2h ;
+
+  tl_h2d_t tl_sm1_25_us_h2d [3];
+  tl_d2h_t tl_sm1_25_us_d2h [3];
+
+  tl_h2d_t tl_sm1_25_ds_h2d ;
+  tl_d2h_t tl_sm1_25_ds_d2h ;
+
+  tl_h2d_t tl_s1n_26_us_h2d ;
+  tl_d2h_t tl_s1n_26_us_d2h ;
 
 
-  tl_h2d_t tl_s1n_25_ds_h2d [17];
-  tl_d2h_t tl_s1n_25_ds_d2h [17];
+  tl_h2d_t tl_s1n_26_ds_h2d [18];
+  tl_d2h_t tl_s1n_26_ds_d2h [18];
 
   // Create steering signal
-  logic [4:0] dev_sel_s1n_25;
-
-  tl_h2d_t tl_asf_26_us_h2d ;
-  tl_d2h_t tl_asf_26_us_d2h ;
-  tl_h2d_t tl_asf_26_ds_h2d ;
-  tl_d2h_t tl_asf_26_ds_d2h ;
+  logic [4:0] dev_sel_s1n_26;
 
 
   tl_h2d_t tl_sm1_27_us_h2d [2];
@@ -207,12 +208,10 @@
   tl_h2d_t tl_sm1_27_ds_h2d ;
   tl_d2h_t tl_sm1_27_ds_d2h ;
 
-
-  tl_h2d_t tl_sm1_28_us_h2d [2];
-  tl_d2h_t tl_sm1_28_us_d2h [2];
-
-  tl_h2d_t tl_sm1_28_ds_h2d ;
-  tl_d2h_t tl_sm1_28_ds_d2h ;
+  tl_h2d_t tl_asf_28_us_h2d ;
+  tl_d2h_t tl_asf_28_us_d2h ;
+  tl_h2d_t tl_asf_28_ds_h2d ;
+  tl_d2h_t tl_asf_28_ds_d2h ;
 
 
   tl_h2d_t tl_sm1_29_us_h2d [2];
@@ -284,342 +283,373 @@
   tl_h2d_t tl_sm1_38_ds_h2d ;
   tl_d2h_t tl_sm1_38_ds_d2h ;
 
-  tl_h2d_t tl_s1n_39_us_h2d ;
-  tl_d2h_t tl_s1n_39_us_d2h ;
+
+  tl_h2d_t tl_sm1_39_us_h2d [2];
+  tl_d2h_t tl_sm1_39_us_d2h [2];
+
+  tl_h2d_t tl_sm1_39_ds_h2d ;
+  tl_d2h_t tl_sm1_39_ds_d2h ;
 
 
-  tl_h2d_t tl_s1n_39_ds_h2d [15];
-  tl_d2h_t tl_s1n_39_ds_d2h [15];
+  tl_h2d_t tl_sm1_40_us_h2d [2];
+  tl_d2h_t tl_sm1_40_us_d2h [2];
+
+  tl_h2d_t tl_sm1_40_ds_h2d ;
+  tl_d2h_t tl_sm1_40_ds_d2h ;
+
+  tl_h2d_t tl_s1n_41_us_h2d ;
+  tl_d2h_t tl_s1n_41_us_d2h ;
+
+
+  tl_h2d_t tl_s1n_41_ds_h2d [16];
+  tl_d2h_t tl_s1n_41_ds_d2h [16];
 
   // Create steering signal
-  logic [3:0] dev_sel_s1n_39;
+  logic [4:0] dev_sel_s1n_41;
 
 
 
-  assign tl_sm1_21_us_h2d[0] = tl_s1n_20_ds_h2d[0];
-  assign tl_s1n_20_ds_d2h[0] = tl_sm1_21_us_d2h[0];
+  assign tl_sm1_22_us_h2d[0] = tl_s1n_21_ds_h2d[0];
+  assign tl_s1n_21_ds_d2h[0] = tl_sm1_22_us_d2h[0];
 
-  assign tl_sm1_22_us_h2d[0] = tl_s1n_20_ds_h2d[1];
-  assign tl_s1n_20_ds_d2h[1] = tl_sm1_22_us_d2h[0];
+  assign tl_sm1_23_us_h2d[0] = tl_s1n_21_ds_h2d[1];
+  assign tl_s1n_21_ds_d2h[1] = tl_sm1_23_us_d2h[0];
 
-  assign tl_sm1_23_us_h2d[0] = tl_s1n_20_ds_h2d[2];
-  assign tl_s1n_20_ds_d2h[2] = tl_sm1_23_us_d2h[0];
+  assign tl_sm1_24_us_h2d[0] = tl_s1n_21_ds_h2d[2];
+  assign tl_s1n_21_ds_d2h[2] = tl_sm1_24_us_d2h[0];
 
-  assign tl_sm1_24_us_h2d[0] = tl_s1n_20_ds_h2d[3];
-  assign tl_s1n_20_ds_d2h[3] = tl_sm1_24_us_d2h[0];
+  assign tl_sm1_25_us_h2d[0] = tl_s1n_21_ds_h2d[3];
+  assign tl_s1n_21_ds_d2h[3] = tl_sm1_25_us_d2h[0];
 
-  assign tl_sm1_21_us_h2d[1] = tl_s1n_25_ds_h2d[0];
-  assign tl_s1n_25_ds_d2h[0] = tl_sm1_21_us_d2h[1];
+  assign tl_sm1_22_us_h2d[1] = tl_s1n_26_ds_h2d[0];
+  assign tl_s1n_26_ds_d2h[0] = tl_sm1_22_us_d2h[1];
 
-  assign tl_sm1_22_us_h2d[1] = tl_s1n_25_ds_h2d[1];
-  assign tl_s1n_25_ds_d2h[1] = tl_sm1_22_us_d2h[1];
+  assign tl_sm1_27_us_h2d[0] = tl_s1n_26_ds_h2d[1];
+  assign tl_s1n_26_ds_d2h[1] = tl_sm1_27_us_d2h[0];
 
-  assign tl_sm1_23_us_h2d[1] = tl_s1n_25_ds_h2d[2];
-  assign tl_s1n_25_ds_d2h[2] = tl_sm1_23_us_d2h[1];
+  assign tl_sm1_23_us_h2d[1] = tl_s1n_26_ds_h2d[2];
+  assign tl_s1n_26_ds_d2h[2] = tl_sm1_23_us_d2h[1];
 
-  assign tl_sm1_24_us_h2d[1] = tl_s1n_25_ds_h2d[3];
-  assign tl_s1n_25_ds_d2h[3] = tl_sm1_24_us_d2h[1];
+  assign tl_sm1_24_us_h2d[1] = tl_s1n_26_ds_h2d[3];
+  assign tl_s1n_26_ds_d2h[3] = tl_sm1_24_us_d2h[1];
 
-  assign tl_sm1_27_us_h2d[0] = tl_s1n_25_ds_h2d[4];
-  assign tl_s1n_25_ds_d2h[4] = tl_sm1_27_us_d2h[0];
+  assign tl_sm1_25_us_h2d[1] = tl_s1n_26_ds_h2d[4];
+  assign tl_s1n_26_ds_d2h[4] = tl_sm1_25_us_d2h[1];
 
-  assign tl_sm1_28_us_h2d[0] = tl_s1n_25_ds_h2d[5];
-  assign tl_s1n_25_ds_d2h[5] = tl_sm1_28_us_d2h[0];
+  assign tl_sm1_29_us_h2d[0] = tl_s1n_26_ds_h2d[5];
+  assign tl_s1n_26_ds_d2h[5] = tl_sm1_29_us_d2h[0];
 
-  assign tl_sm1_29_us_h2d[0] = tl_s1n_25_ds_h2d[6];
-  assign tl_s1n_25_ds_d2h[6] = tl_sm1_29_us_d2h[0];
+  assign tl_sm1_30_us_h2d[0] = tl_s1n_26_ds_h2d[6];
+  assign tl_s1n_26_ds_d2h[6] = tl_sm1_30_us_d2h[0];
 
-  assign tl_sm1_30_us_h2d[0] = tl_s1n_25_ds_h2d[7];
-  assign tl_s1n_25_ds_d2h[7] = tl_sm1_30_us_d2h[0];
+  assign tl_sm1_31_us_h2d[0] = tl_s1n_26_ds_h2d[7];
+  assign tl_s1n_26_ds_d2h[7] = tl_sm1_31_us_d2h[0];
 
-  assign tl_sm1_31_us_h2d[0] = tl_s1n_25_ds_h2d[8];
-  assign tl_s1n_25_ds_d2h[8] = tl_sm1_31_us_d2h[0];
+  assign tl_sm1_32_us_h2d[0] = tl_s1n_26_ds_h2d[8];
+  assign tl_s1n_26_ds_d2h[8] = tl_sm1_32_us_d2h[0];
 
-  assign tl_sm1_32_us_h2d[0] = tl_s1n_25_ds_h2d[9];
-  assign tl_s1n_25_ds_d2h[9] = tl_sm1_32_us_d2h[0];
+  assign tl_sm1_33_us_h2d[0] = tl_s1n_26_ds_h2d[9];
+  assign tl_s1n_26_ds_d2h[9] = tl_sm1_33_us_d2h[0];
 
-  assign tl_sm1_33_us_h2d[0] = tl_s1n_25_ds_h2d[10];
-  assign tl_s1n_25_ds_d2h[10] = tl_sm1_33_us_d2h[0];
+  assign tl_sm1_34_us_h2d[0] = tl_s1n_26_ds_h2d[10];
+  assign tl_s1n_26_ds_d2h[10] = tl_sm1_34_us_d2h[0];
 
-  assign tl_sm1_34_us_h2d[0] = tl_s1n_25_ds_h2d[11];
-  assign tl_s1n_25_ds_d2h[11] = tl_sm1_34_us_d2h[0];
+  assign tl_sm1_35_us_h2d[0] = tl_s1n_26_ds_h2d[11];
+  assign tl_s1n_26_ds_d2h[11] = tl_sm1_35_us_d2h[0];
 
-  assign tl_sm1_35_us_h2d[0] = tl_s1n_25_ds_h2d[12];
-  assign tl_s1n_25_ds_d2h[12] = tl_sm1_35_us_d2h[0];
+  assign tl_sm1_36_us_h2d[0] = tl_s1n_26_ds_h2d[12];
+  assign tl_s1n_26_ds_d2h[12] = tl_sm1_36_us_d2h[0];
 
-  assign tl_sm1_36_us_h2d[0] = tl_s1n_25_ds_h2d[13];
-  assign tl_s1n_25_ds_d2h[13] = tl_sm1_36_us_d2h[0];
+  assign tl_sm1_37_us_h2d[0] = tl_s1n_26_ds_h2d[13];
+  assign tl_s1n_26_ds_d2h[13] = tl_sm1_37_us_d2h[0];
 
-  assign tl_keymgr_o = tl_s1n_25_ds_h2d[14];
-  assign tl_s1n_25_ds_d2h[14] = tl_keymgr_i;
+  assign tl_sm1_38_us_h2d[0] = tl_s1n_26_ds_h2d[14];
+  assign tl_s1n_26_ds_d2h[14] = tl_sm1_38_us_d2h[0];
 
-  assign tl_sm1_37_us_h2d[0] = tl_s1n_25_ds_h2d[15];
-  assign tl_s1n_25_ds_d2h[15] = tl_sm1_37_us_d2h[0];
+  assign tl_keymgr_o = tl_s1n_26_ds_h2d[15];
+  assign tl_s1n_26_ds_d2h[15] = tl_keymgr_i;
 
-  assign tl_sm1_38_us_h2d[0] = tl_s1n_25_ds_h2d[16];
-  assign tl_s1n_25_ds_d2h[16] = tl_sm1_38_us_d2h[0];
+  assign tl_sm1_39_us_h2d[0] = tl_s1n_26_ds_h2d[16];
+  assign tl_s1n_26_ds_d2h[16] = tl_sm1_39_us_d2h[0];
 
-  assign tl_sm1_21_us_h2d[2] = tl_s1n_39_ds_h2d[0];
-  assign tl_s1n_39_ds_d2h[0] = tl_sm1_21_us_d2h[2];
+  assign tl_sm1_40_us_h2d[0] = tl_s1n_26_ds_h2d[17];
+  assign tl_s1n_26_ds_d2h[17] = tl_sm1_40_us_d2h[0];
 
-  assign tl_sm1_23_us_h2d[2] = tl_s1n_39_ds_h2d[1];
-  assign tl_s1n_39_ds_d2h[1] = tl_sm1_23_us_d2h[2];
+  assign tl_sm1_22_us_h2d[2] = tl_s1n_41_ds_h2d[0];
+  assign tl_s1n_41_ds_d2h[0] = tl_sm1_22_us_d2h[2];
 
-  assign tl_sm1_24_us_h2d[2] = tl_s1n_39_ds_h2d[2];
-  assign tl_s1n_39_ds_d2h[2] = tl_sm1_24_us_d2h[2];
+  assign tl_sm1_27_us_h2d[1] = tl_s1n_41_ds_h2d[1];
+  assign tl_s1n_41_ds_d2h[1] = tl_sm1_27_us_d2h[1];
 
-  assign tl_sm1_27_us_h2d[1] = tl_s1n_39_ds_h2d[3];
-  assign tl_s1n_39_ds_d2h[3] = tl_sm1_27_us_d2h[1];
+  assign tl_sm1_24_us_h2d[2] = tl_s1n_41_ds_h2d[2];
+  assign tl_s1n_41_ds_d2h[2] = tl_sm1_24_us_d2h[2];
 
-  assign tl_sm1_28_us_h2d[1] = tl_s1n_39_ds_h2d[4];
-  assign tl_s1n_39_ds_d2h[4] = tl_sm1_28_us_d2h[1];
+  assign tl_sm1_25_us_h2d[2] = tl_s1n_41_ds_h2d[3];
+  assign tl_s1n_41_ds_d2h[3] = tl_sm1_25_us_d2h[2];
 
-  assign tl_sm1_29_us_h2d[1] = tl_s1n_39_ds_h2d[5];
-  assign tl_s1n_39_ds_d2h[5] = tl_sm1_29_us_d2h[1];
+  assign tl_sm1_29_us_h2d[1] = tl_s1n_41_ds_h2d[4];
+  assign tl_s1n_41_ds_d2h[4] = tl_sm1_29_us_d2h[1];
 
-  assign tl_sm1_30_us_h2d[1] = tl_s1n_39_ds_h2d[6];
-  assign tl_s1n_39_ds_d2h[6] = tl_sm1_30_us_d2h[1];
+  assign tl_sm1_30_us_h2d[1] = tl_s1n_41_ds_h2d[5];
+  assign tl_s1n_41_ds_d2h[5] = tl_sm1_30_us_d2h[1];
 
-  assign tl_sm1_31_us_h2d[1] = tl_s1n_39_ds_h2d[7];
-  assign tl_s1n_39_ds_d2h[7] = tl_sm1_31_us_d2h[1];
+  assign tl_sm1_31_us_h2d[1] = tl_s1n_41_ds_h2d[6];
+  assign tl_s1n_41_ds_d2h[6] = tl_sm1_31_us_d2h[1];
 
-  assign tl_sm1_32_us_h2d[1] = tl_s1n_39_ds_h2d[8];
-  assign tl_s1n_39_ds_d2h[8] = tl_sm1_32_us_d2h[1];
+  assign tl_sm1_32_us_h2d[1] = tl_s1n_41_ds_h2d[7];
+  assign tl_s1n_41_ds_d2h[7] = tl_sm1_32_us_d2h[1];
 
-  assign tl_sm1_33_us_h2d[1] = tl_s1n_39_ds_h2d[9];
-  assign tl_s1n_39_ds_d2h[9] = tl_sm1_33_us_d2h[1];
+  assign tl_sm1_33_us_h2d[1] = tl_s1n_41_ds_h2d[8];
+  assign tl_s1n_41_ds_d2h[8] = tl_sm1_33_us_d2h[1];
 
-  assign tl_sm1_34_us_h2d[1] = tl_s1n_39_ds_h2d[10];
-  assign tl_s1n_39_ds_d2h[10] = tl_sm1_34_us_d2h[1];
+  assign tl_sm1_34_us_h2d[1] = tl_s1n_41_ds_h2d[9];
+  assign tl_s1n_41_ds_d2h[9] = tl_sm1_34_us_d2h[1];
 
-  assign tl_sm1_35_us_h2d[1] = tl_s1n_39_ds_h2d[11];
-  assign tl_s1n_39_ds_d2h[11] = tl_sm1_35_us_d2h[1];
+  assign tl_sm1_35_us_h2d[1] = tl_s1n_41_ds_h2d[10];
+  assign tl_s1n_41_ds_d2h[10] = tl_sm1_35_us_d2h[1];
 
-  assign tl_sm1_36_us_h2d[1] = tl_s1n_39_ds_h2d[12];
-  assign tl_s1n_39_ds_d2h[12] = tl_sm1_36_us_d2h[1];
+  assign tl_sm1_36_us_h2d[1] = tl_s1n_41_ds_h2d[11];
+  assign tl_s1n_41_ds_d2h[11] = tl_sm1_36_us_d2h[1];
 
-  assign tl_sm1_37_us_h2d[1] = tl_s1n_39_ds_h2d[13];
-  assign tl_s1n_39_ds_d2h[13] = tl_sm1_37_us_d2h[1];
+  assign tl_sm1_37_us_h2d[1] = tl_s1n_41_ds_h2d[12];
+  assign tl_s1n_41_ds_d2h[12] = tl_sm1_37_us_d2h[1];
 
-  assign tl_sm1_38_us_h2d[1] = tl_s1n_39_ds_h2d[14];
-  assign tl_s1n_39_ds_d2h[14] = tl_sm1_38_us_d2h[1];
+  assign tl_sm1_38_us_h2d[1] = tl_s1n_41_ds_h2d[13];
+  assign tl_s1n_41_ds_d2h[13] = tl_sm1_38_us_d2h[1];
 
-  assign tl_s1n_20_us_h2d = tl_corei_i;
-  assign tl_corei_o = tl_s1n_20_us_d2h;
+  assign tl_sm1_39_us_h2d[1] = tl_s1n_41_ds_h2d[14];
+  assign tl_s1n_41_ds_d2h[14] = tl_sm1_39_us_d2h[1];
 
-  assign tl_rom_o = tl_sm1_21_ds_h2d;
-  assign tl_sm1_21_ds_d2h = tl_rom_i;
+  assign tl_sm1_40_us_h2d[1] = tl_s1n_41_ds_h2d[15];
+  assign tl_s1n_41_ds_d2h[15] = tl_sm1_40_us_d2h[1];
 
-  assign tl_debug_mem_o = tl_sm1_22_ds_h2d;
-  assign tl_sm1_22_ds_d2h = tl_debug_mem_i;
+  assign tl_s1n_21_us_h2d = tl_corei_i;
+  assign tl_corei_o = tl_s1n_21_us_d2h;
 
-  assign tl_ram_main_o = tl_sm1_23_ds_h2d;
-  assign tl_sm1_23_ds_d2h = tl_ram_main_i;
+  assign tl_rom_ctrl__rom_o = tl_sm1_22_ds_h2d;
+  assign tl_sm1_22_ds_d2h = tl_rom_ctrl__rom_i;
 
-  assign tl_eflash_o = tl_sm1_24_ds_h2d;
-  assign tl_sm1_24_ds_d2h = tl_eflash_i;
+  assign tl_debug_mem_o = tl_sm1_23_ds_h2d;
+  assign tl_sm1_23_ds_d2h = tl_debug_mem_i;
 
-  assign tl_s1n_25_us_h2d = tl_cored_i;
-  assign tl_cored_o = tl_s1n_25_us_d2h;
+  assign tl_ram_main_o = tl_sm1_24_ds_h2d;
+  assign tl_sm1_24_ds_d2h = tl_ram_main_i;
 
-  assign tl_peri_o = tl_asf_26_ds_h2d;
-  assign tl_asf_26_ds_d2h = tl_peri_i;
+  assign tl_eflash_o = tl_sm1_25_ds_h2d;
+  assign tl_sm1_25_ds_d2h = tl_eflash_i;
 
-  assign tl_asf_26_us_h2d = tl_sm1_27_ds_h2d;
-  assign tl_sm1_27_ds_d2h = tl_asf_26_us_d2h;
+  assign tl_s1n_26_us_h2d = tl_cored_i;
+  assign tl_cored_o = tl_s1n_26_us_d2h;
 
-  assign tl_flash_ctrl_o = tl_sm1_28_ds_h2d;
-  assign tl_sm1_28_ds_d2h = tl_flash_ctrl_i;
+  assign tl_rom_ctrl__regs_o = tl_sm1_27_ds_h2d;
+  assign tl_sm1_27_ds_d2h = tl_rom_ctrl__regs_i;
 
-  assign tl_aes_o = tl_sm1_29_ds_h2d;
-  assign tl_sm1_29_ds_d2h = tl_aes_i;
+  assign tl_peri_o = tl_asf_28_ds_h2d;
+  assign tl_asf_28_ds_d2h = tl_peri_i;
 
-  assign tl_entropy_src_o = tl_sm1_30_ds_h2d;
-  assign tl_sm1_30_ds_d2h = tl_entropy_src_i;
+  assign tl_asf_28_us_h2d = tl_sm1_29_ds_h2d;
+  assign tl_sm1_29_ds_d2h = tl_asf_28_us_d2h;
 
-  assign tl_csrng_o = tl_sm1_31_ds_h2d;
-  assign tl_sm1_31_ds_d2h = tl_csrng_i;
+  assign tl_flash_ctrl_o = tl_sm1_30_ds_h2d;
+  assign tl_sm1_30_ds_d2h = tl_flash_ctrl_i;
 
-  assign tl_edn0_o = tl_sm1_32_ds_h2d;
-  assign tl_sm1_32_ds_d2h = tl_edn0_i;
+  assign tl_aes_o = tl_sm1_31_ds_h2d;
+  assign tl_sm1_31_ds_d2h = tl_aes_i;
 
-  assign tl_edn1_o = tl_sm1_33_ds_h2d;
-  assign tl_sm1_33_ds_d2h = tl_edn1_i;
+  assign tl_entropy_src_o = tl_sm1_32_ds_h2d;
+  assign tl_sm1_32_ds_d2h = tl_entropy_src_i;
 
-  assign tl_hmac_o = tl_sm1_34_ds_h2d;
-  assign tl_sm1_34_ds_d2h = tl_hmac_i;
+  assign tl_csrng_o = tl_sm1_33_ds_h2d;
+  assign tl_sm1_33_ds_d2h = tl_csrng_i;
 
-  assign tl_rv_plic_o = tl_sm1_35_ds_h2d;
-  assign tl_sm1_35_ds_d2h = tl_rv_plic_i;
+  assign tl_edn0_o = tl_sm1_34_ds_h2d;
+  assign tl_sm1_34_ds_d2h = tl_edn0_i;
 
-  assign tl_otbn_o = tl_sm1_36_ds_h2d;
-  assign tl_sm1_36_ds_d2h = tl_otbn_i;
+  assign tl_edn1_o = tl_sm1_35_ds_h2d;
+  assign tl_sm1_35_ds_d2h = tl_edn1_i;
 
-  assign tl_kmac_o = tl_sm1_37_ds_h2d;
-  assign tl_sm1_37_ds_d2h = tl_kmac_i;
+  assign tl_hmac_o = tl_sm1_36_ds_h2d;
+  assign tl_sm1_36_ds_d2h = tl_hmac_i;
 
-  assign tl_sram_ctrl_main_o = tl_sm1_38_ds_h2d;
-  assign tl_sm1_38_ds_d2h = tl_sram_ctrl_main_i;
+  assign tl_rv_plic_o = tl_sm1_37_ds_h2d;
+  assign tl_sm1_37_ds_d2h = tl_rv_plic_i;
 
-  assign tl_s1n_39_us_h2d = tl_dm_sba_i;
-  assign tl_dm_sba_o = tl_s1n_39_us_d2h;
+  assign tl_otbn_o = tl_sm1_38_ds_h2d;
+  assign tl_sm1_38_ds_d2h = tl_otbn_i;
+
+  assign tl_kmac_o = tl_sm1_39_ds_h2d;
+  assign tl_sm1_39_ds_d2h = tl_kmac_i;
+
+  assign tl_sram_ctrl_main_o = tl_sm1_40_ds_h2d;
+  assign tl_sm1_40_ds_d2h = tl_sram_ctrl_main_i;
+
+  assign tl_s1n_41_us_h2d = tl_dm_sba_i;
+  assign tl_dm_sba_o = tl_s1n_41_us_d2h;
 
   always_comb begin
     // default steering to generate error response if address is not within the range
-    dev_sel_s1n_20 = 3'd4;
-    if ((tl_s1n_20_us_h2d.a_address &
-         ~(ADDR_MASK_ROM)) == ADDR_SPACE_ROM) begin
-      dev_sel_s1n_20 = 3'd0;
+    dev_sel_s1n_21 = 3'd4;
+    if ((tl_s1n_21_us_h2d.a_address &
+         ~(ADDR_MASK_ROM_CTRL__ROM)) == ADDR_SPACE_ROM_CTRL__ROM) begin
+      dev_sel_s1n_21 = 3'd0;
 
-    end else if ((tl_s1n_20_us_h2d.a_address &
+    end else if ((tl_s1n_21_us_h2d.a_address &
                   ~(ADDR_MASK_DEBUG_MEM)) == ADDR_SPACE_DEBUG_MEM) begin
-      dev_sel_s1n_20 = 3'd1;
+      dev_sel_s1n_21 = 3'd1;
 
-    end else if ((tl_s1n_20_us_h2d.a_address &
+    end else if ((tl_s1n_21_us_h2d.a_address &
                   ~(ADDR_MASK_RAM_MAIN)) == ADDR_SPACE_RAM_MAIN) begin
-      dev_sel_s1n_20 = 3'd2;
+      dev_sel_s1n_21 = 3'd2;
 
-    end else if ((tl_s1n_20_us_h2d.a_address &
+    end else if ((tl_s1n_21_us_h2d.a_address &
                   ~(ADDR_MASK_EFLASH)) == ADDR_SPACE_EFLASH) begin
-      dev_sel_s1n_20 = 3'd3;
+      dev_sel_s1n_21 = 3'd3;
 end
   end
 
   always_comb begin
     // default steering to generate error response if address is not within the range
-    dev_sel_s1n_25 = 5'd17;
-    if ((tl_s1n_25_us_h2d.a_address &
-         ~(ADDR_MASK_ROM)) == ADDR_SPACE_ROM) begin
-      dev_sel_s1n_25 = 5'd0;
+    dev_sel_s1n_26 = 5'd18;
+    if ((tl_s1n_26_us_h2d.a_address &
+         ~(ADDR_MASK_ROM_CTRL__ROM)) == ADDR_SPACE_ROM_CTRL__ROM) begin
+      dev_sel_s1n_26 = 5'd0;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
+                  ~(ADDR_MASK_ROM_CTRL__REGS)) == ADDR_SPACE_ROM_CTRL__REGS) begin
+      dev_sel_s1n_26 = 5'd1;
+
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_DEBUG_MEM)) == ADDR_SPACE_DEBUG_MEM) begin
-      dev_sel_s1n_25 = 5'd1;
+      dev_sel_s1n_26 = 5'd2;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_RAM_MAIN)) == ADDR_SPACE_RAM_MAIN) begin
-      dev_sel_s1n_25 = 5'd2;
+      dev_sel_s1n_26 = 5'd3;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_EFLASH)) == ADDR_SPACE_EFLASH) begin
-      dev_sel_s1n_25 = 5'd3;
+      dev_sel_s1n_26 = 5'd4;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_PERI)) == ADDR_SPACE_PERI) begin
-      dev_sel_s1n_25 = 5'd4;
+      dev_sel_s1n_26 = 5'd5;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_FLASH_CTRL)) == ADDR_SPACE_FLASH_CTRL) begin
-      dev_sel_s1n_25 = 5'd5;
+      dev_sel_s1n_26 = 5'd6;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_AES)) == ADDR_SPACE_AES) begin
-      dev_sel_s1n_25 = 5'd6;
+      dev_sel_s1n_26 = 5'd7;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_ENTROPY_SRC)) == ADDR_SPACE_ENTROPY_SRC) begin
-      dev_sel_s1n_25 = 5'd7;
+      dev_sel_s1n_26 = 5'd8;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_CSRNG)) == ADDR_SPACE_CSRNG) begin
-      dev_sel_s1n_25 = 5'd8;
+      dev_sel_s1n_26 = 5'd9;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_EDN0)) == ADDR_SPACE_EDN0) begin
-      dev_sel_s1n_25 = 5'd9;
+      dev_sel_s1n_26 = 5'd10;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_EDN1)) == ADDR_SPACE_EDN1) begin
-      dev_sel_s1n_25 = 5'd10;
+      dev_sel_s1n_26 = 5'd11;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_HMAC)) == ADDR_SPACE_HMAC) begin
-      dev_sel_s1n_25 = 5'd11;
+      dev_sel_s1n_26 = 5'd12;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_RV_PLIC)) == ADDR_SPACE_RV_PLIC) begin
-      dev_sel_s1n_25 = 5'd12;
+      dev_sel_s1n_26 = 5'd13;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_OTBN)) == ADDR_SPACE_OTBN) begin
-      dev_sel_s1n_25 = 5'd13;
+      dev_sel_s1n_26 = 5'd14;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_KEYMGR)) == ADDR_SPACE_KEYMGR) begin
-      dev_sel_s1n_25 = 5'd14;
+      dev_sel_s1n_26 = 5'd15;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_KMAC)) == ADDR_SPACE_KMAC) begin
-      dev_sel_s1n_25 = 5'd15;
+      dev_sel_s1n_26 = 5'd16;
 
-    end else if ((tl_s1n_25_us_h2d.a_address &
+    end else if ((tl_s1n_26_us_h2d.a_address &
                   ~(ADDR_MASK_SRAM_CTRL_MAIN)) == ADDR_SPACE_SRAM_CTRL_MAIN) begin
-      dev_sel_s1n_25 = 5'd16;
+      dev_sel_s1n_26 = 5'd17;
 end
   end
 
   always_comb begin
     // default steering to generate error response if address is not within the range
-    dev_sel_s1n_39 = 4'd15;
-    if ((tl_s1n_39_us_h2d.a_address &
-         ~(ADDR_MASK_ROM)) == ADDR_SPACE_ROM) begin
-      dev_sel_s1n_39 = 4'd0;
+    dev_sel_s1n_41 = 5'd16;
+    if ((tl_s1n_41_us_h2d.a_address &
+         ~(ADDR_MASK_ROM_CTRL__ROM)) == ADDR_SPACE_ROM_CTRL__ROM) begin
+      dev_sel_s1n_41 = 5'd0;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
+                  ~(ADDR_MASK_ROM_CTRL__REGS)) == ADDR_SPACE_ROM_CTRL__REGS) begin
+      dev_sel_s1n_41 = 5'd1;
+
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_RAM_MAIN)) == ADDR_SPACE_RAM_MAIN) begin
-      dev_sel_s1n_39 = 4'd1;
+      dev_sel_s1n_41 = 5'd2;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_EFLASH)) == ADDR_SPACE_EFLASH) begin
-      dev_sel_s1n_39 = 4'd2;
+      dev_sel_s1n_41 = 5'd3;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_PERI)) == ADDR_SPACE_PERI) begin
-      dev_sel_s1n_39 = 4'd3;
+      dev_sel_s1n_41 = 5'd4;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_FLASH_CTRL)) == ADDR_SPACE_FLASH_CTRL) begin
-      dev_sel_s1n_39 = 4'd4;
+      dev_sel_s1n_41 = 5'd5;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_AES)) == ADDR_SPACE_AES) begin
-      dev_sel_s1n_39 = 4'd5;
+      dev_sel_s1n_41 = 5'd6;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_ENTROPY_SRC)) == ADDR_SPACE_ENTROPY_SRC) begin
-      dev_sel_s1n_39 = 4'd6;
+      dev_sel_s1n_41 = 5'd7;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_CSRNG)) == ADDR_SPACE_CSRNG) begin
-      dev_sel_s1n_39 = 4'd7;
+      dev_sel_s1n_41 = 5'd8;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_EDN0)) == ADDR_SPACE_EDN0) begin
-      dev_sel_s1n_39 = 4'd8;
+      dev_sel_s1n_41 = 5'd9;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_EDN1)) == ADDR_SPACE_EDN1) begin
-      dev_sel_s1n_39 = 4'd9;
+      dev_sel_s1n_41 = 5'd10;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_HMAC)) == ADDR_SPACE_HMAC) begin
-      dev_sel_s1n_39 = 4'd10;
+      dev_sel_s1n_41 = 5'd11;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_RV_PLIC)) == ADDR_SPACE_RV_PLIC) begin
-      dev_sel_s1n_39 = 4'd11;
+      dev_sel_s1n_41 = 5'd12;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_OTBN)) == ADDR_SPACE_OTBN) begin
-      dev_sel_s1n_39 = 4'd12;
+      dev_sel_s1n_41 = 5'd13;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_KMAC)) == ADDR_SPACE_KMAC) begin
-      dev_sel_s1n_39 = 4'd13;
+      dev_sel_s1n_41 = 5'd14;
 
-    end else if ((tl_s1n_39_us_h2d.a_address &
+    end else if ((tl_s1n_41_us_h2d.a_address &
                   ~(ADDR_MASK_SRAM_CTRL_MAIN)) == ADDR_SPACE_SRAM_CTRL_MAIN) begin
-      dev_sel_s1n_39 = 4'd14;
+      dev_sel_s1n_41 = 5'd15;
 end
   end
 
@@ -631,14 +661,14 @@
     .DReqDepth (16'h0),
     .DRspDepth (16'h0),
     .N         (4)
-  ) u_s1n_20 (
+  ) u_s1n_21 (
     .clk_i        (clk_main_i),
     .rst_ni       (rst_main_ni),
-    .tl_h_i       (tl_s1n_20_us_h2d),
-    .tl_h_o       (tl_s1n_20_us_d2h),
-    .tl_d_o       (tl_s1n_20_ds_h2d),
-    .tl_d_i       (tl_s1n_20_ds_d2h),
-    .dev_select_i (dev_sel_s1n_20)
+    .tl_h_i       (tl_s1n_21_us_h2d),
+    .tl_h_o       (tl_s1n_21_us_d2h),
+    .tl_d_o       (tl_s1n_21_ds_h2d),
+    .tl_d_i       (tl_s1n_21_ds_d2h),
+    .dev_select_i (dev_sel_s1n_21)
   );
   tlul_socket_m1 #(
     .HReqDepth (12'h0),
@@ -646,20 +676,6 @@
     .DReqDepth (4'h0),
     .DRspDepth (4'h0),
     .M         (3)
-  ) u_sm1_21 (
-    .clk_i        (clk_main_i),
-    .rst_ni       (rst_main_ni),
-    .tl_h_i       (tl_sm1_21_us_h2d),
-    .tl_h_o       (tl_sm1_21_us_d2h),
-    .tl_d_o       (tl_sm1_21_ds_h2d),
-    .tl_d_i       (tl_sm1_21_ds_d2h)
-  );
-  tlul_socket_m1 #(
-    .HReqDepth (8'h0),
-    .HRspDepth (8'h0),
-    .DReqPass  (1'b0),
-    .DRspPass  (1'b0),
-    .M         (2)
   ) u_sm1_22 (
     .clk_i        (clk_main_i),
     .rst_ni       (rst_main_ni),
@@ -669,11 +685,11 @@
     .tl_d_i       (tl_sm1_22_ds_d2h)
   );
   tlul_socket_m1 #(
-    .HReqDepth (12'h0),
-    .HRspDepth (12'h0),
-    .DReqDepth (4'h0),
-    .DRspDepth (4'h0),
-    .M         (3)
+    .HReqDepth (8'h0),
+    .HRspDepth (8'h0),
+    .DReqPass  (1'b0),
+    .DRspPass  (1'b0),
+    .M         (2)
   ) u_sm1_23 (
     .clk_i        (clk_main_i),
     .rst_ni       (rst_main_ni),
@@ -696,35 +712,36 @@
     .tl_d_o       (tl_sm1_24_ds_h2d),
     .tl_d_i       (tl_sm1_24_ds_d2h)
   );
+  tlul_socket_m1 #(
+    .HReqDepth (12'h0),
+    .HRspDepth (12'h0),
+    .DReqDepth (4'h0),
+    .DRspDepth (4'h0),
+    .M         (3)
+  ) u_sm1_25 (
+    .clk_i        (clk_main_i),
+    .rst_ni       (rst_main_ni),
+    .tl_h_i       (tl_sm1_25_us_h2d),
+    .tl_h_o       (tl_sm1_25_us_d2h),
+    .tl_d_o       (tl_sm1_25_ds_h2d),
+    .tl_d_i       (tl_sm1_25_ds_d2h)
+  );
   tlul_socket_1n #(
     .HReqDepth (4'h0),
     .HRspDepth (4'h0),
-    .DReqPass  (17'h1bfff),
-    .DRspPass  (17'h1bfff),
-    .DReqDepth (68'h200000000000000),
-    .DRspDepth (68'h200000000000000),
-    .N         (17)
-  ) u_s1n_25 (
+    .DReqPass  (18'h37fff),
+    .DRspPass  (18'h37fff),
+    .DReqDepth (72'h2000000000000000),
+    .DRspDepth (72'h2000000000000000),
+    .N         (18)
+  ) u_s1n_26 (
     .clk_i        (clk_main_i),
     .rst_ni       (rst_main_ni),
-    .tl_h_i       (tl_s1n_25_us_h2d),
-    .tl_h_o       (tl_s1n_25_us_d2h),
-    .tl_d_o       (tl_s1n_25_ds_h2d),
-    .tl_d_i       (tl_s1n_25_ds_d2h),
-    .dev_select_i (dev_sel_s1n_25)
-  );
-  tlul_fifo_async #(
-    .ReqDepth        (4),// At least 4 to make async work
-    .RspDepth        (4) // At least 4 to make async work
-  ) u_asf_26 (
-    .clk_h_i      (clk_main_i),
-    .rst_h_ni     (rst_main_ni),
-    .clk_d_i      (clk_fixed_i),
-    .rst_d_ni     (rst_fixed_ni),
-    .tl_h_i       (tl_asf_26_us_h2d),
-    .tl_h_o       (tl_asf_26_us_d2h),
-    .tl_d_o       (tl_asf_26_ds_h2d),
-    .tl_d_i       (tl_asf_26_ds_d2h)
+    .tl_h_i       (tl_s1n_26_us_h2d),
+    .tl_h_o       (tl_s1n_26_us_d2h),
+    .tl_d_o       (tl_s1n_26_ds_h2d),
+    .tl_d_i       (tl_s1n_26_ds_d2h),
+    .dev_select_i (dev_sel_s1n_26)
   );
   tlul_socket_m1 #(
     .HReqDepth (8'h0),
@@ -740,25 +757,24 @@
     .tl_d_o       (tl_sm1_27_ds_h2d),
     .tl_d_i       (tl_sm1_27_ds_d2h)
   );
-  tlul_socket_m1 #(
-    .HReqDepth (8'h0),
-    .HRspDepth (8'h0),
-    .DReqPass  (1'b0),
-    .DRspPass  (1'b0),
-    .M         (2)
-  ) u_sm1_28 (
-    .clk_i        (clk_main_i),
-    .rst_ni       (rst_main_ni),
-    .tl_h_i       (tl_sm1_28_us_h2d),
-    .tl_h_o       (tl_sm1_28_us_d2h),
-    .tl_d_o       (tl_sm1_28_ds_h2d),
-    .tl_d_i       (tl_sm1_28_ds_d2h)
+  tlul_fifo_async #(
+    .ReqDepth        (4),// At least 4 to make async work
+    .RspDepth        (4) // At least 4 to make async work
+  ) u_asf_28 (
+    .clk_h_i      (clk_main_i),
+    .rst_h_ni     (rst_main_ni),
+    .clk_d_i      (clk_fixed_i),
+    .rst_d_ni     (rst_fixed_ni),
+    .tl_h_i       (tl_asf_28_us_h2d),
+    .tl_h_o       (tl_asf_28_us_d2h),
+    .tl_d_o       (tl_asf_28_ds_h2d),
+    .tl_d_i       (tl_asf_28_ds_d2h)
   );
   tlul_socket_m1 #(
     .HReqDepth (8'h0),
     .HRspDepth (8'h0),
-    .DReqPass  (1'b0),
-    .DRspPass  (1'b0),
+    .DReqDepth (4'h0),
+    .DRspDepth (4'h0),
     .M         (2)
   ) u_sm1_29 (
     .clk_i        (clk_main_i),
@@ -883,8 +899,8 @@
   tlul_socket_m1 #(
     .HReqDepth (8'h0),
     .HRspDepth (8'h0),
-    .DReqDepth (4'h0),
-    .DRspDepth (4'h0),
+    .DReqPass  (1'b0),
+    .DRspPass  (1'b0),
     .M         (2)
   ) u_sm1_38 (
     .clk_i        (clk_main_i),
@@ -894,20 +910,48 @@
     .tl_d_o       (tl_sm1_38_ds_h2d),
     .tl_d_i       (tl_sm1_38_ds_d2h)
   );
+  tlul_socket_m1 #(
+    .HReqDepth (8'h0),
+    .HRspDepth (8'h0),
+    .DReqPass  (1'b0),
+    .DRspPass  (1'b0),
+    .M         (2)
+  ) u_sm1_39 (
+    .clk_i        (clk_main_i),
+    .rst_ni       (rst_main_ni),
+    .tl_h_i       (tl_sm1_39_us_h2d),
+    .tl_h_o       (tl_sm1_39_us_d2h),
+    .tl_d_o       (tl_sm1_39_ds_h2d),
+    .tl_d_i       (tl_sm1_39_ds_d2h)
+  );
+  tlul_socket_m1 #(
+    .HReqDepth (8'h0),
+    .HRspDepth (8'h0),
+    .DReqDepth (4'h0),
+    .DRspDepth (4'h0),
+    .M         (2)
+  ) u_sm1_40 (
+    .clk_i        (clk_main_i),
+    .rst_ni       (rst_main_ni),
+    .tl_h_i       (tl_sm1_40_us_h2d),
+    .tl_h_o       (tl_sm1_40_us_d2h),
+    .tl_d_o       (tl_sm1_40_ds_h2d),
+    .tl_d_i       (tl_sm1_40_ds_d2h)
+  );
   tlul_socket_1n #(
     .HReqPass  (1'b0),
     .HRspPass  (1'b0),
-    .DReqDepth (60'h0),
-    .DRspDepth (60'h0),
-    .N         (15)
-  ) u_s1n_39 (
+    .DReqDepth (64'h0),
+    .DRspDepth (64'h0),
+    .N         (16)
+  ) u_s1n_41 (
     .clk_i        (clk_main_i),
     .rst_ni       (rst_main_ni),
-    .tl_h_i       (tl_s1n_39_us_h2d),
-    .tl_h_o       (tl_s1n_39_us_d2h),
-    .tl_d_o       (tl_s1n_39_ds_h2d),
-    .tl_d_i       (tl_s1n_39_ds_d2h),
-    .dev_select_i (dev_sel_s1n_39)
+    .tl_h_i       (tl_s1n_41_us_h2d),
+    .tl_h_o       (tl_s1n_41_us_d2h),
+    .tl_d_o       (tl_s1n_41_ds_h2d),
+    .tl_d_i       (tl_s1n_41_ds_d2h),
+    .dev_select_i (dev_sel_s1n_41)
   );
 
 endmodule
diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
index b090654..ecb85a2 100644
--- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
+++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
@@ -24,12 +24,12 @@
   parameter aes_pkg::sbox_impl_e CsrngSBoxImpl = aes_pkg::SBoxImplCanright,
   parameter bit SramCtrlMainInstrExec = 1,
   parameter otbn_pkg::regfile_e OtbnRegFile = otbn_pkg::RegFileFF,
+  parameter  RomCtrlBootRomInitFile = "",
 
   // Manually defined parameters
   parameter ibex_pkg::regfile_e IbexRegFile = ibex_pkg::RegFileFF,
   parameter bit IbexICache = 1,
-  parameter bit IbexPipeLine = 0,
-  parameter     BootRomInitFile = ""
+  parameter bit IbexPipeLine = 0
 ) (
   // Reset, clocks defined as part of intermodule
   input               rst_ni,
@@ -248,6 +248,7 @@
   // edn1
   // sram_ctrl_main
   // otbn
+  // rom_ctrl
 
 
   logic [176:0]  intr_vector;
@@ -499,8 +500,10 @@
   lc_ctrl_pkg::lc_tx_t       lc_ctrl_lc_seed_hw_rd_en;
   logic [3:0] pwrmgr_aon_wakeups;
   logic       pwrmgr_aon_rstreqs;
-  tlul_pkg::tl_h2d_t       rom_tl_req;
-  tlul_pkg::tl_d2h_t       rom_tl_rsp;
+  tlul_pkg::tl_h2d_t       rom_ctrl_rom_tl_req;
+  tlul_pkg::tl_d2h_t       rom_ctrl_rom_tl_rsp;
+  tlul_pkg::tl_h2d_t       rom_ctrl_regs_tl_req;
+  tlul_pkg::tl_d2h_t       rom_ctrl_regs_tl_rsp;
   tlul_pkg::tl_h2d_t       ram_main_tl_req;
   tlul_pkg::tl_d2h_t       ram_main_tl_rsp;
   tlul_pkg::tl_h2d_t       eflash_tl_req;
@@ -698,7 +701,7 @@
     .ram_cfg_i            (ast_ram_1p_cfg),
     // static pinning
     .hart_id_i            (32'b0),
-    .boot_addr_i          (ADDR_SPACE_ROM),
+    .boot_addr_i          (ADDR_SPACE_ROM_CTRL__ROM),
     // TL-UL buses
     .tl_i_o               (main_tl_corei_req),
     .tl_i_i               (main_tl_corei_rsp),
@@ -752,53 +755,6 @@
   assign rstmgr_aon_cpu.ndmreset_req = ndmreset_req;
   assign rstmgr_aon_cpu.rst_cpu_n = rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel];
 
-  // ROM device
-  logic        rom_req;
-  logic [11:0] rom_addr;
-  logic [39:0] rom_rdata;
-  logic        rom_rvalid;
-
-  tlul_adapter_sram #(
-    .SramAw(12),
-    .SramDw(32),
-    .Outstanding(2),
-    .ErrOnWrite(1),
-    .CmdIntgCheck(1),
-    .EnableRspIntgGen(1),
-    .EnableDataIntgGen(1) // TODO: Needs to be updated for intgerity passthrough
-  ) u_tl_adapter_rom (
-    .clk_i   (clkmgr_aon_clocks.clk_main_infra),
-    .rst_ni   (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
-
-    .tl_i        (rom_tl_req),
-    .tl_o        (rom_tl_rsp),
-    .en_ifetch_i (tlul_pkg::InstrEn),
-    .req_o       (rom_req),
-    .gnt_i       (1'b1), // Always grant as only one requester exists
-    .we_o        (),
-    .addr_o      (rom_addr),
-    .wdata_o     (),
-    .wmask_o     (),
-    .intg_error_o(), // Connect to ROM checker and ROM scramble later
-    .rdata_i     (rom_rdata[31:0]),
-    .rvalid_i    (rom_rvalid),
-    .rerror_i    (2'b00)
-  );
-
-  prim_rom_adv #(
-    .Width(40),
-    .Depth(4096),
-    .MemInitFile(BootRomInitFile)
-  ) u_rom_rom (
-    .clk_i   (clkmgr_aon_clocks.clk_main_infra),
-    .rst_ni   (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
-    .req_i    (rom_req),
-    .addr_i   (rom_addr),
-    .rdata_o  (rom_rdata),
-    .rvalid_o (rom_rvalid),
-    .cfg_i    (rom_cfg_i)
-  );
-
   // sram device
   logic        ram_main_req;
   logic        ram_main_gnt;
@@ -2197,6 +2153,26 @@
       .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
 
+  rom_ctrl #(
+    .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[29:29]),
+    .BootRomInitFile(RomCtrlBootRomInitFile)
+  ) u_rom_ctrl (
+      // [29]: fatal
+      .alert_tx_o  ( alert_tx[29:29] ),
+      .alert_rx_i  ( alert_rx[29:29] ),
+
+      // Inter-module signals
+      .rom_cfg_i(ast_rom_cfg),
+      .regs_tl_i(rom_ctrl_regs_tl_req),
+      .regs_tl_o(rom_ctrl_regs_tl_rsp),
+      .rom_tl_i(rom_ctrl_rom_tl_req),
+      .rom_tl_o(rom_ctrl_rom_tl_rsp),
+
+      // Clock and reset connections
+      .clk_i (clkmgr_aon_clocks.clk_main_infra),
+      .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
+  );
+
   // interrupt assignments
   assign intr_vector = {
       intr_otbn_done, // ID 145
@@ -2366,9 +2342,13 @@
     .tl_dm_sba_i(main_tl_dm_sba_req),
     .tl_dm_sba_o(main_tl_dm_sba_rsp),
 
-    // port: tl_rom
-    .tl_rom_o(rom_tl_req),
-    .tl_rom_i(rom_tl_rsp),
+    // port: tl_rom_ctrl__rom
+    .tl_rom_ctrl__rom_o(rom_ctrl_rom_tl_req),
+    .tl_rom_ctrl__rom_i(rom_ctrl_rom_tl_rsp),
+
+    // port: tl_rom_ctrl__regs
+    .tl_rom_ctrl__regs_o(rom_ctrl_regs_tl_req),
+    .tl_rom_ctrl__regs_i(rom_ctrl_regs_tl_rsp),
 
     // port: tl_debug_mem
     .tl_debug_mem_o(main_tl_debug_mem_req),
diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey_pkg.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey_pkg.sv
index 337c08a..c27517f 100644
--- a/hw/top_earlgrey/rtl/autogen/top_earlgrey_pkg.sv
+++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey_pkg.sv
@@ -391,14 +391,24 @@
   parameter int unsigned TOP_EARLGREY_OTBN_SIZE_BYTES = 32'h10000;
 
   /**
-   * Memory base address for rom in top earlgrey.
+   * Peripheral base address for regs device on rom_ctrl in top earlgrey.
    */
-  parameter int unsigned TOP_EARLGREY_ROM_BASE_ADDR = 32'h8000;
+  parameter int unsigned TOP_EARLGREY_ROM_CTRL_REGS_BASE_ADDR = 32'h411E0000;
 
   /**
-   * Memory size for rom in top earlgrey.
+   * Peripheral size in bytes for regs device on rom_ctrl in top earlgrey.
    */
-  parameter int unsigned TOP_EARLGREY_ROM_SIZE_BYTES = 32'h4000;
+  parameter int unsigned TOP_EARLGREY_ROM_CTRL_REGS_SIZE_BYTES = 32'h1000;
+
+  /**
+   * Peripheral base address for rom device on rom_ctrl in top earlgrey.
+   */
+  parameter int unsigned TOP_EARLGREY_ROM_CTRL_ROM_BASE_ADDR = 32'h8000;
+
+  /**
+   * Peripheral size in bytes for rom device on rom_ctrl in top earlgrey.
+   */
+  parameter int unsigned TOP_EARLGREY_ROM_CTRL_ROM_SIZE_BYTES = 32'h4000;
 
   /**
    * Memory base address for ram_main in top earlgrey.
diff --git a/hw/top_earlgrey/rtl/top_earlgrey_artys7.sv b/hw/top_earlgrey/rtl/top_earlgrey_artys7.sv
index 93ddba5..c42283a 100644
--- a/hw/top_earlgrey/rtl/top_earlgrey_artys7.sv
+++ b/hw/top_earlgrey/rtl/top_earlgrey_artys7.sv
@@ -194,7 +194,7 @@
     .IbexRegFile(ibex_pkg::RegFileFPGA),
     .IbexPipeLine(1),
     .OtbnRegFile(otbn_pkg::RegFileFPGA),
-    .BootRomInitFile(BootRomInitFile)
+    .RomCtrlBootRomInitFile(BootRomInitFile)
   ) top_earlgrey (
     // Clocks, resets
     .rst_ni          ( rst_n         ),
diff --git a/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv b/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv
index dc915f6..fe40edf 100644
--- a/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv
+++ b/hw/top_earlgrey/rtl/top_earlgrey_nexysvideo.sv
@@ -451,7 +451,7 @@
     .IbexRegFile(ibex_pkg::RegFileFPGA),
     .IbexPipeLine(1),
     .OtbnRegFile(otbn_pkg::RegFileFPGA),
-    .BootRomInitFile(BootRomInitFile),
+    .RomCtrlBootRomInitFile(BootRomInitFile),
     .OtpCtrlMemInitFile(OtpCtrlMemInitFile),
     .SramCtrlRetAonInstrExec(0),
     .SramCtrlMainInstrExec(1),
diff --git a/hw/top_earlgrey/sw/autogen/top_earlgrey.c b/hw/top_earlgrey/sw/autogen/top_earlgrey.c
index ff9955a..b293313 100644
--- a/hw/top_earlgrey/sw/autogen/top_earlgrey.c
+++ b/hw/top_earlgrey/sw/autogen/top_earlgrey.c
@@ -199,7 +199,7 @@
  * `top_earlgrey_alert_peripheral_t`.
  */
 const top_earlgrey_alert_peripheral_t
-    top_earlgrey_alert_for_peripheral[29] = {
+    top_earlgrey_alert_for_peripheral[30] = {
   [kTopEarlgreyAlertIdOtpCtrlFatalMacroError] = kTopEarlgreyAlertPeripheralOtpCtrl,
   [kTopEarlgreyAlertIdOtpCtrlFatalCheckError] = kTopEarlgreyAlertPeripheralOtpCtrl,
   [kTopEarlgreyAlertIdLcCtrlFatalProgError] = kTopEarlgreyAlertPeripheralLcCtrl,
@@ -229,5 +229,6 @@
   [kTopEarlgreyAlertIdSramCtrlMainFatalParityError] = kTopEarlgreyAlertPeripheralSramCtrlMain,
   [kTopEarlgreyAlertIdOtbnFatal] = kTopEarlgreyAlertPeripheralOtbn,
   [kTopEarlgreyAlertIdOtbnRecov] = kTopEarlgreyAlertPeripheralOtbn,
+  [kTopEarlgreyAlertIdRomCtrlFatal] = kTopEarlgreyAlertPeripheralRomCtrl,
 };
 
diff --git a/hw/top_earlgrey/sw/autogen/top_earlgrey.h b/hw/top_earlgrey/sw/autogen/top_earlgrey.h
index e000b9d..282f1f2 100644
--- a/hw/top_earlgrey/sw/autogen/top_earlgrey.h
+++ b/hw/top_earlgrey/sw/autogen/top_earlgrey.h
@@ -709,16 +709,42 @@
  */
 #define TOP_EARLGREY_OTBN_SIZE_BYTES 0x10000u
 
+/**
+ * Peripheral base address for regs device on rom_ctrl in top earlgrey.
+ *
+ * This should be used with #mmio_region_from_addr to access the memory-mapped
+ * registers associated with the peripheral (usually via a DIF).
+ */
+#define TOP_EARLGREY_ROM_CTRL_REGS_BASE_ADDR 0x411E0000u
 
 /**
- * Memory base address for rom in top earlgrey.
+ * Peripheral size for regs device on rom_ctrl in top earlgrey.
+ *
+ * This is the size (in bytes) of the peripheral's reserved memory area. All
+ * memory-mapped registers associated with this peripheral should have an
+ * address between #TOP_EARLGREY_ROM_CTRL_REGS_BASE_ADDR and
+ * `TOP_EARLGREY_ROM_CTRL_REGS_BASE_ADDR + TOP_EARLGREY_ROM_CTRL_REGS_SIZE_BYTES`.
  */
-#define TOP_EARLGREY_ROM_BASE_ADDR 0x8000u
+#define TOP_EARLGREY_ROM_CTRL_REGS_SIZE_BYTES 0x1000u
 
 /**
- * Memory size for rom in top earlgrey.
+ * Peripheral base address for rom device on rom_ctrl in top earlgrey.
+ *
+ * This should be used with #mmio_region_from_addr to access the memory-mapped
+ * registers associated with the peripheral (usually via a DIF).
  */
-#define TOP_EARLGREY_ROM_SIZE_BYTES 0x4000u
+#define TOP_EARLGREY_ROM_CTRL_ROM_BASE_ADDR 0x8000u
+
+/**
+ * Peripheral size for rom device on rom_ctrl in top earlgrey.
+ *
+ * This is the size (in bytes) of the peripheral's reserved memory area. All
+ * memory-mapped registers associated with this peripheral should have an
+ * address between #TOP_EARLGREY_ROM_CTRL_ROM_BASE_ADDR and
+ * `TOP_EARLGREY_ROM_CTRL_ROM_BASE_ADDR + TOP_EARLGREY_ROM_CTRL_ROM_SIZE_BYTES`.
+ */
+#define TOP_EARLGREY_ROM_CTRL_ROM_SIZE_BYTES 0x4000u
+
 
 /**
  * Memory base address for ram_main in top earlgrey.
@@ -1017,7 +1043,8 @@
   kTopEarlgreyAlertPeripheralEdn1 = 10, /**< edn1 */
   kTopEarlgreyAlertPeripheralSramCtrlMain = 11, /**< sram_ctrl_main */
   kTopEarlgreyAlertPeripheralOtbn = 12, /**< otbn */
-  kTopEarlgreyAlertPeripheralLast = 12, /**< \internal Final Alert peripheral */
+  kTopEarlgreyAlertPeripheralRomCtrl = 13, /**< rom_ctrl */
+  kTopEarlgreyAlertPeripheralLast = 13, /**< \internal Final Alert peripheral */
 } top_earlgrey_alert_peripheral_t;
 
 /**
@@ -1056,7 +1083,8 @@
   kTopEarlgreyAlertIdSramCtrlMainFatalParityError = 26, /**< sram_ctrl_main_fatal_parity_error */
   kTopEarlgreyAlertIdOtbnFatal = 27, /**< otbn_fatal */
   kTopEarlgreyAlertIdOtbnRecov = 28, /**< otbn_recov */
-  kTopEarlgreyAlertIdLast = 28, /**< \internal The Last Valid Alert ID. */
+  kTopEarlgreyAlertIdRomCtrlFatal = 29, /**< rom_ctrl_fatal */
+  kTopEarlgreyAlertIdLast = 29, /**< \internal The Last Valid Alert ID. */
 } top_earlgrey_alert_id_t;
 
 /**
@@ -1066,7 +1094,7 @@
  * `top_earlgrey_alert_peripheral_t`.
  */
 extern const top_earlgrey_alert_peripheral_t
-    top_earlgrey_alert_for_peripheral[29];
+    top_earlgrey_alert_for_peripheral[30];
 
 #define PINMUX_MIO_PERIPH_INSEL_IDX_OFFSET 2
 
diff --git a/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h b/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
index 1e42765..2037991 100644
--- a/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
+++ b/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
@@ -327,6 +327,20 @@
  * registers associated with the peripheral (usually via a DIF).
  */
 #define TOP_EARLGREY_OTBN_BASE_ADDR 0x411D0000
+/**
+ * Peripheral base address for regs device on rom_ctrl in top earlgrey.
+ *
+ * This should be used with #mmio_region_from_addr to access the memory-mapped
+ * registers associated with the peripheral (usually via a DIF).
+ */
+#define TOP_EARLGREY_ROM_CTRL_REGS_BASE_ADDR 0x411E0000
+/**
+ * Peripheral base address for rom device on rom_ctrl in top earlgrey.
+ *
+ * This should be used with #mmio_region_from_addr to access the memory-mapped
+ * registers associated with the peripheral (usually via a DIF).
+ */
+#define TOP_EARLGREY_ROM_CTRL_ROM_BASE_ADDR 0x8000
 #endif  // __ASSEMBLER__
 
 #endif  // OPENTITAN_HW_TOP_EARLGREY_SW_AUTOGEN_TOP_EARLGREY_MEMORY_H_
diff --git a/hw/top_earlgrey/top_earlgrey.core b/hw/top_earlgrey/top_earlgrey.core
index 0874c35..fea3d9a 100644
--- a/hw/top_earlgrey/top_earlgrey.core
+++ b/hw/top_earlgrey/top_earlgrey.core
@@ -45,6 +45,7 @@
       - lowrisc:ip:pwrmgr
       - lowrisc:ip:aon_timer
       - lowrisc:ip:adc_ctrl
+      - lowrisc:ip:rom_ctrl
       - lowrisc:systems:clkmgr
       - lowrisc:systems:sensor_ctrl
       - "!fileset_partner ? (lowrisc:systems:ast_pkg)"
diff --git a/hw/top_earlgrey/top_earlgrey_verilator.cc b/hw/top_earlgrey/top_earlgrey_verilator.cc
index bf18556..b5b90a8 100644
--- a/hw/top_earlgrey/top_earlgrey_verilator.cc
+++ b/hw/top_earlgrey/top_earlgrey_verilator.cc
@@ -21,8 +21,9 @@
       "u_prim_ram_1p_adv.u_mem."
       "gen_generic.u_impl_generic");
 
-  MemArea rom(top_scope + ".u_rom_rom.u_prim_rom.gen_generic.u_impl_generic",
-              0x4000 / 4, 4);
+  MemArea rom(
+      top_scope + ".u_rom_ctrl.u_rom.u_prim_rom.gen_generic.u_impl_generic",
+      0x4000 / 4, 4);
   MemArea ram(top_scope + ".u_ram1p_ram_main." + ram1p_adv_scope, 0x20000 / 4,
               4);
   MemArea flash(top_scope +
diff --git a/hw/top_earlgrey/util/vivado_hook_opt_design_post.tcl b/hw/top_earlgrey/util/vivado_hook_opt_design_post.tcl
index d2171aa..9943f27 100644
--- a/hw/top_earlgrey/util/vivado_hook_opt_design_post.tcl
+++ b/hw/top_earlgrey/util/vivado_hook_opt_design_post.tcl
@@ -10,8 +10,8 @@
 
   send_msg "Designcheck 2-1" INFO "Checking if ROM memory is mapped to BRAM memory."
 
-  if {[catch [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_0" && PRIMITIVE_TYPE =~ BMEM.*.* }]]\
-  && [catch [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_1" && PRIMITIVE_TYPE =~ BMEM.*.* }]] } {
+  if {[catch [get_cells -hierarchical -filter { NAME =~  "*u_rom_ctrl*u_rom*rdata_o_reg_0" && PRIMITIVE_TYPE =~ BMEM.*.* }]]\
+  && [catch [get_cells -hierarchical -filter { NAME =~  "*u_rom_ctrl*u_rom*rdata_o_reg_1" && PRIMITIVE_TYPE =~ BMEM.*.* }]] } {
     send_msg "Designcheck 2-2" INFO "BRAM implementation found for ROM memory."
   } else {
     send_msg "Designcheck 2-3" ERROR "BRAM implementation not found for ROM memory."
diff --git a/hw/top_englishbreakfast/util/vivado_hook_opt_design_post.tcl b/hw/top_englishbreakfast/util/vivado_hook_opt_design_post.tcl
deleted file mode 120000
index 6b3d6bc..0000000
--- a/hw/top_englishbreakfast/util/vivado_hook_opt_design_post.tcl
+++ /dev/null
@@ -1 +0,0 @@
-../../top_earlgrey/util/vivado_hook_opt_design_post.tcl
\ No newline at end of file
diff --git a/hw/top_englishbreakfast/util/vivado_hook_opt_design_post.tcl b/hw/top_englishbreakfast/util/vivado_hook_opt_design_post.tcl
new file mode 100644
index 0000000..d2171aa
--- /dev/null
+++ b/hw/top_englishbreakfast/util/vivado_hook_opt_design_post.tcl
@@ -0,0 +1,19 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# Hook to check BRAM implementation for ROM memory - Only used on the NexysVideo board.
+if {[string first nexysvideo [get_property TOP [current_design]]] != -1} {
+  # Any change in ROM instances path should be updated in following two files
+  # 1. hw/top_earlgrey/data/placement.xdc and
+  # 2. hw/top_earlgrey/util/vivado_hook_opt_design_post.tcl
+
+  send_msg "Designcheck 2-1" INFO "Checking if ROM memory is mapped to BRAM memory."
+
+  if {[catch [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_0" && PRIMITIVE_TYPE =~ BMEM.*.* }]]\
+  && [catch [get_cells -hierarchical -filter { NAME =~  "*rom_rom*rdata_o_reg_1" && PRIMITIVE_TYPE =~ BMEM.*.* }]] } {
+    send_msg "Designcheck 2-2" INFO "BRAM implementation found for ROM memory."
+  } else {
+    send_msg "Designcheck 2-3" ERROR "BRAM implementation not found for ROM memory."
+  }
+}