[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));