pwrmgr,dv] v2s_review_ready
Signed-off-by: Jaedon Kim <jdonjdon@google.com>
diff --git a/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_agent_pkg.sv b/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_agent_pkg.sv
index be40251..5152240 100644
--- a/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_agent_pkg.sv
+++ b/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_agent_pkg.sv
@@ -13,7 +13,10 @@
`include "dv_macros.svh"
// parameters
-
+ parameter uint MAIN_CLK_DELAY_MIN = 15; // cycle of aon clk
+ parameter uint MAIN_CLK_DELAY_MAX = 258; // cycle of aon clk
+ parameter uint ESC_CLK_DELAY_MIN = 1; // cycle of aon clk
+ parameter uint ESC_CLK_DELAY_MAX = 10; // cycle of aon clk
// local types
// forward declare classes to allow typedefs below
typedef class pwrmgr_clk_ctrl_item;
diff --git a/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_monitor.sv b/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_monitor.sv
index 747bb5c..052d5c1 100644
--- a/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_monitor.sv
+++ b/hw/dv/sv/pwrmgr_clk_ctrl_agent/pwrmgr_clk_ctrl_monitor.sv
@@ -44,7 +44,7 @@
if (cfg.vif.pwr_ast_req.io_clk_en == 0) begin
cfg.clk_rst_vif.stop_clk();
@(posedge cfg.vif.pwr_ast_req.io_clk_en);
- #($urandom_range(300_000, 5_152_286) * 1ps);
+ repeat ($urandom_range(MAIN_CLK_DELAY_MIN, MAIN_CLK_DELAY_MAX)) @cfg.vif.cb;
cfg.clk_rst_vif.start_clk();
end
end
@@ -56,12 +56,12 @@
@cfg.vif.cb;
if (ival) begin
@(negedge cfg.vif.pwr_clk_req.io_ip_clk_en);
- repeat($urandom_range(1, 10)) @cfg.vif.cb;
+ repeat($urandom_range(ESC_CLK_DELAY_MIN, ESC_CLK_DELAY_MAX)) @cfg.vif.cb;
cfg.esc_clk_rst_vif.stop_clk();
ival = 0;
end else begin
@(posedge cfg.vif.pwr_clk_req.io_ip_clk_en);
- repeat($urandom_range(1, 10)) @cfg.vif.cb;
+ repeat($urandom_range(ESC_CLK_DELAY_MIN, ESC_CLK_DELAY_MAX)) @cfg.vif.cb;
cfg.esc_clk_rst_vif.start_clk();
ival = 1;
end
diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv
index 1853c20..77aa6e3 100644
--- a/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv
+++ b/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv
@@ -28,6 +28,12 @@
// parameters
parameter int NUM_INTERRUPTS = 1;
+ // clk enable disable delay
+ parameter uint MAIN_CLK_DELAY_MIN = pwrmgr_clk_ctrl_agent_pkg::MAIN_CLK_DELAY_MIN;
+ parameter uint MAIN_CLK_DELAY_MAX = pwrmgr_clk_ctrl_agent_pkg::MAIN_CLK_DELAY_MAX;
+ parameter uint ESC_CLK_DELAY_MIN = pwrmgr_clk_ctrl_agent_pkg::ESC_CLK_DELAY_MIN;
+ parameter uint ESC_CLK_DELAY_MAX = pwrmgr_clk_ctrl_agent_pkg::ESC_CLK_DELAY_MAX;
+
// alerts
parameter uint NUM_ALERTS = 1;
parameter string LIST_OF_ALERTS[] = {"fatal_fault"};
diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv
index c073823..8c97156 100644
--- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv
+++ b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv
@@ -15,15 +15,23 @@
virtual task body();
for (int i = 0; i < num_trans; ++i) begin
wait_for_fast_fsm_active();
- cfg.pwrmgr_vif.glitch_power_reset();
+
+ fork
+ cfg.pwrmgr_vif.glitch_power_reset();
+ begin
+ cfg.pwrmgr_vif.update_ast_main_pok(0);
+ cfg.slow_clk_rst_vif.wait_clks(2);
+ cfg.pwrmgr_vif.update_ast_main_pok(1);
+ end
+ join
cfg.clk_rst_vif.wait_clks(cycles_before_reset);
`DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateResetPrep &&
- cfg.pwrmgr_vif.pwr_rst_req.rstreqs[2] == 1);
- dut_init();,
+ cfg.pwrmgr_vif.pwr_rst_req.rstreqs[2] == 1);,
$sformatf("checker timeout : fast_state %s, pwr_rst_req 0x%x",
cfg.pwrmgr_vif.fast_state.name,
cfg.pwrmgr_vif.pwr_rst_req.rstreqs),
10000)
+ dut_init();
end
endtask : body
endclass
diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv
index 3f0e418..3d6a34b 100644
--- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv
+++ b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Description:
-// The reset test randomly introduces external resets, power glitches, and escalation resets.
+// The reset test randomly introduces external resets.
class pwrmgr_sw_reset_vseq extends pwrmgr_base_vseq;
`uvm_object_utils(pwrmgr_sw_reset_vseq)
@@ -12,6 +12,7 @@
constraint wakeups_en_c {wakeups_en == 0;}
task body();
+ int exp_rst;
wait_for_fast_fsm_active();
check_reset_status('0);
@@ -23,9 +24,15 @@
setup_interrupt(.enable(en_intr));
cfg.pwrmgr_vif.sw_rst_req_i = $urandom_range(0,15);
-
+ exp_rst = (cfg.pwrmgr_vif.sw_rst_req_i == prim_mubi_pkg::MuBi4True);
cfg.slow_clk_rst_vif.wait_clks(4);
+ // sw reset causes fast state machine transition to lowpower state
+ if (exp_rst == 1) begin
+ `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive);,
+ "timeout waiting for non fast-active state",1000)
+ end
+
// This read is not always possible since the CPU may be off.
wait(cfg.pwrmgr_vif.pwr_clk_req.main_ip_clk_en == 1'b1);
diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv
index 7cd0e0a..b5282f2 100644
--- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv
+++ b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv
@@ -84,11 +84,11 @@
// Wait for the slow state machine to be in low power.
wait(cfg.pwrmgr_vif.slow_state == pwrmgr_pkg::SlowPwrStateLowPower);
-
// This will send the wakeup and reset so they almost coincide.
+ // at low power state, do not use clk_rst_vif, cause it is off.
fork
begin
- cfg.clk_rst_vif.wait_clks(cycles_before_reset);
+ cfg.aon_clk_rst_vif.wait_clks(cycles_before_reset);
cfg.pwrmgr_vif.update_resets(resets);
if (power_glitch_reset) begin
`uvm_info(`gfn, "Sending power glitch", UVM_MEDIUM)
@@ -103,7 +103,7 @@
), UVM_MEDIUM)
end
begin
- cfg.clk_rst_vif.wait_clks(cycles_before_wakeup);
+ cfg.aon_clk_rst_vif.wait_clks(cycles_before_wakeup);
cfg.pwrmgr_vif.update_wakeups(wakeups);
`uvm_info(`gfn, $sformatf("Sending wakeup=%b", wakeups), UVM_MEDIUM)
end
@@ -116,9 +116,12 @@
// so we fork them to avoid conflicts.
fork
begin
- cfg.slow_clk_rst_vif.wait_clks(4);
+ // At lowpower state, wait for clock comes back before check any csr
+ @cfg.clk_rst_vif.cb;
+ cfg.slow_clk_rst_vif.wait_clks(3);
// Check wake_status prior to wakeup, or the unit requesting wakeup will have been reset.
// This read will not work in the chip, since the processor will be asleep.
+
check_wake_status(enabled_wakeups);
`uvm_info(`gfn, $sformatf("Got wake_status=0x%x", enabled_wakeups), UVM_MEDIUM)
check_reset_status(enabled_resets);
diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv
index 6a01483..64f7f35 100644
--- a/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv
+++ b/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv
@@ -57,7 +57,10 @@
.clk_i,
.rst_ni,
.rom_intg_chk_dis(u_fsm.rom_intg_chk_dis),
+ .rom_intg_chk_ok(u_fsm.rom_intg_chk_ok),
.lc_dft_en_i,
- .lc_hw_debug_en_i
+ .lc_hw_debug_en_i,
+ .rom_ctrl_done_i(u_fsm.rom_ctrl_done_i),
+ .rom_ctrl_good_i(u_fsm.rom_ctrl_good_i)
);
endmodule
diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core b/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core
index 1ebf70c..79c176d 100644
--- a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core
+++ b/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core
@@ -8,6 +8,7 @@
files_dv:
depend:
- lowrisc:ip:pwrmgr_pkg
+ - lowrisc:dv:pwrmgr_clk_ctrl_agent
files:
- pwrmgr_rstmgr_sva_if.sv
file_type: systemVerilogSource
diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv
index 0ec5a02..481ef77 100644
--- a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv
+++ b/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv
@@ -7,6 +7,7 @@
// these assertions will also be useful at full chip level.
interface pwrmgr_rstmgr_sva_if
import pwrmgr_pkg::*, pwrmgr_reg_pkg::NumRstReqs;
+ import pwrmgr_clk_ctrl_agent_pkg::*;
(
input logic clk_i,
input logic rst_ni,
@@ -40,6 +41,15 @@
localparam int MAX_RST_CYCLES = 4;
`define RST_CYCLES ##[MIN_RST_CYCLES:MAX_RST_CYCLES]
+ // output reset cycle with a clk enalbe disable
+ localparam int MIN_MAIN_RST_CYCLES = 0;
+ localparam int MAX_MAIN_RST_CYCLES = pwrmgr_clk_ctrl_agent_pkg::MAIN_CLK_DELAY_MAX;
+ `define MAIN_RST_CYCLES ##[MIN_MAIN_RST_CYCLES:MAX_MAIN_RST_CYCLES]
+
+ localparam int MIN_ESC_RST_CYCLES = 0;
+ localparam int MAX_ESC_RST_CYCLES = pwrmgr_clk_ctrl_agent_pkg::ESC_CLK_DELAY_MAX;
+ `define ESC_RST_CYCLES ##[MIN_ESC_RST_CYCLES:MAX_ESC_RST_CYCLES]
+
bit disable_sva;
bit reset_or_disable;
@@ -89,11 +99,11 @@
`ASSERT(HwResetOn_A,
$rose(
rstreqs_i[rst] && reset_en[rst]
- ) |-> `RST_CYCLES rstreqs[rst], clk_slow_i, reset_or_disable || !check_rstreqs_en)
+ ) |-> `MAIN_RST_CYCLES rstreqs[rst], clk_slow_i, reset_or_disable || !check_rstreqs_en)
`ASSERT(HwResetOff_A,
$fell(
rstreqs_i[rst] && reset_en[rst]
- ) |-> `RST_CYCLES !rstreqs[rst], clk_slow_i, reset_or_disable || !check_rstreqs_en)
+ ) |-> `MAIN_RST_CYCLES !rstreqs[rst], clk_slow_i, reset_or_disable || !check_rstreqs_en)
end
// This is used to ignore main_rst_req_i (wired to rst_main_n) if it happens during low power,
@@ -112,23 +122,26 @@
`ASSERT(MainPwrRstOn_A,
$rose(
main_rst_req_i && !rst_main_n_ignored_for_main_pwr_rst
- ) |-> `RST_CYCLES rstreqs[ResetMainPwrIdx], clk_slow_i,
+ ) |-> `MAIN_RST_CYCLES rstreqs[ResetMainPwrIdx], clk_slow_i,
reset_or_disable || !check_rstreqs_en)
`ASSERT(MainPwrRstOff_A,
$fell(
main_rst_req_i
- ) |-> `RST_CYCLES !rstreqs[ResetMainPwrIdx], clk_slow_i,
+ ) |-> `MAIN_RST_CYCLES !rstreqs[ResetMainPwrIdx], clk_slow_i,
reset_or_disable || !check_rstreqs_en)
`ASSERT(EscRstOn_A,
$rose(
esc_rst_req_i
- ) |-> `RST_CYCLES rstreqs[ResetEscIdx], clk_slow_i, reset_or_disable || !check_rstreqs_en)
+ ) |-> `ESC_RST_CYCLES rstreqs[ResetEscIdx], clk_slow_i,
+ reset_or_disable || !check_rstreqs_en)
`ASSERT(EscRstOff_A,
$fell(
esc_rst_req_i
- ) |-> `RST_CYCLES !rstreqs[ResetEscIdx], clk_slow_i,
+ ) |-> `ESC_RST_CYCLES !rstreqs[ResetEscIdx], clk_slow_i,
reset_or_disable || !check_rstreqs_en)
// Software initiated resets are not sent to rstmgr since they originated there.
`undef RST_CYCLES
+ `undef MAIN_RST_CYCLES
+ `undef ESC_RST_CYCLES
endinterface
diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv
index a29f98d..922bc6a 100644
--- a/hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv
+++ b/hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv
@@ -7,8 +7,11 @@
input clk_i,
input rst_ni,
input prim_mubi_pkg::mubi4_t rom_intg_chk_dis,
+ input prim_mubi_pkg::mubi4_t rom_intg_chk_ok,
input lc_ctrl_pkg::lc_tx_t lc_dft_en_i,
- input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i
+ input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i,
+ input prim_mubi_pkg::mubi4_t rom_ctrl_done_i,
+ input prim_mubi_pkg::mubi4_t rom_ctrl_good_i
);
bit disable_sva;
@@ -16,15 +19,44 @@
always_comb reset_or_disable = !rst_ni || disable_sva;
+`define ASYNC_ASSERT(_name, _prop, _sigs, _rst) \
+ _name: assert property (@(_sigs) disable iff ((_rst) !== '0) (_prop)) \
+ else begin\
+ `ASSERT_ERROR(_name)\
+ end
// Assuming lc_dft_en_i and lc_hw_debug_en_i are asynchronous
- `ASSERT(RomIntgChkDisTrue_A,
- rom_intg_chk_dis == prim_mubi_pkg::MuBi4True |=>
- (lc_dft_en_i == lc_ctrl_pkg::On && lc_hw_debug_en_i == lc_ctrl_pkg::On),
- rom_intg_chk_dis, reset_or_disable)
+ // rom_intg_chk_dis only allows two states.
+ `ASYNC_ASSERT(RomIntgChkDisTrue_A,
+ rom_intg_chk_dis == prim_mubi_pkg::MuBi4True |->
+ (lc_dft_en_i == lc_ctrl_pkg::On && lc_hw_debug_en_i == lc_ctrl_pkg::On),
+ rom_intg_chk_dis or lc_dft_en_i or lc_hw_debug_en_i, reset_or_disable)
- `ASSERT(RomIntgChkDisFalse_A,
- rom_intg_chk_dis == prim_mubi_pkg::MuBi4False |=>
- (lc_dft_en_i != lc_ctrl_pkg::On || lc_hw_debug_en_i != lc_ctrl_pkg::On),
- rom_intg_chk_dis, reset_or_disable)
+ `ASYNC_ASSERT(RomIntgChkDisFalse_A,
+ rom_intg_chk_dis == prim_mubi_pkg::MuBi4False |->
+ (lc_dft_en_i != lc_ctrl_pkg::On || lc_hw_debug_en_i != lc_ctrl_pkg::On),
+ rom_intg_chk_dis or lc_dft_en_i or lc_hw_debug_en_i, reset_or_disable)
+
+ // check rom_intg_chk_ok
+ // rom_ctrl_i go through cdc. So use synchronous assertion.
+ // rom_intg_chk_ok can be any values.
+ `ASYNC_ASSERT(RomIntgChkOkTrue_A,
+ rom_intg_chk_ok == prim_mubi_pkg::MuBi4True |->
+ (rom_intg_chk_dis == prim_mubi_pkg::MuBi4True &&
+ rom_ctrl_done_i == prim_mubi_pkg::MuBi4True) ||
+ (rom_ctrl_done_i == prim_mubi_pkg::MuBi4True &&
+ rom_ctrl_good_i == prim_mubi_pkg::MuBi4True),
+ rom_intg_chk_ok or rom_intg_chk_dis or rom_ctrl_done_i or rom_ctrl_good_i,
+ reset_or_disable)
+
+ `ASYNC_ASSERT(RomIntgChkOkFalse_A,
+ rom_intg_chk_ok != prim_mubi_pkg::MuBi4True |->
+ (rom_intg_chk_dis == prim_mubi_pkg::MuBi4False ||
+ rom_ctrl_done_i != prim_mubi_pkg::MuBi4True) &&
+ (rom_ctrl_done_i != prim_mubi_pkg::MuBi4True ||
+ rom_ctrl_good_i != prim_mubi_pkg::MuBi4True),
+ rom_intg_chk_ok or rom_intg_chk_dis or rom_ctrl_done_i or rom_ctrl_good_i,
+ reset_or_disable)
+
+`undef ASYNC_ASSERT
endmodule // pwrmgr_sec_cm_checker_assert
diff --git a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson b/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson
index 7eee804..eb032c8 100644
--- a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson
+++ b/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson
@@ -78,7 +78,8 @@
- Drive tb.dut.sw_rst_req_i with mixed valid and invalid values
**Check**:
- - See sw rst only happens when dut gets valid value.
+ - See sw rst only happens when dut gets valid value by
+ probing fast fsm state. The state has to move low power state.
- Collect coverage by binding cip_mubi_cov_if to
tb.dut.sw_rst_req_i
'''
@@ -136,8 +137,8 @@
**Check**:
If slow state is invalid, fast state becomes FastPwrStateInvalid,
pwr_ast_o.pwr_clamp =1 and pwr_ast_o.main_pd_n = 0.
- If fast state is invalid, pwr_rst_o.rst_lc_req = 3,
- pwr_rst_o.rst_sys_req = 3 and pwr_clk_o = 0.
+ If fast state is invalid, pwr_rst_o.rst_lc_req is all one,
+ pwr_rst_o.rst_sys_req is all one and pwr_clk_o = 0.
Dut should be recovered by asserting rst_n = 0.
'''
milestone: V2S
@@ -162,7 +163,8 @@
desc: '''Verify the countermeasure(s) MAIN_PD.RST.LOCAL_ESC.
**Stimulus**:
- - Create power reset glitch by setting 'tb.dut.rst_main_ni' to 0.
+ - Create power reset glitch by setting tb.dut.rst_main_ni
+ and tb.dut.pwr_ast_i.main_pok to 0.
**Check**:
- Check fast state transition to FastPwrStateResetPrep
@@ -184,7 +186,7 @@
**Check**:
- After the csr update under PWRMGR.CTRL_CFG_REGWEN = 0,
read back and check the value is not updated by
- the csr udate attempt.
+ the csr update attempt.
'''
milestone: V2S
tests: ["pwrmgr_sec_cm_ctrl_config_regwen"]