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"]