[util, reggen] Support standardized cdc handling for regfile
- Support two asynchronous schemes on regfile
- Fully asynchronous - a tlul_fifo_async directly instantiated in regfile
- Mixed asynchronous - allow user to selectively mark registers as async
- These two schemes are mutually exclusive
- Add an 'async' key for bus interfaces to indicate the reg block is fully asynchornous
- Add an 'async' key per register to indicate register clock domain
- Add extra clock/reset ports to reg module
- Add prim_subreg_cdc to handle regiser domain clock crossing
Signed-off-by: Timothy Chen <timothytim@google.com>
[aon_timer] Updates to aon_timer to experiment with new cdc scheme
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/adc_ctrl/rtl/adc_ctrl_reg_top.sv b/hw/ip/adc_ctrl/rtl/adc_ctrl_reg_top.sv
index c662ced..13b41df 100644
--- a/hw/ip/adc_ctrl/rtl/adc_ctrl_reg_top.sv
+++ b/hw/ip/adc_ctrl/rtl/adc_ctrl_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -3536,6 +3541,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -3546,12 +3562,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/aes/rtl/aes_reg_top.sv b/hw/ip/aes/rtl/aes_reg_top.sv
index 1fe3ef1..63963ae 100644
--- a/hw/ip/aes/rtl/aes_reg_top.sv
+++ b/hw/ip/aes/rtl/aes_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1422,6 +1427,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1432,12 +1448,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv b/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
index d555726..feb00d3 100644
--- a/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
+++ b/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -5850,6 +5855,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -5860,12 +5876,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/aon_timer/data/aon_timer.hjson b/hw/ip/aon_timer/data/aon_timer.hjson
index c1d3444..9d623d6 100644
--- a/hw/ip/aon_timer/data/aon_timer.hjson
+++ b/hw/ip/aon_timer/data/aon_timer.hjson
@@ -9,7 +9,7 @@
{clock: "clk_aon_i", reset: "rst_aon_ni"}
]
bus_interfaces: [
- { protocol: "tlul", direction: "device" }
+ { protocol: "tlul", direction: "device"}
],
interrupt_list: [
{ name: "wkup_timer_expired",
@@ -82,6 +82,7 @@
desc: "Wakeup Timer Control register",
swaccess: "rw",
hwaccess: "hro",
+ async: "clk_aon_i",
fields: [
{ bits: "0",
name: "enable",
@@ -97,6 +98,7 @@
desc: "Wakeup Timer Threshold Register",
swaccess: "rw",
hwaccess: "hro",
+ async: "clk_aon_i",
fields: [
{ bits: "31:0",
name: "threshold",
@@ -108,6 +110,7 @@
desc: "Wakeup Timer Count Register",
swaccess: "rw",
hwaccess: "hrw",
+ async: "clk_aon_i",
fields: [
{ bits: "31:0",
name: "count",
@@ -133,6 +136,7 @@
desc: "Watchdog Timer Control register",
swaccess: "rw",
hwaccess: "hro",
+ async: "clk_aon_i",
regwen: "WDOG_REGWEN",
fields: [
{ bits: "0",
@@ -149,6 +153,7 @@
desc: "Watchdog Timer Bark Threshold Register",
swaccess: "rw",
hwaccess: "hro",
+ async: "clk_aon_i",
regwen: "WDOG_REGWEN",
fields: [
{ bits: "31:0",
@@ -161,6 +166,7 @@
desc: "Watchdog Timer Bite Threshold Register",
swaccess: "rw",
hwaccess: "hro",
+ async: "clk_aon_i",
regwen: "WDOG_REGWEN",
fields: [
{ bits: "31:0",
@@ -173,6 +179,7 @@
desc: "Watchdog Timer Count Register",
swaccess: "rw",
hwaccess: "hrw",
+ async: "clk_aon_i",
fields: [
{ bits: "31:0",
name: "count",
@@ -220,6 +227,7 @@
desc: "Wakeup request status",
swaccess: "rw0c",
hwaccess: "hrw",
+ async: "clk_aon_i",
fields: [
{ bits: "0",
name: "cause",
diff --git a/hw/ip/aon_timer/rtl/aon_timer.sv b/hw/ip/aon_timer/rtl/aon_timer.sv
index a436eba..e62bc99 100644
--- a/hw/ip/aon_timer/rtl/aon_timer.sv
+++ b/hw/ip/aon_timer/rtl/aon_timer.sv
@@ -41,55 +41,64 @@
localparam int AON_WKUP = 0;
localparam int AON_WDOG = 1;
- // TLUL structs
- tlul_pkg::tl_h2d_t tl_aon_h2d;
- tlul_pkg::tl_d2h_t tl_aon_d2h;
// Register structs
- aon_timer_reg2hw_t aon_reg2hw;
- aon_timer_hw2reg_t aon_hw2reg;
+ aon_timer_reg2hw_t reg2hw;
+ aon_timer_hw2reg_t hw2reg;
// Register write signals
- logic wkup_count_reg_wr;
- logic [31:0] wkup_count_wr_data;
- logic wdog_count_reg_wr;
- logic [31:0] wdog_count_wr_data;
+ logic aon_wkup_count_reg_wr;
+ logic [31:0] aon_wkup_count_wr_data;
+ logic aon_wdog_count_reg_wr;
+ logic [31:0] aon_wdog_count_wr_data;
// Other sync signals
lc_ctrl_pkg::lc_tx_t [2:0] lc_escalate_en;
// Interrupt signals
logic aon_wkup_intr_set;
logic aon_wdog_intr_set;
- logic [1:0] intr_aon_test_q;
- logic intr_aon_test_qe;
- logic [1:0] intr_aon_state_q;
- logic intr_aon_state_de;
- logic [1:0] intr_aon_state_d;
+ logic [1:0] intr_test_q;
+ logic intr_test_qe;
+ logic [1:0] intr_state_q;
+ logic intr_state_de;
+ logic [1:0] intr_state_d;
logic [1:0] intr_out;
// Reset signals
logic aon_rst_req_set;
logic aon_rst_req_d, aon_rst_req_q;
// Alert signals
- logic [NumAlerts-1:0] aon_alert_test, aon_alerts;
+ logic [NumAlerts-1:0] alert_test, alerts;
//////////////////////////////
// Register Write Interface //
//////////////////////////////
- assign aon_hw2reg.wkup_count.de = wkup_count_reg_wr;
- assign aon_hw2reg.wkup_count.d = wkup_count_wr_data;
- assign aon_hw2reg.wdog_count.de = wdog_count_reg_wr;
- assign aon_hw2reg.wdog_count.d = wdog_count_wr_data;
+ logic aon_sleep_mode;
+ prim_flop_2sync #(
+ .Width(1)
+ ) u_sync_sleep_mode (
+ .clk_i (clk_aon_i),
+ .rst_ni (rst_aon_ni),
+ .d_i (sleep_mode_i),
+ .q_o (aon_sleep_mode)
+ );
+
+ assign hw2reg.wkup_count.de = aon_wkup_count_reg_wr;
+ assign hw2reg.wkup_count.d = aon_wkup_count_wr_data;
+ assign hw2reg.wdog_count.de = aon_wdog_count_reg_wr;
+ assign hw2reg.wdog_count.d = aon_wdog_count_wr_data;
// registers instantiation
aon_timer_reg_top u_reg (
- .clk_i (clk_aon_i),
- .rst_ni (rst_aon_ni),
+ .clk_i,
+ .rst_ni,
+ .clk_aon_i,
+ .rst_aon_ni,
- .tl_i (tl_aon_h2d),
- .tl_o (tl_aon_d2h),
+ .tl_i,
+ .tl_o,
- .reg2hw (aon_reg2hw),
- .hw2reg (aon_hw2reg),
+ .reg2hw,
+ .hw2reg,
- .intg_err_o (aon_alerts[0]),
+ .intg_err_o (alerts[0]),
.devmode_i (1'b1)
);
@@ -97,9 +106,9 @@
// Alerts //
////////////
- assign aon_alert_test = {
- aon_reg2hw.alert_test.q &
- aon_reg2hw.alert_test.qe
+ assign alert_test = {
+ reg2hw.alert_test.q &
+ reg2hw.alert_test.qe
};
for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx
@@ -107,35 +116,17 @@
.AsyncOn(AlertAsyncOn[i]),
.IsFatal(1'b1)
) u_prim_alert_sender (
- .clk_i (clk_aon_i),
- .rst_ni (rst_aon_ni),
- .alert_test_i ( aon_alert_test[i] ),
- .alert_req_i ( aon_alerts[0] ),
- .alert_ack_o ( ),
- .alert_state_o ( ),
- .alert_rx_i ( alert_rx_i[i] ),
- .alert_tx_o ( alert_tx_o[i] )
+ .clk_i,
+ .rst_ni,
+ .alert_test_i ( alert_test[i] ),
+ .alert_req_i ( alerts[0] ),
+ .alert_ack_o ( ),
+ .alert_state_o ( ),
+ .alert_rx_i ( alert_rx_i[i] ),
+ .alert_tx_o ( alert_tx_o[i] )
);
end
- ///////////////////////////////////////
- // Sync TLUL signals into AON Domain //
- ///////////////////////////////////////
-
- tlul_fifo_async #(
- .ReqDepth (1), // There will only ever be 1 req outstanding from the core
- .RspDepth (1)
- ) u_tlul_fifo (
- .clk_h_i (clk_i),
- .rst_h_ni (rst_aon_ni), // keep pointers consistent by using single reset
- .clk_d_i (clk_aon_i),
- .rst_d_ni (rst_aon_ni),
- .tl_h_i (tl_i),
- .tl_h_o (tl_o),
- .tl_d_o (tl_aon_h2d),
- .tl_d_i (tl_aon_d2h)
- );
-
// Lifecycle sync
prim_lc_sync #(
.NumCopies(3)
@@ -150,26 +141,16 @@
// Timer Core //
////////////////
- logic sleep_mode;
- prim_flop_2sync #(
- .Width(1)
- ) u_sync_sleep_mode (
- .clk_i (clk_aon_i),
- .rst_ni (rst_aon_ni),
- .d_i (sleep_mode_i),
- .q_o (sleep_mode)
- );
-
aon_timer_core u_core (
.clk_aon_i,
.rst_aon_ni,
- .sleep_mode_i (sleep_mode),
+ .sleep_mode_i (aon_sleep_mode),
.lc_escalate_en_i (lc_escalate_en),
- .reg2hw_i (aon_reg2hw),
- .wkup_count_reg_wr_o (wkup_count_reg_wr),
- .wkup_count_wr_data_o (wkup_count_wr_data),
- .wdog_count_reg_wr_o (wdog_count_reg_wr),
- .wdog_count_wr_data_o (wdog_count_wr_data),
+ .reg2hw_i (reg2hw),
+ .wkup_count_reg_wr_o (aon_wkup_count_reg_wr),
+ .wkup_count_wr_data_o (aon_wkup_count_wr_data),
+ .wdog_count_reg_wr_o (aon_wdog_count_reg_wr),
+ .wdog_count_wr_data_o (aon_wdog_count_wr_data),
.wkup_intr_o (aon_wkup_intr_set),
.wdog_intr_o (aon_wdog_intr_set),
.wdog_reset_req_o (aon_rst_req_set)
@@ -181,15 +162,15 @@
// Wakeup request is set by HW and cleared by SW
// The wakeup cause is always captured and only sent out when the system has entered sleep mode
- assign aon_hw2reg.wkup_cause.de = aon_wkup_intr_set | aon_wdog_intr_set;
- assign aon_hw2reg.wkup_cause.d = 1'b1;
+ assign hw2reg.wkup_cause.de = aon_wkup_intr_set | aon_wdog_intr_set;
+ assign hw2reg.wkup_cause.d = 1'b1;
// wakeup output is flopped in case of clock domain crossing
always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin
if (!rst_aon_ni) begin
aon_timer_wkup_req_o <= '0;
end else begin
- aon_timer_wkup_req_o <= aon_reg2hw.wkup_cause.q & sleep_mode;
+ aon_timer_wkup_req_o <= reg2hw.wkup_cause.q & aon_sleep_mode;
end
end
@@ -197,54 +178,79 @@
// Interrupt Handling //
////////////////////////
+ // capture these signals as the origin sets are pulsed and it may
+ // happen when the bus clocks are not available.
+ logic [1:0] aon_intr_event_q;
+ always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin
+ if (!rst_aon_ni) begin
+ aon_intr_event_q <= '0;
+ end else begin
+ if (aon_wdog_intr_set) begin
+ aon_intr_event_q[AON_WDOG] <= ~aon_intr_event_q[AON_WDOG];
+ end
+ if (aon_wkup_intr_set) begin
+ aon_intr_event_q[AON_WKUP] <= ~aon_intr_event_q[AON_WKUP];
+ end
+ end
+ end
+
+ logic [1:0] aon_intr_set;
+ assign aon_intr_set[AON_WDOG] = aon_wdog_intr_set;
+ assign aon_intr_set[AON_WKUP] = aon_wkup_intr_set;
+
+ logic [1:0] intr_event_q, intr_event_q1;
+
+ for (genvar i = 0; i < 2; i++) begin : gen_intr_sync
+ prim_pulse_sync u_intr_sync (
+ .clk_src_i(clk_aon_i),
+ .rst_src_ni(rst_aon_ni),
+ .src_pulse_i(aon_intr_set[i]),
+ .clk_dst_i(clk_i),
+ .rst_dst_ni(rst_ni),
+ .dst_pulse_o(intr_event_q[i])
+ );
+ end
+
+ always_ff @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ intr_event_q1 <= '0;
+ end else begin
+ intr_event_q1 <= intr_event_q;
+ end
+ end
+
// Registers to interrupt
- assign intr_aon_test_qe = aon_reg2hw.intr_test.wkup_timer_expired.qe |
- aon_reg2hw.intr_test.wdog_timer_expired.qe;
- assign intr_aon_test_q [AON_WKUP] = aon_reg2hw.intr_test.wkup_timer_expired.q;
- assign intr_aon_state_q[AON_WKUP] = aon_reg2hw.intr_state.wkup_timer_expired.q;
- assign intr_aon_test_q [AON_WDOG] = aon_reg2hw.intr_test.wdog_timer_expired.q;
- assign intr_aon_state_q[AON_WDOG] = aon_reg2hw.intr_state.wdog_timer_expired.q;
+ assign intr_test_qe = reg2hw.intr_test.wkup_timer_expired.qe |
+ reg2hw.intr_test.wdog_timer_expired.qe;
+ assign intr_test_q [AON_WKUP] = reg2hw.intr_test.wkup_timer_expired.q;
+ assign intr_state_q[AON_WKUP] = reg2hw.intr_state.wkup_timer_expired.q;
+ assign intr_test_q [AON_WDOG] = reg2hw.intr_test.wdog_timer_expired.q;
+ assign intr_state_q[AON_WDOG] = reg2hw.intr_state.wdog_timer_expired.q;
// Interrupts to registers
- assign aon_hw2reg.intr_state.wkup_timer_expired.d = intr_aon_state_d[AON_WKUP];
- assign aon_hw2reg.intr_state.wkup_timer_expired.de = intr_aon_state_de;
- assign aon_hw2reg.intr_state.wdog_timer_expired.d = intr_aon_state_d[AON_WDOG];
- assign aon_hw2reg.intr_state.wdog_timer_expired.de = intr_aon_state_de;
+ assign hw2reg.intr_state.wkup_timer_expired.d = intr_state_d[AON_WKUP];
+ assign hw2reg.intr_state.wkup_timer_expired.de = intr_state_de;
+ assign hw2reg.intr_state.wdog_timer_expired.d = intr_state_d[AON_WDOG];
+ assign hw2reg.intr_state.wdog_timer_expired.de = intr_state_de;
prim_intr_hw #(
.Width (2)
) u_intr_hw (
- .clk_i (clk_aon_i),
- .rst_ni (rst_aon_ni),
- .event_intr_i ({aon_wdog_intr_set, aon_wkup_intr_set}),
-
+ .clk_i,
+ .rst_ni,
+ .event_intr_i (intr_event_q ^ intr_event_q1),
.reg2hw_intr_enable_q_i (2'b11),
- .reg2hw_intr_test_q_i (intr_aon_test_q),
- .reg2hw_intr_test_qe_i (intr_aon_test_qe),
- .reg2hw_intr_state_q_i (intr_aon_state_q),
- .hw2reg_intr_state_de_o (intr_aon_state_de),
- .hw2reg_intr_state_d_o (intr_aon_state_d),
+ .reg2hw_intr_test_q_i (intr_test_q),
+ .reg2hw_intr_test_qe_i (intr_test_qe),
+ .reg2hw_intr_state_q_i (intr_state_q),
+ .hw2reg_intr_state_de_o (intr_state_de),
+ .hw2reg_intr_state_d_o (intr_state_d),
.intr_o (intr_out)
);
- prim_flop_2sync #(
- .Width(1)
- ) u_sync_wkup_intr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .d_i (intr_out[AON_WKUP]),
- .q_o (intr_wkup_timer_expired_o)
- );
-
- prim_flop_2sync #(
- .Width(1)
- ) u_sync_wdog_intr (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
- .d_i (intr_out[AON_WDOG]),
- .q_o (intr_wdog_timer_bark_o)
- );
+ assign intr_wkup_timer_expired_o = intr_out[AON_WKUP];
+ assign intr_wdog_timer_bark_o = intr_out[AON_WDOG];
// The interrupt line can be routed as nmi as well.
assign nmi_wdog_timer_bark_o = intr_wdog_timer_bark_o;
diff --git a/hw/ip/aon_timer/rtl/aon_timer_core.sv b/hw/ip/aon_timer/rtl/aon_timer_core.sv
index 044ceba..9fe0f7d 100644
--- a/hw/ip/aon_timer/rtl/aon_timer_core.sv
+++ b/hw/ip/aon_timer/rtl/aon_timer_core.sv
@@ -72,6 +72,8 @@
// Timer reset
assign wdog_reset_req_o = wdog_incr & (reg2hw_i.wdog_count.q == reg2hw_i.wdog_bite_thold.q);
- assign unused_reg2hw = |{reg2hw_i.intr_state, reg2hw_i.intr_test, reg2hw_i.wkup_cause};
+ assign unused_reg2hw = |{reg2hw_i.intr_state, reg2hw_i.intr_test, reg2hw_i.wkup_cause,
+ reg2hw_i.alert_test};
+
endmodule
diff --git a/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv b/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv
index 69087c6..e891aea 100644
--- a/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv
+++ b/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv
@@ -9,6 +9,8 @@
module aon_timer_reg_top (
input clk_i,
input rst_ni,
+ input clk_aon_i,
+ input rst_aon_ni,
input tlul_pkg::tl_h2d_t tl_i,
output tlul_pkg::tl_d2h_t tl_o,
@@ -41,14 +43,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +76,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +87,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +98,22 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+ logic sync_aon_update;
+ prim_pulse_sync u_aon_tgl (
+ .clk_src_i(clk_aon_i),
+ .rst_src_ni(rst_aon_ni),
+ .src_pulse_i(1'b1),
+ .clk_dst_i(clk_i),
+ .rst_dst_ni(rst_ni),
+ .dst_pulse_o(sync_aon_update)
+ );
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -109,31 +125,40 @@
logic wkup_ctrl_we;
logic wkup_ctrl_enable_qs;
logic wkup_ctrl_enable_wd;
+ logic wkup_ctrl_enable_busy;
logic [11:0] wkup_ctrl_prescaler_qs;
logic [11:0] wkup_ctrl_prescaler_wd;
+ logic wkup_ctrl_prescaler_busy;
logic wkup_thold_we;
logic [31:0] wkup_thold_qs;
logic [31:0] wkup_thold_wd;
+ logic wkup_thold_busy;
logic wkup_count_we;
logic [31:0] wkup_count_qs;
logic [31:0] wkup_count_wd;
+ logic wkup_count_busy;
logic wdog_regwen_we;
logic wdog_regwen_qs;
logic wdog_regwen_wd;
logic wdog_ctrl_we;
logic wdog_ctrl_enable_qs;
logic wdog_ctrl_enable_wd;
+ logic wdog_ctrl_enable_busy;
logic wdog_ctrl_pause_in_sleep_qs;
logic wdog_ctrl_pause_in_sleep_wd;
+ logic wdog_ctrl_pause_in_sleep_busy;
logic wdog_bark_thold_we;
logic [31:0] wdog_bark_thold_qs;
logic [31:0] wdog_bark_thold_wd;
+ logic wdog_bark_thold_busy;
logic wdog_bite_thold_we;
logic [31:0] wdog_bite_thold_qs;
logic [31:0] wdog_bite_thold_wd;
+ logic wdog_bite_thold_busy;
logic wdog_count_we;
logic [31:0] wdog_count_qs;
logic [31:0] wdog_count_wd;
+ logic wdog_count_busy;
logic intr_state_we;
logic intr_state_wkup_timer_expired_qs;
logic intr_state_wkup_timer_expired_wd;
@@ -145,6 +170,7 @@
logic wkup_cause_we;
logic wkup_cause_qs;
logic wkup_cause_wd;
+ logic wkup_cause_busy;
// Register instances
// R[alert_test]: V(True)
@@ -166,108 +192,92 @@
// R[wkup_ctrl]: V(False)
// F[enable]: 0:0
- prim_subreg #(
+ prim_subreg_async #(
.DW (1),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (1'h0)
) u_wkup_ctrl_enable (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wkup_ctrl_we),
- .wd (wkup_ctrl_enable_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wkup_ctrl.enable.q),
-
- // to register interface (read)
- .qs (wkup_ctrl_enable_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wkup_ctrl_we),
+ .src_wd_i (wkup_ctrl_enable_wd),
+ .dst_de_i (1'b0),
+ .dst_d_i ('0),
+ .src_busy_o (wkup_ctrl_enable_busy),
+ .src_qs_o (wkup_ctrl_enable_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wkup_ctrl.enable.q)
);
// F[prescaler]: 12:1
- prim_subreg #(
+ prim_subreg_async #(
.DW (12),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (12'h0)
) u_wkup_ctrl_prescaler (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wkup_ctrl_we),
- .wd (wkup_ctrl_prescaler_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wkup_ctrl.prescaler.q),
-
- // to register interface (read)
- .qs (wkup_ctrl_prescaler_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wkup_ctrl_we),
+ .src_wd_i (wkup_ctrl_prescaler_wd),
+ .dst_de_i (1'b0),
+ .dst_d_i ('0),
+ .src_busy_o (wkup_ctrl_prescaler_busy),
+ .src_qs_o (wkup_ctrl_prescaler_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wkup_ctrl.prescaler.q)
);
// R[wkup_thold]: V(False)
- prim_subreg #(
+ prim_subreg_async #(
.DW (32),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (32'h0)
) u_wkup_thold (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wkup_thold_we),
- .wd (wkup_thold_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wkup_thold.q),
-
- // to register interface (read)
- .qs (wkup_thold_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wkup_thold_we),
+ .src_wd_i (wkup_thold_wd),
+ .dst_de_i (1'b0),
+ .dst_d_i ('0),
+ .src_busy_o (wkup_thold_busy),
+ .src_qs_o (wkup_thold_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wkup_thold.q)
);
// R[wkup_count]: V(False)
- prim_subreg #(
+ prim_subreg_async #(
.DW (32),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (32'h0)
) u_wkup_count (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wkup_count_we),
- .wd (wkup_count_wd),
-
- // from internal hardware
- .de (hw2reg.wkup_count.de),
- .d (hw2reg.wkup_count.d),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wkup_count.q),
-
- // to register interface (read)
- .qs (wkup_count_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wkup_count_we),
+ .src_wd_i (wkup_count_wd),
+ .dst_de_i (hw2reg.wkup_count.de),
+ .dst_d_i (hw2reg.wkup_count.d),
+ .src_busy_o (wkup_count_busy),
+ .src_qs_o (wkup_count_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wkup_count.q)
);
@@ -301,135 +311,115 @@
// R[wdog_ctrl]: V(False)
// F[enable]: 0:0
- prim_subreg #(
+ prim_subreg_async #(
.DW (1),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (1'h0)
) u_wdog_ctrl_enable (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wdog_ctrl_we & wdog_regwen_qs),
- .wd (wdog_ctrl_enable_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wdog_ctrl.enable.q),
-
- // to register interface (read)
- .qs (wdog_ctrl_enable_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wdog_ctrl_we & wdog_regwen_qs),
+ .src_wd_i (wdog_ctrl_enable_wd),
+ .dst_de_i (1'b0),
+ .dst_d_i ('0),
+ .src_busy_o (wdog_ctrl_enable_busy),
+ .src_qs_o (wdog_ctrl_enable_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wdog_ctrl.enable.q)
);
// F[pause_in_sleep]: 1:1
- prim_subreg #(
+ prim_subreg_async #(
.DW (1),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (1'h0)
) u_wdog_ctrl_pause_in_sleep (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wdog_ctrl_we & wdog_regwen_qs),
- .wd (wdog_ctrl_pause_in_sleep_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wdog_ctrl.pause_in_sleep.q),
-
- // to register interface (read)
- .qs (wdog_ctrl_pause_in_sleep_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wdog_ctrl_we & wdog_regwen_qs),
+ .src_wd_i (wdog_ctrl_pause_in_sleep_wd),
+ .dst_de_i (1'b0),
+ .dst_d_i ('0),
+ .src_busy_o (wdog_ctrl_pause_in_sleep_busy),
+ .src_qs_o (wdog_ctrl_pause_in_sleep_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wdog_ctrl.pause_in_sleep.q)
);
// R[wdog_bark_thold]: V(False)
- prim_subreg #(
+ prim_subreg_async #(
.DW (32),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (32'h0)
) u_wdog_bark_thold (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wdog_bark_thold_we & wdog_regwen_qs),
- .wd (wdog_bark_thold_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wdog_bark_thold.q),
-
- // to register interface (read)
- .qs (wdog_bark_thold_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wdog_bark_thold_we & wdog_regwen_qs),
+ .src_wd_i (wdog_bark_thold_wd),
+ .dst_de_i (1'b0),
+ .dst_d_i ('0),
+ .src_busy_o (wdog_bark_thold_busy),
+ .src_qs_o (wdog_bark_thold_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wdog_bark_thold.q)
);
// R[wdog_bite_thold]: V(False)
- prim_subreg #(
+ prim_subreg_async #(
.DW (32),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (32'h0)
) u_wdog_bite_thold (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wdog_bite_thold_we & wdog_regwen_qs),
- .wd (wdog_bite_thold_wd),
-
- // from internal hardware
- .de (1'b0),
- .d ('0),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wdog_bite_thold.q),
-
- // to register interface (read)
- .qs (wdog_bite_thold_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wdog_bite_thold_we & wdog_regwen_qs),
+ .src_wd_i (wdog_bite_thold_wd),
+ .dst_de_i (1'b0),
+ .dst_d_i ('0),
+ .src_busy_o (wdog_bite_thold_busy),
+ .src_qs_o (wdog_bite_thold_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wdog_bite_thold.q)
);
// R[wdog_count]: V(False)
- prim_subreg #(
+ prim_subreg_async #(
.DW (32),
.SwAccess(prim_subreg_pkg::SwAccessRW),
.RESVAL (32'h0)
) u_wdog_count (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wdog_count_we),
- .wd (wdog_count_wd),
-
- // from internal hardware
- .de (hw2reg.wdog_count.de),
- .d (hw2reg.wdog_count.d),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wdog_count.q),
-
- // to register interface (read)
- .qs (wdog_count_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wdog_count_we),
+ .src_wd_i (wdog_count_wd),
+ .dst_de_i (hw2reg.wdog_count.de),
+ .dst_d_i (hw2reg.wdog_count.d),
+ .src_busy_o (wdog_count_busy),
+ .src_qs_o (wdog_count_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wdog_count.q)
);
@@ -521,28 +511,24 @@
// R[wkup_cause]: V(False)
- prim_subreg #(
+ prim_subreg_async #(
.DW (1),
.SwAccess(prim_subreg_pkg::SwAccessW0C),
.RESVAL (1'h0)
) u_wkup_cause (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
-
- // from register interface
- .we (wkup_cause_we),
- .wd (wkup_cause_wd),
-
- // from internal hardware
- .de (hw2reg.wkup_cause.de),
- .d (hw2reg.wkup_cause.d),
-
- // to internal hardware
- .qe (),
- .q (reg2hw.wkup_cause.q),
-
- // to register interface (read)
- .qs (wkup_cause_qs)
+ .clk_src_i (clk_i),
+ .rst_src_ni (rst_ni),
+ .clk_dst_i (clk_aon_i),
+ .rst_dst_ni (rst_aon_ni),
+ .src_update_i (sync_aon_update),
+ .src_we_i (wkup_cause_we),
+ .src_wd_i (wkup_cause_wd),
+ .dst_de_i (hw2reg.wkup_cause.de),
+ .dst_d_i (hw2reg.wkup_cause.d),
+ .src_busy_o (wkup_cause_busy),
+ .src_qs_o (wkup_cause_qs),
+ .dst_qe_o (),
+ .q (reg2hw.wkup_cause.q)
);
@@ -690,6 +676,45 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ addr_hit[1]: begin
+ reg_busy =
+ wkup_ctrl_enable_busy |
+ wkup_ctrl_prescaler_busy;
+ end
+ addr_hit[2]: begin
+ reg_busy = wkup_thold_busy;
+ end
+ addr_hit[3]: begin
+ reg_busy = wkup_count_busy;
+ end
+ addr_hit[5]: begin
+ reg_busy =
+ wdog_ctrl_enable_busy |
+ wdog_ctrl_pause_in_sleep_busy;
+ end
+ addr_hit[6]: begin
+ reg_busy = wdog_bark_thold_busy;
+ end
+ addr_hit[7]: begin
+ reg_busy = wdog_bite_thold_busy;
+ end
+ addr_hit[8]: begin
+ reg_busy = wdog_count_busy;
+ end
+ addr_hit[11]: begin
+ reg_busy = wkup_cause_busy;
+ end
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -700,12 +725,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv b/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv
index be5ac3a..86c690d 100644
--- a/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv
+++ b/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -335,6 +340,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -345,12 +361,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv
index 87d27f9..1d96823 100644
--- a/hw/ip/csrng/rtl/csrng_reg_top.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1793,6 +1798,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1803,12 +1819,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/edn/rtl/edn_reg_top.sv b/hw/ip/edn/rtl/edn_reg_top.sv
index 5701d78..d298c25 100644
--- a/hw/ip/edn/rtl/edn_reg_top.sv
+++ b/hw/ip/edn/rtl/edn_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1014,6 +1019,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1024,12 +1040,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv b/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv
index 3493ae8..c703b8a 100644
--- a/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv
+++ b/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -3091,6 +3096,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -3101,12 +3117,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_core_reg_top.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_core_reg_top.sv
index e768b89..73ff107 100644
--- a/hw/ip/flash_ctrl/rtl/flash_ctrl_core_reg_top.sv
+++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_core_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [3];
@@ -106,8 +108,8 @@
.DReqDepth ({3{4'h0}}),
.DRspDepth ({3{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -136,8 +138,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -147,10 +149,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -12322,6 +12327,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -12332,12 +12348,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv
index 53c5691..65335a1 100644
--- a/hw/ip/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv
+++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv
@@ -24,10 +24,11 @@
import flash_ctrl_reg_pkg::* ;
+
// incoming payload check
logic intg_err;
tlul_cmd_intg_chk u_chk (
- .tl_i,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -51,7 +52,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [0];
@@ -73,8 +74,8 @@
.DReqDepth ({0{4'h0}}),
.DRspDepth ({0{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
diff --git a/hw/ip/gpio/rtl/gpio_reg_top.sv b/hw/ip/gpio/rtl/gpio_reg_top.sv
index 7b1aa9c..7fa64ea 100644
--- a/hw/ip/gpio/rtl/gpio_reg_top.sv
+++ b/hw/ip/gpio/rtl/gpio_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -753,6 +758,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -763,12 +779,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/hmac/rtl/hmac_reg_top.sv b/hw/ip/hmac/rtl/hmac_reg_top.sv
index e0540f1..73c7863 100644
--- a/hw/ip/hmac/rtl/hmac_reg_top.sv
+++ b/hw/ip/hmac/rtl/hmac_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [2];
@@ -104,8 +106,8 @@
.DReqDepth ({2{4'h0}}),
.DRspDepth ({2{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -131,8 +133,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -142,10 +144,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1222,6 +1227,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1232,12 +1248,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/i2c/rtl/i2c_reg_top.sv b/hw/ip/i2c/rtl/i2c_reg_top.sv
index 1fd9250..857d66d 100644
--- a/hw/ip/i2c/rtl/i2c_reg_top.sv
+++ b/hw/ip/i2c/rtl/i2c_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -3200,6 +3205,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -3210,12 +3226,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/keymgr/rtl/keymgr_reg_top.sv b/hw/ip/keymgr/rtl/keymgr_reg_top.sv
index b6e2e62..59ea9be 100644
--- a/hw/ip/keymgr/rtl/keymgr_reg_top.sv
+++ b/hw/ip/keymgr/rtl/keymgr_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -2599,6 +2604,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -2609,12 +2625,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/kmac/rtl/kmac_reg_top.sv b/hw/ip/kmac/rtl/kmac_reg_top.sv
index 37aeea9..a94576d 100644
--- a/hw/ip/kmac/rtl/kmac_reg_top.sv
+++ b/hw/ip/kmac/rtl/kmac_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [3];
@@ -106,8 +108,8 @@
.DReqDepth ({3{4'h0}}),
.DRspDepth ({3{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -136,8 +138,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -147,10 +149,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -2589,6 +2594,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -2599,12 +2615,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv
index 32eba82..fb91e96 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1139,6 +1144,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1149,12 +1165,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/otbn/rtl/otbn_reg_top.sv b/hw/ip/otbn/rtl/otbn_reg_top.sv
index 7f00872..9da0db1 100644
--- a/hw/ip/otbn/rtl/otbn_reg_top.sv
+++ b/hw/ip/otbn/rtl/otbn_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(0)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [3];
@@ -106,8 +108,8 @@
.DReqDepth ({3{4'h0}}),
.DRspDepth ({3{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -136,8 +138,8 @@
.RegDw(DW),
.EnableDataIntgGen(1)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -147,10 +149,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -869,6 +874,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -879,12 +895,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv
index 2134b4e..c1ac0e7 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_core_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [2];
@@ -104,8 +106,8 @@
.DReqDepth ({2{4'h0}}),
.DRspDepth ({2{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -131,8 +133,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -142,10 +144,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1773,6 +1778,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1783,12 +1799,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv
index b9a3870..4052500 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_prim_reg_top.sv
@@ -24,10 +24,11 @@
import otp_ctrl_reg_pkg::* ;
+
// incoming payload check
logic intg_err;
tlul_cmd_intg_chk u_chk (
- .tl_i,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -51,7 +52,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [0];
@@ -73,8 +74,8 @@
.DReqDepth ({0{4'h0}}),
.DRspDepth ({0{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_top.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_top.sv
new file mode 100644
index 0000000..d75b4af
--- /dev/null
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_top.sv
@@ -0,0 +1,1818 @@
+// 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 otp_ctrl_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 [2],
+ input tlul_pkg::tl_d2h_t tl_win_i [2],
+
+ // To HW
+ output otp_ctrl_reg_pkg::otp_ctrl_reg2hw_t reg2hw, // Write
+ input otp_ctrl_reg_pkg::otp_ctrl_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 otp_ctrl_reg_pkg::* ;
+
+ localparam int AW = 14;
+ 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;
+ logic reg_busy;
+
+ 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(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 #(
+ .EnableRspIntgGen(1),
+ .EnableDataIntgGen(1)
+ ) u_rsp_intg_gen (
+ .tl_i(tl_o_pre),
+ .tl_o(tl_o)
+ );
+
+ tlul_pkg::tl_h2d_t tl_socket_h2d [3];
+ tlul_pkg::tl_d2h_t tl_socket_d2h [3];
+
+ logic [1:0] reg_steer;
+
+ // socket_1n connection
+ assign tl_reg_h2d = tl_socket_h2d[2];
+ assign tl_socket_d2h[2] = tl_reg_d2h;
+
+ assign tl_win_o[0] = tl_socket_h2d[0];
+ assign tl_socket_d2h[0] = tl_win_i[0];
+ assign tl_win_o[1] = tl_socket_h2d[1];
+ assign tl_socket_d2h[1] = tl_win_i[1];
+
+ // Create Socket_1n
+ tlul_socket_1n #(
+ .N (3),
+ .HReqPass (1'b1),
+ .HRspPass (1'b1),
+ .DReqPass ({3{1'b1}}),
+ .DRspPass ({3{1'b1}}),
+ .HReqDepth (4'h0),
+ .HRspDepth (4'h0),
+ .DReqDepth ({3{4'h0}}),
+ .DRspDepth ({3{4'h0}})
+ ) u_socket (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+ .tl_h_i (tl_i),
+ .tl_h_o (tl_o_pre),
+ .tl_d_o (tl_socket_h2d),
+ .tl_d_i (tl_socket_d2h),
+ .dev_select_i (reg_steer)
+ );
+
+ // Create steering logic
+ always_comb begin
+ reg_steer = 2; // Default set to register
+
+ // TODO: Can below codes be unique case () inside ?
+ if (tl_i.a_address[AW-1:0] >= 4096 && tl_i.a_address[AW-1:0] < 6144) begin
+ reg_steer = 0;
+ end
+ if (tl_i.a_address[AW-1:0] >= 8192 && tl_i.a_address[AW-1:0] < 8256) begin
+ reg_steer = 1;
+ end
+ if (intg_err) begin
+ reg_steer = 2;
+ end
+ end
+
+ tlul_adapter_reg #(
+ .RegAw(AW),
+ .RegDw(DW),
+ .EnableDataIntgGen(0)
+ ) u_reg_if (
+ .clk_i (clk_i),
+ .rst_ni (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),
+ .busy_i (reg_busy),
+ .rdata_i (reg_rdata),
+ .error_i (reg_error)
+ );
+
+ // cdc oversampling signals
+
+ 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 intr_state_we;
+ logic intr_state_otp_operation_done_qs;
+ logic intr_state_otp_operation_done_wd;
+ logic intr_state_otp_error_qs;
+ logic intr_state_otp_error_wd;
+ logic intr_enable_we;
+ logic intr_enable_otp_operation_done_qs;
+ logic intr_enable_otp_operation_done_wd;
+ logic intr_enable_otp_error_qs;
+ logic intr_enable_otp_error_wd;
+ logic intr_test_we;
+ logic intr_test_otp_operation_done_wd;
+ logic intr_test_otp_error_wd;
+ logic alert_test_we;
+ logic alert_test_fatal_macro_error_wd;
+ logic alert_test_fatal_check_error_wd;
+ logic alert_test_fatal_bus_integ_error_wd;
+ logic status_re;
+ logic status_creator_sw_cfg_error_qs;
+ logic status_owner_sw_cfg_error_qs;
+ logic status_hw_cfg_error_qs;
+ logic status_secret0_error_qs;
+ logic status_secret1_error_qs;
+ logic status_secret2_error_qs;
+ logic status_life_cycle_error_qs;
+ logic status_dai_error_qs;
+ logic status_lci_error_qs;
+ logic status_timeout_error_qs;
+ logic status_lfsr_fsm_error_qs;
+ logic status_scrambling_fsm_error_qs;
+ logic status_key_deriv_fsm_error_qs;
+ logic status_bus_integ_error_qs;
+ logic status_dai_idle_qs;
+ logic status_check_pending_qs;
+ logic err_code_re;
+ logic [2:0] err_code_err_code_0_qs;
+ logic [2:0] err_code_err_code_1_qs;
+ logic [2:0] err_code_err_code_2_qs;
+ logic [2:0] err_code_err_code_3_qs;
+ logic [2:0] err_code_err_code_4_qs;
+ logic [2:0] err_code_err_code_5_qs;
+ logic [2:0] err_code_err_code_6_qs;
+ logic [2:0] err_code_err_code_7_qs;
+ logic [2:0] err_code_err_code_8_qs;
+ logic direct_access_regwen_re;
+ logic direct_access_regwen_qs;
+ logic direct_access_cmd_we;
+ logic direct_access_cmd_rd_wd;
+ logic direct_access_cmd_wr_wd;
+ logic direct_access_cmd_digest_wd;
+ logic direct_access_address_we;
+ logic [10:0] direct_access_address_qs;
+ logic [10:0] direct_access_address_wd;
+ logic direct_access_wdata_0_we;
+ logic [31:0] direct_access_wdata_0_qs;
+ logic [31:0] direct_access_wdata_0_wd;
+ logic direct_access_wdata_1_we;
+ logic [31:0] direct_access_wdata_1_qs;
+ logic [31:0] direct_access_wdata_1_wd;
+ logic direct_access_rdata_0_re;
+ logic [31:0] direct_access_rdata_0_qs;
+ logic direct_access_rdata_1_re;
+ logic [31:0] direct_access_rdata_1_qs;
+ logic check_trigger_regwen_we;
+ logic check_trigger_regwen_qs;
+ logic check_trigger_regwen_wd;
+ logic check_trigger_we;
+ logic check_trigger_integrity_wd;
+ logic check_trigger_consistency_wd;
+ logic check_regwen_we;
+ logic check_regwen_qs;
+ logic check_regwen_wd;
+ logic check_timeout_we;
+ logic [31:0] check_timeout_qs;
+ logic [31:0] check_timeout_wd;
+ logic integrity_check_period_we;
+ logic [31:0] integrity_check_period_qs;
+ logic [31:0] integrity_check_period_wd;
+ logic consistency_check_period_we;
+ logic [31:0] consistency_check_period_qs;
+ logic [31:0] consistency_check_period_wd;
+ logic creator_sw_cfg_read_lock_we;
+ logic creator_sw_cfg_read_lock_qs;
+ logic creator_sw_cfg_read_lock_wd;
+ logic owner_sw_cfg_read_lock_we;
+ logic owner_sw_cfg_read_lock_qs;
+ logic owner_sw_cfg_read_lock_wd;
+ logic creator_sw_cfg_digest_0_re;
+ logic [31:0] creator_sw_cfg_digest_0_qs;
+ logic creator_sw_cfg_digest_1_re;
+ logic [31:0] creator_sw_cfg_digest_1_qs;
+ logic owner_sw_cfg_digest_0_re;
+ logic [31:0] owner_sw_cfg_digest_0_qs;
+ logic owner_sw_cfg_digest_1_re;
+ logic [31:0] owner_sw_cfg_digest_1_qs;
+ logic hw_cfg_digest_0_re;
+ logic [31:0] hw_cfg_digest_0_qs;
+ logic hw_cfg_digest_1_re;
+ logic [31:0] hw_cfg_digest_1_qs;
+ logic secret0_digest_0_re;
+ logic [31:0] secret0_digest_0_qs;
+ logic secret0_digest_1_re;
+ logic [31:0] secret0_digest_1_qs;
+ logic secret1_digest_0_re;
+ logic [31:0] secret1_digest_0_qs;
+ logic secret1_digest_1_re;
+ logic [31:0] secret1_digest_1_qs;
+ logic secret2_digest_0_re;
+ logic [31:0] secret2_digest_0_qs;
+ logic secret2_digest_1_re;
+ logic [31:0] secret2_digest_1_qs;
+
+ // Register instances
+ // R[intr_state]: V(False)
+
+ // F[otp_operation_done]: 0:0
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("W1C"),
+ .RESVAL (1'h0)
+ ) u_intr_state_otp_operation_done (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (intr_state_we),
+ .wd (intr_state_otp_operation_done_wd),
+
+ // from internal hardware
+ .de (hw2reg.intr_state.otp_operation_done.de),
+ .d (hw2reg.intr_state.otp_operation_done.d),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.intr_state.otp_operation_done.q),
+
+ // to register interface (read)
+ .qs (intr_state_otp_operation_done_qs)
+ );
+
+
+ // F[otp_error]: 1:1
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("W1C"),
+ .RESVAL (1'h0)
+ ) u_intr_state_otp_error (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (intr_state_we),
+ .wd (intr_state_otp_error_wd),
+
+ // from internal hardware
+ .de (hw2reg.intr_state.otp_error.de),
+ .d (hw2reg.intr_state.otp_error.d),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.intr_state.otp_error.q),
+
+ // to register interface (read)
+ .qs (intr_state_otp_error_qs)
+ );
+
+
+ // R[intr_enable]: V(False)
+
+ // F[otp_operation_done]: 0:0
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("RW"),
+ .RESVAL (1'h0)
+ ) u_intr_enable_otp_operation_done (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (intr_enable_we),
+ .wd (intr_enable_otp_operation_done_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.intr_enable.otp_operation_done.q),
+
+ // to register interface (read)
+ .qs (intr_enable_otp_operation_done_qs)
+ );
+
+
+ // F[otp_error]: 1:1
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("RW"),
+ .RESVAL (1'h0)
+ ) u_intr_enable_otp_error (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (intr_enable_we),
+ .wd (intr_enable_otp_error_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.intr_enable.otp_error.q),
+
+ // to register interface (read)
+ .qs (intr_enable_otp_error_qs)
+ );
+
+
+ // R[intr_test]: V(True)
+
+ // F[otp_operation_done]: 0:0
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_intr_test_otp_operation_done (
+ .re (1'b0),
+ .we (intr_test_we),
+ .wd (intr_test_otp_operation_done_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.intr_test.otp_operation_done.qe),
+ .q (reg2hw.intr_test.otp_operation_done.q),
+ .qs ()
+ );
+
+
+ // F[otp_error]: 1:1
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_intr_test_otp_error (
+ .re (1'b0),
+ .we (intr_test_we),
+ .wd (intr_test_otp_error_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.intr_test.otp_error.qe),
+ .q (reg2hw.intr_test.otp_error.q),
+ .qs ()
+ );
+
+
+ // R[alert_test]: V(True)
+
+ // F[fatal_macro_error]: 0:0
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_alert_test_fatal_macro_error (
+ .re (1'b0),
+ .we (alert_test_we),
+ .wd (alert_test_fatal_macro_error_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.alert_test.fatal_macro_error.qe),
+ .q (reg2hw.alert_test.fatal_macro_error.q),
+ .qs ()
+ );
+
+
+ // F[fatal_check_error]: 1:1
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_alert_test_fatal_check_error (
+ .re (1'b0),
+ .we (alert_test_we),
+ .wd (alert_test_fatal_check_error_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.alert_test.fatal_check_error.qe),
+ .q (reg2hw.alert_test.fatal_check_error.q),
+ .qs ()
+ );
+
+
+ // F[fatal_bus_integ_error]: 2:2
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_alert_test_fatal_bus_integ_error (
+ .re (1'b0),
+ .we (alert_test_we),
+ .wd (alert_test_fatal_bus_integ_error_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.alert_test.fatal_bus_integ_error.qe),
+ .q (reg2hw.alert_test.fatal_bus_integ_error.q),
+ .qs ()
+ );
+
+
+ // R[status]: V(True)
+
+ // F[creator_sw_cfg_error]: 0:0
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_creator_sw_cfg_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.creator_sw_cfg_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_creator_sw_cfg_error_qs)
+ );
+
+
+ // F[owner_sw_cfg_error]: 1:1
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_owner_sw_cfg_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.owner_sw_cfg_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_owner_sw_cfg_error_qs)
+ );
+
+
+ // F[hw_cfg_error]: 2:2
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_hw_cfg_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.hw_cfg_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_hw_cfg_error_qs)
+ );
+
+
+ // F[secret0_error]: 3:3
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_secret0_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.secret0_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_secret0_error_qs)
+ );
+
+
+ // F[secret1_error]: 4:4
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_secret1_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.secret1_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_secret1_error_qs)
+ );
+
+
+ // F[secret2_error]: 5:5
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_secret2_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.secret2_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_secret2_error_qs)
+ );
+
+
+ // F[life_cycle_error]: 6:6
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_life_cycle_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.life_cycle_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_life_cycle_error_qs)
+ );
+
+
+ // F[dai_error]: 7:7
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_dai_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.dai_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_dai_error_qs)
+ );
+
+
+ // F[lci_error]: 8:8
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_lci_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.lci_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_lci_error_qs)
+ );
+
+
+ // F[timeout_error]: 9:9
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_timeout_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.timeout_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_timeout_error_qs)
+ );
+
+
+ // F[lfsr_fsm_error]: 10:10
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_lfsr_fsm_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.lfsr_fsm_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_lfsr_fsm_error_qs)
+ );
+
+
+ // F[scrambling_fsm_error]: 11:11
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_scrambling_fsm_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.scrambling_fsm_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_scrambling_fsm_error_qs)
+ );
+
+
+ // F[key_deriv_fsm_error]: 12:12
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_key_deriv_fsm_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.key_deriv_fsm_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_key_deriv_fsm_error_qs)
+ );
+
+
+ // F[bus_integ_error]: 13:13
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_bus_integ_error (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.bus_integ_error.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_bus_integ_error_qs)
+ );
+
+
+ // F[dai_idle]: 14:14
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_dai_idle (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.dai_idle.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_dai_idle_qs)
+ );
+
+
+ // F[check_pending]: 15:15
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_status_check_pending (
+ .re (status_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.status.check_pending.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (status_check_pending_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg err_code
+ // R[err_code]: V(True)
+
+ // F[err_code_0]: 2:0
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_0 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_0_qs)
+ );
+
+
+ // F[err_code_1]: 5:3
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_1 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_1_qs)
+ );
+
+
+ // F[err_code_2]: 8:6
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_2 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[2].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_2_qs)
+ );
+
+
+ // F[err_code_3]: 11:9
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_3 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[3].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_3_qs)
+ );
+
+
+ // F[err_code_4]: 14:12
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_4 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[4].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_4_qs)
+ );
+
+
+ // F[err_code_5]: 17:15
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_5 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[5].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_5_qs)
+ );
+
+
+ // F[err_code_6]: 20:18
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_6 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[6].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_6_qs)
+ );
+
+
+ // F[err_code_7]: 23:21
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_7 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[7].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_7_qs)
+ );
+
+
+ // F[err_code_8]: 26:24
+ prim_subreg_ext #(
+ .DW (3)
+ ) u_err_code_err_code_8 (
+ .re (err_code_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.err_code[8].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (err_code_err_code_8_qs)
+ );
+
+
+
+ // R[direct_access_regwen]: V(True)
+
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_direct_access_regwen (
+ .re (direct_access_regwen_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.direct_access_regwen.d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (direct_access_regwen_qs)
+ );
+
+
+ // R[direct_access_cmd]: V(True)
+
+ // F[rd]: 0:0
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_direct_access_cmd_rd (
+ .re (1'b0),
+ .we (direct_access_cmd_we & direct_access_regwen_qs),
+ .wd (direct_access_cmd_rd_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.direct_access_cmd.rd.qe),
+ .q (reg2hw.direct_access_cmd.rd.q),
+ .qs ()
+ );
+
+
+ // F[wr]: 1:1
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_direct_access_cmd_wr (
+ .re (1'b0),
+ .we (direct_access_cmd_we & direct_access_regwen_qs),
+ .wd (direct_access_cmd_wr_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.direct_access_cmd.wr.qe),
+ .q (reg2hw.direct_access_cmd.wr.q),
+ .qs ()
+ );
+
+
+ // F[digest]: 2:2
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_direct_access_cmd_digest (
+ .re (1'b0),
+ .we (direct_access_cmd_we & direct_access_regwen_qs),
+ .wd (direct_access_cmd_digest_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.direct_access_cmd.digest.qe),
+ .q (reg2hw.direct_access_cmd.digest.q),
+ .qs ()
+ );
+
+
+ // R[direct_access_address]: V(False)
+
+ prim_subreg #(
+ .DW (11),
+ .SWACCESS("RW"),
+ .RESVAL (11'h0)
+ ) u_direct_access_address (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (direct_access_address_we & direct_access_regwen_qs),
+ .wd (direct_access_address_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.direct_access_address.q),
+
+ // to register interface (read)
+ .qs (direct_access_address_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg direct_access_wdata
+ // R[direct_access_wdata_0]: V(False)
+
+ prim_subreg #(
+ .DW (32),
+ .SWACCESS("RW"),
+ .RESVAL (32'h0)
+ ) u_direct_access_wdata_0 (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (direct_access_wdata_0_we & direct_access_regwen_qs),
+ .wd (direct_access_wdata_0_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.direct_access_wdata[0].q),
+
+ // to register interface (read)
+ .qs (direct_access_wdata_0_qs)
+ );
+
+ // Subregister 1 of Multireg direct_access_wdata
+ // R[direct_access_wdata_1]: V(False)
+
+ prim_subreg #(
+ .DW (32),
+ .SWACCESS("RW"),
+ .RESVAL (32'h0)
+ ) u_direct_access_wdata_1 (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (direct_access_wdata_1_we & direct_access_regwen_qs),
+ .wd (direct_access_wdata_1_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.direct_access_wdata[1].q),
+
+ // to register interface (read)
+ .qs (direct_access_wdata_1_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg direct_access_rdata
+ // R[direct_access_rdata_0]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_direct_access_rdata_0 (
+ .re (direct_access_rdata_0_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.direct_access_rdata[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (direct_access_rdata_0_qs)
+ );
+
+ // Subregister 1 of Multireg direct_access_rdata
+ // R[direct_access_rdata_1]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_direct_access_rdata_1 (
+ .re (direct_access_rdata_1_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.direct_access_rdata[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (direct_access_rdata_1_qs)
+ );
+
+
+ // R[check_trigger_regwen]: V(False)
+
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("W0C"),
+ .RESVAL (1'h1)
+ ) u_check_trigger_regwen (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (check_trigger_regwen_we),
+ .wd (check_trigger_regwen_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (),
+
+ // to register interface (read)
+ .qs (check_trigger_regwen_qs)
+ );
+
+
+ // R[check_trigger]: V(True)
+
+ // F[integrity]: 0:0
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_check_trigger_integrity (
+ .re (1'b0),
+ .we (check_trigger_we & check_trigger_regwen_qs),
+ .wd (check_trigger_integrity_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.check_trigger.integrity.qe),
+ .q (reg2hw.check_trigger.integrity.q),
+ .qs ()
+ );
+
+
+ // F[consistency]: 1:1
+ prim_subreg_ext #(
+ .DW (1)
+ ) u_check_trigger_consistency (
+ .re (1'b0),
+ .we (check_trigger_we & check_trigger_regwen_qs),
+ .wd (check_trigger_consistency_wd),
+ .d ('0),
+ .qre (),
+ .qe (reg2hw.check_trigger.consistency.qe),
+ .q (reg2hw.check_trigger.consistency.q),
+ .qs ()
+ );
+
+
+ // R[check_regwen]: V(False)
+
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("W0C"),
+ .RESVAL (1'h1)
+ ) u_check_regwen (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (check_regwen_we),
+ .wd (check_regwen_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (),
+
+ // to register interface (read)
+ .qs (check_regwen_qs)
+ );
+
+
+ // R[check_timeout]: V(False)
+
+ prim_subreg #(
+ .DW (32),
+ .SWACCESS("RW"),
+ .RESVAL (32'h0)
+ ) u_check_timeout (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (check_timeout_we & check_regwen_qs),
+ .wd (check_timeout_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.check_timeout.q),
+
+ // to register interface (read)
+ .qs (check_timeout_qs)
+ );
+
+
+ // R[integrity_check_period]: V(False)
+
+ prim_subreg #(
+ .DW (32),
+ .SWACCESS("RW"),
+ .RESVAL (32'h0)
+ ) u_integrity_check_period (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (integrity_check_period_we & check_regwen_qs),
+ .wd (integrity_check_period_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.integrity_check_period.q),
+
+ // to register interface (read)
+ .qs (integrity_check_period_qs)
+ );
+
+
+ // R[consistency_check_period]: V(False)
+
+ prim_subreg #(
+ .DW (32),
+ .SWACCESS("RW"),
+ .RESVAL (32'h0)
+ ) u_consistency_check_period (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (consistency_check_period_we & check_regwen_qs),
+ .wd (consistency_check_period_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.consistency_check_period.q),
+
+ // to register interface (read)
+ .qs (consistency_check_period_qs)
+ );
+
+
+ // R[creator_sw_cfg_read_lock]: V(False)
+
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("W0C"),
+ .RESVAL (1'h1)
+ ) u_creator_sw_cfg_read_lock (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (creator_sw_cfg_read_lock_we & direct_access_regwen_qs),
+ .wd (creator_sw_cfg_read_lock_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.creator_sw_cfg_read_lock.q),
+
+ // to register interface (read)
+ .qs (creator_sw_cfg_read_lock_qs)
+ );
+
+
+ // R[owner_sw_cfg_read_lock]: V(False)
+
+ prim_subreg #(
+ .DW (1),
+ .SWACCESS("W0C"),
+ .RESVAL (1'h1)
+ ) u_owner_sw_cfg_read_lock (
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
+
+ // from register interface
+ .we (owner_sw_cfg_read_lock_we & direct_access_regwen_qs),
+ .wd (owner_sw_cfg_read_lock_wd),
+
+ // from internal hardware
+ .de (1'b0),
+ .d ('0),
+
+ // to internal hardware
+ .qe (),
+ .q (reg2hw.owner_sw_cfg_read_lock.q),
+
+ // to register interface (read)
+ .qs (owner_sw_cfg_read_lock_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg creator_sw_cfg_digest
+ // R[creator_sw_cfg_digest_0]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_creator_sw_cfg_digest_0 (
+ .re (creator_sw_cfg_digest_0_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.creator_sw_cfg_digest[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (creator_sw_cfg_digest_0_qs)
+ );
+
+ // Subregister 1 of Multireg creator_sw_cfg_digest
+ // R[creator_sw_cfg_digest_1]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_creator_sw_cfg_digest_1 (
+ .re (creator_sw_cfg_digest_1_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.creator_sw_cfg_digest[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (creator_sw_cfg_digest_1_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg owner_sw_cfg_digest
+ // R[owner_sw_cfg_digest_0]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_owner_sw_cfg_digest_0 (
+ .re (owner_sw_cfg_digest_0_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.owner_sw_cfg_digest[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (owner_sw_cfg_digest_0_qs)
+ );
+
+ // Subregister 1 of Multireg owner_sw_cfg_digest
+ // R[owner_sw_cfg_digest_1]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_owner_sw_cfg_digest_1 (
+ .re (owner_sw_cfg_digest_1_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.owner_sw_cfg_digest[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (owner_sw_cfg_digest_1_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg hw_cfg_digest
+ // R[hw_cfg_digest_0]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_hw_cfg_digest_0 (
+ .re (hw_cfg_digest_0_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.hw_cfg_digest[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (hw_cfg_digest_0_qs)
+ );
+
+ // Subregister 1 of Multireg hw_cfg_digest
+ // R[hw_cfg_digest_1]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_hw_cfg_digest_1 (
+ .re (hw_cfg_digest_1_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.hw_cfg_digest[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (hw_cfg_digest_1_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg secret0_digest
+ // R[secret0_digest_0]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_secret0_digest_0 (
+ .re (secret0_digest_0_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.secret0_digest[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (secret0_digest_0_qs)
+ );
+
+ // Subregister 1 of Multireg secret0_digest
+ // R[secret0_digest_1]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_secret0_digest_1 (
+ .re (secret0_digest_1_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.secret0_digest[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (secret0_digest_1_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg secret1_digest
+ // R[secret1_digest_0]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_secret1_digest_0 (
+ .re (secret1_digest_0_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.secret1_digest[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (secret1_digest_0_qs)
+ );
+
+ // Subregister 1 of Multireg secret1_digest
+ // R[secret1_digest_1]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_secret1_digest_1 (
+ .re (secret1_digest_1_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.secret1_digest[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (secret1_digest_1_qs)
+ );
+
+
+
+ // Subregister 0 of Multireg secret2_digest
+ // R[secret2_digest_0]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_secret2_digest_0 (
+ .re (secret2_digest_0_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.secret2_digest[0].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (secret2_digest_0_qs)
+ );
+
+ // Subregister 1 of Multireg secret2_digest
+ // R[secret2_digest_1]: V(True)
+
+ prim_subreg_ext #(
+ .DW (32)
+ ) u_secret2_digest_1 (
+ .re (secret2_digest_1_re),
+ .we (1'b0),
+ .wd ('0),
+ .d (hw2reg.secret2_digest[1].d),
+ .qre (),
+ .qe (),
+ .q (),
+ .qs (secret2_digest_1_qs)
+ );
+
+
+
+
+ logic [32:0] addr_hit;
+ always_comb begin
+ addr_hit = '0;
+ addr_hit[ 0] = (reg_addr == OTP_CTRL_INTR_STATE_OFFSET);
+ addr_hit[ 1] = (reg_addr == OTP_CTRL_INTR_ENABLE_OFFSET);
+ addr_hit[ 2] = (reg_addr == OTP_CTRL_INTR_TEST_OFFSET);
+ addr_hit[ 3] = (reg_addr == OTP_CTRL_ALERT_TEST_OFFSET);
+ addr_hit[ 4] = (reg_addr == OTP_CTRL_STATUS_OFFSET);
+ addr_hit[ 5] = (reg_addr == OTP_CTRL_ERR_CODE_OFFSET);
+ addr_hit[ 6] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_REGWEN_OFFSET);
+ addr_hit[ 7] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_CMD_OFFSET);
+ addr_hit[ 8] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_ADDRESS_OFFSET);
+ addr_hit[ 9] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_WDATA_0_OFFSET);
+ addr_hit[10] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_WDATA_1_OFFSET);
+ addr_hit[11] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_RDATA_0_OFFSET);
+ addr_hit[12] = (reg_addr == OTP_CTRL_DIRECT_ACCESS_RDATA_1_OFFSET);
+ addr_hit[13] = (reg_addr == OTP_CTRL_CHECK_TRIGGER_REGWEN_OFFSET);
+ addr_hit[14] = (reg_addr == OTP_CTRL_CHECK_TRIGGER_OFFSET);
+ addr_hit[15] = (reg_addr == OTP_CTRL_CHECK_REGWEN_OFFSET);
+ addr_hit[16] = (reg_addr == OTP_CTRL_CHECK_TIMEOUT_OFFSET);
+ addr_hit[17] = (reg_addr == OTP_CTRL_INTEGRITY_CHECK_PERIOD_OFFSET);
+ addr_hit[18] = (reg_addr == OTP_CTRL_CONSISTENCY_CHECK_PERIOD_OFFSET);
+ addr_hit[19] = (reg_addr == OTP_CTRL_CREATOR_SW_CFG_READ_LOCK_OFFSET);
+ addr_hit[20] = (reg_addr == OTP_CTRL_OWNER_SW_CFG_READ_LOCK_OFFSET);
+ addr_hit[21] = (reg_addr == OTP_CTRL_CREATOR_SW_CFG_DIGEST_0_OFFSET);
+ addr_hit[22] = (reg_addr == OTP_CTRL_CREATOR_SW_CFG_DIGEST_1_OFFSET);
+ addr_hit[23] = (reg_addr == OTP_CTRL_OWNER_SW_CFG_DIGEST_0_OFFSET);
+ addr_hit[24] = (reg_addr == OTP_CTRL_OWNER_SW_CFG_DIGEST_1_OFFSET);
+ addr_hit[25] = (reg_addr == OTP_CTRL_HW_CFG_DIGEST_0_OFFSET);
+ addr_hit[26] = (reg_addr == OTP_CTRL_HW_CFG_DIGEST_1_OFFSET);
+ addr_hit[27] = (reg_addr == OTP_CTRL_SECRET0_DIGEST_0_OFFSET);
+ addr_hit[28] = (reg_addr == OTP_CTRL_SECRET0_DIGEST_1_OFFSET);
+ addr_hit[29] = (reg_addr == OTP_CTRL_SECRET1_DIGEST_0_OFFSET);
+ addr_hit[30] = (reg_addr == OTP_CTRL_SECRET1_DIGEST_1_OFFSET);
+ addr_hit[31] = (reg_addr == OTP_CTRL_SECRET2_DIGEST_0_OFFSET);
+ addr_hit[32] = (reg_addr == OTP_CTRL_SECRET2_DIGEST_1_OFFSET);
+ end
+
+ assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
+
+ // Check sub-word write is permitted
+ always_comb begin
+ wr_err = (reg_we &
+ ((addr_hit[ 0] & (|(OTP_CTRL_PERMIT[ 0] & ~reg_be))) |
+ (addr_hit[ 1] & (|(OTP_CTRL_PERMIT[ 1] & ~reg_be))) |
+ (addr_hit[ 2] & (|(OTP_CTRL_PERMIT[ 2] & ~reg_be))) |
+ (addr_hit[ 3] & (|(OTP_CTRL_PERMIT[ 3] & ~reg_be))) |
+ (addr_hit[ 4] & (|(OTP_CTRL_PERMIT[ 4] & ~reg_be))) |
+ (addr_hit[ 5] & (|(OTP_CTRL_PERMIT[ 5] & ~reg_be))) |
+ (addr_hit[ 6] & (|(OTP_CTRL_PERMIT[ 6] & ~reg_be))) |
+ (addr_hit[ 7] & (|(OTP_CTRL_PERMIT[ 7] & ~reg_be))) |
+ (addr_hit[ 8] & (|(OTP_CTRL_PERMIT[ 8] & ~reg_be))) |
+ (addr_hit[ 9] & (|(OTP_CTRL_PERMIT[ 9] & ~reg_be))) |
+ (addr_hit[10] & (|(OTP_CTRL_PERMIT[10] & ~reg_be))) |
+ (addr_hit[11] & (|(OTP_CTRL_PERMIT[11] & ~reg_be))) |
+ (addr_hit[12] & (|(OTP_CTRL_PERMIT[12] & ~reg_be))) |
+ (addr_hit[13] & (|(OTP_CTRL_PERMIT[13] & ~reg_be))) |
+ (addr_hit[14] & (|(OTP_CTRL_PERMIT[14] & ~reg_be))) |
+ (addr_hit[15] & (|(OTP_CTRL_PERMIT[15] & ~reg_be))) |
+ (addr_hit[16] & (|(OTP_CTRL_PERMIT[16] & ~reg_be))) |
+ (addr_hit[17] & (|(OTP_CTRL_PERMIT[17] & ~reg_be))) |
+ (addr_hit[18] & (|(OTP_CTRL_PERMIT[18] & ~reg_be))) |
+ (addr_hit[19] & (|(OTP_CTRL_PERMIT[19] & ~reg_be))) |
+ (addr_hit[20] & (|(OTP_CTRL_PERMIT[20] & ~reg_be))) |
+ (addr_hit[21] & (|(OTP_CTRL_PERMIT[21] & ~reg_be))) |
+ (addr_hit[22] & (|(OTP_CTRL_PERMIT[22] & ~reg_be))) |
+ (addr_hit[23] & (|(OTP_CTRL_PERMIT[23] & ~reg_be))) |
+ (addr_hit[24] & (|(OTP_CTRL_PERMIT[24] & ~reg_be))) |
+ (addr_hit[25] & (|(OTP_CTRL_PERMIT[25] & ~reg_be))) |
+ (addr_hit[26] & (|(OTP_CTRL_PERMIT[26] & ~reg_be))) |
+ (addr_hit[27] & (|(OTP_CTRL_PERMIT[27] & ~reg_be))) |
+ (addr_hit[28] & (|(OTP_CTRL_PERMIT[28] & ~reg_be))) |
+ (addr_hit[29] & (|(OTP_CTRL_PERMIT[29] & ~reg_be))) |
+ (addr_hit[30] & (|(OTP_CTRL_PERMIT[30] & ~reg_be))) |
+ (addr_hit[31] & (|(OTP_CTRL_PERMIT[31] & ~reg_be))) |
+ (addr_hit[32] & (|(OTP_CTRL_PERMIT[32] & ~reg_be)))));
+ end
+ assign intr_state_we = addr_hit[0] & reg_we & !reg_error;
+
+ assign intr_state_otp_operation_done_wd = reg_wdata[0];
+
+ assign intr_state_otp_error_wd = reg_wdata[1];
+ assign intr_enable_we = addr_hit[1] & reg_we & !reg_error;
+
+ assign intr_enable_otp_operation_done_wd = reg_wdata[0];
+
+ assign intr_enable_otp_error_wd = reg_wdata[1];
+ assign intr_test_we = addr_hit[2] & reg_we & !reg_error;
+
+ assign intr_test_otp_operation_done_wd = reg_wdata[0];
+
+ assign intr_test_otp_error_wd = reg_wdata[1];
+ assign alert_test_we = addr_hit[3] & reg_we & !reg_error;
+
+ assign alert_test_fatal_macro_error_wd = reg_wdata[0];
+
+ assign alert_test_fatal_check_error_wd = reg_wdata[1];
+
+ assign alert_test_fatal_bus_integ_error_wd = reg_wdata[2];
+ assign status_re = addr_hit[4] & reg_re & !reg_error;
+ assign err_code_re = addr_hit[5] & reg_re & !reg_error;
+ assign direct_access_regwen_re = addr_hit[6] & reg_re & !reg_error;
+ assign direct_access_cmd_we = addr_hit[7] & reg_we & !reg_error;
+
+ assign direct_access_cmd_rd_wd = reg_wdata[0];
+
+ assign direct_access_cmd_wr_wd = reg_wdata[1];
+
+ assign direct_access_cmd_digest_wd = reg_wdata[2];
+ assign direct_access_address_we = addr_hit[8] & reg_we & !reg_error;
+
+ assign direct_access_address_wd = reg_wdata[10:0];
+ assign direct_access_wdata_0_we = addr_hit[9] & reg_we & !reg_error;
+
+ assign direct_access_wdata_0_wd = reg_wdata[31:0];
+ assign direct_access_wdata_1_we = addr_hit[10] & reg_we & !reg_error;
+
+ assign direct_access_wdata_1_wd = reg_wdata[31:0];
+ assign direct_access_rdata_0_re = addr_hit[11] & reg_re & !reg_error;
+ assign direct_access_rdata_1_re = addr_hit[12] & reg_re & !reg_error;
+ assign check_trigger_regwen_we = addr_hit[13] & reg_we & !reg_error;
+
+ assign check_trigger_regwen_wd = reg_wdata[0];
+ assign check_trigger_we = addr_hit[14] & reg_we & !reg_error;
+
+ assign check_trigger_integrity_wd = reg_wdata[0];
+
+ assign check_trigger_consistency_wd = reg_wdata[1];
+ assign check_regwen_we = addr_hit[15] & reg_we & !reg_error;
+
+ assign check_regwen_wd = reg_wdata[0];
+ assign check_timeout_we = addr_hit[16] & reg_we & !reg_error;
+
+ assign check_timeout_wd = reg_wdata[31:0];
+ assign integrity_check_period_we = addr_hit[17] & reg_we & !reg_error;
+
+ assign integrity_check_period_wd = reg_wdata[31:0];
+ assign consistency_check_period_we = addr_hit[18] & reg_we & !reg_error;
+
+ assign consistency_check_period_wd = reg_wdata[31:0];
+ assign creator_sw_cfg_read_lock_we = addr_hit[19] & reg_we & !reg_error;
+
+ assign creator_sw_cfg_read_lock_wd = reg_wdata[0];
+ assign owner_sw_cfg_read_lock_we = addr_hit[20] & reg_we & !reg_error;
+
+ assign owner_sw_cfg_read_lock_wd = reg_wdata[0];
+ assign creator_sw_cfg_digest_0_re = addr_hit[21] & reg_re & !reg_error;
+ assign creator_sw_cfg_digest_1_re = addr_hit[22] & reg_re & !reg_error;
+ assign owner_sw_cfg_digest_0_re = addr_hit[23] & reg_re & !reg_error;
+ assign owner_sw_cfg_digest_1_re = addr_hit[24] & reg_re & !reg_error;
+ assign hw_cfg_digest_0_re = addr_hit[25] & reg_re & !reg_error;
+ assign hw_cfg_digest_1_re = addr_hit[26] & reg_re & !reg_error;
+ assign secret0_digest_0_re = addr_hit[27] & reg_re & !reg_error;
+ assign secret0_digest_1_re = addr_hit[28] & reg_re & !reg_error;
+ assign secret1_digest_0_re = addr_hit[29] & reg_re & !reg_error;
+ assign secret1_digest_1_re = addr_hit[30] & reg_re & !reg_error;
+ assign secret2_digest_0_re = addr_hit[31] & reg_re & !reg_error;
+ assign secret2_digest_1_re = addr_hit[32] & reg_re & !reg_error;
+
+ // Read data return
+ always_comb begin
+ reg_rdata_next = '0;
+ unique case (1'b1)
+ addr_hit[0]: begin
+ reg_rdata_next[0] = intr_state_otp_operation_done_qs;
+ reg_rdata_next[1] = intr_state_otp_error_qs;
+ end
+
+ addr_hit[1]: begin
+ reg_rdata_next[0] = intr_enable_otp_operation_done_qs;
+ reg_rdata_next[1] = intr_enable_otp_error_qs;
+ end
+
+ addr_hit[2]: begin
+ reg_rdata_next[0] = '0;
+ reg_rdata_next[1] = '0;
+ end
+
+ addr_hit[3]: begin
+ reg_rdata_next[0] = '0;
+ reg_rdata_next[1] = '0;
+ reg_rdata_next[2] = '0;
+ end
+
+ addr_hit[4]: begin
+ reg_rdata_next[0] = status_creator_sw_cfg_error_qs;
+ reg_rdata_next[1] = status_owner_sw_cfg_error_qs;
+ reg_rdata_next[2] = status_hw_cfg_error_qs;
+ reg_rdata_next[3] = status_secret0_error_qs;
+ reg_rdata_next[4] = status_secret1_error_qs;
+ reg_rdata_next[5] = status_secret2_error_qs;
+ reg_rdata_next[6] = status_life_cycle_error_qs;
+ reg_rdata_next[7] = status_dai_error_qs;
+ reg_rdata_next[8] = status_lci_error_qs;
+ reg_rdata_next[9] = status_timeout_error_qs;
+ reg_rdata_next[10] = status_lfsr_fsm_error_qs;
+ reg_rdata_next[11] = status_scrambling_fsm_error_qs;
+ reg_rdata_next[12] = status_key_deriv_fsm_error_qs;
+ reg_rdata_next[13] = status_bus_integ_error_qs;
+ reg_rdata_next[14] = status_dai_idle_qs;
+ reg_rdata_next[15] = status_check_pending_qs;
+ end
+
+ addr_hit[5]: begin
+ reg_rdata_next[2:0] = err_code_err_code_0_qs;
+ reg_rdata_next[5:3] = err_code_err_code_1_qs;
+ reg_rdata_next[8:6] = err_code_err_code_2_qs;
+ reg_rdata_next[11:9] = err_code_err_code_3_qs;
+ reg_rdata_next[14:12] = err_code_err_code_4_qs;
+ reg_rdata_next[17:15] = err_code_err_code_5_qs;
+ reg_rdata_next[20:18] = err_code_err_code_6_qs;
+ reg_rdata_next[23:21] = err_code_err_code_7_qs;
+ reg_rdata_next[26:24] = err_code_err_code_8_qs;
+ end
+
+ addr_hit[6]: begin
+ reg_rdata_next[0] = direct_access_regwen_qs;
+ end
+
+ addr_hit[7]: begin
+ reg_rdata_next[0] = '0;
+ reg_rdata_next[1] = '0;
+ reg_rdata_next[2] = '0;
+ end
+
+ addr_hit[8]: begin
+ reg_rdata_next[10:0] = direct_access_address_qs;
+ end
+
+ addr_hit[9]: begin
+ reg_rdata_next[31:0] = direct_access_wdata_0_qs;
+ end
+
+ addr_hit[10]: begin
+ reg_rdata_next[31:0] = direct_access_wdata_1_qs;
+ end
+
+ addr_hit[11]: begin
+ reg_rdata_next[31:0] = direct_access_rdata_0_qs;
+ end
+
+ addr_hit[12]: begin
+ reg_rdata_next[31:0] = direct_access_rdata_1_qs;
+ end
+
+ addr_hit[13]: begin
+ reg_rdata_next[0] = check_trigger_regwen_qs;
+ end
+
+ addr_hit[14]: begin
+ reg_rdata_next[0] = '0;
+ reg_rdata_next[1] = '0;
+ end
+
+ addr_hit[15]: begin
+ reg_rdata_next[0] = check_regwen_qs;
+ end
+
+ addr_hit[16]: begin
+ reg_rdata_next[31:0] = check_timeout_qs;
+ end
+
+ addr_hit[17]: begin
+ reg_rdata_next[31:0] = integrity_check_period_qs;
+ end
+
+ addr_hit[18]: begin
+ reg_rdata_next[31:0] = consistency_check_period_qs;
+ end
+
+ addr_hit[19]: begin
+ reg_rdata_next[0] = creator_sw_cfg_read_lock_qs;
+ end
+
+ addr_hit[20]: begin
+ reg_rdata_next[0] = owner_sw_cfg_read_lock_qs;
+ end
+
+ addr_hit[21]: begin
+ reg_rdata_next[31:0] = creator_sw_cfg_digest_0_qs;
+ end
+
+ addr_hit[22]: begin
+ reg_rdata_next[31:0] = creator_sw_cfg_digest_1_qs;
+ end
+
+ addr_hit[23]: begin
+ reg_rdata_next[31:0] = owner_sw_cfg_digest_0_qs;
+ end
+
+ addr_hit[24]: begin
+ reg_rdata_next[31:0] = owner_sw_cfg_digest_1_qs;
+ end
+
+ addr_hit[25]: begin
+ reg_rdata_next[31:0] = hw_cfg_digest_0_qs;
+ end
+
+ addr_hit[26]: begin
+ reg_rdata_next[31:0] = hw_cfg_digest_1_qs;
+ end
+
+ addr_hit[27]: begin
+ reg_rdata_next[31:0] = secret0_digest_0_qs;
+ end
+
+ addr_hit[28]: begin
+ reg_rdata_next[31:0] = secret0_digest_1_qs;
+ end
+
+ addr_hit[29]: begin
+ reg_rdata_next[31:0] = secret1_digest_0_qs;
+ end
+
+ addr_hit[30]: begin
+ reg_rdata_next[31:0] = secret1_digest_1_qs;
+ end
+
+ addr_hit[31]: begin
+ reg_rdata_next[31:0] = secret2_digest_0_qs;
+ end
+
+ addr_hit[32]: begin
+ reg_rdata_next[31:0] = secret2_digest_1_qs;
+ end
+
+ default: begin
+ reg_rdata_next = '1;
+ end
+ endcase
+ end
+
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ 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, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
+
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
+
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
+
+ // 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/pattgen/rtl/pattgen_reg_top.sv b/hw/ip/pattgen/rtl/pattgen_reg_top.sv
index ec6b0da..2368204 100644
--- a/hw/ip/pattgen/rtl/pattgen_reg_top.sv
+++ b/hw/ip/pattgen/rtl/pattgen_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -850,6 +855,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -860,12 +876,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/pinmux/rtl/pinmux_reg_top.sv b/hw/ip/pinmux/rtl/pinmux_reg_top.sv
index a499017..276e961 100644
--- a/hw/ip/pinmux/rtl/pinmux_reg_top.sv
+++ b/hw/ip/pinmux/rtl/pinmux_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -17951,6 +17956,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -17961,12 +17977,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/prim/prim_subreg.core b/hw/ip/prim/prim_subreg.core
index df4672b..815ca24 100644
--- a/hw/ip/prim/prim_subreg.core
+++ b/hw/ip/prim/prim_subreg.core
@@ -10,8 +10,11 @@
files:
- rtl/prim_subreg_pkg.sv
- rtl/prim_subreg_arb.sv
+ - rtl/prim_subreg_cdc.sv
- rtl/prim_subreg.sv
+ - rtl/prim_subreg_async.sv
- rtl/prim_subreg_ext.sv
+ - rtl/prim_subreg_ext_async.sv
- rtl/prim_subreg_shadow.sv
file_type: systemVerilogSource
diff --git a/hw/ip/prim/rtl/prim_subreg_async.sv b/hw/ip/prim/rtl/prim_subreg_async.sv
new file mode 100644
index 0000000..b9d1ae1
--- /dev/null
+++ b/hw/ip/prim/rtl/prim_subreg_async.sv
@@ -0,0 +1,85 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Asynchronous implementation of prim_subreg
+
+module prim_subreg_async
+ import prim_subreg_pkg::*;
+#(
+ parameter int DW = 32 ,
+ parameter sw_access_e SwAccess = SwAccessRW,
+ parameter logic [DW-1:0] RESVAL = '0 // Reset value
+) (
+ input clk_src_i,
+ input rst_src_ni,
+ input clk_dst_i,
+ input rst_dst_ni,
+
+ // destination sample pulse
+ input src_update_i,
+
+ // From SW: valid for RW, WO, W1C, W1S, W0C, RC
+ // In case of RC, Top connects Read Pulse to we
+ input src_we_i,
+ input [DW-1:0] src_wd_i,
+
+ // From HW: valid for HRW, HWO
+ input dst_de_i,
+ input [DW-1:0] dst_d_i,
+
+ // output to Reg Read
+ output logic src_busy_o,
+ output logic [DW-1:0] src_qs_o,
+
+ // output to HW read
+ output logic dst_qe_o,
+ // This output does not follow comportable convention to work with
+ // current DV assumptions.
+ output logic [DW-1:0] q
+);
+
+ logic dst_we;
+ logic [DW-1:0] dst_wdata;
+ logic [DW-1:0] q_int;
+
+ prim_subreg_cdc #(
+ .DW(DW),
+ .RESVAL(RESVAL)
+ ) u_reg_cdc (
+ .clk_src_i,
+ .rst_src_ni,
+ .clk_dst_i,
+ .rst_dst_ni,
+ .src_update_i,
+ .src_req_i(src_we_i),
+ // data that crosses domain
+ .src_data_i(src_wd_i),
+ // data readback to software
+ .src_data_o(src_qs_o),
+ .src_busy_o,
+ .dst_req_o(dst_we),
+ // hardware written data
+ .dst_data_i(q_int),
+ // data to write to hardware
+ .dst_data_o(dst_wdata)
+ );
+
+ prim_subreg #(
+ .DW(DW),
+ .SwAccess(SwAccess),
+ .RESVAL(RESVAL)
+ ) u_subreg (
+ .clk_i(clk_dst_i),
+ .rst_ni(rst_dst_ni),
+ .we(dst_we),
+ .wd(dst_wdata),
+ .de(dst_de_i),
+ .d(dst_d_i),
+ .qe(dst_qe_o),
+ .q(q_int),
+ .qs()
+ );
+ assign q = q_int;
+
+endmodule
diff --git a/hw/ip/prim/rtl/prim_subreg_cdc.sv b/hw/ip/prim/rtl/prim_subreg_cdc.sv
new file mode 100644
index 0000000..18618be
--- /dev/null
+++ b/hw/ip/prim/rtl/prim_subreg_cdc.sv
@@ -0,0 +1,135 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Component handling register CDC
+
+`include "prim_assert.sv"
+
+module prim_subreg_cdc #(
+ parameter int DW = 32,
+ parameter logic [DW-1:0] RESVAL = '0 // Reset value
+) (
+ input clk_src_i,
+ input rst_src_ni,
+ input clk_dst_i,
+ input rst_dst_ni,
+
+ input src_update_i,
+ input src_req_i,
+ input [DW-1:0] src_data_i,
+ output logic src_busy_o,
+ output logic [DW-1:0] src_data_o,
+
+ input [DW-1:0] dst_data_i,
+ output logic dst_req_o,
+ output logic [DW-1:0] dst_data_o
+);
+
+ ////////////////////////////
+ // Source domain
+ ////////////////////////////
+ logic src_ack;
+ logic src_busy_q;
+ logic [DW-1:0] src_q;
+
+ // busy indication back-pressures upstream if the register is accessed
+ // again. The busy indication is also used as a "commit" indication for
+ // resolving software and hardware write conflicts
+ always_ff @(posedge clk_src_i or negedge rst_src_ni) begin
+ if (!rst_src_ni) begin
+ src_busy_q <= '0;
+ end else if (src_req_i) begin
+ src_busy_q <= 1'b1;
+ end else if (src_busy_q && src_ack) begin
+ src_busy_q <= 1'b0;
+ end
+ end
+
+ assign src_busy_o = src_busy_q;
+
+ // src_q acts as both the write holding register and the software read back
+ // register.
+ // When software performs a write, the write data is captured in src_q for
+ // CDC purposes. When not performing a write, the src_q periodically
+ // samples the destination domain using the src_update_i indication.
+ //
+ // To resolve software and hardware conflicts, the process is as follows:
+ // When software issues a write, this module asserts "busy". While busy,
+ // src_q does not sample the destination value. Since the
+ // logic has committed to updating based on software command, there is an irreversible
+ // window from which hardware writes are ignored. Once the busy window completes,
+ // the cdc portion then begins sampling once more.
+ //
+ // This is consistent with prim_subreg_arb where during software / hardware conflicts,
+ // software is always prioritized. The main difference is the conflict resolution window
+ // is now larger instead of just one destination clock cycle.
+
+ logic busy;
+ assign busy = src_busy_q & !src_ack;
+
+ always_ff @(posedge clk_src_i or negedge rst_src_ni) begin
+ if (!rst_src_ni) begin
+ src_q <= RESVAL;
+ end else if (src_req_i && !busy) begin
+ src_q <= src_data_i;
+ end else if (src_busy_q && src_ack || src_update_i && !busy) begin
+ // sample data whenever a busy transaction finishes OR
+ // when an update pulse is seen.
+ // TODO: We should add a cover group to test different sync timings
+ // between src_ack and src_update. Ie, there can be 3 scearios:
+ // 1. update one cycle before ack
+ // 2. ack one cycle before update
+ // 3. update / ack on the same cycle
+ // During all 3 cases the read data should be correct
+ src_q <= dst_data_i;
+ end
+ end
+
+ // src_q is always updated in the clk_src domain.
+ // when performing an update to the destination domain, it is guaranteed
+ // to not change by protocol.
+ assign src_data_o = src_q;
+ assign dst_data_o = src_q;
+
+ ////////////////////////////
+ // CDC handling
+ ////////////////////////////
+ prim_sync_reqack u_prim_sync (
+ .clk_src_i,
+ .rst_src_ni,
+ .clk_dst_i,
+ .rst_dst_ni,
+ .req_chk_i(1'b0),
+ // prim_sync_reqack does not natively handle single
+ // pulse requests, so use src_busy to even it out.
+ .src_req_i(src_req_i | src_busy_q),
+ .src_ack_o(src_ack),
+ .dst_req_o(dst_req_o),
+ // immediately ack on destination once request is seen
+ .dst_ack_i(dst_req_o)
+ );
+
+ `ASSERT_KNOWN(SrcBusyKnown_A, src_busy_o, clk_src_i, !rst_src_ni)
+ `ASSERT_KNOWN(DstReqKnown_A, dst_req_o, clk_dst_i, !rst_dst_ni)
+
+ // If busy goes high, we must eventually see an ack
+ `ASSERT(HungHandShake_A, $rose(src_busy_o) |-> strong(##[0:$] src_ack), clk_src_i, !rst_src_ni)
+
+ `ifdef SIMULATION
+ logic async_flag;
+ always_ff @(posedge src_req_i or posedge dst_req_o or
+ negedge rst_src_ni or negedge rst_dst_ni) begin
+ if (!rst_src_ni && !rst_dst_ni) begin
+ async_flag <= '0;
+ end else if (src_req_i) begin
+ async_flag <= 1'b1;
+ end else if (dst_req_o) begin
+ async_flag <= 1'b0;
+ end
+ end
+ `ASSERT(ReqTimeout_A, $rose(async_flag) |-> strong(##[0:3] dst_req_o), clk_dst_i, !rst_dst_ni)
+ `endif
+
+
+endmodule // prim_subreg_cdc
diff --git a/hw/ip/prim/rtl/prim_subreg_ext_async.sv b/hw/ip/prim/rtl/prim_subreg_ext_async.sv
new file mode 100644
index 0000000..7b8576e
--- /dev/null
+++ b/hw/ip/prim/rtl/prim_subreg_ext_async.sv
@@ -0,0 +1,68 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Asynchronous implementation of prim_subreg_ext
+
+module prim_subreg_ext_async #(
+ parameter int unsigned DW = 32
+) (
+ input clk_src_i,
+ input rst_src_ni,
+ input clk_dst_i,
+ input rst_dst_ni,
+
+ // source domain signals
+ input re,
+ input we,
+ input [DW-1:0] wd,
+ input src_update_i,
+ output logic src_busy_o,
+
+ // destination domain signals
+ input [DW-1:0] d,
+
+ // outputs to destination domain
+ output logic qe,
+ output logic qre,
+ output logic [DW-1:0] q,
+
+ // outputs to source domain
+ output logic [DW-1:0] qs
+);
+
+ logic dst_req;
+ logic [DW-1:0] dst_wdata;
+ logic dst_we;
+ logic unused_src_we;
+
+ // Capture both data and write-enable
+ // write enable is needed to determine whether qe or qre should be generated
+ // in the desitnation domain.
+ prim_subreg_cdc #(
+ .DW(DW + 1)
+ ) u_reg_cdc (
+ .clk_src_i,
+ .rst_src_ni,
+ .clk_dst_i,
+ .rst_dst_ni,
+ .src_update_i,
+ .src_req_i(re | we),
+ .src_data_i({wd, we}),
+ .src_data_o({qs, unused_src_we}),
+ .src_busy_o,
+ .dst_req_o(dst_req),
+ .dst_data_i({d, 1'b0}),
+ .dst_data_o({dst_wdata, dst_we})
+ );
+
+ /////////////////////
+ // Destination domain
+ /////////////////////
+
+ assign qe = dst_req ? dst_we : '0;
+ assign qre = dst_req ? ~dst_we : '0;
+ assign q = dst_req ? dst_wdata : '0;
+
+
+endmodule
diff --git a/hw/ip/pwm/rtl/pwm_reg_top.sv b/hw/ip/pwm/rtl/pwm_reg_top.sv
index e54be57..8b2a130 100644
--- a/hw/ip/pwm/rtl/pwm_reg_top.sv
+++ b/hw/ip/pwm/rtl/pwm_reg_top.sv
@@ -40,14 +40,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -71,7 +73,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -82,8 +84,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -93,10 +95,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -2181,6 +2186,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -2191,12 +2207,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv b/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv
index 1054560..c12cc98 100644
--- a/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv
+++ b/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -836,6 +841,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -846,12 +862,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
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
index b29706b..a37b59d 100644
--- a/hw/ip/rom_ctrl/rtl/rom_ctrl_regs_reg_top.sv
+++ b/hw/ip/rom_ctrl/rtl/rom_ctrl_regs_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -768,6 +773,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -778,12 +794,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
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
index da9fbd3..b5246ff 100644
--- a/hw/ip/rom_ctrl/rtl/rom_ctrl_rom_reg_top.sv
+++ b/hw/ip/rom_ctrl/rtl/rom_ctrl_rom_reg_top.sv
@@ -29,10 +29,11 @@
import rom_ctrl_reg_pkg::* ;
+
// incoming payload check
logic intg_err;
tlul_cmd_intg_chk u_chk (
- .tl_i,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -56,7 +57,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_win_o = tl_i;
diff --git a/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv b/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv
index 28e60fc..0494e24 100644
--- a/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv
+++ b/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -512,6 +517,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -522,12 +538,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv b/hw/ip/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv
index 39ad51b..7575efe 100644
--- a/hw/ip/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv
+++ b/hw/ip/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1290,6 +1295,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1300,12 +1316,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/rv_dm/rtl/rv_dm_regs_reg_top.sv b/hw/ip/rv_dm/rtl/rv_dm_regs_reg_top.sv
index 0f99a74..dfc1768 100644
--- a/hw/ip/rv_dm/rtl/rv_dm_regs_reg_top.sv
+++ b/hw/ip/rv_dm/rtl/rv_dm_regs_reg_top.sv
@@ -40,14 +40,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -71,7 +73,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -82,8 +84,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -93,10 +95,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -156,6 +161,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -166,12 +182,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/rv_dm/rtl/rv_dm_rom_reg_top.sv b/hw/ip/rv_dm/rtl/rv_dm_rom_reg_top.sv
index 68b2083..86fc22a 100644
--- a/hw/ip/rv_dm/rtl/rv_dm_rom_reg_top.sv
+++ b/hw/ip/rv_dm/rtl/rv_dm_rom_reg_top.sv
@@ -29,10 +29,11 @@
import rv_dm_reg_pkg::* ;
+
// incoming payload check
logic intg_err;
tlul_cmd_intg_chk u_chk (
- .tl_i,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -56,7 +57,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_win_o = tl_i;
diff --git a/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv b/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv
index f91e2b5..12aa254 100644
--- a/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv
+++ b/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -4427,6 +4432,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -4437,12 +4453,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv b/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv
index 8ce4007..c682f34 100644
--- a/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv
+++ b/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -536,6 +541,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -546,12 +562,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/spi_device/rtl/spi_device_reg_top.sv b/hw/ip/spi_device/rtl/spi_device_reg_top.sv
index dd7dafa..4f2a0e7 100644
--- a/hw/ip/spi_device/rtl/spi_device_reg_top.sv
+++ b/hw/ip/spi_device/rtl/spi_device_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [2];
@@ -104,8 +106,8 @@
.DReqDepth ({2{4'h0}}),
.DRspDepth ({2{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -131,8 +133,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -142,10 +144,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -14302,6 +14307,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -14312,12 +14328,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/spi_host/rtl/spi_host_reg_top.sv b/hw/ip/spi_host/rtl/spi_host_reg_top.sv
index 8ad601d..731e63a 100644
--- a/hw/ip/spi_host/rtl/spi_host_reg_top.sv
+++ b/hw/ip/spi_host/rtl/spi_host_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [2];
@@ -104,8 +106,8 @@
.DReqDepth ({2{4'h0}}),
.DRspDepth ({2{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -131,8 +133,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -142,10 +144,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1822,6 +1827,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1832,12 +1848,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/spi_host/rtl/spi_host_window.sv b/hw/ip/spi_host/rtl/spi_host_window.sv
index 768a93d..2af9cda 100644
--- a/hw/ip/spi_host/rtl/spi_host_window.sv
+++ b/hw/ip/spi_host/rtl/spi_host_window.sv
@@ -40,6 +40,7 @@
.addr_o (addr),
.wdata_o (tx_data_o),
.be_o (tx_be_o),
+ .busy_i ('0),
.rdata_i (rx_data_i),
.error_i (win_error)
);
diff --git a/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv b/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv
index d5d1917..1353931 100644
--- a/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv
+++ b/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -456,6 +461,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -466,12 +482,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/sysrst_ctrl/rtl/sysrst_ctrl_reg_top.sv b/hw/ip/sysrst_ctrl/rtl/sysrst_ctrl_reg_top.sv
index 4b526e5..999f324 100644
--- a/hw/ip/sysrst_ctrl/rtl/sysrst_ctrl_reg_top.sv
+++ b/hw/ip/sysrst_ctrl/rtl/sysrst_ctrl_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -4611,6 +4616,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -4621,12 +4637,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/tlul/rtl/tlul_adapter_reg.sv b/hw/ip/tlul/rtl/tlul_adapter_reg.sv
index 49625f9..54c0d9c 100644
--- a/hw/ip/tlul/rtl/tlul_adapter_reg.sv
+++ b/hw/ip/tlul/rtl/tlul_adapter_reg.sv
@@ -27,6 +27,7 @@
output logic [RegAw-1:0] addr_o,
output logic [RegDw-1:0] wdata_o,
output logic [RegBw-1:0] be_o,
+ input busy_i,
input [RegDw-1:0] rdata_i,
input error_i
);
@@ -108,8 +109,13 @@
assign data_intg = '0;
end
+ logic req_valid;
+ assign req_valid = tl_i.a_valid;
+
assign tl_o = '{
- a_ready: ~outstanding,
+ // busy is selected based on address
+ // thus if there is no valid transaction, we should ignore busy
+ a_ready: ~(outstanding | req_valid & busy_i),
d_valid: outstanding,
d_opcode: rspop,
d_param: '0,
diff --git a/hw/ip/trial1/data/trial1.hjson b/hw/ip/trial1/data/trial1.hjson
index 4b7697e..4052afc 100644
--- a/hw/ip/trial1/data/trial1.hjson
+++ b/hw/ip/trial1/data/trial1.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
{ name: "TRIAL1",
regwidth: 32,
- clocking: [{clock: "clk_fixed", reset: "rst_fixed_n"}],
+ clocking: [{clock: "clk_fixed_i", reset: "rst_fixed_n"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/trial1/rtl/trial1_reg_top.sv b/hw/ip/trial1/rtl/trial1_reg_top.sv
index 40798c3..4c21906 100644
--- a/hw/ip/trial1/rtl/trial1_reg_top.sv
+++ b/hw/ip/trial1/rtl/trial1_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1272,6 +1277,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1282,12 +1298,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/uart/rtl/uart_reg_top.sv b/hw/ip/uart/rtl/uart_reg_top.sv
index 4c5740f..e4d0381 100644
--- a/hw/ip/uart/rtl/uart_reg_top.sv
+++ b/hw/ip/uart/rtl/uart_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1635,6 +1640,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1645,12 +1661,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/usbdev/rtl/usbdev_reg_top.sv b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
index 111f5f8..75ee722 100644
--- a/hw/ip/usbdev/rtl/usbdev_reg_top.sv
+++ b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [2];
@@ -104,8 +106,8 @@
.DReqDepth ({2{4'h0}}),
.DRspDepth ({2{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -131,8 +133,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -142,10 +144,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -6702,6 +6707,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -6712,12 +6728,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/ip/usbuart/rtl/usbuart_reg_top.sv b/hw/ip/usbuart/rtl/usbuart_reg_top.sv
index 1b70d0c..ec7f13c 100644
--- a/hw/ip/usbuart/rtl/usbuart_reg_top.sv
+++ b/hw/ip/usbuart/rtl/usbuart_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1757,6 +1762,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1767,12 +1783,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
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 8172158..5f6c923 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
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -16900,6 +16905,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -16910,12 +16926,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv b/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
index a3a5fba..02be432 100644
--- a/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -2508,6 +2513,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -2518,12 +2534,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv b/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv
index e99b488..35382ad 100644
--- a/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv
+++ b/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -718,6 +723,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -728,12 +744,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_core_reg_top.sv b/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_core_reg_top.sv
index e768b89..73ff107 100644
--- a/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_core_reg_top.sv
+++ b/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_core_reg_top.sv
@@ -46,14 +46,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -77,7 +79,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [3];
@@ -106,8 +108,8 @@
.DReqDepth ({3{4'h0}}),
.DRspDepth ({3{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
@@ -136,8 +138,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -147,10 +149,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -12322,6 +12327,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -12332,12 +12348,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_prim_reg_top.sv b/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_prim_reg_top.sv
index 53c5691..65335a1 100644
--- a/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_prim_reg_top.sv
+++ b/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_prim_reg_top.sv
@@ -24,10 +24,11 @@
import flash_ctrl_reg_pkg::* ;
+
// incoming payload check
logic intg_err;
tlul_cmd_intg_chk u_chk (
- .tl_i,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -51,7 +52,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
tlul_pkg::tl_h2d_t tl_socket_h2d [0];
@@ -73,8 +74,8 @@
.DReqDepth ({0{4'h0}}),
.DRspDepth ({0{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_h_i (tl_i),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
diff --git a/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv b/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv
index 36a1897..741afa7 100644
--- a/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv
+++ b/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -25916,6 +25921,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -25926,12 +25942,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv b/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv
index b657f8e..787b243 100644
--- a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv
+++ b/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1200,6 +1205,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1210,12 +1226,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv b/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv
index f8c10c6..5021532 100644
--- a/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv
+++ b/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -993,6 +998,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1003,12 +1019,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv b/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv
index 01dd5f3..cb7d631 100644
--- a/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv
+++ b/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -23530,6 +23535,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -23540,12 +23556,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv b/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv
index e24bf41..e41bf6b 100644
--- a/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv
+++ b/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv
@@ -41,14 +41,16 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
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,
+ .tl_i(tl_i),
.err_o(intg_err)
);
@@ -72,7 +74,7 @@
.EnableDataIntgGen(1)
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(tl_o)
);
assign tl_reg_h2d = tl_i;
@@ -83,8 +85,8 @@
.RegDw(DW),
.EnableDataIntgGen(0)
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (clk_i),
+ .rst_ni (rst_ni),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -94,10 +96,13 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+ // cdc oversampling signals
+
assign reg_rdata = reg_rdata_next ;
assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
@@ -1733,6 +1738,17 @@
endcase
end
+ // register busy
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+
+
// Unused signal tieoff
// wdata / byte enable are not always fully used
@@ -1743,12 +1759,12 @@
assign unused_be = ^reg_be;
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni)
+ `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni)
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni)
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni)
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
diff --git a/util/reggen/bus_interfaces.py b/util/reggen/bus_interfaces.py
index 98ce995..32d3312 100644
--- a/util/reggen/bus_interfaces.py
+++ b/util/reggen/bus_interfaces.py
@@ -14,30 +14,36 @@
def __init__(self,
has_unnamed_host: bool,
named_hosts: List[str],
+ host_async: Dict[Optional[str], str],
has_unnamed_device: bool,
- named_devices: List[str]):
+ named_devices: List[str],
+ device_async: Dict[Optional[str], str]):
assert has_unnamed_device or named_devices
assert len(named_hosts) == len(set(named_hosts))
assert len(named_devices) == len(set(named_devices))
self.has_unnamed_host = has_unnamed_host
self.named_hosts = named_hosts
+ self.host_async = host_async
self.has_unnamed_device = has_unnamed_device
self.named_devices = named_devices
+ self.device_async = device_async
@staticmethod
def from_raw(raw: object, where: str) -> 'BusInterfaces':
has_unnamed_host = False
named_hosts = []
+ host_async = {}
has_unnamed_device = False
named_devices = []
+ device_async = {}
for idx, raw_entry in enumerate(check_list(raw, where)):
entry_what = 'entry {} of {}'.format(idx + 1, where)
ed = check_keys(raw_entry, entry_what,
['protocol', 'direction'],
- ['name'])
+ ['name', 'async'])
protocol = check_str(ed['protocol'],
'protocol field of ' + entry_what)
@@ -54,6 +60,9 @@
name = check_optional_str(ed.get('name'),
'name field of ' + entry_what)
+ async_clk = check_optional_str(ed.get('async'),
+ 'async field of ' + entry_what)
+
if direction == 'host':
if name is None:
if has_unnamed_host:
@@ -67,6 +76,9 @@
'with name {!r} at {}'
.format(name, where))
named_hosts.append(name)
+
+ if async_clk is not None:
+ host_async[name] = async_clk
else:
if name is None:
if has_unnamed_device:
@@ -81,11 +93,14 @@
.format(name, where))
named_devices.append(name)
+ if async_clk is not None:
+ device_async[name] = async_clk
+
if not (has_unnamed_device or named_devices):
raise ValueError('No device interface at ' + where)
- return BusInterfaces(has_unnamed_host, named_hosts,
- has_unnamed_device, named_devices)
+ return BusInterfaces(has_unnamed_host, named_hosts, host_async,
+ has_unnamed_device, named_devices, device_async)
def has_host(self) -> bool:
return bool(self.has_unnamed_host or self.named_hosts)
diff --git a/util/reggen/clocking.py b/util/reggen/clocking.py
index 41108fd..b2330c4 100644
--- a/util/reggen/clocking.py
+++ b/util/reggen/clocking.py
@@ -7,6 +7,7 @@
from typing import Dict, List, Optional
from .lib import check_keys, check_list, check_bool, check_optional_name
+import re
class ClockingItem:
@@ -14,12 +15,14 @@
clock: Optional[str],
reset: Optional[str],
idle: Optional[str],
- primary: bool):
+ primary: bool,
+ clock_base_name: Optional[str]):
if primary:
assert clock is not None
assert reset is not None
self.clock = clock
+ self.clock_base_name = clock_base_name
self.reset = reset
self.primary = primary
self.idle = idle
@@ -35,6 +38,15 @@
primary = check_bool(rd.get('primary', only_item),
'primary field of ' + what)
+ match = re.match(r'^clk_([A-Za-z0-9_]+)_i', str(clock))
+ if not clock or clock in ['clk_i', 'scan_clk_i']:
+ clock_base_name = ""
+ elif match:
+ clock_base_name = match.group(1)
+ else:
+ raise ValueError(f'clock name must be of the form clk_*_i or clk_i. '
+ f'{clock} is illegal.')
+
if primary:
if clock is None:
raise ValueError('No clock signal for primary '
@@ -43,7 +55,7 @@
raise ValueError('No reset signal for primary '
f'clocking item at {what}.')
- return ClockingItem(clock, reset, idle, primary)
+ return ClockingItem(clock, reset, idle, primary, clock_base_name)
def _asdict(self) -> Dict[str, object]:
ret = {} # type: Dict[str, object]
@@ -100,3 +112,15 @@
def reset_signals(self) -> List[str]:
return [item.reset for item in self.items if item.reset is not None]
+
+ def get_by_clock(self, name: Optional[str]) -> ClockingItem:
+ ret = None
+ for item in self.items:
+ if name == item.clock:
+ ret = item
+ break
+
+ if ret is None:
+ raise ValueError(f'The requested clock {name} does not exist.')
+ else:
+ return ret
diff --git a/util/reggen/ip_block.py b/util/reggen/ip_block.py
index 06d473c..9a59d3c 100644
--- a/util/reggen/ip_block.py
+++ b/util/reggen/ip_block.py
@@ -202,8 +202,6 @@
scan = check_bool(rd.get('scan', False), 'scan field of ' + what)
- reg_blocks = RegBlock.build_blocks(init_block, rd['registers'])
-
r_inter_signals = check_list(rd.get('inter_signal_list', []),
'inter_signal_list field')
inter_signals = [
@@ -224,6 +222,10 @@
clocking = Clocking.from_raw(rd['clocking'],
'clocking field of ' + what)
+ reg_blocks = RegBlock.build_blocks(init_block, rd['registers'],
+ bus_interfaces,
+ clocking)
+
xputs = (
Signal.from_raw_list('available_inout_list for block ' + name,
rd.get('available_inout_list', [])),
diff --git a/util/reggen/multi_register.py b/util/reggen/multi_register.py
index 1963bd4..004bd26 100644
--- a/util/reggen/multi_register.py
+++ b/util/reggen/multi_register.py
@@ -5,6 +5,7 @@
from typing import Dict, List
from reggen import register
+from .clocking import Clocking
from .field import Field
from .lib import check_keys, check_str, check_name, check_bool
from .params import ReggenParams
@@ -38,7 +39,13 @@
'compact': [
'pb', "If true, allow multireg compacting."
"If false, do not compact."
- ]
+ ],
+ 'cdc': [
+ 's',
+ "indicates the register must cross to a different "
+ "clock domain before use. The value shown here "
+ "should correspond to one of the module's clocks."
+ ],
})
@@ -48,7 +55,8 @@
addrsep: int,
reg_width: int,
params: ReggenParams,
- raw: object):
+ raw: object,
+ clocks: Clocking):
super().__init__(offset)
rd = check_keys(raw, 'multireg',
@@ -64,7 +72,12 @@
reg_rd = {key: value
for key, value in rd.items()
if key in reg_allowed_keys}
- self.reg = Register.from_raw(reg_width, offset, params, reg_rd)
+ self.reg = Register.from_raw(reg_width, offset, params, reg_rd, clocks)
+
+ # The entire multi-reg block is always on the same clock
+ # This is guaranteed by design
+ self.async_name = self.reg.async_name
+ self.async_clk = self.reg.async_clk
self.cname = check_name(rd['cname'],
'cname field of multireg {}'
diff --git a/util/reggen/reg_block.py b/util/reggen/reg_block.py
index fa9d3c4..b75415d 100644
--- a/util/reggen/reg_block.py
+++ b/util/reggen/reg_block.py
@@ -9,6 +9,8 @@
from .alert import Alert
from .access import SWAccess, HWAccess
+from .bus_interfaces import BusInterfaces
+from .clocking import Clocking, ClockingItem
from .field import Field
from .signal import Signal
from .lib import check_int, check_list, check_str_dict, check_str
@@ -25,6 +27,8 @@
self._reg_width = reg_width
self._params = params
+ self.name = "" # type: str
+ self.clocks = {} # type: Dict[str, ClockingItem]
self.offset = 0
self.multiregs = [] # type: List[MultiRegister]
self.registers = [] # type: List[Register]
@@ -57,9 +61,14 @@
# A list of all write enable names
self.wennames = [] # type: List[str]
+ # Boolean indication that the block is fully asynchronous
+ self.async_if = False
+
@staticmethod
def build_blocks(block: 'RegBlock',
- raw: object) -> Dict[Optional[str], 'RegBlock']:
+ raw: object,
+ bus: BusInterfaces,
+ clocks: Clocking) -> Dict[Optional[str], 'RegBlock']:
'''Build a dictionary of blocks for a 'registers' field in the hjson
There are two different syntaxes we might see here. The simple syntax
@@ -76,7 +85,10 @@
'''
if isinstance(raw, list):
# This is the simple syntax
- block.add_raw_registers(raw, 'registers field at top-level')
+ block.add_raw_registers(raw,
+ 'registers field at top-level',
+ clocks,
+ bus.device_async.get(None))
return {None: block}
# This is the more complicated syntax
@@ -101,22 +113,38 @@
block.add_raw_registers(rb_val,
'item {} of the registers '
'dictionary at top-level'
- .format(idx + 1))
+ .format(idx + 1),
+ clocks,
+ bus.device_async.get(r_key))
block.validate()
assert rb_key not in ret
+ block.name = rb_key
ret[rb_key] = block
return ret
- def add_raw_registers(self, raw: object, what: str) -> None:
+ def add_raw_registers(self,
+ raw: object,
+ what: str,
+ clocks: Clocking,
+ async_if: Optional[str]) -> None:
+
+ # the interface is fully asynchronous
+ if async_if:
+ self.async_if = True
+ self.clocks[async_if] = clocks.get_by_clock(async_if)
+
rl = check_list(raw, 'registers field at top-level')
for entry_idx, entry_raw in enumerate(rl):
where = ('entry {} of the top-level registers field'
.format(entry_idx + 1))
- self.add_raw(where, entry_raw)
+ self.add_raw(where, entry_raw, clocks)
- def add_raw(self, where: str, raw: object) -> None:
+ def add_raw(self,
+ where: str,
+ raw: object,
+ clocks: Clocking) -> None:
entry = check_str_dict(raw, where)
handlers = {
@@ -151,14 +179,49 @@
entry_where = ('At offset {:#x}, {}, type {!r}'
.format(self.offset, where, entry_type))
- handlers[entry_type](entry_where, entry_body)
+ handlers[entry_type](entry_where, entry_body, clocks)
- def _handle_register(self, where: str, body: object) -> None:
+ def _validate_async(self, name: Optional[str], clk: object) -> None:
+ '''Check for async definition consistency
+
+ If a reg block is marked fully asynchronous through its bus interface,
+ its register definition cannot also mark individual registers with
+ asynchronous designations.
+
+ The two asynchronous regfile schemes are mutually exclusive.
+ '''
+
+ if self.name:
+ block_name = self.name
+ else:
+ block_name = "Default"
+
+ if self.async_if and name:
+ raise ValueError(f'''
+ {block_name} register block has incompatible async definitions.
+ The corresponding device interface is marked fully async, however
+ there are individual registers that also contain the async_clk
+ designation, this is not allowed.
+
+ Either remove all register async_clk designations, or remove
+ async designation of the bus interface.
+ ''')
+
+ # If there is an asynchronous clock defined, then the clock must be a
+ # valid clocking item
+ if name:
+ assert isinstance(clk, ClockingItem)
+ self.clocks[name] = clk
+
+ def _handle_register(self, where: str, body: object, clocks: Clocking) -> None:
reg = Register.from_raw(self._reg_width,
- self.offset, self._params, body)
+ self.offset, self._params, body, clocks)
+
+ self._validate_async(reg.async_name, reg.async_clk)
+
self.add_register(reg)
- def _handle_reserved(self, where: str, body: object) -> None:
+ def _handle_reserved(self, where: str, body: object, clocks: Optional[Clocking]) -> None:
nreserved = check_int(body, 'body of ' + where)
if nreserved <= 0:
raise ValueError('Reserved count in {} is {}, '
@@ -167,7 +230,7 @@
self.offset += self._addrsep * nreserved
- def _handle_skipto(self, where: str, body: object) -> None:
+ def _handle_skipto(self, where: str, body: object, clocks: Optional[Clocking]) -> None:
skipto = check_int(body, 'body of ' + where)
if skipto < self.offset:
raise ValueError('Destination of skipto in {} is {:#x}, '
@@ -179,7 +242,7 @@
.format(where, skipto, self._addrsep))
self.offset = skipto
- def _handle_window(self, where: str, body: object) -> None:
+ def _handle_window(self, where: str, body: object, clocks: Optional[Clocking]) -> None:
window = Window.from_raw(self.offset,
self._reg_width, self._params, body)
if window.name is not None:
@@ -191,9 +254,14 @@
self.name_to_offset[lname]))
self.add_window(window)
- def _handle_multireg(self, where: str, body: object) -> None:
+ def _handle_multireg(self, where: str, body: object, clocks: Clocking) -> None:
mr = MultiRegister(self.offset,
- self._addrsep, self._reg_width, self._params, body)
+ self._addrsep, self._reg_width, self._params, body,
+ clocks)
+
+ # validate async schemes
+ self._validate_async(mr.async_name, mr.async_clk)
+
for reg in mr.regs:
lname = reg.name.lower()
if lname in self.name_to_offset:
@@ -344,6 +412,8 @@
reg = Register(self.offset,
reg_name,
reg_desc,
+ async_name="",
+ async_clk=None,
hwext=is_testreg,
hwqe=is_testreg,
hwre=False,
diff --git a/util/reggen/reg_top.sv.tpl b/util/reggen/reg_top.sv.tpl
index aa29048..b9d9d34 100644
--- a/util/reggen/reg_top.sv.tpl
+++ b/util/reggen/reg_top.sv.tpl
@@ -9,6 +9,7 @@
from reggen.lib import get_basename
from reggen.register import Register
from reggen.multi_register import MultiRegister
+ from reggen.bits import Bits
num_wins = len(rb.windows)
num_wins_width = ((num_wins+1).bit_length()) - 1
@@ -42,12 +43,28 @@
common_data_intg_gen = 0 if rb.has_data_intg_passthru else 1
adapt_data_intg_gen = 1 if rb.has_data_intg_passthru else 0
assert common_data_intg_gen != adapt_data_intg_gen
+
+ # declare a fully asynchronous interface
+ reg_clk_expr = "clk_i"
+ reg_rst_expr = "rst_ni"
+ tl_h2d_expr = "tl_i"
+ tl_d2h_expr = "tl_o"
+ if rb.async_if:
+ tl_h2d_expr = "tl_async_h2d"
+ tl_d2h_expr = "tl_async_d2h"
+ for clock in rb.clocks.values():
+ reg_clk_expr = clock.clock
+ reg_rst_expr = clock.reset
%>
`include "prim_assert.sv"
module ${mod_name} (
input clk_i,
input rst_ni,
+% for clock in rb.clocks.values():
+ input ${clock.clock},
+ input ${clock.reset},
+% endfor
input tlul_pkg::tl_h2d_t tl_i,
output tlul_pkg::tl_d2h_t tl_o,
@@ -94,21 +111,40 @@
logic addrmiss, wr_err;
logic [DW-1:0] reg_rdata_next;
+ logic reg_busy;
tlul_pkg::tl_h2d_t tl_reg_h2d;
tlul_pkg::tl_d2h_t tl_reg_d2h;
% endif
+ % if rb.async_if:
+ tlul_pkg::tl_h2d_t tl_async_h2d;
+ tlul_pkg::tl_d2h_t tl_async_d2h;
+ tlul_fifo_async #(
+ .ReqDepth(2),
+ .RspDepth(2)
+ ) u_if_sync (
+ .clk_h_i(clk_i),
+ .rst_h_ni(rst_ni),
+ .clk_d_i(${reg_clk_expr}),
+ .rst_d_ni(${reg_rst_expr}),
+ .tl_h_i(tl_i),
+ .tl_h_o(tl_o),
+ .tl_d_o(${tl_h2d_expr}),
+ .tl_d_i(${tl_d2h_expr})
+ );
+ % endif
+
// incoming payload check
logic intg_err;
tlul_cmd_intg_chk u_chk (
- .tl_i,
+ .tl_i(${tl_h2d_expr}),
.err_o(intg_err)
);
logic intg_err_q;
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
+ always_ff @(posedge ${reg_clk_expr} or negedge ${reg_rst_expr}) begin
+ if (!${reg_rst_expr}) begin
intg_err_q <= '0;
end else if (intg_err) begin
intg_err_q <= 1'b1;
@@ -126,17 +162,17 @@
.EnableDataIntgGen(${common_data_intg_gen})
) u_rsp_intg_gen (
.tl_i(tl_o_pre),
- .tl_o
+ .tl_o(${tl_d2h_expr})
);
% if num_dsp == 1:
## Either no windows (and just registers) or no registers and only
## one window.
% if num_wins == 0:
- assign tl_reg_h2d = tl_i;
+ assign tl_reg_h2d = ${tl_h2d_expr};
assign tl_o_pre = tl_reg_d2h;
% else:
- assign tl_win_o = tl_i;
+ assign tl_win_o = ${tl_h2d_expr};
assign tl_o_pre = tl_win_i;
% endif
% else:
@@ -183,9 +219,9 @@
.DReqDepth ({${num_dsp}{4'h0}}),
.DRspDepth ({${num_dsp}{4'h0}})
) u_socket (
- .clk_i,
- .rst_ni,
- .tl_h_i (tl_i),
+ .clk_i (${reg_clk_expr}),
+ .rst_ni (${reg_rst_expr}),
+ .tl_h_i (${tl_h2d_expr}),
.tl_h_o (tl_o_pre),
.tl_d_o (tl_socket_h2d),
.tl_d_i (tl_socket_d2h),
@@ -202,12 +238,12 @@
base_addr = w.offset
limit_addr = w.offset + w.size_in_bytes
- hi_check = 'tl_i.a_address[AW-1:0] < {}'.format(limit_addr)
+ hi_check = f'{tl_h2d_expr}.a_address[AW-1:0] < {limit_addr}'
addr_checks = []
if base_addr > 0:
- addr_checks.append('tl_i.a_address[AW-1:0] >= {}'.format(base_addr))
+ addr_checks.append(f'{tl_h2d_expr}.a_address[AW-1:0] >= {base_addr}')
if limit_addr < 2**addr_width:
- addr_checks.append('tl_i.a_address[AW-1:0] < {}'.format(limit_addr))
+ addr_checks.append(f'{tl_h2d_expr}.a_address[AW-1:0] < {limit_addr}')
addr_test = ' && '.join(addr_checks)
%>\
@@ -231,8 +267,8 @@
.RegDw(DW),
.EnableDataIntgGen(${adapt_data_intg_gen})
) u_reg_if (
- .clk_i,
- .rst_ni,
+ .clk_i (${reg_clk_expr}),
+ .rst_ni (${reg_rst_expr}),
.tl_i (tl_reg_h2d),
.tl_o (tl_reg_d2h),
@@ -242,10 +278,32 @@
.addr_o (reg_addr),
.wdata_o (reg_wdata),
.be_o (reg_be),
+ .busy_i (reg_busy),
.rdata_i (reg_rdata),
.error_i (reg_error)
);
+% if not rb.async_if:
+ // cdc oversampling signals
+ % for clock in rb.clocks.values():
+ <%
+ clk_name = clock.clock_base_name
+ tgl_expr = clk_name + "_tgl"
+ cname = clock.clock
+ rname = clock.reset
+ %>\
+ logic sync_${clk_name}_update;
+ prim_pulse_sync u_${tgl_expr} (
+ .clk_src_i(${cname}),
+ .rst_src_ni(${rname}),
+ .src_pulse_i(1'b1),
+ .clk_dst_i(${reg_clk_expr}),
+ .rst_dst_ni(${reg_rst_expr}),
+ .dst_pulse_o(sync_${clk_name}_update)
+ );
+ % endfor
+% endif
+
% if block.expose_reg_if:
assign reg2hw.reg_if.reg_we = reg_we;
assign reg2hw.reg_if.reg_re = reg_re;
@@ -267,7 +325,7 @@
fld_suff = '_' + f.name.lower() if len(r.fields) > 1 else ''
sig_name = r.name.lower() + fld_suff
%>\
-${field_sig_decl(f, sig_name, r.hwext, r.shadowed)}\
+${field_sig_decl(f, sig_name, r.hwext, r.shadowed, r.async_clk)}\
% endfor
% endfor
@@ -401,6 +459,35 @@
end
endcase
end
+
+ // register busy
+ % if rb.async_if:
+ assign reg_busy = '0;
+ % else:
+ always_comb begin
+ reg_busy = '0;
+ unique case (1'b1)
+ % for i, r in enumerate(regs_flat):
+ % if r.async_clk and len(r.fields) == 1:
+ addr_hit[${i}]: begin
+ reg_busy = ${r.name.lower() + "_busy"};
+ end
+ % elif r.async_clk:
+ addr_hit[${i}]: begin
+ reg_busy =
+ % for f in r.fields:
+ ${r.name.lower() + "_" + f.name.lower() + "_busy"}${";" if loop.last else " |"}
+ % endfor
+ end
+ % endif
+ % endfor
+ default: begin
+ reg_busy = '0;
+ end
+ endcase
+ end
+ % endif
+
% endif
// Unused signal tieoff
@@ -420,12 +507,12 @@
% if rb.all_regs:
// Assertions for Register Interface
- `ASSERT_PULSE(wePulse, reg_we)
- `ASSERT_PULSE(rePulse, reg_re)
+ `ASSERT_PULSE(wePulse, reg_we, ${reg_clk_expr}, !${reg_rst_expr})
+ `ASSERT_PULSE(rePulse, reg_re, ${reg_clk_expr}, !${reg_rst_expr})
- `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o.d_valid)
+ `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, ${reg_clk_expr}, !${reg_rst_expr})
- `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit))
+ `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), ${reg_clk_expr}, !${reg_rst_expr})
// this is formulated as an assumption such that the FPV testbenches do disprove this
// property by mistake
@@ -453,13 +540,16 @@
logic ${reg.name.lower()}_we;
% endif
</%def>\
-<%def name="field_sig_decl(field, sig_name, hwext, shadowed)">\
+<%def name="field_sig_decl(field, sig_name, hwext, shadowed, async_clk)">\
% if field.swaccess.allows_read():
logic ${str_arr_sv(field.bits)}${sig_name}_qs;
% endif
% if field.swaccess.allows_write():
logic ${str_arr_sv(field.bits)}${sig_name}_wd;
% endif
+ % if async_clk:
+ logic ${str_arr_sv(Bits(0,0))}${sig_name}_busy;
+ % endif
</%def>\
<%def name="finst_gen(reg, field, finst_name, fsig_name)">\
<%
@@ -498,10 +588,27 @@
qs_expr = f'{finst_name}_qs' if field.swaccess.allows_read() else ''
%>\
+<%
+ clk_expr = reg.async_clk.clock if reg.async_clk else reg_clk_expr
+ rst_expr = reg.async_clk.reset if reg.async_clk else reg_rst_expr
+ if reg.async_clk:
+ update_expr = "sync_" + reg.async_clk.clock.strip("_iclk_")+ "_update"
+%>\
% if reg.hwext: ## if hwext, instantiate prim_subreg_ext
- prim_subreg_ext #(
+<%
+ subreg_block = "prim_subreg_ext_async" if reg.async_clk else "prim_subreg_ext"
+%>\
+ ${subreg_block} #(
.DW (${field.bits.width()})
) u_${finst_name} (
+ % if reg.async_clk:
+ .clk_src_i (${reg_clk_expr}),
+ .rst_src_ni (${reg_rst_expr}),
+ .clk_dst_i (${clk_expr}),
+ .rst_dst_ni (${rst_expr}),
+ .src_update_i (${update_expr}),
+ .src_busy_o (${finst_name}_busy),
+ % endif
.re (${re_expr}),
.we (${we_expr}),
.wd (${wd_expr}),
@@ -527,14 +634,34 @@
% if is_const_reg:
// constant-only read
assign ${finst_name}_qs = ${resval_expr};
+ % elif reg.async_clk:
+ prim_subreg_async #(
+ .DW (${field.bits.width()}),
+ .SwAccess(prim_subreg_pkg::SwAccess${field.swaccess.value[1].name.upper()}),
+ .RESVAL (${resval_expr})
+ ) u_${finst_name} (
+ .clk_src_i (${reg_clk_expr}),
+ .rst_src_ni (${reg_rst_expr}),
+ .clk_dst_i (${clk_expr}),
+ .rst_dst_ni (${rst_expr}),
+ .src_update_i (${update_expr}),
+ .src_we_i (${we_expr}),
+ .src_wd_i (${wd_expr}),
+ .dst_de_i (${de_expr}),
+ .dst_d_i (${d_expr}),
+ .src_busy_o (${finst_name}_busy),
+ .src_qs_o (${qs_expr}),
+ .dst_qe_o (${qe_expr}),
+ .q (${q_expr})
+ );
% else:
${subreg_block} #(
.DW (${field.bits.width()}),
.SwAccess(prim_subreg_pkg::SwAccess${field.swaccess.value[1].name.upper()}),
.RESVAL (${resval_expr})
) u_${finst_name} (
- .clk_i (clk_i),
- .rst_ni (rst_ni),
+ .clk_i (${reg_clk_expr}),
+ .rst_ni (${reg_rst_expr}),
// from register interface
% if reg.shadowed:
@@ -594,3 +721,25 @@
reg_rdata_next[${str_bits_sv(field.bits)}] = '0;
% endif
</%def>\
+<%def name="reg_enable_gen(reg, idx)">\
+ % if reg.needs_re():
+ assign ${reg.name.lower()}_re = addr_hit[${idx}] & reg_re & !reg_error;
+ % endif
+ % if reg.needs_we():
+ assign ${reg.name.lower()}_we = addr_hit[${idx}] & reg_we & !reg_error;
+ % endif
+</%def>\
+<%def name="reg_cdc_gen(field, sig_name, hwext, shadowed, idx)">\
+<%
+ needs_wd = field.swaccess.allows_write()
+ space = '\n' if needs_wd or needs_re else ''
+%>\
+${space}\
+% if needs_wd:
+ % if field.swaccess.swrd() == SwRdAccess.RC:
+ assign ${sig_name}_wd = '1;
+ % else:
+ assign ${sig_name}_wd = reg_wdata[${str_bits_sv(field.bits)}];
+ % endif
+% endif
+</%def>\
diff --git a/util/reggen/register.py b/util/reggen/register.py
index 86cd005..537ac8c 100644
--- a/util/reggen/register.py
+++ b/util/reggen/register.py
@@ -5,6 +5,7 @@
from typing import Dict, List, Optional
from .access import SWAccess, HWAccess
+from .clocking import Clocking
from .field import Field
from .lib import (check_keys, check_str, check_name, check_bool,
check_list, check_str_list, check_int)
@@ -20,6 +21,12 @@
}
OPTIONAL_FIELDS = {
+ 'async': [
+ 's',
+ "indicates the register must cross to a different "
+ "clock domain before use. The value shown here "
+ "should correspond to one of the module's clocks."
+ ],
'swaccess': [
's',
"software access permission to use for "
@@ -82,6 +89,8 @@
offset: int,
name: str,
desc: str,
+ async_name: str,
+ async_clk: object,
hwext: bool,
hwqe: bool,
hwre: bool,
@@ -95,6 +104,8 @@
super().__init__(offset)
self.name = name
self.desc = desc
+ self.async_name = async_name
+ self.async_clk = async_clk
self.hwext = hwext
self.hwqe = hwqe
self.hwre = hwre
@@ -182,7 +193,8 @@
def from_raw(reg_width: int,
offset: int,
params: ReggenParams,
- raw: object) -> 'Register':
+ raw: object,
+ clocks: Clocking) -> 'Register':
rd = check_keys(raw, 'register',
list(REQUIRED_FIELDS.keys()),
list(OPTIONAL_FIELDS.keys()))
@@ -190,6 +202,20 @@
name = check_name(rd['name'], 'name of register')
desc = check_str(rd['desc'], 'desc for {} register'.format(name))
+ async_name = check_str(rd.get('async', ''), 'async clock for {} register'.format(name))
+ async_clk = None
+
+ if async_name:
+ valid_clocks = clocks.clock_signals()
+ if async_name not in valid_clocks:
+ raise ValueError('async clock {} defined for {} does not exist '
+ 'in valid module clocks {}.'
+ .format(async_name,
+ name,
+ valid_clocks))
+ else:
+ async_clk = clocks.get_by_clock(async_name)
+
swaccess = SWAccess('{} register'.format(name),
rd.get('swaccess', 'none'))
hwaccess = HWAccess('{} register'.format(name),
@@ -260,7 +286,7 @@
'storage_err_alert for {} register'
.format(name))
- return Register(offset, name, desc,
+ return Register(offset, name, desc, async_name, async_clk,
hwext, hwqe, hwre, regwen,
tags, resval, shadowed, fields,
update_err_alert, storage_err_alert)
@@ -380,7 +406,7 @@
# we've replicated fields).
new_resval = None
- return Register(offset, new_name, self.desc,
+ return Register(offset, new_name, self.desc, self.async_name, self.async_clk,
self.hwext, self.hwqe, self.hwre, new_regwen,
self.tags, new_resval, self.shadowed, new_fields,
self.update_err_alert, self.storage_err_alert)