[dv/rstmgr] Drive por_n_i[1] and bind SVA to chip

Set por_n_i[1] to non-zero values in unit tests.
If por_n_i[1] is always 0, a number of assertion failures are masked.
Full chip sets por_n_i[1] to non-zero values, which exposed failures.
Add missing assertions for some resets_o members.
Tighten some assertions.

Signed-off-by: Guillermo Maturana <maturana@google.com>
diff --git a/hw/ip/rstmgr/dv/env/rstmgr_if.sv b/hw/ip/rstmgr/dv/env/rstmgr_if.sv
index df298d3..a929a37 100644
--- a/hw/ip/rstmgr/dv/env/rstmgr_if.sv
+++ b/hw/ip/rstmgr/dv/env/rstmgr_if.sv
@@ -11,7 +11,7 @@
 );
 
   import rstmgr_env_pkg::*;
-  import rstmgr_pkg::*;
+  import rstmgr_pkg::PowerDomains;
 
   logic                        [PowerDomains-1:0] por_n;
 
diff --git a/hw/ip/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv b/hw/ip/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv
index 8fa2150..33e0d3b 100644
--- a/hw/ip/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv
+++ b/hw/ip/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv
@@ -246,9 +246,9 @@
   endtask
 
   task por_reset();
-    cfg.rstmgr_vif.por_n = 1'b0;
+    cfg.rstmgr_vif.por_n = '0;
     cfg.aon_clk_rst_vif.wait_clks(POR_CLK_CYCLES);
-    cfg.rstmgr_vif.por_n = 1'b1;
+    cfg.rstmgr_vif.por_n = '1;
     @(posedge cfg.rstmgr_vif.resets_o.rst_por_io_div4_n[0]);
   endtask
 
diff --git a/hw/ip/rstmgr/dv/sva/rstmgr_bind.sv b/hw/ip/rstmgr/dv/sva/rstmgr_bind.sv
index 1c78438..b6b70cc 100644
--- a/hw/ip/rstmgr/dv/sva/rstmgr_bind.sv
+++ b/hw/ip/rstmgr/dv/sva/rstmgr_bind.sv
@@ -33,6 +33,8 @@
     .clk_usb_i,
     .por_n_i,
     .resets_o,
+    .rst_lc_req(pwr_i.rst_lc_req),
+    .rst_sys_req(pwr_i.rst_sys_req),
     .rst_lc_src_n(pwr_o.rst_lc_src_n),
     .rst_sys_src_n(pwr_o.rst_sys_src_n),
     .scan_rst_ni,
diff --git a/hw/ip/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv b/hw/ip/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv
index 18a844c..87d624f 100644
--- a/hw/ip/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv
+++ b/hw/ip/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv
@@ -9,6 +9,9 @@
 // In addition, a scan reset is at the same level as por.
 //
 // Local terminology: A cascading relationship is between an "above" and a "below" reset.
+//
+// Some individual reset outputs will always be off. Allowing for this in general would
+// weaken the property that some resets MUST rise following other rise.
 interface rstmgr_cascading_sva_if (
   input logic clk_i,
   input logic clk_aon_i,
@@ -19,6 +22,8 @@
   input logic clk_usb_i,
   input [rstmgr_pkg::PowerDomains-1:0] por_n_i,
   input rstmgr_pkg::rstmgr_out_t resets_o,
+  input [rstmgr_pkg::PowerDomains-1:0] rst_lc_req,
+  input [rstmgr_pkg::PowerDomains-1:0] rst_sys_req,
   input [rstmgr_pkg::PowerDomains-1:0] rst_lc_src_n,
   input [rstmgr_pkg::PowerDomains-1:0] rst_sys_src_n,
   input logic scan_rst_ni,
@@ -48,7 +53,7 @@
   // Cycles are counted from the output rst_por_aon_n or scan reset edges. The rise times can be
   // higher since in the chip the aon reset goes through the pwrmgr slow fsm where it causes an
   // lc rise request and there may be multiple synchronizers in the path.
-  localparam edge_bounds_t LcCycles = '{fall: '{min: 0, max: 4}, rise: '{min: 2, max: 10}};
+  localparam edge_bounds_t LcCycles = '{fall: '{min: 0, max: 4}, rise: '{min: 1, max: 4}};
 
   // In the real system the rise of rst_lc_src_n is triggered by the pwr_i.rst_lc_req input,
   // which can take a few cycles since it comes from the pwrmgr after it gets reset,
@@ -56,7 +61,7 @@
   // a rise in rst_lc_src_n. There is an SVA for the rise in pwrmgr_rstmgr_sva_if.
 
   // The cycles are counted from Lc edges.
-  localparam edge_bounds_t SysCycles = '{fall: '{min: 0, max: 4}, rise: '{min: 0, max: 8}};
+  localparam edge_bounds_t SysCycles = '{fall: '{min: 0, max: 2}, rise: '{min: 1, max: 5}};
 
   // The different peripheral edges are synchronized to their respective clocks,
   // so these counts assume synchronization and are triggered on the correct clock.
@@ -65,43 +70,37 @@
   bit disable_sva;
 
   // Macros to avoid excessive boiler-plate code below.
-  `define FALL_ASSERT(name, from, to, cycles, clk) \
-    `ASSERT(name``AboveFallBelowHigh_A, \
-            $fell(from) && to |-> ##[cycles.fall.min:cycles.fall.max] $fell(to), clk, disable_sva)
+  `define FALL_ASSERT(_name, _from, _to, _cycles, _clk) \
+    `ASSERT(_name``AboveFallBelowHigh_A, \
+            $fell(_from) && _to |-> ##[_cycles.fall.min:_cycles.fall.max] $fell(_to), _clk, \
+            disable_sva)
 
-  `define RISE_ASSERTS(name, from, to, cycles, clk) \
-    `ASSERT(name``AboveRise_A, \
-            $rose(from) |-> ##[cycles.rise.min:cycles.rise.max] $rose(to), clk, disable_sva) \
-    `ASSERT(name``BelowRise_A, \
-            $rose(to) |-> from == 1'b1, clk, disable_sva)
+  `define RISE_ASSERTS(_name, _from, _to, _cycles, _clk) \
+    `ASSERT(_name``AboveRise_A, \
+            $rose(_from) |-> ##[_cycles.rise.min:_cycles.rise.max] (!_from || $rose(_to)), _clk, \
+            disable_sva) \
+    `ASSERT(_name``BelowRise_A, $rose(_to) |-> _from == 1'b1, _clk, disable_sva)
 
-  `define CASCADED_ASSERTS(name, from, to, cycles, clk) \
-      `FALL_ASSERT(name, from, to, cycles, clk) \
-      `RISE_ASSERTS(name, from, to, cycles, clk)
+  `define CASCADED_ASSERTS(_name, _from, _to, _cycles, _clk) \
+      `FALL_ASSERT(_name, _from, _to, _cycles, _clk) \
+      `RISE_ASSERTS(_name, _from, _to, _cycles, _clk)
 
   // A fall in por_n_i leads to a fall in rst_por_aon_n[0].
-  `FALL_ASSERT(CascadePorToAon, por_n_i[rstmgr_pkg::DomainAonSel], resets_o.rst_por_aon_n[0],
-               PorCycles, clk_aon_i)
+  `FALL_ASSERT(CascadePorToAon, por_n_i[rstmgr_pkg::DomainAonSel],
+               resets_o.rst_por_aon_n[rstmgr_pkg::DomainAonSel], PorCycles, clk_aon_i)
 
   // A number of consecutive cycles with por_n_i inactive (high) should cause the aon resets to
   // become inactive. This checks POR stretching.
 
-  // The antecedent: por_n_i rising and being stably high for a minimum number of cycles.
+  // The antecedent: por_n_i rising and being active for enough cycles.
   sequence PorStable_S;
     $rose(
         por_n_i[rstmgr_pkg::DomainAonSel]
-    ) ##1 por_n_i[rstmgr_pkg::DomainAonSel] [* PorCycles.rise.min];
-  endsequence
-
-  // The consequence: reset will rise after some cycles.
-  sequence EventualAonRstRise_S;
-    ##[0:PorCycles.rise.max-PorCycles.rise.min] $rose(
-        resets_o.rst_por_aon_n[0]
-    );
+    ) ##1 (por_n_i[rstmgr_pkg::DomainAonSel] [* PorCycles.rise.max]);
   endsequence
 
   // The reset stretching assertion.
-  `ASSERT(StablePorToAonRise_A, PorStable_S |-> EventualAonRstRise_S, clk_aon_i, disable_sva)
+  `ASSERT(StablePorToAonRise_A, PorStable_S |-> resets_o.rst_por_aon_n[0], clk_aon_i, disable_sva)
 
   logic scan_reset_n;
   always_comb scan_reset_n = scan_rst_ni || (scanmode_i != lc_ctrl_pkg::On);
@@ -111,53 +110,82 @@
 
   // The internal reset is triggered by one of the generated reset outputs.
   logic [rstmgr_pkg::PowerDomains-1:0] local_rst_n;
-  always_comb local_rst_n = {rstmgr_pkg::PowerDomains{resets_o.rst_por_io_div4_n[0]}};
+  always_comb
+    local_rst_n = {rstmgr_pkg::PowerDomains{resets_o.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]}};
 
-  for (genvar pd = 0; pd < rstmgr_pkg::PowerDomains; ++pd) begin : power_domains
-    // The AON reset triggers the various por reset for the different clock domains through
-    // syncronizers.
-    `CASCADED_ASSERTS(CascadeEffAonToRstPor, effective_aon_rst[pd], resets_o.rst_por_n[pd],
-                      SyncCycles, clk_main_i)
-    `CASCADED_ASSERTS(CascadeEffAonToRstPorIo, effective_aon_rst[pd], resets_o.rst_por_io_n[pd],
-                      SyncCycles, clk_io_i)
-    `CASCADED_ASSERTS(CascadeEffAonToRstPorIoDiv2, effective_aon_rst[pd],
-                      resets_o.rst_por_io_div2_n[pd], SyncCycles, clk_io_div2_i)
+  for (genvar pd = 0; pd < rstmgr_pkg::PowerDomains; ++pd) begin : g_power_domains
+    // The AON reset triggers the various POR reset for the different clock domains through
+    // synchronizers.
     `CASCADED_ASSERTS(CascadeEffAonToRstPorIoDiv4, effective_aon_rst[pd],
                       resets_o.rst_por_io_div4_n[pd], SyncCycles, clk_io_div4_i)
-    `CASCADED_ASSERTS(CascadeEffAonToRstPorUcb, effective_aon_rst[pd], resets_o.rst_por_usb_n[pd],
-                      SyncCycles, clk_usb_i)
 
     // The root lc reset is triggered either by the internal reset, or by the pwr_i.rst_lc_req
     // input. The latter is checked independently in pwrmgr_rstmgr_sva_if.
-    `CASCADED_ASSERTS(CascadeLocalRstToLc, local_rst_n[pd], rst_lc_src_n[pd], LcCycles, clk_i)
+    `CASCADED_ASSERTS(CascadeLocalRstToLc, local_rst_n[pd] && !rst_lc_req[pd], rst_lc_src_n[pd],
+                      LcCycles, clk_i)
 
     // The root sys reset is triggered by the lc reset, or independently by external requests.
     // The latter is checked independently in pwrmgr_rstmgr_sva_if.
-    `CASCADED_ASSERTS(CascadeLcToSys, rst_lc_src_n[pd], rst_sys_src_n[pd], SysCycles, clk_i)
+    `CASCADED_ASSERTS(CascadeLcToSys, rst_lc_src_n[pd] && !rst_sys_req[pd], rst_sys_src_n[pd],
+                      SysCycles, clk_i)
+
+    // Controlled by rst_lc_src_n.
+    `CASCADED_ASSERTS(CascadeLcToLcIoDiv4, rst_lc_src_n[pd], resets_o.rst_lc_io_div4_n[pd],
+                      SysCycles, clk_io_div4_i)
+    `CASCADED_ASSERTS(CascadeLcToLcIoDiv4Shadowed, rst_lc_src_n[pd],
+                      resets_o.rst_lc_io_div4_shadowed_n[pd], SysCycles, clk_io_div4_i)
+
+    // Controlled by rst_sys_src_n.
+    `CASCADED_ASSERTS(CascadeSysToSysAon, rst_sys_src_n[pd], resets_o.rst_sys_aon_n[pd], SysCycles,
+                      clk_aon_i)
+    `CASCADED_ASSERTS(CascadeSysToSysIoDiv4, rst_sys_src_n[pd], resets_o.rst_sys_io_div4_n[pd],
+                      SysCycles, clk_io_div4_i)
   end
 
+  // Aon to POR
+  `CASCADED_ASSERTS(CascadeEffAonToRstPor, effective_aon_rst[rstmgr_pkg::DomainAonSel],
+                    resets_o.rst_por_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_main_i)
+  `CASCADED_ASSERTS(CascadeEffAonToRstPorIo, effective_aon_rst[rstmgr_pkg::DomainAonSel],
+                    resets_o.rst_por_io_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_io_i)
+  `CASCADED_ASSERTS(CascadeEffAonToRstPorIoDiv2, effective_aon_rst[rstmgr_pkg::DomainAonSel],
+                    resets_o.rst_por_io_div2_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_io_div2_i)
+  `CASCADED_ASSERTS(CascadeEffAonToRstPorUcb, effective_aon_rst[rstmgr_pkg::DomainAonSel],
+                    resets_o.rst_por_usb_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_usb_i)
+
+  // Controlled by rst_lc_src_n.
+  `CASCADED_ASSERTS(CascadeLcToLcAon, rst_lc_src_n[rstmgr_pkg::DomainAonSel],
+                    resets_o.rst_lc_aon_n[rstmgr_pkg::DomainAonSel], SysCycles, clk_aon_i)
+  `CASCADED_ASSERTS(CascadeLcToLc, rst_lc_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_lc_n[rstmgr_pkg::Domain0Sel], SysCycles, clk_main_i)
+
+  // Controlled by rst_sys_src_n.
+  `CASCADED_ASSERTS(CascadeSysToSys, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_sys_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_main_i)
+  `CASCADED_ASSERTS(CascadeSysToSysShadowed, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_sys_shadowed_n[rstmgr_pkg::Domain0Sel], SysCycles, clk_main_i)
+
   // Peripheral resets cascade from sys.
   // We only care for power domain 1 for peripherals.
-  `CASCADED_ASSERTS(CascadeSysToSpiDevice, rst_sys_src_n[1], resets_o.rst_spi_device_n[1],
-                    PeriCycles, clk_io_div4_i)
-  `CASCADED_ASSERTS(CascadeSysToSpiHost0, rst_sys_src_n[1], resets_o.rst_spi_host0_n[1], PeriCycles,
-                    clk_io_div4_i)
-  `CASCADED_ASSERTS(CascadeSysToSpiHost0Core, rst_sys_src_n[1], resets_o.rst_spi_host0_core_n[1],
-                    PeriCycles, clk_io_i)
-  `CASCADED_ASSERTS(CascadeSysToSpiHost1, rst_sys_src_n[1], resets_o.rst_spi_host1_n[1], PeriCycles,
-                    clk_io_div4_i)
-  `CASCADED_ASSERTS(CascadeSysToSpiHost1Core, rst_sys_src_n[1], resets_o.rst_spi_host1_core_n[1],
-                    PeriCycles, clk_io_i)
-  `CASCADED_ASSERTS(CascadeSysToUsb, rst_sys_src_n[1], resets_o.rst_usb_n[1], PeriCycles,
-                    clk_io_div4_i)
-  `CASCADED_ASSERTS(CascadeSysToUsbIf, rst_sys_src_n[1], resets_o.rst_usbif_n[1], PeriCycles,
-                    clk_usb_i)
-  `CASCADED_ASSERTS(CascadeSysToI2C0, rst_sys_src_n[1], resets_o.rst_i2c0_n[1], PeriCycles,
-                    clk_io_div4_i)
-  `CASCADED_ASSERTS(CascadeSysToI2C1, rst_sys_src_n[1], resets_o.rst_i2c1_n[1], PeriCycles,
-                    clk_io_div4_i)
-  `CASCADED_ASSERTS(CascadeSysToI2C2, rst_sys_src_n[1], resets_o.rst_i2c2_n[1], PeriCycles,
-                    clk_io_div4_i)
+  `CASCADED_ASSERTS(CascadeSysToSpiDevice, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_spi_device_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_div4_i)
+  `CASCADED_ASSERTS(CascadeSysToSpiHost0, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_spi_host0_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_div4_i)
+  `CASCADED_ASSERTS(CascadeSysToSpiHost0Core, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_spi_host0_core_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_i)
+  `CASCADED_ASSERTS(CascadeSysToSpiHost1, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_spi_host1_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_div4_i)
+  `CASCADED_ASSERTS(CascadeSysToSpiHost1Core, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_spi_host1_core_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_i)
+  `CASCADED_ASSERTS(CascadeSysToUsb, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_usb_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_div4_i)
+  `CASCADED_ASSERTS(CascadeSysToUsbIf, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_usbif_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_usb_i)
+  `CASCADED_ASSERTS(CascadeSysToI2C0, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_i2c0_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_div4_i)
+  `CASCADED_ASSERTS(CascadeSysToI2C1, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_i2c1_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_div4_i)
+  `CASCADED_ASSERTS(CascadeSysToI2C2, rst_sys_src_n[rstmgr_pkg::Domain0Sel],
+                    resets_o.rst_i2c2_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_io_div4_i)
   `undef FALL_ASSERT
   `undef RISE_ASSERTS
   `undef CASCADED_ASSERTS
diff --git a/hw/top_earlgrey/dv/chip_sim.core b/hw/top_earlgrey/dv/chip_sim.core
index f8ff6c4..ab30c17 100644
--- a/hw/top_earlgrey/dv/chip_sim.core
+++ b/hw/top_earlgrey/dv/chip_sim.core
@@ -15,6 +15,7 @@
       - lowrisc:ip:tlul
       - lowrisc:dv:chip_test
       - lowrisc:dv:pwrmgr_sva
+      - lowrisc:dv:rstmgr_sva
       - lowrisc:dv:xbar_main_bind
       - lowrisc:dv:xbar_peri_bind
       - lowrisc:dv:xbar_test
diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
index 09995e6..37044bc 100644
--- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson
+++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson
@@ -25,6 +25,7 @@
 
   // Add additional tops for simulation.
   sim_tops: ["pwrmgr_bind",
+             "rstmgr_bind",
              "xbar_main_bind",
              "xbar_peri_bind"]