[dv/sysrst_ctrl] Check z3_wakeup timing
This PR checks if `z3_wakeup` output is set at the correct timing.
Signed-off-by: Cindy Chen <chencindy@opentitan.org>
diff --git a/hw/ip/sysrst_ctrl/dv/env/seq_lib/sysrst_ctrl_ultra_low_pwr_vseq.sv b/hw/ip/sysrst_ctrl/dv/env/seq_lib/sysrst_ctrl_ultra_low_pwr_vseq.sv
index d95eb9d..81c0bfd 100644
--- a/hw/ip/sysrst_ctrl/dv/env/seq_lib/sysrst_ctrl_ultra_low_pwr_vseq.sv
+++ b/hw/ip/sysrst_ctrl/dv/env/seq_lib/sysrst_ctrl_ultra_low_pwr_vseq.sv
@@ -14,6 +14,9 @@
rand uint16_t set_pwrb_timer, set_lid_timer, set_ac_timer;
rand int pwrb_cycles, ac_cycles, lid_cycles;
rand bit en_ulp;
+ // TODO: z3_wakeup check logic could move to scb.
+ uint16_t get_ac_timer, get_pwrb_timer, get_lid_timer;
+ bit enable_ulp, exp_z3_wakeup;
constraint set_pwrb_timer_c {
set_pwrb_timer dist {
@@ -59,7 +62,10 @@
task drive_ac();
cfg.vif.ac_present = 1;
- cfg.clk_aon_rst_vif.wait_clks(ac_cycles);
+ for (int i = 0; i < ac_cycles; i++) begin
+ cfg.clk_aon_rst_vif.wait_clks(1);
+ if (exp_z3_wakeup == 0 && enable_ulp && i > (get_ac_timer + 1)) exp_z3_wakeup = 1;
+ end
cfg.vif.ac_present = 0;
endtask
@@ -67,7 +73,10 @@
cfg.vif.pwrb_in = 1;
cfg.clk_aon_rst_vif.wait_clks($urandom_range(1,20));
cfg.vif.pwrb_in = 0;
- cfg.clk_aon_rst_vif.wait_clks(pwrb_cycles);
+ for (int i = 0; i < pwrb_cycles; i++) begin
+ cfg.clk_aon_rst_vif.wait_clks(1);
+ if (exp_z3_wakeup == 0 && enable_ulp && i > (get_pwrb_timer + 1)) exp_z3_wakeup = 1;
+ end
cfg.vif.pwrb_in = 1;
endtask
@@ -75,18 +84,31 @@
cfg.vif.lid_open = 0;
cfg.clk_aon_rst_vif.wait_clks($urandom_range(1,20));
cfg.vif.lid_open = 1;
- cfg.clk_aon_rst_vif.wait_clks(lid_cycles);
+ for (int i = 0; i < lid_cycles; i++) begin
+ cfg.clk_aon_rst_vif.wait_clks(1);
+ if (exp_z3_wakeup == 0 && enable_ulp && i > (get_lid_timer + 1)) exp_z3_wakeup = 1;
+ end
cfg.vif.lid_open = 0;
endtask
+ virtual task check_z3_wkup_nonblocking();
+ fork
+ forever begin
+ @(posedge cfg.vif.z3_wakeup);
+ cfg.clk_aon_rst_vif.wait_n_clks(1);
+ `DV_CHECK(exp_z3_wakeup, 1)
+ end
+ join_none;
+ endtask
+
task body();
uvm_reg_data_t rdata, wkup_sts_rdata;
- uint16_t get_ac_timer, get_pwrb_timer, get_lid_timer;
- bit enable_ulp;
`uvm_info(`gfn, "Starting the body from ultra_low_pwr_vseq", UVM_LOW)
+ check_z3_wkup_nonblocking();
+
repeat (num_trans) begin
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(en_ulp)
@@ -99,6 +121,12 @@
csr_wr(ral.ulp_lid_debounce_ctl, set_lid_timer);
csr_wr(ral.ulp_pwrb_debounce_ctl, set_pwrb_timer);
+ csr_rd(ral.ulp_ac_debounce_ctl, get_ac_timer);
+ csr_rd(ral.ulp_pwrb_debounce_ctl, get_pwrb_timer);
+ csr_rd(ral.ulp_lid_debounce_ctl, get_lid_timer);
+ csr_rd(ral.ulp_ctl, rdata);
+ enable_ulp = get_field_val(ral.ulp_ctl.ulp_enable, rdata);
+
// Disable the bus clock
cfg.clk_rst_vif.stop_clk();
@@ -134,12 +162,6 @@
// Enable the bus clock to read the status register
cfg.clk_rst_vif.start_clk();
- csr_rd(ral.ulp_ac_debounce_ctl, get_ac_timer);
- csr_rd(ral.ulp_pwrb_debounce_ctl, get_pwrb_timer);
- csr_rd(ral.ulp_lid_debounce_ctl, get_lid_timer);
- csr_rd(ral.ulp_ctl, rdata);
- enable_ulp = get_field_val(ral.ulp_ctl.ulp_enable, rdata);
-
`uvm_info(`gfn, {$sformatf("enable_ulp=%0b, pwrb_cycles=%0d, pwrb_timer=%0d",
enable_ulp, pwrb_cycles, get_pwrb_timer),
$sformatf("ac_cycles=%0d, get_ac_timer=%0d", ac_cycles, get_ac_timer),
@@ -175,10 +197,16 @@
// Clear the wkup_status register
csr_wr(ral.wkup_status, 'h1);
cfg.clk_aon_rst_vif.wait_clks(20);
+
// Check if the register is cleared
csr_rd_check(ral.wkup_status, .compare_value(0));
+
+ // Check z3_wakeup reset back to 0
+ `DV_CHECK_EQ(cfg.vif.z3_wakeup, 0);
+ exp_z3_wakeup = 0;
end else begin
`DV_CHECK_EQ(cfg.vif.z3_wakeup, 0);
+ `DV_CHECK_EQ(exp_z3_wakeup, 0);
csr_rd(ral.wkup_status,wkup_sts_rdata);
csr_rd_check(ral.wkup_status, .compare_value(0));
csr_rd_check(ral.ulp_status, .compare_value(0));