Merge "[ml_top/hw] Update Kelvin with mlu mask on branch"
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson
index 164c73a..5c178f4 100644
--- a/hw/top_matcha/dv/chip_sim_cfg.hjson
+++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -409,98 +409,98 @@
   tests: [
     {
       name: chip_sw_smc_isp_wrapper_tpg_64_64_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_isp_wrapper_tpg_64_64_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_env_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_env_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_isp_wrapper_irq_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_isp_wrapper_irq_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_tlul_mailbox_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_tlul_mailbox_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_cam_irq_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_cam_irq_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_ml_sram_smoketest
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_ml_dmem_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_kelvin_hello_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_kelvin_hello_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_ml_top_irq_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_ml_top_irq_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_supervisor_mode_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_supervisor_mode_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_virtual_memory_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_virtual_memory_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_interrupt_boundary_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_interrupt_boundary_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_lsu_interrupt_boundary_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_lsu_interrupt_boundary_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_page_boundary_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_page_boundary_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_lsu_page_boundary_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_lsu_page_boundary_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
@@ -549,35 +549,35 @@
     }
     {
       name: chip_sw_smc_i2s_rx_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_i2s_rx_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_i2s_tx_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_i2s_tx_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_rv_timer_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_rv_timer_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_kelvin_checksum_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_kelvin_checksum_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
     }
     {
       name: chip_sw_smc_isp_wrapper_test
-      uvm_test_seq: chip_sw_base_vseq
+      uvm_test_seq: chip_sw_smc_base_vseq
       sw_images: ["//sw/device/tests/smc:smc_isp_wrapper_test:6:matcha"]
       en_run_modes: ["sw_test_mode_test_simple_sec"]
       run_opts:["+sw_test_timeout_ns=40_000_000"]
@@ -667,7 +667,7 @@
     {
       name: chip_sw_sleep_pin_retention
       uvm_test_seq: chip_sw_sleep_pin_retention_vseq
-      sw_images: ["//sw/device/tests/sim_dv:sleep_pin_retention_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:sleep_pin_retention_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
     }
     {
@@ -826,7 +826,7 @@
     {
       name: chip_sw_gpio
       uvm_test_seq: chip_sw_gpio_vseq
-      sw_images: ["//sw/device/tests/sim_dv:gpio_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:gpio_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
     }
     {
@@ -1092,7 +1092,7 @@
     {
       name: chip_sw_pwrmgr_random_sleep_all_reset_reqs
       uvm_test_seq: chip_sw_random_sleep_all_reset_vseq
-      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_random_sleep_all_reset_reqs_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_random_sleep_all_reset_reqs_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+sw_test_timeout_ns=50_000_000"]
       run_timeout_mins: 120
@@ -1100,7 +1100,7 @@
     {
       name: chip_sw_pwrmgr_deep_sleep_all_reset_reqs
       uvm_test_seq: chip_sw_deep_sleep_all_reset_vseq
-      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_deep_sleep_all_reset_reqs_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_deep_sleep_all_reset_reqs_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+sw_test_timeout_ns=50_000_000"]
       run_timeout_mins: 120
@@ -1108,28 +1108,28 @@
     {
       name: chip_sw_pwrmgr_normal_sleep_all_reset_reqs
       uvm_test_seq: chip_sw_deep_sleep_all_reset_vseq
-      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_normal_sleep_all_reset_reqs_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_normal_sleep_all_reset_reqs_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_timeout_mins: 120
     }
     {
       name: chip_sw_pwrmgr_sleep_power_glitch_reset
       uvm_test_seq: chip_sw_main_power_glitch_vseq
-      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_sleep_power_glitch_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_sleep_power_glitch_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+bypass_alert_ready_to_end_check=1"]
     }
     {
       name: chip_sw_pwrmgr_deep_sleep_power_glitch_reset
       uvm_test_seq: chip_sw_deep_power_glitch_vseq
-      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_deep_sleep_power_glitch_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_deep_sleep_power_glitch_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+bypass_alert_ready_to_end_check=1"]
     }
     {
       name: chip_sw_pwrmgr_random_sleep_power_glitch_reset
       uvm_test_seq: chip_sw_random_power_glitch_vseq
-      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_random_sleep_power_glitch_reset_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_random_sleep_power_glitch_reset_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+bypass_alert_ready_to_end_check=1",
                  "+sw_test_timeout_ns=24_000_000"]
@@ -1629,7 +1629,7 @@
     {
       name: chip_sw_pwrmgr_b2b_sleep_reset_req
       uvm_test_seq: chip_sw_repeat_reset_wkup_vseq
-      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_b2b_sleep_reset_test:1"]
+      sw_images: ["//sw/device/tests/sim_dv:pwrmgr_b2b_sleep_reset_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
       run_opts: ["+sw_test_timeout_ns=35_000_000"]
       run_timeout_mins: 120
@@ -2017,6 +2017,7 @@
         "chip_sw_csrng_smoketest",
         "chip_sw_dma_main_test",
         "chip_sw_example_flash",
+        "chip_sw_gpio",
         "chip_sw_i2c_host_tx_rx",
         "chip_sw_mem_test",
         "chip_sw_rom_ctrl_integrity_check",
@@ -2070,6 +2071,7 @@
         "chip_sw_flash_ctrl_access",
         "chip_sw_flash_ctrl_access_jitter_en",
         "chip_sw_flash_ctrl_access_jitter_en_reduced_freq",
+        "chip_sw_gpio",
         "chip_sw_hmac_enc",
         "chip_sw_hmac_smoketest",
         "chip_sw_i2c_host_tx_rx",
@@ -2081,6 +2083,8 @@
         "chip_sw_otbn_smoketest",
         "chip_sw_otp_ctrl_escalation",
         "chip_sw_otp_ctrl_smoketest",
+        "chip_sw_pwrmgr_deep_sleep_power_glitch_reset",
+        "chip_sw_pwrmgr_sleep_power_glitch_reset",
         "chip_sw_rom_ctrl_integrity_check",
         "chip_sw_rstmgr_smoketest",
         "chip_sw_rstmgr_sw_req",
@@ -2092,6 +2096,7 @@
         "chip_sw_rv_timer_irq",
         "chip_sw_sensor_ctrl_alert",
         "chip_sw_sensor_ctrl_status",
+        "chip_sw_sleep_pin_retention",
         "chip_sw_smc_cam_irq_test",
         "chip_sw_smc_ctrl_test",
         "chip_sw_smc_env_test",
@@ -2139,6 +2144,7 @@
         "chip_sw_flash_ctrl_access",
         "chip_sw_flash_ctrl_access_jitter_en",
         "chip_sw_flash_ctrl_access_jitter_en_reduced_freq",
+        "chip_sw_gpio",
         "chip_sw_hmac_enc",
         "chip_sw_hmac_smoketest",
         "chip_sw_i2c_host_tx_rx",
@@ -2150,6 +2156,13 @@
         "chip_sw_otbn_smoketest",
         "chip_sw_otp_ctrl_escalation",
         "chip_sw_otp_ctrl_smoketest",
+        "chip_sw_pwrmgr_b2b_sleep_reset_req",
+        "chip_sw_pwrmgr_deep_sleep_all_reset_reqs",
+        "chip_sw_pwrmgr_deep_sleep_power_glitch_reset",
+        "chip_sw_pwrmgr_normal_sleep_all_reset_reqs",
+        "chip_sw_pwrmgr_random_sleep_all_reset_reqs",
+        "chip_sw_pwrmgr_random_sleep_power_glitch_reset",
+        "chip_sw_pwrmgr_sleep_power_glitch_reset",
         "chip_sw_pwrmgr_sleep_sensor_ctrl_alert_wakeup",
         "chip_sw_rom_ctrl_integrity_check",
         "chip_sw_rstmgr_smoketest",
@@ -2162,6 +2175,7 @@
         "chip_sw_rv_timer_irq",
         "chip_sw_sensor_ctrl_alert",
         "chip_sw_sensor_ctrl_status",
+        "chip_sw_sleep_pin_retention",
         "chip_sw_smc_cam_irq_test",
         "chip_sw_smc_ctrl_test",
         "chip_sw_smc_env_test",
diff --git a/hw/top_matcha/dv/env/chip_env.core b/hw/top_matcha/dv/env/chip_env.core
index 28fb4bf..8b229e1 100644
--- a/hw/top_matcha/dv/env/chip_env.core
+++ b/hw/top_matcha/dv/env/chip_env.core
@@ -55,6 +55,7 @@
       - seq_lib/chip_prim_tl_access_vseq.sv: {is_include_file: true}
       - seq_lib/chip_tap_straps_vseq.sv: {is_include_file: true}
       - seq_lib/chip_sw_base_vseq.sv: {is_include_file: true}
+      - seq_lib/chip_sw_smc_base_vseq.sv: {is_include_file: true}
       - seq_lib/chip_sw_uart_smoke_vseq.sv: {is_include_file: true}
       - seq_lib/chip_jtag_base_vseq.sv: {is_include_file: true}
       - seq_lib/chip_sw_alert_handler_entropy_vseq.sv: {is_include_file: true}
diff --git a/hw/top_matcha/dv/env/chip_if.sv b/hw/top_matcha/dv/env/chip_if.sv
index 5b576bc..6663de3 100644
--- a/hw/top_matcha/dv/env/chip_if.sv
+++ b/hw/top_matcha/dv/env/chip_if.sv
@@ -404,9 +404,9 @@
   // hw/top_matcha/rtl/chip_matcha_verilator.sv and
   // sw/device/lib/testing/pinmux_testutils.c
   pins_if #(.Width(NUM_GPIOS), .PullStrength("Weak")) gpios_if(
-    .pins({mios[top_matcha_pkg::MioPadIor10], mios[top_matcha_pkg::MioPadIoc8],
+    .pins({mios[top_matcha_pkg::MioPadIor10], mios[top_matcha_pkg::MioPadIod1],
            mios[top_matcha_pkg::MioPadIor7], mios[top_matcha_pkg::MioPadIor6],
-           mios[top_matcha_pkg::MioPadIoc5], mios[top_matcha_pkg::MioPadIoc9],
+           mios[top_matcha_pkg::MioPadIod0], mios[top_matcha_pkg::MioPadIoc9],
            mios[top_matcha_pkg::MioPadIoc7], mios[top_matcha_pkg::MioPadIoc2],
            mios[top_matcha_pkg::MioPadIoc1], mios[top_matcha_pkg::MioPadIoc0],
            mios[top_matcha_pkg::MioPadIoc6], mios[top_matcha_pkg::MioPadIob12],
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_sw_base_vseq.sv b/hw/top_matcha/dv/env/seq_lib/chip_sw_base_vseq.sv
index ad8fdc2..f2a74c4 100644
--- a/hw/top_matcha/dv/env/seq_lib/chip_sw_base_vseq.sv
+++ b/hw/top_matcha/dv/env/seq_lib/chip_sw_base_vseq.sv
@@ -1,3 +1,4 @@
+// Copyright 2023 Google LLC.
 // Copyright lowRISC contributors.
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
@@ -58,7 +59,6 @@
     `uvm_info(`gfn, "Starting cpu_init", UVM_MEDIUM)
 
     // Initialize the sw logger interface.
-    // SEC
     foreach (cfg.sw_images[i]) begin
       if (i inside {SwTypeRom, SwTypeDebug, SwTypeTestSlotA, SwTypeTestSlotB}) begin
         cfg.sw_logger_vif.add_sw_log_db(cfg.sw_images[i]);
@@ -67,19 +67,9 @@
     cfg.sw_logger_vif.sw_log_addr = SW_DV_LOG_ADDR;
     cfg.sw_logger_vif.write_sw_logs_to_file = cfg.write_sw_logs_to_file;
     cfg.sw_logger_vif.ready();
-    // SMC
-    foreach (cfg.sw_images[i]) begin
-      if (i inside {SwTypeSmc}) begin
-        cfg.sw_smc_logger_vif.add_sw_log_db(cfg.sw_images[i]);
-      end
-    end
-    cfg.sw_smc_logger_vif.sw_log_addr = SW_DV_SMC_LOG_ADDR;
-    cfg.sw_smc_logger_vif.write_sw_logs_to_file = cfg.write_sw_logs_to_file;
-    cfg.sw_smc_logger_vif.ready();
 
     // Initialize the sw test status.
-    cfg.sw_test_status_vif.sw_test_status_addr     = SW_DV_TEST_STATUS_ADDR;
-    cfg.sw_smc_test_status_vif.sw_test_status_addr = SW_DV_SMC_TEST_STATUS_ADDR;
+    cfg.sw_test_status_vif.sw_test_status_addr = SW_DV_TEST_STATUS_ADDR;
 
     `uvm_info(`gfn, "Initializing SRAMs", UVM_MEDIUM)
 
@@ -129,11 +119,6 @@
       cfg.mem_bkdr_util_h[FlashBank1Data].load_mem_from_file(
           {cfg.sw_images[SwTypeTestSlotB], ".64.scr.vmem"});
     end
-    // SMC RAM sw imsage load
-    if (cfg.sw_images.exists(SwTypeSmc)) begin
-      cfg.mem_bkdr_util_h[Smc_ram].load_mem_from_file(
-            {cfg.sw_images[SwTypeSmc], ".32.vmem"});
-    end
 
     config_jitter();
 
@@ -247,7 +232,7 @@
     fork
       begin: isolation_thread
         fork
-          wait (cfg.sw_test_status_vif.sw_test_done || cfg.sw_smc_test_status_vif.sw_test_done);
+          wait (cfg.sw_test_status_vif.sw_test_done);
           #(cfg.sw_test_timeout_ns * 1ns);
         join_any
         disable fork;
@@ -258,24 +243,15 @@
 
   // Print pass / fail message to the log.
   virtual function void log_sw_test_status();
-    if(cfg.sw_test_status_vif.sw_test_done || cfg.sw_smc_test_status_vif.sw_test_done) begin
-        if(cfg.sw_test_status_vif.sw_test_done) begin
-            case (cfg.sw_test_status_vif.sw_test_status)
-              SwTestStatusPassed: `uvm_info(`gfn, "[SEC] SW TEST PASSED!", UVM_LOW)
-              SwTestStatusFailed: `uvm_error(`gfn, "[SEC] SW TEST FAILED!")
-            endcase
-        end
-        if(cfg.sw_smc_test_status_vif.sw_test_done) begin
-            case (cfg.sw_smc_test_status_vif.sw_test_status)
-              SwTestStatusPassed: `uvm_info(`gfn, "[SMC] SW TEST PASSED!", UVM_LOW)
-              SwTestStatusFailed: `uvm_error(`gfn, "[SMC] SW TEST FAILED!")
-            endcase
-        end
-    end
-    else begin
+    case (cfg.sw_test_status_vif.sw_test_status)
+      SwTestStatusPassed: `uvm_info(`gfn, "SW TEST PASSED!", UVM_LOW)
+      SwTestStatusFailed: `uvm_error(`gfn, "SW TEST FAILED!")
+      default: begin
+        // If the SW test has not reached the passed / failed state, then it timed out.
         `uvm_error(`gfn, $sformatf("SW TEST TIMED OUT. STATE: %0s, TIMEOUT = %0d ns\n",
-                cfg.sw_smc_test_status_vif.sw_test_status.name(), cfg.sw_test_timeout_ns))
-    end
+            cfg.sw_test_status_vif.sw_test_status.name(), cfg.sw_test_timeout_ns))
+      end
+    endcase
   endfunction
 
   // Configure the provided spi_agent_cfg to use flash mode, and add the
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv b/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv
index c6266ca..e6a5ddc 100644
--- a/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv
+++ b/hw/top_matcha/dv/env/seq_lib/chip_sw_gpio_vseq.sv
@@ -1,3 +1,4 @@
+// Copyright 2023 Google LLC.
 // Copyright lowRISC contributors.
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
@@ -20,6 +21,7 @@
     gpio_output_test();
 
     // Run the GPIO input tests.
+    cfg.chip_vif.gpios_if.disconnect();
     gpio_input_test();
   endtask
 
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_sw_smc_base_vseq.sv b/hw/top_matcha/dv/env/seq_lib/chip_sw_smc_base_vseq.sv
new file mode 100644
index 0000000..612c3f2
--- /dev/null
+++ b/hw/top_matcha/dv/env/seq_lib/chip_sw_smc_base_vseq.sv
@@ -0,0 +1,69 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class chip_sw_smc_base_vseq extends chip_sw_base_vseq;
+  `uvm_object_utils(chip_sw_smc_base_vseq)
+
+  `uvm_object_new
+
+  virtual task cpu_init();
+    super.cpu_init();
+
+   `uvm_info(`gfn, "Starting SMC cpu_init", UVM_MEDIUM)
+
+    foreach (cfg.sw_images[i]) begin
+      if (i inside {SwTypeSmc}) begin
+        cfg.sw_smc_logger_vif.add_sw_log_db(cfg.sw_images[i]);
+      end
+    end
+    cfg.sw_smc_logger_vif.sw_log_addr = SW_DV_SMC_LOG_ADDR;
+    cfg.sw_smc_logger_vif.write_sw_logs_to_file = cfg.write_sw_logs_to_file;
+    cfg.sw_smc_logger_vif.ready();
+
+    // Initialize the sw test status.
+    cfg.sw_smc_test_status_vif.sw_test_status_addr = SW_DV_SMC_TEST_STATUS_ADDR;
+
+    // SMC RAM sw image load
+    if (cfg.sw_images.exists(SwTypeSmc)) begin
+      cfg.mem_bkdr_util_h[Smc_ram].load_mem_from_file(
+            {cfg.sw_images[SwTypeSmc], ".32.vmem"});
+    end
+
+    `uvm_info(`gfn, "SMC cpu_init completed", UVM_MEDIUM)
+  endtask
+
+  virtual task body();
+    cfg.sw_smc_test_status_vif.set_num_iterations(num_trans);
+    // Initialize the CPU to kick off the sw test. TODO: Should be called in pre_start() instead.
+    cpu_init();
+  endtask
+
+  virtual task wait_for_sw_test_done();
+   `uvm_info(`gfn, "Waiting for the SW test to finish", UVM_MEDIUM)
+    fork
+      begin: isolation_thread
+        fork
+          wait (cfg.sw_smc_test_status_vif.sw_test_done);
+          #(cfg.sw_test_timeout_ns * 1ns);
+        join_any
+        disable fork;
+        log_sw_test_status();
+      end: isolation_thread
+    join
+  endtask
+
+  virtual function void log_sw_test_status();
+    case (cfg.sw_smc_test_status_vif.sw_test_status)
+      SwTestStatusPassed: `uvm_info(`gfn, "SW TEST PASSED!", UVM_LOW)
+      SwTestStatusFailed: `uvm_error(`gfn, "SW TEST FAILED!")
+      default: begin
+        // If the SW test has not reached the passed / failed state, then it timed out.
+        `uvm_error(`gfn, $sformatf("SW TEST TIMED OUT. STATE: %0s, TIMEOUT = %0d ns\n",
+            cfg.sw_smc_test_status_vif.sw_test_status.name(), cfg.sw_test_timeout_ns))
+      end
+    endcase
+  endfunction
+
+endclass
diff --git a/hw/top_matcha/dv/env/seq_lib/chip_vseq_list.sv b/hw/top_matcha/dv/env/seq_lib/chip_vseq_list.sv
index ebe1a2b..3701ea8 100644
--- a/hw/top_matcha/dv/env/seq_lib/chip_vseq_list.sv
+++ b/hw/top_matcha/dv/env/seq_lib/chip_vseq_list.sv
@@ -11,6 +11,7 @@
 `include "chip_jtag_mem_vseq.sv"
 // This needs to be listed prior to all sequences that derive from it.
 `include "chip_sw_base_vseq.sv"
+`include "chip_sw_smc_base_vseq.sv"
 `include "chip_sw_uart_smoke_vseq.sv"
 `include "chip_jtag_base_vseq.sv"
 `include "chip_prim_tl_access_vseq.sv"
diff --git a/hw/top_matcha/ip/ast/ast.core b/hw/top_matcha/ip/ast/ast.core
index 9211b6c..ac3dadc 100644
--- a/hw/top_matcha/ip/ast/ast.core
+++ b/hw/top_matcha/ip/ast/ast.core
@@ -45,6 +45,8 @@
       - rtl/sys_osc.sv
       - rtl/usb_clk.sv
       - rtl/usb_osc.sv
+      - rtl/audio_clk.sv
+      - rtl/audio_osc.sv
       - rtl/gfr_clk_mux2.sv
       - rtl/ast_clks_byp.sv
       - rtl/rglts_pdm_3p3v.sv
diff --git a/hw/top_matcha/ip/ast/rtl/ast.sv b/hw/top_matcha/ip/ast/rtl/ast.sv
index 0c7c900..5f00c1c 100644
--- a/hw/top_matcha/ip/ast/rtl/ast.sv
+++ b/hw/top_matcha/ip/ast/rtl/ast.sv
@@ -98,18 +98,22 @@
   output logic [UsbCalibWidth-1:0] usb_io_pu_cal_o,  // USB IO Pull-up Calibration Setting
 
   // smc source clock
+  input clk_src_smc_en_i,                     // SMC Source Clock Enable
   output logic clk_src_smc_o,                 // SMC Source Clock
   output logic clk_src_smc_val_o,             // SMC Source Clock Valid
 
   // ml source clock
+  input clk_src_ml_en_i,                      // ML Source Clock Enable
   output logic clk_src_ml_o,                  // ML Source Clock
   output logic clk_src_ml_val_o,              // ML Source Clock Valid
 
   // video source clock
+  input clk_src_video_en_i,                   // VideO Source Clock Enable
   output logic clk_src_video_o,               // Video Source Clock
   output logic clk_src_video_val_o,           // Video Source Clock Valid
 
   // audio source clock
+  input clk_src_audio_en_i,                   // AUDIO Source Clock Enable
   output logic clk_src_audio_o,               // audio Source Clock
   output logic clk_src_audio_val_o,           // audio Source Clock Valid
 
@@ -518,6 +522,36 @@
 
 
 ///////////////////////////////////////
+// AUDIO Clock (Always ON)
+///////////////////////////////////////
+logic rst_audio_clk_n, clk_audio_pd_n;
+logic clk_src_audio_en, clk_osc_audio, clk_osc_audio_val;
+
+assign rst_audio_clk_n = vcmain_pok_por && vcc_pok;
+assign clk_audio_pd_n  = scan_mode || !deep_sleep;
+
+`ifdef AST_BYPASS_CLK
+logic clk_audio_ext;
+assign clk_audio_ext = clk_osc_byp_i.audio;
+`endif
+
+assign clk_src_audio_en = clk_src_audio_en_i;
+
+audio_clk u_audio_clk (
+  .vcore_pok_h_i ( vcaon_pok_h ),
+  .clk_audio_pd_ni ( clk_audio_pd_n ),
+  .rst_audio_clk_ni ( rst_audio_clk_n ),
+  .clk_src_audio_en_i ( clk_src_audio_en ),
+  .scan_mode_i ( scan_mode ),
+  .audio_osc_cal_i ( sys_io_osc_cal ),
+`ifdef AST_BYPASS_CLK
+  .clk_audio_ext_i ( clk_audio_ext ),
+`endif
+  .clk_src_audio_o ( clk_osc_audio ),
+  .clk_src_audio_val_o ( clk_osc_audio_val )
+);
+
+///////////////////////////////////////
 // AST Clocks Bypass
 ///////////////////////////////////////
 logic clk_src_sys, clk_src_io, clk_src_usb, clk_src_aon;
@@ -536,6 +570,9 @@
   .clk_osc_usb_val_i ( clk_osc_usb_val ),
   .clk_osc_aon_i ( clk_osc_aon ),
   .clk_osc_aon_val_i ( clk_osc_aon_val ),
+  .clk_src_audio_en_i ( clk_src_audio_en_i ),
+  .clk_osc_audio_i ( clk_osc_audio ),
+  .clk_osc_audio_val_i ( clk_osc_audio_val ),
   .clk_ast_ext_i ( clk_ast_ext_i ),
   .io_clk_byp_req_i ( io_clk_byp_req_i ),
   .all_clk_byp_req_i ( all_clk_byp_req_i ),
@@ -550,7 +587,9 @@
   .clk_src_usb_o ( clk_src_usb ),
   .clk_src_usb_val_o ( clk_src_usb_val_o ),
   .clk_src_aon_o ( clk_src_aon ),
-  .clk_src_aon_val_o ( clk_src_aon_val_o )
+  .clk_src_aon_val_o ( clk_src_aon_val_o ),
+  .clk_src_audio_o ( clk_src_audio ),
+  .clk_src_audio_val_o ( clk_src_audio_val_o )
 );
 
 // System source clock buffer
@@ -590,47 +629,48 @@
 );
 
 
-// TO-DO(pbf): Add PLL output for new clocks: smc, ml, video, audio
-// For now, just use the same clock as clk_osc_ss
-
-assign clk_src_smc_val_o = 1'b1;
-assign clk_src_ml_val_o = 1'b1;
-assign clk_src_video_val_o = 1'b1;
-assign clk_src_audio_val_o = 1'b1;
+// TO-DO(VSI): Add PLL output for new clocks: smc, ml, video
+// For DV test purpose as of now, smc/ml/video clock will just use the same clock as clk_src_syc.
 
 // SMC source clock buffer
 ////////////////////////////////////////
 prim_clock_buf #(
   .NoFpgaBuf ( 1'b1 )
 ) u_clk_src_smc_buf (
-  .clk_i ( clk_src_sys ),  // TO-DO(pbf): use the sys_clk for now. Change to different clock late.
+  .clk_i ( clk_src_sys ),  // TO-DO(VSI): use the sys_clk for now. Change to SMC clock late.
   .clk_o ( clk_src_smc_o )
 );
 
+assign clk_src_smc_val_o = clk_src_sys_val_o;
+
 // ML source clock buffer
 ////////////////////////////////////////
 prim_clock_buf #(
   .NoFpgaBuf ( 1'b1 )
 ) u_clk_src_ml_buf (
-  .clk_i ( clk_src_sys ),  // TO-DO(pbf):use the sys_clk for now. Change to different clock late.
+  .clk_i ( clk_src_sys ),  // TO-DO(VSI):use the sys_clk for now. Change to ML clock late.
   .clk_o ( clk_src_ml_o )
 );
 
+assign clk_src_ml_val_o = clk_src_sys_val_o;
+
 // video source clock buffer
 ////////////////////////////////////////
 prim_clock_buf #(
   .NoFpgaBuf ( 1'b1 )
 ) u_clk_src_video_buf (
-  .clk_i ( clk_src_sys ),  // TO-DO(pbf):use the sys_clk for now. Change to different clock late.
+  .clk_i ( clk_src_sys ),  // TO-DO(VSI):use the sys_clk for now. Change to video clock late.
   .clk_o ( clk_src_video_o )
 );
 
+assign clk_src_video_val_o = clk_src_sys_val_o;
+
 // audio source clock buffer
 ////////////////////////////////////////
 prim_clock_buf #(
   .NoFpgaBuf ( 1'b1 )
 ) u_clk_src_audio_buf (
-  .clk_i ( clk_src_usb ),  // TO-DO(pbf): use 48Mhz usb clock as audio clock for FPGA for now.
+  .clk_i ( clk_src_audio ),
   .clk_o ( clk_src_audio_o )
 );
 
diff --git a/hw/top_matcha/ip/ast/rtl/ast_clks_byp.sv b/hw/top_matcha/ip/ast/rtl/ast_clks_byp.sv
index f7d6c0e..f21c774 100644
--- a/hw/top_matcha/ip/ast/rtl/ast_clks_byp.sv
+++ b/hw/top_matcha/ip/ast/rtl/ast_clks_byp.sv
@@ -26,6 +26,9 @@
   input clk_osc_usb_val_i,                  // USB Oscillator Clock Valid
   input clk_osc_aon_i,                      // AON Oscillator Clock
   input clk_osc_aon_val_i,                  // AON Oscillator Clock Valid
+  input clk_src_audio_en_i,                 // IO Source Clock Enable
+  input clk_osc_audio_i,                    // AUDIO Oscillator Clock
+  input clk_osc_audio_val_i,                // AUDIO Oscillator Clock Valid
   input clk_ast_ext_i,                      // External Clock
   input prim_mubi_pkg::mubi4_t io_clk_byp_req_i,    // External IO clock mux for OTP bootstrap
   input prim_mubi_pkg::mubi4_t all_clk_byp_req_i,   // External all clock mux override
@@ -40,7 +43,9 @@
   output logic clk_src_usb_o,               // USB Source Clock
   output logic clk_src_usb_val_o,           // USB Source Clock Valid
   output logic clk_src_aon_o,               // AON Source Clock
-  output logic clk_src_aon_val_o            // AON Source Clock Valid
+  output logic clk_src_aon_val_o,           // AON Source Clock Valid
+  output logic clk_src_audio_o,             // AON Source Clock
+  output logic clk_src_audio_val_o          // AON Source Clock Valid
 );
 
 logic scan_mode_i, scan_reset_ni;
@@ -267,7 +272,32 @@
   .clk_o ( clk_ext_usb )
 );
 
+// AUDIO External Clock Enable
+////////////////////////////////////////
+logic clk_ext_audio, clk_ext_audio_en, clk_ext_audio_val;
+logic clk_src_audio_en;
 
+prim_flop_2sync #(
+  .Width ( 1 ),
+  .ResetValue ( 1'b0 )
+) u_no_scan_clk_src_audio_en_sync (
+  .clk_i ( clk_ext ),
+  .rst_ni ( rst_aon_exda_n ),
+  .d_i ( clk_src_audio_en_i ),
+  .q_o ( clk_src_audio_en )
+);
+
+assign clk_ext_audio_en  = deep_sleep_n && clk_src_audio_en;
+assign clk_ext_audio_val = clk_ext_audio_en;
+
+prim_clock_gating #(
+  .NoFpgaGate ( 1'b1)
+) u_clk_ext_audio_ckgt (
+  .clk_i ( clk_ext ),
+  .en_i ( clk_ext_audio_en ),
+  .test_en_i ( scan_mode_i ),
+  .clk_o ( clk_ext_audio )
+);
 ////////////////////////////////////////
 // SW Bypass select logic
 ////////////////////////////////////////
@@ -305,16 +335,17 @@
 );
 
 // Decode logic
-logic ot_all_clk_byp, ot_sys_clk_byp, ot_io_clk_byp, ot_usb_clk_byp, ot_aon_clk_byp;
+logic ot_all_clk_byp, ot_sys_clk_byp, ot_io_clk_byp, ot_usb_clk_byp, ot_aon_clk_byp, ot_audio_clk_byp;
 
 prim_mubi4_dec u_all_byp_sel ( .mubi_i ( ot_all_clk_byp_req ), .mubi_dec_o ( ot_all_clk_byp ) );
 prim_mubi4_dec u_sys_byp_sel ( .mubi_i ( ot_all_clk_byp_req ), .mubi_dec_o ( ot_sys_clk_byp ) );
 prim_mubi4_dec u_io_byp_sel  ( .mubi_i ( ot_io_clk_byp_req ),  .mubi_dec_o ( ot_io_clk_byp ) );
 prim_mubi4_dec u_usb_byp_sel ( .mubi_i ( ot_all_clk_byp_req ), .mubi_dec_o ( ot_usb_clk_byp ) );
 prim_mubi4_dec u_aon_byp_sel ( .mubi_i ( ot_all_clk_byp_req ), .mubi_dec_o ( ot_aon_clk_byp ) );
+prim_mubi4_dec u_audio_byp_sel ( .mubi_i ( ot_all_clk_byp_req ), .mubi_dec_o ( ot_audio_clk_byp ) );
 
 // De-Glitch selects (decode "noise")
-logic sw_sys_clk_byp, sw_usb_clk_byp, sw_aon_clk_byp, sw_exfr_is_96m;
+logic sw_sys_clk_byp, sw_usb_clk_byp, sw_aon_clk_byp, sw_exfr_is_96m, sw_audio_clk_byp;
 
 prim_flop #(
   .Width ( 1 ),
@@ -376,6 +407,16 @@
   .q_o ( sw_exfr_is_96m )
 );
 
+prim_flop #(
+  .Width ( 1 ),
+  .ResetValue ( 1'b0 )
+) u_sw_audio_clk_byp_dgl (
+  .clk_i ( clk_aon ),
+  .rst_ni ( rst_aon_n ),
+  .d_i ( ot_audio_clk_byp ),
+  .q_o ( sw_audio_clk_byp )
+);
+
 logic sys_clk_byp;
 
 assign sys_clk_byp = sw_sys_clk_byp;
@@ -408,9 +449,13 @@
 
 assign extfreq_is_96m = sw_exfr_is_96m;
 
+logic audio_clk_byp;
+
+assign audio_clk_byp = sw_audio_clk_byp;
+
 // Block changes during scan mode
 ////////////////////////////////////////
-logic sys_clk_byp_sel, io_clk_byp_sel, usb_clk_byp_sel, aon_clk_byp_sel;
+logic sys_clk_byp_sel, io_clk_byp_sel, usb_clk_byp_sel, aon_clk_byp_sel, audio_clk_byp_sel;
 
 always_latch begin
   if ( !scan_mode_i ) begin
@@ -419,6 +464,7 @@
     usb_clk_byp_sel = usb_clk_byp;
     aon_clk_byp_sel = aon_clk_byp;
     ext_freq_is_96m = extfreq_is_96m;
+    audio_clk_byp_sel = audio_clk_byp;
   end
 end
 
@@ -426,8 +472,8 @@
 ////////////////////////////////////////
 // Clocks Bypass Muxes
 ////////////////////////////////////////
-logic sys_clk_osc_en, io_clk_osc_en, usb_clk_osc_en, aon_clk_osc_en;
-logic sys_clk_byp_en, io_clk_byp_en, usb_clk_byp_en, aon_clk_byp_en;
+logic sys_clk_osc_en, io_clk_osc_en, usb_clk_osc_en, aon_clk_osc_en, audio_clk_osc_en;
+logic sys_clk_byp_en, io_clk_byp_en, usb_clk_byp_en, aon_clk_byp_en, audio_clk_byp_en;
 logic rst_clk_osc_n, rst_clk_ext_n;
 
 assign rst_clk_osc_n = vcaon_pok;
@@ -455,6 +501,7 @@
 
 logic rst_clk_osc_sys_n, rst_clk_ext_sys_n, rst_clk_osc_io_n, rst_clk_ext_io_n;
 logic rst_clk_osc_usb_n, rst_clk_ext_usb_n, rst_clk_osc_aon_n, rst_clk_ext_aon_n;
+logic rst_clk_osc_audio_n, rst_clk_ext_audio_n;
 
 prim_buf u_rst_clk_osc_sys (
   .in_i ( rst_clk_osc_n ),
@@ -496,6 +543,16 @@
   .out_o ( rst_clk_ext_aon_n )
 );
 
+prim_buf u_rst_clk_osc_audio (
+  .in_i ( rst_clk_osc_n ),
+  .out_o ( rst_clk_osc_audio_n )
+);
+
+prim_buf u_rst_clk_ext_audio (
+  .in_i ( rst_clk_ext_n ),
+  .out_o ( rst_clk_ext_audio_n )
+);
+
 // SYS Clock Bypass Mux
 ////////////////////////////////////////
 gfr_clk_mux2 u_clk_src_sys_sel (
@@ -560,6 +617,22 @@
   .clk_o ( clk_src_aon_o )
 );
 
+// AUDIO Clock Bypass Mux
+////////////////////////////////////////
+gfr_clk_mux2 u_clk_src_audio_sel (
+  .clk_osc_i ( clk_osc_audio_i ),
+  .clk_osc_val_i ( clk_osc_audio_val_i ),
+  .rst_clk_osc_ni ( rst_clk_osc_audio_n ),
+  .clk_ext_i ( clk_ext_audio ),
+  .clk_ext_val_i ( clk_ext_audio_val ),
+  .rst_clk_ext_ni ( rst_clk_ext_audio_n ),
+  .ext_sel_i ( audio_clk_byp_sel ),
+  .clk_osc_en_o ( audio_clk_osc_en ),
+  .clk_ext_en_o ( audio_clk_byp_en ),
+  .clk_val_o ( clk_src_audio_val_o ),
+  .clk_o ( clk_src_audio_o )
+);
+
 // rst_aon_n deasset to io clock
 ////////////////////////////////////////
 logic rst_aon_n_ioda, rst_aon_ioda_n;
@@ -585,7 +658,7 @@
     all_clks_byp_en_src <= 1'b0;
   end else begin
     all_clks_byp_en_src <= sw_all_clk_byp && sys_clk_byp_en && io_clk_byp_en &&
-                             usb_clk_byp_en && aon_clk_byp_en;
+                             usb_clk_byp_en && aon_clk_byp_en && audio_clk_byp_en;
   end
 end
 
diff --git a/hw/top_matcha/ip/ast/rtl/audio_clk.sv b/hw/top_matcha/ip/ast/rtl/audio_clk.sv
new file mode 100644
index 0000000..4ad7d32
--- /dev/null
+++ b/hw/top_matcha/ip/ast/rtl/audio_clk.sv
@@ -0,0 +1,63 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//############################################################################
+// *Name: audio_clk
+// *Module Description: AUDIO Clock
+//############################################################################
+
+module audio_clk (
+  input vcore_pok_h_i,               // VCORE POK @3.3V (for OSC)
+  input clk_audio_pd_ni,                // IO Clock Power-down
+  input rst_audio_clk_ni,               // IO Clock Logic reset
+  input clk_src_audio_en_i,             // IO Source Clock Enable
+  input scan_mode_i,                 // Scan Mode
+  input audio_osc_cal_i,                // IO Oscillator Calibrated
+`ifdef AST_BYPASS_CLK
+  input clk_audio_ext_i,                // FPGA/VERILATOR Clock input
+`endif
+  output logic clk_src_audio_o,         // IO Source Clock
+  output logic clk_src_audio_val_o      // IO Source Clock Valid
+);
+
+logic clk, osc_en, audio_clk_en;
+
+assign osc_en = (clk_src_audio_en_i && clk_audio_pd_ni && rst_audio_clk_ni);
+assign audio_clk_en = scan_mode_i || osc_en;
+
+// Clock Oscilator
+///////////////////////////////////////
+audio_osc u_audio_osc (
+  .vcore_pok_h_i ( vcore_pok_h_i ),
+  .audio_en_i ( audio_clk_en ),
+  .audio_osc_cal_i ( audio_osc_cal_i ),
+`ifdef AST_BYPASS_CLK
+  .clk_audio_ext_i ( clk_audio_ext_i ),
+`endif
+  .audio_clk_o ( clk )
+);  // of u_audio_osc
+
+// Clock & Valid
+///////////////////////////////////////
+prim_clock_buf #(
+  .NoFpgaBuf ( 1'b1 )
+) u_clk_audio_buf(
+  .clk_i ( clk ),
+  .clk_o ( clk_src_audio_o )
+);
+
+// 2-stage de-assertion
+logic rst_val_n;
+assign rst_val_n = audio_clk_en;
+
+prim_flop_2sync #(
+  .Width ( 1 ),
+  .ResetValue ( 1'b0 )
+) u_no_scan_val_sync (
+  .clk_i ( clk_src_audio_o ),
+  .rst_ni ( rst_val_n ),
+  .d_i ( 1'b1 ),
+  .q_o ( clk_src_audio_val_o )
+);
+
+endmodule : audio_clk
diff --git a/hw/top_matcha/ip/ast/rtl/audio_osc.sv b/hw/top_matcha/ip/ast/rtl/audio_osc.sv
new file mode 100644
index 0000000..c24f4e7
--- /dev/null
+++ b/hw/top_matcha/ip/ast/rtl/audio_osc.sv
@@ -0,0 +1,131 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//############################################################################
+// *Name: audio_osc
+// *Module Description: AUDIO Clock Oscilator
+//############################################################################
+
+module audio_osc (
+  input vcore_pok_h_i,    // VCORE POK @3.3V
+  input audio_en_i,          // IO Source Clock Enable
+  input audio_osc_cal_i,     // IO Oscillator Calibrated
+`ifdef AST_BYPASS_CLK
+  input clk_audio_ext_i,     // FPGA/VERILATOR Clock input
+`endif
+  output logic audio_clk_o   // IO Clock Output
+);
+
+`ifndef AST_BYPASS_CLK
+`ifndef SYNTHESIS
+// Behavioral Model
+////////////////////////////////////////
+timeunit 1ns / 1ps;
+
+real CLK_PERIOD;
+
+reg init_start;
+initial init_start = 1'b0;
+
+initial begin
+  #1;
+  init_start  = 1'b1;
+  #1;
+  $display("\n%m: IO Clock Power-up Frequency: %0d Hz", $rtoi(10**9/CLK_PERIOD));
+end
+
+// Enable 5us RC Delay on rise
+wire en_osc_re_buf, en_osc_re;
+buf #(ast_bhv_pkg::IO_EN_RDLY, 0) b0 (en_osc_re_buf, (vcore_pok_h_i && audio_en_i));
+assign en_osc_re = en_osc_re_buf && init_start;
+
+
+// Clock Oscillator
+////////////////////////////////////////
+real CalIoClkPeriod, UncIoClkPeriod, IoClkPeriod;
+
+initial CalIoClkPeriod = $itor( 1000000/48 );                    // ~20833.333333ps (48MHz)
+initial UncIoClkPeriod = $itor( $urandom_range(55555, 25000) );  // 55555-25000ps (18-40MHz)
+
+assign IoClkPeriod = (audio_osc_cal_i && init_start) ? CalIoClkPeriod : UncIoClkPeriod;
+assign CLK_PERIOD = IoClkPeriod/1000;
+
+// Free running oscillator
+reg clk_osc;
+initial clk_osc = 1'b1;
+
+always begin
+   #(CLK_PERIOD/2) clk_osc = ~clk_osc;
+end
+
+logic en_osc;
+
+// HDL Clock Gate
+logic en_clk, clk;
+
+always_latch begin
+  if ( !clk_osc ) en_clk = en_osc;
+end
+
+assign clk = clk_osc && en_clk;
+`else  // of SYNTHESIS
+// SYNTHESIS/LINTER
+///////////////////////////////////////
+logic en_osc_re;
+assign en_osc_re = vcore_pok_h_i && audio_en_i;
+
+logic clk, en_osc;
+assign clk = 1'b0;
+`endif  // of SYNTHESIS
+`else  // of AST_BYPASS_CLK
+// VERILATOR/FPGA
+///////////////////////////////////////
+logic en_osc_re;
+assign en_osc_re = vcore_pok_h_i && audio_en_i;
+
+// Clock Oscillator
+////////////////////////////////////////
+logic clk, en_osc;
+
+prim_clock_gating #(
+  .NoFpgaGate ( 1'b1 )
+) u_clk_ckgt (
+  .clk_i ( clk_audio_ext_i ),
+  .en_i ( en_osc ),
+  .test_en_i ( 1'b0 ),
+  .clk_o ( clk )
+);
+`endif
+
+logic en_osc_fe;
+
+// Syncronize en_osc to clk FE for glitch free disable
+always_ff @( negedge clk, negedge vcore_pok_h_i ) begin
+  if ( !vcore_pok_h_i ) begin
+    en_osc_fe <= 1'b0;
+  end else begin
+    en_osc_fe <= en_osc_re;
+  end
+end
+
+assign en_osc = en_osc_re || en_osc_fe;  // EN -> 1 || EN -> 0
+
+// Clock Output Buffer
+////////////////////////////////////////
+prim_clock_buf #(
+  .NoFpgaBuf ( 1'b1 )
+) u_buf (
+  .clk_i ( clk ),
+  .clk_o ( audio_clk_o )
+);
+
+
+`ifdef SYNTHESIS
+/////////////////////////
+// Unused Signals
+/////////////////////////
+logic unused_sigs;
+assign unused_sigs = ^{ audio_osc_cal_i };
+`endif
+
+endmodule : audio_osc
diff --git a/hw/top_matcha/ip/smc/rtl/smc_core.sv b/hw/top_matcha/ip/smc/rtl/smc_core.sv
index 43e5242..7748ffc 100644
--- a/hw/top_matcha/ip/smc/rtl/smc_core.sv
+++ b/hw/top_matcha/ip/smc/rtl/smc_core.sv
@@ -949,7 +949,6 @@
       .mmu_data_rdata_o      ( mmu_data_rdata     ),
 
       .lsu_req_i             ( lsu_req            ),
-      .lsu_req_done_i        ( lsu_req_done       ),
       .lsu_req_in_dec_i      ( lsu_req_in_dec     ),
 
       // General Control Signals
diff --git a/hw/top_matcha/ip/smc/rtl/smc_mmu.sv b/hw/top_matcha/ip/smc/rtl/smc_mmu.sv
index ca56ac8..69880b4 100644
--- a/hw/top_matcha/ip/smc/rtl/smc_mmu.sv
+++ b/hw/top_matcha/ip/smc/rtl/smc_mmu.sv
@@ -49,7 +49,6 @@
     output logic [31:0]          mmu_data_rdata_o,
 
     input logic                  lsu_req_i,
-    input logic                  lsu_req_done_i, // used to ensure we don't store to dmem twice after a ptw finishes
     input logic                  lsu_req_in_dec_i,
 
     // General Control Signals
@@ -248,7 +247,7 @@
   assign paging_en_lsu  = satp_i.mode & (priv_lvl_lsu_i != PRIV_LVL_M);
 
   // Categorize atomic RMW ops and stores as writes for pte permissions
-  assign is_write     = (mmu_data_we_i != LOAD) ? 1'b1 : 1'b0;
+  assign is_write = mmu_data_we_i != LOAD;
 
   // Check page access errors based on privilege mode and mstatus bits only
   assign dmem_access_error =
@@ -367,7 +366,7 @@
       data_addr_o        = dtlb_superpage ? {dtlb_pte_content.ppn[19:10], mmu_data_addr_i[21:0]} :
                                             {dtlb_pte_content.ppn[19:0],  mmu_data_addr_i[11:0]};
       data_req_o         = mmu_data_req_i;
-      data_we            = is_write & (ptw_finish_lsu_dec_q | lsu_req_done_i);
+      data_we            = is_write;
       data_be_o          = mmu_data_be_i;
       data_wdata_o       = mmu_data_wdata_i;
 
diff --git a/hw/top_matcha/rtl/autogen/chip_matcha_asic.sv b/hw/top_matcha/rtl/autogen/chip_matcha_asic.sv
index 2475bdd..9f4cb53 100644
--- a/hw/top_matcha/rtl/autogen/chip_matcha_asic.sv
+++ b/hw/top_matcha/rtl/autogen/chip_matcha_asic.sv
@@ -1036,15 +1036,19 @@
     .clk_src_usb_o         ( ast_base_clks.clk_usb ),
     .clk_src_usb_val_o     ( ast_base_pwr.usb_clk_val ),
     // smc source clock
+    .clk_src_smc_en_i      ( base_ast_pwr.smc_clk_en ),
     .clk_src_smc_o         ( ast_base_clks.clk_smc ),
     .clk_src_smc_val_o     ( ast_base_pwr.smc_clk_val),
     // ml source clock
+    .clk_src_ml_en_i       ( base_ast_pwr.ml_clk_en ),
     .clk_src_ml_o          ( ast_base_clks.clk_ml ),
     .clk_src_ml_val_o      ( ast_base_pwr.ml_clk_val),
     // video source clock
+    .clk_src_video_en_i    ( base_ast_pwr.video_clk_en ),
     .clk_src_video_o       ( ast_base_clks.clk_video ),
     .clk_src_video_val_o   ( ast_base_pwr.video_clk_val),
     // audio source clock
+    .clk_src_audio_en_i    ( base_ast_pwr.audio_clk_en ),
     .clk_src_audio_o       ( ast_base_clks.clk_audio ),
     .clk_src_audio_val_o   ( ast_base_pwr.audio_clk_val),
     // adc
diff --git a/hw/top_matcha/rtl/autogen/chip_matcha_nexus.sv b/hw/top_matcha/rtl/autogen/chip_matcha_nexus.sv
index fad1369..f8fb1dd 100644
--- a/hw/top_matcha/rtl/autogen/chip_matcha_nexus.sv
+++ b/hw/top_matcha/rtl/autogen/chip_matcha_nexus.sv
@@ -824,15 +824,19 @@
     .clk_src_usb_o         ( ast_base_clks.clk_usb ),
     .clk_src_usb_val_o     ( ast_base_pwr.usb_clk_val ),
     // smc source clock
+    .clk_src_smc_en_i      ( base_ast_pwr.smc_clk_en ),
     .clk_src_smc_o         ( ast_base_clks.clk_smc ),
     .clk_src_smc_val_o     ( ast_base_pwr.smc_clk_val),
     // ml source clock
+    .clk_src_ml_en_i       ( base_ast_pwr.ml_clk_en ),
     .clk_src_ml_o          ( ast_base_clks.clk_ml ),
     .clk_src_ml_val_o      ( ast_base_pwr.ml_clk_val),
     // video source clock
+    .clk_src_video_en_i    ( base_ast_pwr.video_clk_en ),
     .clk_src_video_o       ( ast_base_clks.clk_video ),
     .clk_src_video_val_o   ( ast_base_pwr.video_clk_val),
     // audio source clock
+    .clk_src_audio_en_i    ( base_ast_pwr.audio_clk_en ),
     .clk_src_audio_o       ( ast_base_clks.clk_audio ),
     .clk_src_audio_val_o   ( ast_base_pwr.audio_clk_val),
     // adc
diff --git a/hw/top_matcha/rtl/chip_matcha_verilator.sv b/hw/top_matcha/rtl/chip_matcha_verilator.sv
index d66f69b..8bee784 100644
--- a/hw/top_matcha/rtl/chip_matcha_verilator.sv
+++ b/hw/top_matcha/rtl/chip_matcha_verilator.sv
@@ -486,15 +486,19 @@
     .clk_src_usb_o         ( ast_base_clks.clk_usb ),
     .clk_src_usb_val_o     ( ast_base_pwr.usb_clk_val ),
     // smc source clock
+    .clk_src_smc_en_i      ( base_ast_pwr.smc_clk_en ),
     .clk_src_smc_o         ( ast_base_clks.clk_smc ),
     .clk_src_smc_val_o     ( ast_base_pwr.smc_clk_val),
     // ml source clock
+    .clk_src_ml_en_i       ( base_ast_pwr.ml_clk_en ),
     .clk_src_ml_o          ( ast_base_clks.clk_ml ),
     .clk_src_ml_val_o      ( ast_base_pwr.ml_clk_val),
     // video source clock
+    .clk_src_video_en_i    ( base_ast_pwr.video_clk_en ),
     .clk_src_video_o       ( ast_base_clks.clk_video ),
     .clk_src_video_val_o   ( ast_base_pwr.video_clk_val),
     // audio source clock
+    .clk_src_audio_en_i    ( base_ast_pwr.audio_clk_en ),
     .clk_src_audio_o       ( ast_base_clks.clk_audio ),
     .clk_src_audio_val_o   ( ast_base_pwr.audio_clk_val),
     // adc
diff --git a/sw/device/lib/testing/pinmux_testutils.c b/sw/device/lib/testing/pinmux_testutils.c
index ea18a08..d71a23e 100644
--- a/sw/device/lib/testing/pinmux_testutils.c
+++ b/sw/device/lib/testing/pinmux_testutils.c
@@ -17,41 +17,41 @@
 // hw/top_matcha/rtl/chip_matcha_verilator.sv and
 // hw/top_matcha/dv/env/chip_if.sv
 const dif_pinmux_index_t kPinmuxTestutilsGpioInselPins[kDifGpioNumPins] = {
-  kTopMatchaPinmuxInselIoa0, kTopMatchaPinmuxInselIoa1,
-  kTopMatchaPinmuxInselIoa2, kTopMatchaPinmuxInselIoa3,
-  kTopMatchaPinmuxInselIoa4, kTopMatchaPinmuxInselIoa5,
-  kTopMatchaPinmuxInselIoa6, kTopMatchaPinmuxInselIoa7,
-  kTopMatchaPinmuxInselIoa8, kTopMatchaPinmuxInselIob0,
-  kTopMatchaPinmuxInselIob1, kTopMatchaPinmuxInselIob2,
-  kTopMatchaPinmuxInselIob3, kTopMatchaPinmuxInselIob4,
-  kTopMatchaPinmuxInselIob5, kTopMatchaPinmuxInselIob6,
-  kTopMatchaPinmuxInselIob7, kTopMatchaPinmuxInselIob8,
-  kTopMatchaPinmuxInselIob10, kTopMatchaPinmuxInselIob11,
-  kTopMatchaPinmuxInselIob12, kTopMatchaPinmuxInselIoc6,
-  kTopMatchaPinmuxInselIoc0, kTopMatchaPinmuxInselIoc1,
-  kTopMatchaPinmuxInselIoc2, kTopMatchaPinmuxInselIoc7,
-  kTopMatchaPinmuxInselIoc9, kTopMatchaPinmuxInselIoc5,
-  kTopMatchaPinmuxInselIor6, kTopMatchaPinmuxInselIor7,
-  kTopMatchaPinmuxInselIoc8, kTopMatchaPinmuxInselIor10,
+    kTopMatchaPinmuxInselIoa0,  kTopMatchaPinmuxInselIoa1,
+    kTopMatchaPinmuxInselIoa2,  kTopMatchaPinmuxInselIoa3,
+    kTopMatchaPinmuxInselIoa4,  kTopMatchaPinmuxInselIoa5,
+    kTopMatchaPinmuxInselIoa6,  kTopMatchaPinmuxInselIoa7,
+    kTopMatchaPinmuxInselIoa8,  kTopMatchaPinmuxInselIob0,
+    kTopMatchaPinmuxInselIob1,  kTopMatchaPinmuxInselIob2,
+    kTopMatchaPinmuxInselIob3,  kTopMatchaPinmuxInselIob4,
+    kTopMatchaPinmuxInselIob5,  kTopMatchaPinmuxInselIob6,
+    kTopMatchaPinmuxInselIob7,  kTopMatchaPinmuxInselIob8,
+    kTopMatchaPinmuxInselIob10, kTopMatchaPinmuxInselIob11,
+    kTopMatchaPinmuxInselIob12, kTopMatchaPinmuxInselIoc6,
+    kTopMatchaPinmuxInselIoc0,  kTopMatchaPinmuxInselIoc1,
+    kTopMatchaPinmuxInselIoc2,  kTopMatchaPinmuxInselIoc7,
+    kTopMatchaPinmuxInselIoc9,  kTopMatchaPinmuxInselIod0,
+    kTopMatchaPinmuxInselIor6,  kTopMatchaPinmuxInselIor7,
+    kTopMatchaPinmuxInselIod1,  kTopMatchaPinmuxInselIor10,
 };
 
 const dif_pinmux_index_t kPinmuxTestutilsGpioMioOutPins[kDifGpioNumPins] = {
-  kTopMatchaPinmuxMioOutIoa0, kTopMatchaPinmuxMioOutIoa1,
-  kTopMatchaPinmuxMioOutIoa2, kTopMatchaPinmuxMioOutIoa3,
-  kTopMatchaPinmuxMioOutIoa4, kTopMatchaPinmuxMioOutIoa5,
-  kTopMatchaPinmuxMioOutIoa6, kTopMatchaPinmuxMioOutIoa7,
-  kTopMatchaPinmuxMioOutIoa8, kTopMatchaPinmuxMioOutIob0,
-  kTopMatchaPinmuxMioOutIob1, kTopMatchaPinmuxMioOutIob2,
-  kTopMatchaPinmuxMioOutIob3, kTopMatchaPinmuxMioOutIob4,
-  kTopMatchaPinmuxMioOutIob5, kTopMatchaPinmuxMioOutIob6,
-  kTopMatchaPinmuxMioOutIob7, kTopMatchaPinmuxMioOutIob8,
-  kTopMatchaPinmuxMioOutIob10, kTopMatchaPinmuxMioOutIob11,
-  kTopMatchaPinmuxMioOutIob12, kTopMatchaPinmuxMioOutIoc6,
-  kTopMatchaPinmuxMioOutIoc0, kTopMatchaPinmuxMioOutIoc1,
-  kTopMatchaPinmuxMioOutIoc2, kTopMatchaPinmuxMioOutIoc7,
-  kTopMatchaPinmuxMioOutIoc9, kTopMatchaPinmuxMioOutIoc5,
-  kTopMatchaPinmuxMioOutIor6, kTopMatchaPinmuxMioOutIor7,
-  kTopMatchaPinmuxMioOutIoc8, kTopMatchaPinmuxMioOutIor10,
+    kTopMatchaPinmuxMioOutIoa0,  kTopMatchaPinmuxMioOutIoa1,
+    kTopMatchaPinmuxMioOutIoa2,  kTopMatchaPinmuxMioOutIoa3,
+    kTopMatchaPinmuxMioOutIoa4,  kTopMatchaPinmuxMioOutIoa5,
+    kTopMatchaPinmuxMioOutIoa6,  kTopMatchaPinmuxMioOutIoa7,
+    kTopMatchaPinmuxMioOutIoa8,  kTopMatchaPinmuxMioOutIob0,
+    kTopMatchaPinmuxMioOutIob1,  kTopMatchaPinmuxMioOutIob2,
+    kTopMatchaPinmuxMioOutIob3,  kTopMatchaPinmuxMioOutIob4,
+    kTopMatchaPinmuxMioOutIob5,  kTopMatchaPinmuxMioOutIob6,
+    kTopMatchaPinmuxMioOutIob7,  kTopMatchaPinmuxMioOutIob8,
+    kTopMatchaPinmuxMioOutIob10, kTopMatchaPinmuxMioOutIob11,
+    kTopMatchaPinmuxMioOutIob12, kTopMatchaPinmuxMioOutIoc6,
+    kTopMatchaPinmuxMioOutIoc0,  kTopMatchaPinmuxMioOutIoc1,
+    kTopMatchaPinmuxMioOutIoc2,  kTopMatchaPinmuxMioOutIoc7,
+    kTopMatchaPinmuxMioOutIoc9,  kTopMatchaPinmuxMioOutIod0,
+    kTopMatchaPinmuxMioOutIor6,  kTopMatchaPinmuxMioOutIor7,
+    kTopMatchaPinmuxMioOutIod1,  kTopMatchaPinmuxMioOutIor10,
 };
 
 void pinmux_testutils_init(dif_pinmux_t *pinmux) {
@@ -104,3 +104,5 @@
   CHECK_DIF_OK(dif_pinmux_output_select(pinmux, kTopMatchaPinmuxMioOutIoc11,
                                         kTopMatchaPinmuxOutselSmcUartTx));
 }
+
+uint32_t pinmux_testutils_get_testable_gpios_mask(void) { return 0xffffffff; }
diff --git a/sw/device/lib/testing/pinmux_testutils.h b/sw/device/lib/testing/pinmux_testutils.h
index 984b27f..657d6f0 100644
--- a/sw/device/lib/testing/pinmux_testutils.h
+++ b/sw/device/lib/testing/pinmux_testutils.h
@@ -25,4 +25,12 @@
 extern const dif_pinmux_index_t kPinmuxTestutilsGpioInselPins[kDifGpioNumPins];
 extern const dif_pinmux_index_t kPinmuxTestutilsGpioMioOutPins[kDifGpioNumPins];
 
+/**
+ * Returns the mask of testable GPIO pins.
+ *
+ * Returns a simulation-device-specific mask that enables testing of only a
+ * subset of GPIOs depending on the IO allocation limitations.
+ */
+uint32_t pinmux_testutils_get_testable_gpios_mask(void);
+
 #endif  // MATCHA_SW_DEVICE_LIB_TESTING_PINMUX_TESTUTILS_H_
diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD
index 8740d12..66a73fd 100644
--- a/sw/device/tests/sim_dv/BUILD
+++ b/sw/device/tests/sim_dv/BUILD
@@ -8,32 +8,22 @@
 matcha_dv_test(
     name = "uart_tx_rx_test",
     srcs = ["uart_tx_rx_test.c"],
-    targets = ["dv"],
     deps = [
-        "//hw/top_matcha/ip/clkmgr/data/autogen:clkmgr_regs",
-        "//hw/top_matcha/ip/pinmux/data/autogen:pinmux_regs",
-        "//hw/top_matcha/sw/autogen:top_matcha",
         "//sw/device/lib/dif:clkmgr",
+        "//sw/device/lib/dif:pinmux",
         "//sw/device/lib/dif:rv_plic_sec",
         "//sw/device/lib/testing:clkmgr_testutils",
-        "//sw/device/lib/testing/test_framework:ottf_main",
+        "//sw/device/tests:test_dv_lib",
         "@lowrisc_opentitan//hw/ip/lc_ctrl/data:lc_ctrl_regs",
-        "@lowrisc_opentitan//sw/device/lib/base:mmio",
         "@lowrisc_opentitan//sw/device/lib/dif:lc_ctrl",
         "@lowrisc_opentitan//sw/device/lib/dif:uart",
-        "@lowrisc_opentitan//sw/device/lib/runtime:hart",
-        "@lowrisc_opentitan//sw/device/lib/runtime:irq",
-        "@lowrisc_opentitan//sw/device/lib/runtime:log",
     ],
 )
 
 matcha_dv_test(
     name = "rv_dm_ndm_reset_req",
     srcs = ["rv_dm_ndm_reset_req.c"],
-    targets = ["dv"],
     deps = [
-        "//hw/top_matcha/ip/pinmux/data/autogen:pinmux_regs",
-        "//hw/top_matcha/sw/autogen:top_matcha",
         "//sw/device/lib/dif:pinmux",
         "//sw/device/lib/dif:rstmgr",
         "//sw/device/tests:test_dv_lib",
@@ -54,26 +44,103 @@
 matcha_dv_test(
     name = "i2c_host_tx_rx_test",
     srcs = ["i2c_host_tx_rx_test.c"],
-    targets = ["dv"],
     deps = [
-        "//hw/top_matcha/ip/pinmux/data/autogen:pinmux_regs",
         "//sw/device/lib/dif:pinmux",
         "//sw/device/lib/dif:rstmgr",
+        "//sw/device/lib/testing:isr_testutils",
         "//sw/device/tests:test_dv_lib",
         "@lowrisc_opentitan//sw/device/lib/dif:i2c",
         "@lowrisc_opentitan//sw/device/lib/testing:i2c_testutils",
-        "//sw/device/lib/testing:isr_testutils",
         "@lowrisc_opentitan//sw/device/lib/testing:rand_testutils",
     ],
 )
 
+cc_library(
+    name = "pwrmgr_reset_test_lib",
+    deps = [
+        "//sw/device/lib/dif:alert_handler",
+        "//sw/device/lib/dif:pinmux",
+        "//sw/device/lib/dif:rstmgr",
+        "//sw/device/lib/dif:rv_plic_sec",
+        "//sw/device/lib/testing:pinmux_testutils",
+        "//sw/device/tests:test_dv_lib",
+        "@lowrisc_opentitan//sw/device/lib/base:abs_mmio",
+        "@lowrisc_opentitan//sw/device/lib/dif:aon_timer",
+        "@lowrisc_opentitan//sw/device/lib/dif:flash_ctrl",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+        "@lowrisc_opentitan//sw/device/lib/dif:rv_timer",
+        "@lowrisc_opentitan//sw/device/lib/dif:sysrst_ctrl",
+        "@lowrisc_opentitan//sw/device/lib/testing:alert_handler_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:aon_timer_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:flash_ctrl_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils",
+    ],
+)
+
+matcha_dv_test(
+    name = "pwrmgr_random_sleep_all_reset_reqs_test",
+    srcs = ["pwrmgr_random_sleep_all_reset_reqs_test.c"],
+    deps = [
+        ":pwrmgr_reset_test_lib",
+    ],
+)
+
+matcha_dv_test(
+    name = "pwrmgr_deep_sleep_all_reset_reqs_test",
+    srcs = ["pwrmgr_deep_sleep_all_reset_reqs_test.c"],
+    deps = [
+        ":pwrmgr_reset_test_lib",
+    ],
+)
+
+matcha_dv_test(
+    name = "pwrmgr_normal_sleep_all_reset_reqs_test",
+    srcs = ["pwrmgr_normal_sleep_all_reset_reqs_test.c"],
+    deps = [
+        ":pwrmgr_reset_test_lib",
+    ],
+)
+
+matcha_dv_test(
+    name = "pwrmgr_random_sleep_power_glitch_reset_test",
+    srcs = ["pwrmgr_random_sleep_power_glitch_reset_test.c"],
+    deps = [
+        ":pwrmgr_reset_test_lib",
+    ],
+)
+
+matcha_dv_test(
+    name = "pwrmgr_b2b_sleep_reset_test",
+    srcs = ["pwrmgr_b2b_sleep_reset_test.c"],
+    deps = [
+        ":pwrmgr_reset_test_lib",
+    ],
+)
+
+matcha_dv_test(
+    name = "sleep_pin_retention_test",
+    srcs = ["sleep_pin_retention_test.c"],
+    deps = [
+        "//sw/device/lib/dif:pinmux",
+        "//sw/device/lib/dif:rv_plic_sec",
+        "//sw/device/lib/testing:isr_testutils",
+        "//sw/device/tests:test_dv_lib",
+        "@lowrisc_opentitan//sw/device/lib/dif:gpio",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rand_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils",
+    ],
+)
+
 ################################################################################
 #  Place the Opentitan-sourced DV test below.                                  #
 #  Opentitan DV binary build flow does not support centOS7, so we pull the     #
 #  source code and build them here using `matcha_dv_test` rule.                #
 ################################################################################
 
-
 matcha_dv_test(
     name = "spi_tx_rx_test",
     srcs = ["@lowrisc_opentitan//sw/device/tests/sim_dv:spi_tx_rx_test.c"],
@@ -168,3 +235,39 @@
         "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils",
     ],
 )
+
+matcha_dv_test(
+    name = "pwrmgr_sleep_power_glitch_test",
+    srcs = ["@lowrisc_opentitan//sw/device/tests/sim_dv:pwrmgr_sleep_power_glitch_test.c"],
+    deps = [
+        "//sw/device/lib/dif:rstmgr",
+        "//sw/device/tests:test_dv_lib_opentitan",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils",
+    ],
+)
+
+matcha_dv_test(
+    name = "pwrmgr_deep_sleep_power_glitch_test",
+    srcs = ["@lowrisc_opentitan//sw/device/tests/sim_dv:pwrmgr_deep_sleep_power_glitch_test.c"],
+    deps = [
+        "//sw/device/lib/dif:rstmgr",
+        "//sw/device/tests:test_dv_lib_opentitan",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils",
+    ],
+)
+
+matcha_dv_test(
+    name = "gpio_test",
+    srcs = ["@lowrisc_opentitan//sw/device/tests/sim_dv:gpio_test.c"],
+    deps = [
+        "//sw/device/lib/dif:rv_plic_sec",
+        "//sw/device/lib/testing:pinmux_testutils",
+        "//sw/device/tests:test_dv_lib_opentitan",
+        "@lowrisc_opentitan//sw/device/lib/dif:gpio",
+        "@lowrisc_opentitan//sw/device/lib/testing:rv_plic_testutils",
+    ],
+)
diff --git a/sw/device/tests/sim_dv/pwrmgr_b2b_sleep_reset_test.c b/sw/device/tests/sim_dv/pwrmgr_b2b_sleep_reset_test.c
new file mode 100644
index 0000000..35b3be0
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_b2b_sleep_reset_test.c
@@ -0,0 +1,182 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "aon_timer_regs.h"
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/dif/dif_sysrst_ctrl.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rstmgr_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+/*
+   PWRMGR BACK TO BACK DEEP SLEEP, RESET / WAKEUP TEST
+
+   This test introduces reset or wakeup event close to (before or after)
+   entering low power state.
+
+   'kNumRound' is set to 10 by sv sequence (chip_sw_repeat_reset_wkup_vseq.sv)
+
+   For the reset event, the sequence assert power on resest by driving POR_N
+   PAD. For the wake up event, the seqeunce assert power button in by driving
+   IOR13 PAD.
+
+ */
+OTTF_DEFINE_TEST_CONFIG();
+
+static volatile const uint8_t kNumRound;
+
+static dif_flash_ctrl_state_t flash_ctrl;
+static dif_sysrst_ctrl_t sysrst_ctrl;
+static dif_pinmux_t pinmux;
+
+/**
+ * sysrst_ctrl config for test #1
+ * . set sysrst_ctrl.KEY_INTR_CTL.pwrb_in_H2L to 1
+ * . use IOR13 as pwrb_in
+ */
+static void prgm_push_button_wakeup() {
+  dif_sysrst_ctrl_input_change_config_t config = {
+      .input_changes = kDifSysrstCtrlInputPowerButtonH2L,
+      .debounce_time_threshold = 1,  // 5us
+  };
+  CHECK_DIF_OK(
+      dif_sysrst_ctrl_input_change_detect_configure(&sysrst_ctrl, config));
+  CHECK_DIF_OK(dif_pinmux_input_select(
+      &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonPwrbIn,
+      kTopMatchaPinmuxInselIor13));
+}
+
+bool test_main(void) {
+  // Issue a wakeup signal in ~1.5 ms through the AON timer.
+  // This timer is needed when reset or  wakeup fail to
+  // bring state machine back to active state.
+  // This can happen when wake up event comes before low power
+  // entry event.
+  uint32_t wakeup_threshold = kDeviceType == kDeviceSimVerilator ? 3000 : 300;
+
+  // Initialize pwrmgr
+  dif_pwrmgr_t pwrmgr;
+  CHECK_DIF_OK(dif_pwrmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+
+  // Initialize rstmgr since this will check some registers.
+  dif_rstmgr_t rstmgr;
+  CHECK_DIF_OK(dif_rstmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+  // Initialize flash_ctrl
+  CHECK_DIF_OK(dif_flash_ctrl_init_state(
+      &flash_ctrl,
+      mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR)));
+
+  // Initialize sysrst_ctrl
+  CHECK_DIF_OK(dif_sysrst_ctrl_init(
+      mmio_region_from_addr(TOP_MATCHA_SYSRST_CTRL_AON_BASE_ADDR),
+      &sysrst_ctrl));
+
+  // Initialize pinmux
+  CHECK_DIF_OK(dif_pinmux_init(
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+
+  // First check the flash stored value
+  uint32_t event_idx = flash_ctrl_testutils_counter_get(0);
+  // Enable flash access
+  flash_ctrl_testutils_default_region_access(&flash_ctrl,
+                                             /*rd_en*/ true,
+                                             /*prog_en*/ true,
+                                             /*erase_en*/ true,
+                                             /*scramble_en*/ false,
+                                             /*ecc_en*/ false,
+                                             /*he_en*/ false);
+
+  // Increment flash counter to know where we are
+  flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+
+  // Read wakeup reason before check
+  dif_pwrmgr_wakeup_reason_t wakeup_reason;
+  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
+  LOG_INFO("wakeup type:%d   wakeup reason: 0x%02X", wakeup_reason.types,
+           wakeup_reason.request_sources);
+
+  if (wakeup_reason.types == 0) {
+    // POR reset
+    CHECK(wakeup_reason.request_sources == 0);
+  } else if (wakeup_reason.types == kDifPwrmgrWakeupTypeRequest) {
+    // sysrst_ctrl or aon_timer
+    CHECK(wakeup_reason.request_sources == (kDifPwrmgrWakeupRequestSourceOne |
+                                            kDifPwrmgrWakeupRequestSourceFive));
+  } else {
+    LOG_ERROR("unexpected wakeup_type: 0x%x", wakeup_reason.types);
+  }
+
+  // Read reset info  before check
+  dif_rstmgr_reset_info_bitfield_t rst_info;
+  rst_info = rstmgr_testutils_reason_get();
+  rstmgr_testutils_reason_clear();
+  LOG_INFO("reset info = 0x%02X", rst_info);
+
+  if (rst_info != kDifRstmgrResetInfoPor &&
+      rst_info != kDifRstmgrResetInfoLowPowerExit) {
+    LOG_ERROR("unexpected reset info: 0x%x", rst_info);
+  }
+
+  dif_aon_timer_t aon_timer;
+  CHECK_DIF_OK(dif_aon_timer_init(
+      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+  // Status clean up
+  if (event_idx > 0) {
+    // aon timer clean up
+    CHECK_DIF_OK(dif_aon_timer_wakeup_stop(&aon_timer));
+    //    mmio_region_write32(
+    //        mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR),
+    //        AON_TIMER_WKUP_CAUSE_REG_OFFSET, 0);
+    CHECK_DIF_OK(dif_aon_timer_clear_wakeup_cause(&aon_timer));
+    // sysrst ctrl status clean up
+    CHECK_DIF_OK(dif_sysrst_ctrl_ulp_wakeup_clear_status(&sysrst_ctrl));
+  }
+
+  if (event_idx < kNumRound) {
+    LOG_INFO("Test round %d", event_idx);
+  } else {
+    LOG_INFO("Test finish");
+    return true;
+  }
+
+  // pin mux / sysrst ctrl set up for push button wakeup
+  prgm_push_button_wakeup();
+
+  // Prepare rstmgr for a reset.
+  rstmgr_testutils_pre_reset(&rstmgr);
+
+  // This is mark for sv sequence to prepare to asserting parallel event.
+  LOG_INFO("ready for power down");
+  busy_spin_micros(10);
+  // timer setup in case wake up comes before entering low power mode
+  aon_timer_testutils_wakeup_config(&aon_timer, wakeup_threshold);
+
+  // Deep sleep.
+  pwrmgr_testutils_enable_low_power(
+      &pwrmgr,
+      (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
+       kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
+       kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
+      0);
+
+  // Enter low power mode.
+  wait_for_interrupt();
+
+  return false;
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_deep_sleep_all_reset_reqs_test.c b/sw/device/tests/sim_dv/pwrmgr_deep_sleep_all_reset_reqs_test.c
new file mode 100644
index 0000000..b5f3191
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_deep_sleep_all_reset_reqs_test.c
@@ -0,0 +1,520 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/math.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_alert_handler.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/dif/dif_rv_timer.h"
+#include "sw/device/lib/dif/dif_sysrst_ctrl.h"
+#include "sw/device/lib/runtime/irq.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/alert_handler_testutils.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rstmgr_testutils.h"
+#include "sw/device/lib/testing/rv_plic_testutils.h"
+#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+// In dvsim, one run
+// with --waves can take
+// 1.874h  | 38.068ms
+// without --waves,
+// 38.072m | 39.484ms
+
+OTTF_DEFINE_TEST_CONFIG();
+static volatile const uint8_t RST_IDX[7] = {0, 1, 2, 3, 4, 5, 6};
+static const uint32_t kPlicTarget = kTopMatchaPlicTargetIbex0;
+
+/**
+ * Objects to access the peripherals used in this test via dif API.
+ */
+static dif_flash_ctrl_state_t flash_ctrl;
+static dif_rv_plic_t plic;
+static dif_alert_handler_t alert_handler;
+static dif_aon_timer_t aon_timer;
+static dif_pwrmgr_t pwrmgr;
+static dif_sysrst_ctrl_t sysrst_ctrl_aon;
+static dif_rstmgr_t rstmgr;
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ *
+ * Notice these settings are suitable for sim_dv. For other platforms we scale
+ * the resulting cycles by a factor of 10.
+ */
+enum {
+  kWdogBarkMicros = 3 * 100,          // 300 us
+  kWdogBiteMicros = 4 * 100,          // 400 us
+  kEscalationPhase0Micros = 1 * 100,  // 100 us
+  // The cpu value is slightly larger to avoid flakey results.
+  kEscalationPhase0MicrosCpu = kEscalationPhase0Micros + 20,  // 120 us
+  kEscalationPhase1Micros = 5 * 100,                          // 500 us
+  kEscalationPhase2Micros = 50,                               // 50 us
+};
+
+static_assert(
+    kWdogBarkMicros < kWdogBiteMicros &&
+        kWdogBarkMicros > kEscalationPhase0Micros &&
+        kWdogBarkMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros) &&
+        kWdogBiteMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros),
+    "The wdog bark and bite shall happens during the escalation phase 1");
+
+/**
+ * External ISR.
+ *
+ * Handles all peripheral interrupts on Ibex. PLIC asserts an external interrupt
+ * line to the CPU, which results in a call to this OTTF ISR. This ISR
+ * overrides the default OTTF implementation.
+ */
+void ottf_external_isr(void) {
+  top_matcha_plic_peripheral_t peripheral;
+  dif_rv_plic_irq_id_t irq_id;
+  uint32_t irq = 0;
+  uint32_t alert = 0;
+
+  CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic, kPlicTarget, &irq_id));
+
+  peripheral = (top_matcha_plic_peripheral_t)
+      top_matcha_plic_interrupt_for_peripheral[irq_id];
+
+  if (peripheral == kTopMatchaPlicPeripheralAonTimerAon) {
+    irq =
+        (dif_aon_timer_irq_t)(irq_id -
+                              (dif_rv_plic_irq_id_t)
+                                  kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired);
+
+    // Stops escalation process.
+    CHECK_DIF_OK(dif_alert_handler_escalation_clear(&alert_handler,
+                                                    kDifAlertHandlerClassA));
+    CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(&aon_timer, irq));
+
+    CHECK(irq != kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark,
+          "AON Timer Wdog should not bark");
+
+  } else if (peripheral == kTopMatchaPlicPeripheralAlertHandler) {
+    irq = (dif_rv_plic_irq_id_t)(irq_id -
+                                 (dif_rv_plic_irq_id_t)
+                                     kTopMatchaPlicIrqIdAlertHandlerClassa);
+
+    CHECK_DIF_OK(dif_alert_handler_alert_acknowledge(&alert_handler, alert));
+
+    dif_alert_handler_class_state_t state;
+    CHECK_DIF_OK(dif_alert_handler_get_class_state(
+        &alert_handler, kDifAlertHandlerClassA, &state));
+
+    CHECK(state == kDifAlertHandlerClassStatePhase0, "Wrong phase %d", state);
+
+    CHECK_DIF_OK(dif_alert_handler_irq_acknowledge(&alert_handler, irq));
+  }
+
+  // Complete the IRQ by writing the IRQ source to the Ibex specific CC
+  // register.
+  CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic, kPlicTarget, irq_id));
+}
+
+/**
+ * Initialize the peripherals used in this test.
+ */
+void init_peripherals(void) {
+  // Initialize pwrmgr.
+  CHECK_DIF_OK(dif_pwrmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+
+  // Initialize sysrst_ctrl.
+  CHECK_DIF_OK(dif_sysrst_ctrl_init(
+      mmio_region_from_addr(TOP_MATCHA_SYSRST_CTRL_AON_BASE_ADDR),
+      &sysrst_ctrl_aon));
+
+  // Initialize rstmgr to check the reset reason.
+  CHECK_DIF_OK(dif_rstmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+  // Initialize aon timer to use the wdog.
+  CHECK_DIF_OK(dif_aon_timer_init(
+      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+  // Initialize flash_ctrl
+  CHECK_DIF_OK(dif_flash_ctrl_init_state(
+      &flash_ctrl,
+      mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR)));
+
+  // Initialize plic.
+  CHECK_DIF_OK(dif_rv_plic_init(
+      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic));
+
+  rv_plic_testutils_irq_range_enable(
+      &plic, kPlicTarget, kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired,
+      kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark);
+
+  // Initialize alert handler.
+  CHECK_DIF_OK(dif_alert_handler_init(
+      mmio_region_from_addr(TOP_MATCHA_ALERT_HANDLER_BASE_ADDR),
+      &alert_handler));
+}
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ */
+static void alert_handler_config(void) {
+  dif_alert_handler_alert_t alerts[] = {kTopMatchaAlertIdPwrmgrAonFatalFault};
+  dif_alert_handler_class_t alert_classes[] = {kDifAlertHandlerClassA};
+
+  dif_alert_handler_escalation_phase_t esc_phases[] = {
+      {.phase = kDifAlertHandlerClassStatePhase0,
+       .signal = 0,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase0Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase1,
+       .signal = 1,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase1Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase2,
+       .signal = 3,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase2Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()}};
+
+  dif_alert_handler_class_config_t class_config[] = {{
+      .auto_lock_accumulation_counter = kDifToggleDisabled,
+      .accumulator_threshold = 0,
+      .irq_deadline_cycles = alert_handler_testutils_get_cycles_from_us(10) *
+                             alert_handler_testutils_cycle_rescaling_factor(),
+      .escalation_phases = esc_phases,
+      .escalation_phases_len = ARRAYSIZE(esc_phases),
+      .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase3,
+  }};
+
+  dif_alert_handler_class_t classes[] = {kDifAlertHandlerClassA};
+  dif_alert_handler_config_t config = {
+      .alerts = alerts,
+      .alert_classes = alert_classes,
+      .alerts_len = ARRAYSIZE(alerts),
+      .classes = classes,
+      .class_configs = class_config,
+      .classes_len = ARRAYSIZE(class_config),
+      .ping_timeout = 0,
+  };
+
+  alert_handler_testutils_configure_all(&alert_handler, config,
+                                        kDifToggleEnabled);
+  // Enables alert handler irq.
+  CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
+      &alert_handler, kDifAlertHandlerIrqClassa, kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer interrupt test.
+ */
+static void trigger_escalate(dif_aon_timer_t *aon_timer,
+                             const dif_pwrmgr_t *pwrmgr) {
+  uint64_t bark_cycles =
+      udiv64_slow(kWdogBarkMicros * kClockFreqAonHz, 1000000, NULL) *
+      alert_handler_testutils_cycle_rescaling_factor();
+  uint64_t bite_cycles =
+      udiv64_slow(kWdogBiteMicros * kClockFreqAonHz, 1000000, NULL) *
+      alert_handler_testutils_cycle_rescaling_factor();
+
+  CHECK(bite_cycles < UINT32_MAX,
+        "The value %u can't fit into the 32 bits timer counter.", bite_cycles);
+
+  LOG_INFO(
+      "Wdog will bark after %u/%u us/cycles and bite after %u/%u us/cycles",
+      (uint32_t)kWdogBarkMicros, (uint32_t)bark_cycles,
+      (uint32_t)kWdogBiteMicros, (uint32_t)bite_cycles);
+
+  // Setup the wdog bark and bite timeouts.
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+
+  // Trigger the alert handler to escalate.
+  dif_pwrmgr_alert_t alert = kDifPwrmgrAlertFatalFault;
+  CHECK_DIF_OK(dif_pwrmgr_alert_force(pwrmgr, alert));
+}
+
+/**
+ * Configure the sysrst.
+ */
+static void config_sysrst(const dif_pwrmgr_t *pwrmgr,
+                          const dif_sysrst_ctrl_t *sysrst_ctrl_aon) {
+  LOG_INFO("sysrst enabled");
+
+  // Set sysrst as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceOne,
+                                              kDifToggleEnabled));
+  LOG_INFO("Reset Request SourceOne is set");
+
+  // Configure sysrst key combo
+  // reset pulse : 50 us
+  // detect durration : 50 us
+
+  dif_sysrst_ctrl_key_combo_config_t sysrst_ctrl_key_combo_config = {
+      .keys = kDifSysrstCtrlKeyAll,
+      .detection_time_threshold = 10,
+      .actions = kDifSysrstCtrlKeyComboActionAll,
+      .embedded_controller_reset_duration = 10};
+
+  CHECK_DIF_OK(dif_sysrst_ctrl_key_combo_detect_configure(
+      sysrst_ctrl_aon, kDifSysrstCtrlKeyCombo0, sysrst_ctrl_key_combo_config));
+  // Configure sysrst input change
+  // debounce durration : 100 us
+  dif_sysrst_ctrl_input_change_config_t sysrst_ctrl_input_change_config = {
+      .input_changes = kDifSysrstCtrlInputAll, .debounce_time_threshold = 20};
+
+  // Configure pinmux
+  dif_pinmux_t pinmux;
+  CHECK_DIF_OK(dif_pinmux_init(
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+
+  CHECK_DIF_OK(dif_sysrst_ctrl_input_change_detect_configure(
+      sysrst_ctrl_aon, sysrst_ctrl_input_change_config));
+
+  CHECK_DIF_OK(dif_pinmux_input_select(
+      &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonKey0In,
+      kTopMatchaPinmuxInselIor13));
+}
+
+static void low_power_sysrst(const dif_pwrmgr_t *pwrmgr) {
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceOne,
+                                    0);
+  LOG_INFO("Low power set for sysrst");
+
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+static void timer_on(uint32_t usec) {
+  busy_spin_micros(usec);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for reset!");
+}
+
+/**
+ * Configure the wdog.
+ */
+static void config_wdog(const dif_aon_timer_t *aon_timer,
+                        const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us,
+                        uint64_t bite_time_us) {
+  uint32_t bark_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bark_time_us);
+  uint32_t bite_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bite_time_us);
+
+  LOG_INFO("Wdog will bark after %u us and bite after %u us",
+           (uint32_t)bark_time_us, (uint32_t)bite_time_us);
+  // Setup the wdog bark and bite timeouts.
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+  // Set wdog as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer wdog bite reset test.
+ */
+static void wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                           const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+
+  // The `intr_state` takes 3 aon clock cycles to rise plus 2 extra cycles as a
+  // precaution.
+  uint32_t wait_us =
+      bark_time_us +
+      udiv64_slow(5 * 1000000 + kClockFreqAonHz - 1, kClockFreqAonHz, NULL);
+
+  // Wait bark time and check that the bark interrupt requested.
+  busy_spin_micros(wait_us);
+  bool is_pending = false;
+  CHECK_DIF_OK(dif_aon_timer_irq_is_pending(
+      aon_timer, kDifAonTimerIrqWdogTimerBark, &is_pending));
+  CHECK(is_pending, "Wdog bark irq did not rise after %u microseconds",
+        wait_us);
+
+  // Wait for the remaining time to the wdog bite.
+  busy_spin_micros(wait_us);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for Wdog bite reset!");
+}
+
+/**
+ * Execute the aon timer wdog bite reset during sleep test.
+ */
+static void sleep_wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                                 const dif_pwrmgr_t *pwrmgr,
+                                 uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+}
+
+static void low_power_wdog(const dif_pwrmgr_t *pwrmgr) {
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceTwo,
+                                    0);
+  LOG_INFO("Low power set for watch dog");
+  wait_for_interrupt();
+  // If we arrive here the test must fail.
+  CHECK(false, "Fail to enter in low power mode!");
+}
+
+static void low_power_por(const dif_pwrmgr_t *pwrmgr) {
+  // Set por as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(
+      pwrmgr,
+      (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
+       kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
+       kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
+      0);
+  LOG_INFO("ready for pad por");
+
+  // Enter in low power mode.
+  wait_for_interrupt();
+  // If we arrive here the test must fail.
+  CHECK(false, "Fail to enter in low power mode!");
+}
+
+bool test_main(void) {
+  // Enable global and external IRQ at Ibex.
+  irq_global_ctrl(true);
+  irq_external_ctrl(true);
+
+  init_peripherals();
+
+  // Enable all the AON interrupts used in this test.
+  rv_plic_testutils_irq_range_enable(&plic, kPlicTarget,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassa,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassd);
+
+  alert_handler_config();
+
+  // First check the flash stored value.
+  uint32_t event_idx = flash_ctrl_testutils_counter_get(0);
+
+  // Enable flash access
+  flash_ctrl_testutils_default_region_access(&flash_ctrl,
+                                             /*rd_en*/ true,
+                                             /*prog_en*/ true,
+                                             /*erase_en*/ true,
+                                             /*scramble_en*/ false,
+                                             /*ecc_en*/ false,
+                                             /*he_en*/ false);
+
+  // Increment flash counter to know where we are.
+  flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+
+  LOG_INFO("Test round %d", event_idx);
+  LOG_INFO("RST_IDX[%d] = %d", event_idx, RST_IDX[event_idx]);
+
+  // Check if there was a HW reset caused by expected cases.
+  dif_rstmgr_reset_info_bitfield_t rst_info;
+  rst_info = rstmgr_testutils_reason_get();
+  rstmgr_testutils_reason_clear();
+
+  CHECK(rst_info == kDifRstmgrResetInfoPor ||
+            rst_info == kDifRstmgrResetInfoSysRstCtrl ||
+            rst_info == kDifRstmgrResetInfoWatchdog ||
+            rst_info == kDifRstmgrResetInfoEscalation ||
+            rst_info == kDifRstmgrResetInfoLowPowerExit ||
+            rst_info == (kDifRstmgrResetInfoSysRstCtrl |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info ==
+                (kDifRstmgrResetInfoPor | kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoWatchdog |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoEscalation |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == kDifRstmgrResetInfoSw,
+        "Wrong reset reason %02X", rst_info);
+
+  switch (RST_IDX[event_idx]) {
+    case 0:
+      LOG_INFO("Booting and setting deep sleep followed by sysrst");
+      config_sysrst(&pwrmgr, &sysrst_ctrl_aon);
+      low_power_sysrst(&pwrmgr);
+      break;
+    case 1:
+      LOG_INFO("Booting and setting deep sleep followed by hw por");
+      low_power_por(&pwrmgr);
+      break;
+    case 2:
+      LOG_INFO(
+          "Booting and setting deep sleep mode followed for low_power entry "
+          "reset");
+      LOG_INFO("Let SV wait timer reset");
+      // Executing the wdog bite reset during sleep test.
+      // actually the same test as deep sleep + watchdog
+      rstmgr_testutils_pre_reset(&rstmgr);
+      sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+      low_power_wdog(&pwrmgr);
+      break;
+    case 3:
+      LOG_INFO(
+          "Booting and setting deep sleep followed by watchdog reset "
+          "combined "
+          "with sw_req");
+      LOG_INFO("Let SV wait timer reset");
+      // Executing the wdog bite reset during sleep test.
+      rstmgr_testutils_pre_reset(&rstmgr);
+
+      // Assert reeset req
+      CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+      LOG_INFO("Device reset from sw");
+      sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+      low_power_wdog(&pwrmgr);
+      break;
+    case 4:
+      LOG_INFO("Booting and setting deep sleep followed by watchdog reset");
+      LOG_INFO("Let SV wait timer reset");
+      // Executing the wdog bite reset during sleep test.
+      rstmgr_testutils_pre_reset(&rstmgr);
+      sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+      low_power_wdog(&pwrmgr);
+      break;
+    case 5:
+      LOG_INFO("Booting and running normal sleep followed by escalation reset");
+      LOG_INFO("Let SV wait timer reset");
+      trigger_escalate(&aon_timer, &pwrmgr);
+      timer_on(kEscalationPhase0MicrosCpu);
+      break;
+    case 6:
+      LOG_INFO("Last Booting");
+      return true;
+      break;
+    default:
+      LOG_INFO("Booting for undefined case");
+  }
+
+  return false;
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_normal_sleep_all_reset_reqs_test.c b/sw/device/tests/sim_dv/pwrmgr_normal_sleep_all_reset_reqs_test.c
new file mode 100644
index 0000000..151b9c5
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_normal_sleep_all_reset_reqs_test.c
@@ -0,0 +1,532 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/math.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_alert_handler.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/dif/dif_rv_timer.h"
+#include "sw/device/lib/dif/dif_sysrst_ctrl.h"
+#include "sw/device/lib/runtime/irq.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/alert_handler_testutils.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rstmgr_testutils.h"
+#include "sw/device/lib/testing/rv_plic_testutils.h"
+#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+static volatile const uint8_t RST_IDX[7] = {0, 1, 2, 3, 4, 5, 6};
+static const uint32_t kPlicTarget = kTopMatchaPlicTargetIbex0;
+
+/**
+ * Objects to access the peripherals used in this test via dif API.
+ */
+static dif_flash_ctrl_state_t flash_ctrl;
+static dif_rv_plic_t plic;
+static dif_alert_handler_t alert_handler;
+static dif_aon_timer_t aon_timer;
+static dif_pwrmgr_t pwrmgr;
+static dif_sysrst_ctrl_t sysrst_ctrl_aon;
+static dif_rstmgr_t rstmgr;
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ *
+ * Notice these settings are suitable for sim_dv. For other platforms we scale
+ * the resulting cycles by a factor of 10.
+ */
+enum {
+  kWdogBarkMicros = 3 * 100,          // 300 us
+  kWdogBiteMicros = 4 * 100,          // 400 us
+  kEscalationPhase0Micros = 1 * 100,  // 100 us
+  // The cpu value is slightly larger to avoid flakey results.
+  kEscalationPhase0MicrosCpu = kEscalationPhase0Micros + 20,  // 120 us
+  kEscalationPhase1Micros = 5 * 100,                          // 500 us
+  kEscalationPhase2Micros = 50,                               // 50 us
+};
+
+static_assert(
+    kWdogBarkMicros < kWdogBiteMicros &&
+        kWdogBarkMicros > kEscalationPhase0Micros &&
+        kWdogBarkMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros) &&
+        kWdogBiteMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros),
+    "The wdog bark and bite shall happens during the escalation phase 1");
+
+/**
+ * External ISR.
+ *
+ * Handles all peripheral interrupts on Ibex. PLIC asserts an external interrupt
+ * line to the CPU, which results in a call to this OTTF ISR. This ISR
+ * overrides the default OTTF implementation.
+ */
+void ottf_external_isr(void) {
+  top_matcha_plic_peripheral_t peripheral;
+  dif_rv_plic_irq_id_t irq_id;
+  uint32_t irq = 0;
+  uint32_t alert = 0;
+
+  CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic, kPlicTarget, &irq_id));
+
+  peripheral = (top_matcha_plic_peripheral_t)
+      top_matcha_plic_interrupt_for_peripheral[irq_id];
+
+  if (peripheral == kTopMatchaPlicPeripheralAonTimerAon) {
+    irq =
+        (dif_aon_timer_irq_t)(irq_id -
+                              (dif_rv_plic_irq_id_t)
+                                  kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired);
+
+    // Stops escalation process.
+    CHECK_DIF_OK(dif_alert_handler_escalation_clear(&alert_handler,
+                                                    kDifAlertHandlerClassA));
+    CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(&aon_timer, irq));
+
+    CHECK(irq != kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark,
+          "AON Timer Wdog should not bark");
+
+  } else if (peripheral == kTopMatchaPlicPeripheralAlertHandler) {
+    irq = (dif_aon_timer_irq_t)(irq_id -
+                                (dif_rv_plic_irq_id_t)
+                                    kTopMatchaPlicIrqIdAlertHandlerClassa);
+
+    CHECK_DIF_OK(dif_alert_handler_alert_acknowledge(&alert_handler, alert));
+
+    dif_alert_handler_class_state_t state;
+    CHECK_DIF_OK(dif_alert_handler_get_class_state(
+        &alert_handler, kDifAlertHandlerClassA, &state));
+
+    CHECK(state == kDifAlertHandlerClassStatePhase0, "Wrong phase %d", state);
+
+    CHECK_DIF_OK(dif_alert_handler_irq_acknowledge(&alert_handler, irq));
+  }
+
+  // Complete the IRQ by writing the IRQ source to the Ibex specific CC
+  // register.
+  CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic, kPlicTarget, irq_id));
+}
+
+/**
+ * Initialize the peripherals used in this test.
+ */
+void init_peripherals(void) {
+  // Initialize pwrmgr.
+  CHECK_DIF_OK(dif_pwrmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+
+  // Initialize sysrst_ctrl.
+  CHECK_DIF_OK(dif_sysrst_ctrl_init(
+      mmio_region_from_addr(TOP_MATCHA_SYSRST_CTRL_AON_BASE_ADDR),
+      &sysrst_ctrl_aon));
+
+  // Initialize rstmgr to check the reset reason.
+  CHECK_DIF_OK(dif_rstmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+  // Initialize aon timer to use the wdog.
+  CHECK_DIF_OK(dif_aon_timer_init(
+      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+  // Initialize flash_ctrl
+  CHECK_DIF_OK(dif_flash_ctrl_init_state(
+      &flash_ctrl,
+      mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR)));
+
+  // Initialize plic.
+  CHECK_DIF_OK(dif_rv_plic_init(
+      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic));
+
+  rv_plic_testutils_irq_range_enable(
+      &plic, kPlicTarget, kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired,
+      kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark);
+
+  // Initialize alert handler.
+  CHECK_DIF_OK(dif_alert_handler_init(
+      mmio_region_from_addr(TOP_MATCHA_ALERT_HANDLER_BASE_ADDR),
+      &alert_handler));
+}
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ */
+static void alert_handler_config(void) {
+  dif_alert_handler_alert_t alerts[] = {kTopMatchaAlertIdPwrmgrAonFatalFault};
+  dif_alert_handler_class_t alert_classes[] = {kDifAlertHandlerClassA};
+
+  dif_alert_handler_escalation_phase_t esc_phases[] = {
+      {.phase = kDifAlertHandlerClassStatePhase0,
+       .signal = 0,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase0Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase1,
+       .signal = 1,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase1Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase2,
+       .signal = 3,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase2Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()}};
+
+  dif_alert_handler_class_config_t class_config[] = {{
+      .auto_lock_accumulation_counter = kDifToggleDisabled,
+      .accumulator_threshold = 0,
+      .irq_deadline_cycles = alert_handler_testutils_get_cycles_from_us(10) *
+                             alert_handler_testutils_cycle_rescaling_factor(),
+      .escalation_phases = esc_phases,
+      .escalation_phases_len = ARRAYSIZE(esc_phases),
+      .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase3,
+  }};
+
+  dif_alert_handler_class_t classes[] = {kDifAlertHandlerClassA};
+  dif_alert_handler_config_t config = {
+      .alerts = alerts,
+      .alert_classes = alert_classes,
+      .alerts_len = ARRAYSIZE(alerts),
+      .classes = classes,
+      .class_configs = class_config,
+      .classes_len = ARRAYSIZE(class_config),
+      .ping_timeout = 0,
+  };
+
+  alert_handler_testutils_configure_all(&alert_handler, config,
+                                        kDifToggleEnabled);
+  // Enables alert handler irq.
+  CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
+      &alert_handler, kDifAlertHandlerIrqClassa, kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer interrupt test.
+ */
+static void config_escalate(dif_aon_timer_t *aon_timer,
+                            const dif_pwrmgr_t *pwrmgr) {
+  uint64_t bark_cycles =
+      udiv64_slow(kWdogBarkMicros * kClockFreqAonHz, 1000000, NULL) *
+      alert_handler_testutils_cycle_rescaling_factor();
+  uint64_t bite_cycles =
+      udiv64_slow(kWdogBiteMicros * kClockFreqAonHz, 1000000, NULL) *
+      alert_handler_testutils_cycle_rescaling_factor();
+
+  CHECK(bite_cycles < UINT32_MAX,
+        "The value %u can't fit into the 32 bits timer counter.", bite_cycles);
+
+  LOG_INFO(
+      "Wdog will bark after %u/%u us/cycles and bite after %u/%u us/cycles",
+      (uint32_t)kWdogBarkMicros, (uint32_t)bark_cycles,
+      (uint32_t)kWdogBiteMicros, (uint32_t)bite_cycles);
+
+  // Setup the wdog bark and bite timeouts.
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+
+  // Trigger the alert handler to escalate.
+  dif_pwrmgr_alert_t alert = kDifPwrmgrAlertFatalFault;
+  CHECK_DIF_OK(dif_pwrmgr_alert_force(pwrmgr, alert));
+}
+
+/**
+ * Configure the sysrst.
+ */
+static void config_sysrst(const dif_pwrmgr_t *pwrmgr,
+                          const dif_sysrst_ctrl_t *sysrst_ctrl_aon) {
+  LOG_INFO("sysrst enabled");
+
+  // Set sysrst as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceOne,
+                                              kDifToggleEnabled));
+  LOG_INFO("Reset Request SourceOne is set");
+
+  // Configure sysrst key combo
+  // reset pulse : 50 us
+  // detect durration : 50 us
+
+  dif_sysrst_ctrl_key_combo_config_t sysrst_ctrl_key_combo_config = {
+      .keys = kDifSysrstCtrlKeyAll,
+      .detection_time_threshold = 10,
+      .actions = kDifSysrstCtrlKeyComboActionAll,
+      .embedded_controller_reset_duration = 10};
+
+  CHECK_DIF_OK(dif_sysrst_ctrl_key_combo_detect_configure(
+      sysrst_ctrl_aon, kDifSysrstCtrlKeyCombo0, sysrst_ctrl_key_combo_config));
+  // Configure sysrst input change
+  // debounce durration : 100 us
+  dif_sysrst_ctrl_input_change_config_t sysrst_ctrl_input_change_config = {
+      .input_changes = kDifSysrstCtrlInputAll, .debounce_time_threshold = 20};
+
+  // Configure pinmux
+  dif_pinmux_t pinmux;
+  CHECK_DIF_OK(dif_pinmux_init(
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+
+  CHECK_DIF_OK(dif_sysrst_ctrl_input_change_detect_configure(
+      sysrst_ctrl_aon, sysrst_ctrl_input_change_config));
+
+  CHECK_DIF_OK(dif_pinmux_input_select(
+      &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonKey0In,
+      kTopMatchaPinmuxInselIor13));
+}
+
+static void normal_sleep_sysrst(const dif_pwrmgr_t *pwrmgr) {
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceOne,
+                                    config);
+  LOG_INFO("Normal sleep set for sysrst");
+
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+static void timer_on(uint32_t usec) {
+  busy_spin_micros(usec);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for reset!");
+}
+
+/**
+ * Configure the wdog.
+ */
+static void config_wdog(const dif_aon_timer_t *aon_timer,
+                        const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us,
+                        uint64_t bite_time_us) {
+  uint32_t bark_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bark_time_us);
+  uint32_t bite_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bite_time_us);
+
+  LOG_INFO("Wdog will bark after %u us and bite after %u us",
+           (uint32_t)bark_time_us, (uint32_t)bite_time_us);
+  // Setup the wdog bark and bite timeouts.
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+  // Set wdog as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer wdog bite reset test.
+ */
+static void wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                           const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+
+  // The `intr_state` takes 3 aon clock cycles to rise plus 2 extra cycles as a
+  // precaution.
+  uint32_t wait_us =
+      bark_time_us +
+      udiv64_slow(5 * 1000000 + kClockFreqAonHz - 1, kClockFreqAonHz, NULL);
+
+  // Wait bark time and check that the bark interrupt requested.
+  busy_spin_micros(wait_us);
+  bool is_pending = false;
+  CHECK_DIF_OK(dif_aon_timer_irq_is_pending(
+      aon_timer, kDifAonTimerIrqWdogTimerBark, &is_pending));
+  CHECK(is_pending, "Wdog bark irq did not rise after %u microseconds",
+        wait_us);
+
+  // Wait for the remaining time to the wdog bite.
+  busy_spin_micros(wait_us);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for Wdog bite reset!");
+}
+
+/**
+ * Execute the aon timer wdog bite reset during sleep test.
+ */
+static void sleep_wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                                 const dif_pwrmgr_t *pwrmgr,
+                                 uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+}
+
+static void normal_sleep_wdog(const dif_pwrmgr_t *pwrmgr) {
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+
+  // Enter in low power mode.
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceTwo,
+                                    config);
+  LOG_INFO("Normal sleep set for watchdog");
+  wait_for_interrupt();
+}
+
+static void normal_sleep_por(const dif_pwrmgr_t *pwrmgr) {
+  // Set por as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(
+      pwrmgr,
+      (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
+       kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
+       kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
+      config);
+  LOG_INFO("ready for pad por");
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+bool test_main(void) {
+  // Enable global and external IRQ at Ibex.
+  irq_global_ctrl(true);
+  irq_external_ctrl(true);
+
+  init_peripherals();
+
+  // Enable all the AON interrupts used in this test.
+  rv_plic_testutils_irq_range_enable(&plic, kPlicTarget,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassa,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassd);
+
+  alert_handler_config();
+
+  // First check the flash stored value
+  uint32_t event_idx = flash_ctrl_testutils_counter_get(0);
+
+  // Enable flash access
+  flash_ctrl_testutils_default_region_access(&flash_ctrl,
+                                             /*rd_en*/ true,
+                                             /*prog_en*/ true,
+                                             /*erase_en*/ true,
+                                             /*scramble_en*/ false,
+                                             /*ecc_en*/ false,
+                                             /*he_en*/ false);
+
+  // Increment flash counter to know where we are
+  flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+
+  LOG_INFO("Test round %d", event_idx);
+  LOG_INFO("RST_IDX[%d] = %d", event_idx, RST_IDX[event_idx]);
+
+  // Check if there was a HW reset caused by expected cases
+  dif_rstmgr_reset_info_bitfield_t rst_info;
+  rst_info = rstmgr_testutils_reason_get();
+  rstmgr_testutils_reason_clear();
+
+  CHECK(rst_info == kDifRstmgrResetInfoPor ||
+            rst_info == kDifRstmgrResetInfoSysRstCtrl ||
+            rst_info == kDifRstmgrResetInfoWatchdog ||
+            rst_info == kDifRstmgrResetInfoEscalation ||
+            rst_info == kDifRstmgrResetInfoLowPowerExit ||
+            rst_info == (kDifRstmgrResetInfoSysRstCtrl |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info ==
+                (kDifRstmgrResetInfoPor | kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoWatchdog |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoEscalation |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == kDifRstmgrResetInfoSw,
+        "Wrong reset reason %02X", rst_info);
+
+  switch (RST_IDX[event_idx]) {
+    case 0:
+      LOG_INFO("Booting and setting normal sleep followed by sysrst");
+      config_sysrst(&pwrmgr, &sysrst_ctrl_aon);
+      normal_sleep_sysrst(&pwrmgr);
+      timer_on(kWdogBiteMicros);
+      break;
+    case 1:
+      LOG_INFO("Booting and setting normal sleep followed by hw por");
+      normal_sleep_por(&pwrmgr);
+      timer_on(kWdogBiteMicros);
+      break;
+    case 2:
+      LOG_INFO(
+          "Booting and setting normal sleep mode followed for low_power "
+          "entry reset");
+      LOG_INFO("Let SV wait timer reset");
+      // actually the same test as normal sleep + watchdog
+      rstmgr_testutils_pre_reset(&rstmgr);
+      sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+      normal_sleep_wdog(&pwrmgr);
+      timer_on(kEscalationPhase0MicrosCpu);
+      break;
+    case 3:
+      LOG_INFO(
+          "Booting and setting normal sleep followed by watchdog reset "
+          "combined "
+          "with sw_req");
+      LOG_INFO("Let SV wait timer reset");
+      // Executing the wdog bite reset during sleep test.
+      rstmgr_testutils_pre_reset(&rstmgr);
+
+      // Assert reeset req
+      CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+      LOG_INFO("Device reset from sw");
+      sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+      normal_sleep_wdog(&pwrmgr);
+      timer_on(kEscalationPhase0MicrosCpu);
+      break;
+    case 4:
+      LOG_INFO("Booting and setting normal sleep followed by watchdog reset");
+      LOG_INFO("Let SV wait timer reset");
+      // Executing the wdog bite reset during sleep test.
+      rstmgr_testutils_pre_reset(&rstmgr);
+      sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+      normal_sleep_wdog(&pwrmgr);
+      timer_on(kEscalationPhase0MicrosCpu);
+      break;
+    case 5:
+      LOG_INFO("Booting and running normal sleep followed by escalation reset");
+      LOG_INFO("Let SV wait timer reset");
+      config_escalate(&aon_timer, &pwrmgr);
+      timer_on(kEscalationPhase0MicrosCpu);
+      break;
+    case 6:
+      LOG_INFO("Last Booting");
+      return true;
+      break;
+    default:
+      LOG_INFO("Booting for undefined case");
+  }
+
+  return false;
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_random_sleep_all_reset_reqs_test.c b/sw/device/tests/sim_dv/pwrmgr_random_sleep_all_reset_reqs_test.c
new file mode 100644
index 0000000..440a84b
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_random_sleep_all_reset_reqs_test.c
@@ -0,0 +1,617 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/math.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_alert_handler.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/dif/dif_rv_timer.h"
+#include "sw/device/lib/dif/dif_sysrst_ctrl.h"
+#include "sw/device/lib/runtime/irq.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/alert_handler_testutils.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rstmgr_testutils.h"
+#include "sw/device/lib/testing/rv_plic_testutils.h"
+#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+static volatile const uint8_t RST_IDX[12] = {0, 1, 2, 3, 4,  5,
+                                             6, 7, 8, 9, 10, 11};
+static const uint32_t kPlicTarget = kTopMatchaPlicTargetIbex0;
+
+/**
+ * Objects to access the peripherals used in this test via dif API.
+ */
+static dif_flash_ctrl_state_t flash_ctrl;
+static dif_rv_plic_t plic;
+static dif_alert_handler_t alert_handler;
+static dif_aon_timer_t aon_timer;
+static dif_pwrmgr_t pwrmgr;
+static dif_sysrst_ctrl_t sysrst_ctrl_aon;
+static dif_rstmgr_t rstmgr;
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ */
+enum {
+  kWdogBarkMicros = 3 * 100,          // 300 us
+  kWdogBiteMicros = 4 * 100,          // 400 us
+  kEscalationPhase0Micros = 1 * 100,  // 100 us
+  // The cpu value is slightly larger as the busy_spin_micros
+  // routine cycle count comes out slightly smaller due to the
+  // fact that it does not divide by exactly 1M
+  // see sw/device/lib/runtime/hart.c
+  kEscalationPhase0MicrosCpu = kEscalationPhase0Micros + 20,  // 120 us
+  kEscalationPhase1Micros = 5 * 100,                          // 500 us
+  kEscalationPhase2Micros = 50,                               // 50 us
+};
+
+static_assert(
+    kWdogBarkMicros < kWdogBiteMicros &&
+        kWdogBarkMicros > kEscalationPhase0Micros &&
+        kWdogBarkMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros) &&
+        kWdogBiteMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros),
+    "The wdog bark and bite shall happens during the escalation phase 1");
+
+/**
+ * External ISR.
+ *
+ * Handles all peripheral interrupts on Ibex. PLIC asserts an external interrupt
+ * line to the CPU, which results in a call to this OTTF ISR. This ISR
+ * overrides the default OTTF implementation.
+ */
+void ottf_external_isr(void) {
+  top_matcha_plic_peripheral_t peripheral;
+  dif_rv_plic_irq_id_t irq_id;
+  uint32_t irq = 0;
+  uint32_t alert = 0;
+
+  CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic, kPlicTarget, &irq_id));
+
+  peripheral = (top_matcha_plic_peripheral_t)
+      top_matcha_plic_interrupt_for_peripheral[irq_id];
+
+  if (peripheral == kTopMatchaPlicPeripheralAonTimerAon) {
+    irq =
+        (dif_aon_timer_irq_t)(irq_id -
+                              (dif_rv_plic_irq_id_t)
+                                  kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired);
+
+    // Stops escalation process.
+    CHECK_DIF_OK(dif_alert_handler_escalation_clear(&alert_handler,
+                                                    kDifAlertHandlerClassA));
+    CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(&aon_timer, irq));
+
+    CHECK(irq != kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark,
+          "AON Timer Wdog should not bark");
+
+  } else if (peripheral == kTopMatchaPlicPeripheralAlertHandler) {
+    irq = (dif_rv_plic_irq_id_t)(irq_id -
+                                 (dif_rv_plic_irq_id_t)
+                                     kTopMatchaPlicIrqIdAlertHandlerClassa);
+
+    CHECK_DIF_OK(dif_alert_handler_alert_acknowledge(&alert_handler, alert));
+
+    dif_alert_handler_class_state_t state;
+    CHECK_DIF_OK(dif_alert_handler_get_class_state(
+        &alert_handler, kDifAlertHandlerClassA, &state));
+
+    CHECK(state == kDifAlertHandlerClassStatePhase0, "Wrong phase %d", state);
+
+    CHECK_DIF_OK(dif_alert_handler_irq_acknowledge(&alert_handler, irq));
+  }
+
+  // Complete the IRQ by writing the IRQ source to the Ibex specific CC
+  // register.
+  CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic, kPlicTarget, irq_id));
+}
+
+/**
+ * Initialize the peripherals used in this test.
+ */
+void init_peripherals(void) {
+  // Initialize pwrmgr.
+  CHECK_DIF_OK(dif_pwrmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+
+  // Initialize sysrst_ctrl.
+  CHECK_DIF_OK(dif_sysrst_ctrl_init(
+      mmio_region_from_addr(TOP_MATCHA_SYSRST_CTRL_AON_BASE_ADDR),
+      &sysrst_ctrl_aon));
+
+  // Initialize rstmgr to check the reset reason.
+  CHECK_DIF_OK(dif_rstmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+  // Initialize aon timer to use the wdog.
+  CHECK_DIF_OK(dif_aon_timer_init(
+      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+  // Initialize flash_ctrl
+  CHECK_DIF_OK(dif_flash_ctrl_init_state(
+      &flash_ctrl,
+      mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR)));
+
+  // Initialize plic.
+  CHECK_DIF_OK(dif_rv_plic_init(
+      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic));
+
+  rv_plic_testutils_irq_range_enable(
+      &plic, kPlicTarget, kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired,
+      kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark);
+
+  // Initialize alert handler.
+  CHECK_DIF_OK(dif_alert_handler_init(
+      mmio_region_from_addr(TOP_MATCHA_ALERT_HANDLER_BASE_ADDR),
+      &alert_handler));
+}
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ */
+static void alert_handler_config(void) {
+  dif_alert_handler_alert_t alerts[] = {kTopMatchaAlertIdPwrmgrAonFatalFault};
+  dif_alert_handler_class_t alert_classes[] = {kDifAlertHandlerClassA};
+
+  dif_alert_handler_escalation_phase_t esc_phases[] = {
+      {.phase = kDifAlertHandlerClassStatePhase0,
+       .signal = 0,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase0Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase1,
+       .signal = 1,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase1Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase2,
+       .signal = 3,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase2Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()}};
+
+  dif_alert_handler_class_config_t class_config[] = {{
+      .auto_lock_accumulation_counter = kDifToggleDisabled,
+      .accumulator_threshold = 0,
+      .irq_deadline_cycles = alert_handler_testutils_get_cycles_from_us(10) *
+                             alert_handler_testutils_cycle_rescaling_factor(),
+      .escalation_phases = esc_phases,
+      .escalation_phases_len = ARRAYSIZE(esc_phases),
+      .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase3,
+  }};
+
+  dif_alert_handler_class_t classes[] = {kDifAlertHandlerClassA};
+  dif_alert_handler_config_t config = {
+      .alerts = alerts,
+      .alert_classes = alert_classes,
+      .alerts_len = ARRAYSIZE(alerts),
+      .classes = classes,
+      .class_configs = class_config,
+      .classes_len = ARRAYSIZE(class_config),
+      .ping_timeout = 0,
+  };
+
+  alert_handler_testutils_configure_all(&alert_handler, config,
+                                        kDifToggleEnabled);
+  // Enables alert handler irq.
+  CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
+      &alert_handler, kDifAlertHandlerIrqClassa, kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer interrupt test.
+ */
+static void config_escalate(dif_aon_timer_t *aon_timer,
+                            const dif_pwrmgr_t *pwrmgr) {
+  uint64_t bark_cycles =
+      udiv64_slow(kWdogBarkMicros * kClockFreqAonHz, 1000000, NULL) *
+      alert_handler_testutils_cycle_rescaling_factor();
+  uint64_t bite_cycles =
+      udiv64_slow(kWdogBiteMicros * kClockFreqAonHz, 1000000, NULL) *
+      alert_handler_testutils_cycle_rescaling_factor();
+
+  CHECK(bite_cycles < UINT32_MAX,
+        "The value %u can't fit into the 32 bits timer counter.", bite_cycles);
+
+  LOG_INFO(
+      "Wdog will bark after %u/%u us/cycles and bite after %u/%u us/cycles",
+      (uint32_t)kWdogBarkMicros, (uint32_t)bark_cycles,
+      (uint32_t)kWdogBiteMicros, (uint32_t)bite_cycles);
+
+  // Setup the wdog bark and bite timeouts.
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+
+  // Trigger the alert handler to escalate.
+  dif_pwrmgr_alert_t alert = kDifPwrmgrAlertFatalFault;
+  CHECK_DIF_OK(dif_pwrmgr_alert_force(pwrmgr, alert));
+}
+
+/**
+ * Configure the sysrst.
+ */
+static void config_sysrst(const dif_pwrmgr_t *pwrmgr,
+                          const dif_sysrst_ctrl_t *sysrst_ctrl_aon) {
+  LOG_INFO("sysrst enabled");
+
+  // Set sysrst as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceOne,
+                                              kDifToggleEnabled));
+  LOG_INFO("Reset Request SourceOne is set");
+
+  // Configure sysrst key combo
+  // reset pulse : 50 us
+  // detect durration : 50 us
+
+  dif_sysrst_ctrl_key_combo_config_t sysrst_ctrl_key_combo_config = {
+      .keys = kDifSysrstCtrlKeyAll,
+      .detection_time_threshold = 10,
+      .actions = kDifSysrstCtrlKeyComboActionAll,
+      .embedded_controller_reset_duration = 10};
+
+  CHECK_DIF_OK(dif_sysrst_ctrl_key_combo_detect_configure(
+      sysrst_ctrl_aon, kDifSysrstCtrlKeyCombo0, sysrst_ctrl_key_combo_config));
+  // Configure sysrst input change
+  // debounce durration : 100 us
+  dif_sysrst_ctrl_input_change_config_t sysrst_ctrl_input_change_config = {
+      .input_changes = kDifSysrstCtrlInputAll, .debounce_time_threshold = 20};
+
+  // Configure pinmux
+  dif_pinmux_t pinmux;
+  CHECK_DIF_OK(dif_pinmux_init(
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+
+  CHECK_DIF_OK(dif_sysrst_ctrl_input_change_detect_configure(
+      sysrst_ctrl_aon, sysrst_ctrl_input_change_config));
+
+  CHECK_DIF_OK(dif_pinmux_input_select(
+      &pinmux, kTopMatchaPinmuxPeripheralInSysrstCtrlAonKey0In,
+      kTopMatchaPinmuxInselIor13));
+}
+
+static void low_power_sysrst(const dif_pwrmgr_t *pwrmgr) {
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceOne,
+                                    0);
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+static void normal_sleep_sysrst(const dif_pwrmgr_t *pwrmgr) {
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceOne,
+                                    config);
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+static void timer_on(uint32_t usec) {
+  busy_spin_micros(usec);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for reset!");
+}
+
+/**
+ * Configure the wdog.
+ */
+static void config_wdog(const dif_aon_timer_t *aon_timer,
+                        const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us,
+                        uint64_t bite_time_us) {
+  uint32_t bark_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bark_time_us);
+  uint32_t bite_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bite_time_us);
+
+  LOG_INFO("Wdog will bark after %u us and bite after %u us",
+           (uint32_t)bark_time_us, (uint32_t)bite_time_us);
+  // Setup the wdog bark and bite timeouts.
+
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+  // Set wdog as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer wdog bite reset test.
+ */
+static void wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                           const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+
+  // The `intr_state` takes 3 aon clock cycles to rise plus 2 extra cycles as a
+  // precaution.
+  uint32_t wait_us =
+      bark_time_us +
+      udiv64_slow(5 * 1000000 + kClockFreqAonHz - 1, kClockFreqAonHz, NULL);
+
+  // Wait bark time and check that the bark interrupt requested.
+  busy_spin_micros(wait_us);
+  bool is_pending = false;
+  CHECK_DIF_OK(dif_aon_timer_irq_is_pending(
+      aon_timer, kDifAonTimerIrqWdogTimerBark, &is_pending));
+  CHECK(is_pending, "Wdog bark irq did not rise after %u microseconds",
+        wait_us);
+
+  // Wait for the remaining time to the wdog bite.
+  busy_spin_micros(wait_us);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for Wdog bite reset!");
+}
+
+/**
+ * Execute the aon timer wdog bite reset during sleep test.
+ */
+static void sleep_wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                                 const dif_pwrmgr_t *pwrmgr,
+                                 uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+}
+
+static void low_power_wdog(const dif_pwrmgr_t *pwrmgr) {
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  // Enter in low power mode.
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceTwo,
+                                    0);
+  LOG_INFO("Low power set for watch dog");
+  wait_for_interrupt();
+  // If we arrive here the test must fail.
+  CHECK(false, "Fail to enter in low power mode!");
+}
+
+static void normal_sleep_wdog(const dif_pwrmgr_t *pwrmgr) {
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+
+  // Enter in low power mode.
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceTwo,
+                                    config);
+  LOG_INFO("Normal sleep set for watchdog");
+  wait_for_interrupt();
+}
+
+static void low_power_por(const dif_pwrmgr_t *pwrmgr) {
+  // Set por as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(
+      pwrmgr,
+      (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
+       kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
+       kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
+      0);
+  // Enter in low power mode.
+  wait_for_interrupt();
+  // If we arrive here the test must fail.
+  CHECK(false, "Fail to enter in low power mode!");
+}
+
+static void normal_sleep_por(const dif_pwrmgr_t *pwrmgr) {
+  // Set por as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(
+      pwrmgr,
+      (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
+       kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
+       kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
+      config);
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+bool test_main(void) {
+  // Enable global and external IRQ at Ibex.
+  irq_global_ctrl(true);
+  irq_external_ctrl(true);
+
+  init_peripherals();
+
+  // Enable all the AON interrupts used in this test.
+  rv_plic_testutils_irq_range_enable(&plic, kPlicTarget,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassa,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassd);
+
+  alert_handler_config();
+
+  // First check the flash stored value
+  uint32_t event_idx = flash_ctrl_testutils_counter_get(0);
+
+  // Enable flash access
+  flash_ctrl_testutils_default_region_access(&flash_ctrl,
+                                             /*rd_en*/ true,
+                                             /*prog_en*/ true,
+                                             /*erase_en*/ true,
+                                             /*scramble_en*/ false,
+                                             /*ecc_en*/ false,
+                                             /*he_en*/ false);
+
+  // Increment flash counter to know where we are
+  flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+
+  LOG_INFO("Test round %d", event_idx);
+  LOG_INFO("RST_IDX[%d] = %d", event_idx, RST_IDX[event_idx]);
+
+  // Check if there was a HW reset caused by expected cases
+  dif_rstmgr_reset_info_bitfield_t rst_info;
+  rst_info = rstmgr_testutils_reason_get();
+  rstmgr_testutils_reason_clear();
+
+  CHECK(rst_info == kDifRstmgrResetInfoPor ||
+            rst_info == kDifRstmgrResetInfoSysRstCtrl ||
+            rst_info == kDifRstmgrResetInfoWatchdog ||
+            rst_info == kDifRstmgrResetInfoEscalation ||
+            rst_info == kDifRstmgrResetInfoLowPowerExit ||
+            rst_info == (kDifRstmgrResetInfoSysRstCtrl |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info ==
+                (kDifRstmgrResetInfoPor | kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoWatchdog |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoEscalation |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == kDifRstmgrResetInfoSw,
+        "Wrong reset reason %02X", rst_info);
+
+  LOG_INFO("New reset event");
+
+  switch (RST_IDX[event_idx] / 2) {
+    case 0:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Booting and setting normal sleep followed by sysrst");
+        config_sysrst(&pwrmgr, &sysrst_ctrl_aon);
+        normal_sleep_sysrst(&pwrmgr);
+        timer_on(kWdogBiteMicros);
+      } else {
+        LOG_INFO("Booting and setting deep sleep followed by sysrst");
+        config_sysrst(&pwrmgr, &sysrst_ctrl_aon);
+        low_power_sysrst(&pwrmgr);
+      }
+      break;
+    case 1:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Booting and setting normal sleep followed by hw por");
+        normal_sleep_por(&pwrmgr);
+        timer_on(kWdogBiteMicros);
+      } else {
+        LOG_INFO("Booting and setting deep sleep followed by hw por");
+        low_power_por(&pwrmgr);
+      }
+      break;
+    case 2:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO(
+            "Booting and setting normal sleep mode followed for low_power "
+            "entry reset");
+        LOG_INFO("Let SV wait timer reset");
+        // actually the same test as normal sleep + watchdog
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        normal_sleep_wdog(&pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      } else {
+        LOG_INFO(
+            "Booting and setting deep sleep mode followed for low_power entry "
+            "reset");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        // actually the same test as deep sleep + watchdog
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        low_power_wdog(&pwrmgr);
+      }
+      break;
+
+    case 3:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO(
+            "Booting and setting normal sleep followed by watchdog reset "
+            "combined "
+            "with sw_req");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+        LOG_INFO("Device reset from sw");
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        normal_sleep_wdog(&pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      } else {
+        LOG_INFO(
+            "Booting and setting deep sleep followed by watchdog reset "
+            "combined "
+            "with sw_req");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+        LOG_INFO("Device reset from sw");
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        low_power_wdog(&pwrmgr);
+      }
+      break;
+    case 4:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Booting and setting normal sleep followed by watchdog reset");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        normal_sleep_wdog(&pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      } else {
+        LOG_INFO("Booting and setting deep sleep followed by watchdog reset");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        low_power_wdog(&pwrmgr);
+      }
+      break;
+    case 5:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Last Booting");
+
+        return true;
+      } else {
+        LOG_INFO(
+            "Booting and running normal sleep followed by escalation reset");
+        config_escalate(&aon_timer, &pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      }
+      break;
+    default:
+      LOG_INFO("Booting for undefined case");
+  }
+  return false;
+}
diff --git a/sw/device/tests/sim_dv/pwrmgr_random_sleep_power_glitch_reset_test.c b/sw/device/tests/sim_dv/pwrmgr_random_sleep_power_glitch_reset_test.c
new file mode 100644
index 0000000..3f16463
--- /dev/null
+++ b/sw/device/tests/sim_dv/pwrmgr_random_sleep_power_glitch_reset_test.c
@@ -0,0 +1,577 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/math.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_alert_handler.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_flash_ctrl.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/dif/dif_rv_timer.h"
+#include "sw/device/lib/dif/dif_sysrst_ctrl.h"
+#include "sw/device/lib/runtime/irq.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/alert_handler_testutils.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/flash_ctrl_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rstmgr_testutils.h"
+#include "sw/device/lib/testing/rv_plic_testutils.h"
+#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+static volatile const uint8_t RST_IDX[12] = {0, 1, 2, 3, 4,  5,
+                                             6, 7, 8, 9, 10, 11};
+static const uint32_t kPlicTarget = kTopMatchaPlicTargetIbex0;
+
+/**
+ * Objects to access the peripherals used in this test via dif API.
+ */
+static dif_flash_ctrl_state_t flash_ctrl;
+static dif_rv_plic_t plic;
+static dif_alert_handler_t alert_handler;
+static dif_aon_timer_t aon_timer;
+static dif_pwrmgr_t pwrmgr;
+static dif_rstmgr_t rstmgr;
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ */
+enum {
+  kWdogBarkMicros = 3 * 100,          // 300 us
+  kWdogBiteMicros = 4 * 100,          // 400 us
+  kEscalationPhase0Micros = 1 * 100,  // 100 us
+  // The cpu value is slightly larger as the busy_spin_micros
+  // routine cycle count comes out slightly smaller due to the
+  // fact that it does not divide by exactly 1M
+  // see sw/device/lib/runtime/hart.c
+  kEscalationPhase0MicrosCpu = kEscalationPhase0Micros + 20,  // 120 us
+  kEscalationPhase1Micros = 5 * 100,                          // 500 us
+  kEscalationPhase2Micros = 50,                               // 50 us
+};
+
+static_assert(
+    kWdogBarkMicros < kWdogBiteMicros &&
+        kWdogBarkMicros > kEscalationPhase0Micros &&
+        kWdogBarkMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros) &&
+        kWdogBiteMicros < (kEscalationPhase0Micros + kEscalationPhase1Micros),
+    "The wdog bark and bite shall happens during the escalation phase 1");
+
+/**
+ * External ISR.
+ *
+ * Handles all peripheral interrupts on Ibex. PLIC asserts an external interrupt
+ * line to the CPU, which results in a call to this OTTF ISR. This ISR
+ * overrides the default OTTF implementation.
+ */
+void ottf_external_isr(void) {
+  top_matcha_plic_peripheral_t peripheral;
+  dif_rv_plic_irq_id_t irq_id;
+  uint32_t irq = 0;
+  uint32_t alert = 0;
+
+  CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic, kPlicTarget, &irq_id));
+
+  peripheral = (top_matcha_plic_peripheral_t)
+      top_matcha_plic_interrupt_for_peripheral[irq_id];
+
+  if (peripheral == kTopMatchaPlicPeripheralAonTimerAon) {
+    irq =
+        (dif_aon_timer_irq_t)(irq_id -
+                              (dif_rv_plic_irq_id_t)
+                                  kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired);
+
+    // Stops escalation process.
+    CHECK_DIF_OK(dif_alert_handler_escalation_clear(&alert_handler,
+                                                    kDifAlertHandlerClassA));
+    CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(&aon_timer, irq));
+
+    CHECK(irq != kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark,
+          "AON Timer Wdog should not bark");
+
+  } else if (peripheral == kTopMatchaPlicPeripheralAlertHandler) {
+    irq = (dif_rv_plic_irq_id_t)(irq_id -
+                                 (dif_rv_plic_irq_id_t)
+                                     kTopMatchaPlicIrqIdAlertHandlerClassa);
+
+    CHECK_DIF_OK(dif_alert_handler_alert_acknowledge(&alert_handler, alert));
+
+    dif_alert_handler_class_state_t state;
+    CHECK_DIF_OK(dif_alert_handler_get_class_state(
+        &alert_handler, kDifAlertHandlerClassA, &state));
+
+    CHECK(state == kDifAlertHandlerClassStatePhase0, "Wrong phase %d", state);
+
+    CHECK_DIF_OK(dif_alert_handler_irq_acknowledge(&alert_handler, irq));
+  }
+
+  // Complete the IRQ by writing the IRQ source to the Ibex specific CC
+  // register.
+  CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic, kPlicTarget, irq_id));
+}
+
+/**
+ * Initialize the peripherals used in this test.
+ */
+void init_peripherals(void) {
+  // Initialize pwrmgr.
+  CHECK_DIF_OK(dif_pwrmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+
+  // Initialize rstmgr to check the reset reason.
+  CHECK_DIF_OK(dif_rstmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+  // Initialize aon timer to use the wdog.
+  CHECK_DIF_OK(dif_aon_timer_init(
+      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+  // Initialize flash_ctrl
+  CHECK_DIF_OK(dif_flash_ctrl_init_state(
+      &flash_ctrl,
+      mmio_region_from_addr(TOP_MATCHA_FLASH_CTRL_CORE_BASE_ADDR)));
+
+  // Initialize plic.
+  CHECK_DIF_OK(dif_rv_plic_init(
+      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic));
+
+  rv_plic_testutils_irq_range_enable(
+      &plic, kPlicTarget, kTopMatchaPlicIrqIdAonTimerAonWkupTimerExpired,
+      kTopMatchaPlicIrqIdAonTimerAonWdogTimerBark);
+
+  // Initialize alert handler.
+  CHECK_DIF_OK(dif_alert_handler_init(
+      mmio_region_from_addr(TOP_MATCHA_ALERT_HANDLER_BASE_ADDR),
+      &alert_handler));
+}
+
+/**
+ * Program the alert handler to escalate on alerts upto phase 2 (i.e. reset) but
+ * the phase 1 (i.e. wipe secrets) should occur and last during the time the
+ * wdog is programed to bark.
+ */
+static void alert_handler_config(void) {
+  dif_alert_handler_alert_t alerts[] = {kTopMatchaAlertIdPwrmgrAonFatalFault};
+  dif_alert_handler_class_t alert_classes[] = {kDifAlertHandlerClassA};
+
+  dif_alert_handler_escalation_phase_t esc_phases[] = {
+      {.phase = kDifAlertHandlerClassStatePhase0,
+       .signal = 0,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase0Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase1,
+       .signal = 1,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase1Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()},
+      {.phase = kDifAlertHandlerClassStatePhase2,
+       .signal = 3,
+       .duration_cycles =
+           alert_handler_testutils_get_cycles_from_us(kEscalationPhase2Micros) *
+           alert_handler_testutils_cycle_rescaling_factor()}};
+
+  dif_alert_handler_class_config_t class_config[] = {{
+      .auto_lock_accumulation_counter = kDifToggleDisabled,
+      .accumulator_threshold = 0,
+      .irq_deadline_cycles =
+          alert_handler_testutils_get_cycles_from_us(kEscalationPhase0Micros) *
+          alert_handler_testutils_cycle_rescaling_factor(),
+      .escalation_phases = esc_phases,
+      .escalation_phases_len = ARRAYSIZE(esc_phases),
+      .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase3,
+  }};
+
+  dif_alert_handler_class_t classes[] = {kDifAlertHandlerClassA};
+  dif_alert_handler_config_t config = {
+      .alerts = alerts,
+      .alert_classes = alert_classes,
+      .alerts_len = ARRAYSIZE(alerts),
+      .classes = classes,
+      .class_configs = class_config,
+      .classes_len = ARRAYSIZE(class_config),
+      .ping_timeout = 0,
+  };
+
+  alert_handler_testutils_configure_all(&alert_handler, config,
+                                        kDifToggleEnabled);
+  // Enables alert handler irq.
+  CHECK_DIF_OK(dif_alert_handler_irq_set_enabled(
+      &alert_handler, kDifAlertHandlerIrqClassa, kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer interrupt test.
+ */
+static void config_escalate(dif_aon_timer_t *aon_timer,
+                            const dif_pwrmgr_t *pwrmgr) {
+  uint64_t bark_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(kWdogBarkMicros) *
+      alert_handler_testutils_cycle_rescaling_factor();
+  uint64_t bite_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(kWdogBiteMicros) *
+      alert_handler_testutils_cycle_rescaling_factor();
+
+  LOG_INFO(
+      "Wdog will bark after %u/%u us/cycles and bite after %u/%u us/cycles",
+      (uint32_t)kWdogBarkMicros, (uint32_t)bark_cycles,
+      (uint32_t)kWdogBiteMicros, (uint32_t)bite_cycles);
+
+  // Setup the wdog bark and bite timeouts.
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+
+  // Trigger the alert handler to escalate.
+  dif_pwrmgr_alert_t alert = kDifPwrmgrAlertFatalFault;
+  CHECK_DIF_OK(dif_pwrmgr_alert_force(pwrmgr, alert));
+}
+
+static void low_power_glitch_reset(const dif_pwrmgr_t *pwrmgr) {
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceFive,
+                                    0);
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+static void normal_sleep_glitch_reset(const dif_pwrmgr_t *pwrmgr) {
+  // Place device into normal (shallow) power
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceFive,
+                                    config);
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+static void timer_on(uint32_t usec) {
+  busy_spin_micros(usec);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for reset!");
+}
+
+/**
+ * Configure the wdog.
+ */
+static void config_wdog(const dif_aon_timer_t *aon_timer,
+                        const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us,
+                        uint64_t bite_time_us) {
+  uint32_t bark_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bark_time_us);
+  uint32_t bite_cycles =
+      aon_timer_testutils_get_aon_cycles_from_us(bite_time_us);
+
+  LOG_INFO("Wdog will bark after %u us and bite after %u us",
+           (uint32_t)bark_time_us, (uint32_t)bite_time_us);
+  // Setup the wdog bark and bite timeouts.
+
+  aon_timer_testutils_watchdog_config(aon_timer, bark_cycles, bite_cycles,
+                                      false);
+  // Set wdog as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+}
+
+/**
+ * Execute the aon timer wdog bite reset test.
+ */
+static void wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                           const dif_pwrmgr_t *pwrmgr, uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+
+  // The `intr_state` takes 3 aon clock cycles to rise plus 2 extra cycles as a
+  // precaution.
+  uint32_t wait_us =
+      bark_time_us +
+      alert_handler_testutils_get_cycles_from_us(kEscalationPhase0Micros) *
+          alert_handler_testutils_cycle_rescaling_factor();
+
+  // Wait bark time and check that the bark interrupt requested.
+  busy_spin_micros(wait_us);
+  bool is_pending = false;
+  CHECK_DIF_OK(dif_aon_timer_irq_is_pending(
+      aon_timer, kDifAonTimerIrqWdogTimerBark, &is_pending));
+  CHECK(is_pending, "Wdog bark irq did not rise after %u microseconds",
+        wait_us);
+
+  // Wait for the remaining time to the wdog bite.
+  busy_spin_micros(wait_us);
+  // If we arrive here the test must fail.
+  CHECK(false, "Timeout waiting for Wdog bite reset!");
+}
+
+/**
+ * Execute the aon timer wdog bite reset during sleep test.
+ */
+static void sleep_wdog_bite_test(const dif_aon_timer_t *aon_timer,
+                                 const dif_pwrmgr_t *pwrmgr,
+                                 uint64_t bark_time_us) {
+  uint64_t bite_time_us = bark_time_us * 2;
+  config_wdog(aon_timer, pwrmgr, bark_time_us, bite_time_us);
+}
+
+static void low_power_wdog(const dif_pwrmgr_t *pwrmgr) {
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  // Enter in low power mode.
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceTwo,
+                                    0);
+  LOG_INFO("Low power set for watch dog");
+  wait_for_interrupt();
+  // If we arrive here the test must fail.
+  CHECK(false, "Fail to enter in low power mode!");
+}
+
+static void normal_sleep_wdog(const dif_pwrmgr_t *pwrmgr) {
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+
+  // Enter in low power mode.
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceTwo,
+                                    config);
+  LOG_INFO("Normal sleep set for watchdog");
+  wait_for_interrupt();
+}
+
+static void low_power_por(const dif_pwrmgr_t *pwrmgr) {
+  // Set por as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+
+  // Program the pwrmgr to go to deep sleep state (clocks off).
+  pwrmgr_testutils_enable_low_power(
+      pwrmgr,
+      (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
+       kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
+       kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
+      0);
+  // Enter in low power mode.
+  wait_for_interrupt();
+  // If we arrive here the test must fail.
+  CHECK(false, "Fail to enter in low power mode!");
+}
+
+static void normal_sleep_por(const dif_pwrmgr_t *pwrmgr) {
+  // Set por as a reset source.
+  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(pwrmgr, kDifPwrmgrReqTypeReset,
+                                              kDifPwrmgrResetRequestSourceTwo,
+                                              kDifToggleEnabled));
+
+  // Place device into low power and immediately wake.
+  dif_pwrmgr_domain_config_t config;
+  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
+           kDifPwrmgrDomainOptionCoreClockInLowPower |
+           kDifPwrmgrDomainOptionIoClockInLowPower |
+           kDifPwrmgrDomainOptionMainPowerInLowPower;
+
+  // Program the pwrmgr to go to swallow sleep state (clocks on).
+  pwrmgr_testutils_enable_low_power(
+      pwrmgr,
+      (kDifPwrmgrWakeupRequestSourceOne | kDifPwrmgrWakeupRequestSourceTwo |
+       kDifPwrmgrWakeupRequestSourceThree | kDifPwrmgrWakeupRequestSourceFour |
+       kDifPwrmgrWakeupRequestSourceFive | kDifPwrmgrWakeupRequestSourceSix),
+      config);
+  // Enter in low power mode.
+  wait_for_interrupt();
+}
+
+bool test_main(void) {
+  // Enable global and external IRQ at Ibex.
+  irq_global_ctrl(true);
+  irq_external_ctrl(true);
+
+  init_peripherals();
+
+  // Enable all the AON interrupts used in this test.
+  rv_plic_testutils_irq_range_enable(&plic, kPlicTarget,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassa,
+                                     kTopMatchaPlicIrqIdAlertHandlerClassd);
+
+  alert_handler_config();
+
+  // First check the flash stored value
+  uint32_t event_idx = flash_ctrl_testutils_counter_get(0);
+
+  // Enable flash access
+  flash_ctrl_testutils_default_region_access(&flash_ctrl,
+                                             /*rd_en*/ true,
+                                             /*prog_en*/ true,
+                                             /*erase_en*/ true,
+                                             /*scramble_en*/ false,
+                                             /*ecc_en*/ false,
+                                             /*he_en*/ false);
+
+  // Increment flash counter to know where we are
+  flash_ctrl_testutils_counter_increment(&flash_ctrl, 0);
+
+  LOG_INFO("Test round %d", event_idx);
+  LOG_INFO("RST_IDX[%d] = %d", event_idx, RST_IDX[event_idx]);
+
+  // Check if there was a HW reset caused by expected cases
+  dif_rstmgr_reset_info_bitfield_t rst_info;
+  rst_info = rstmgr_testutils_reason_get();
+  rstmgr_testutils_reason_clear();
+  LOG_INFO("reset info = %02X", rst_info);
+
+  CHECK(rst_info == kDifRstmgrResetInfoPor ||
+            rst_info == kDifRstmgrResetInfoSysRstCtrl ||
+            rst_info == kDifRstmgrResetInfoWatchdog ||
+            rst_info == kDifRstmgrResetInfoEscalation ||
+            rst_info == kDifRstmgrResetInfoLowPowerExit ||
+            rst_info == (kDifRstmgrResetInfoSysRstCtrl |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoPowerUnstable |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoPowerUnstable |
+                         kDifRstmgrResetInfoWatchdog |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoPowerUnstable |
+                         kDifRstmgrResetInfoWatchdog) ||
+            rst_info == kDifRstmgrResetInfoPowerUnstable ||
+            rst_info ==
+                (kDifRstmgrResetInfoPor | kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoWatchdog |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == (kDifRstmgrResetInfoEscalation |
+                         kDifRstmgrResetInfoLowPowerExit) ||
+            rst_info == kDifRstmgrResetInfoSw,
+        "Wrong reset reason %02X", rst_info);
+
+  switch (RST_IDX[event_idx] / 2) {
+    case 0:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Booting and setting normal sleep followed by glitch reset");
+        LOG_INFO("Let SV wait timer reset");
+        normal_sleep_glitch_reset(&pwrmgr);
+        timer_on(kWdogBiteMicros);
+      } else {
+        LOG_INFO("Booting and setting deep sleep followed by glitch reset");
+        LOG_INFO("Let SV wait timer reset");
+        low_power_glitch_reset(&pwrmgr);
+      }
+      break;
+    case 1:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Booting and setting normal sleep followed by hw por");
+        LOG_INFO("Let SV wait timer reset");
+        normal_sleep_por(&pwrmgr);
+        timer_on(kWdogBiteMicros);
+      } else {
+        LOG_INFO("Booting and setting deep sleep followed by hw por");
+        LOG_INFO("Let SV wait timer reset");
+        low_power_por(&pwrmgr);
+      }
+      break;
+    case 2:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO(
+            "Booting and setting normal sleep mode followed for low_power "
+            "entry reset");
+        LOG_INFO("Let SV wait timer reset");
+        // actually the same test as normal sleep + watchdog
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        normal_sleep_wdog(&pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      } else {
+        LOG_INFO(
+            "Booting and setting deep sleep mode followed for low_power entry "
+            "reset");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        // actually the same test as deep sleep + watchdog
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        low_power_wdog(&pwrmgr);
+      }
+      break;
+
+    case 3:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO(
+            "Booting and setting normal sleep followed by watchdog reset "
+            "combined "
+            "with sw_req");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+        LOG_INFO("Device reset from sw");
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        normal_sleep_wdog(&pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      } else {
+        LOG_INFO(
+            "Booting and setting deep sleep followed by watchdog reset "
+            "combined "
+            "with sw_req");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
+        LOG_INFO("Device reset from sw");
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        low_power_wdog(&pwrmgr);
+      }
+      break;
+    case 4:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Booting and setting normal sleep followed by watchdog reset");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        normal_sleep_wdog(&pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      } else {
+        LOG_INFO("Booting and setting deep sleep followed by watchdog reset");
+        LOG_INFO("Let SV wait timer reset");
+        // Executing the wdog bite reset during sleep test.
+        rstmgr_testutils_pre_reset(&rstmgr);
+        sleep_wdog_bite_test(&aon_timer, &pwrmgr, 200);
+        low_power_wdog(&pwrmgr);
+      }
+      break;
+    case 5:
+      if (RST_IDX[event_idx] % 2) {
+        LOG_INFO("Last Booting");
+
+        return true;
+      } else {
+        LOG_INFO(
+            "Booting and running normal sleep followed by escalation reset");
+        config_escalate(&aon_timer, &pwrmgr);
+        timer_on(kEscalationPhase0MicrosCpu);
+      }
+      break;
+    default:
+      LOG_INFO("Booting for undefined case");
+  }
+
+  return false;
+}
diff --git a/sw/device/tests/sim_dv/sleep_pin_retention_test.c b/sw/device/tests/sim_dv/sleep_pin_retention_test.c
new file mode 100644
index 0000000..750e90e
--- /dev/null
+++ b/sw/device/tests/sim_dv/sleep_pin_retention_test.c
@@ -0,0 +1,214 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_gpio.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rv_plic.h"
+#include "sw/device/lib/runtime/irq.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/autogen/isr_testutils.h"
+#include "sw/device/lib/testing/pwrmgr_testutils.h"
+#include "sw/device/lib/testing/rand_testutils.h"
+#include "sw/device/lib/testing/rv_plic_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+
+// PLIC structures
+static const uint32_t kPlicTarget = kTopMatchaPlicTargetIbex0;
+static dif_gpio_t gpio;
+static dif_pwrmgr_t pwrmgr;
+static dif_pinmux_t pinmux;
+static dif_pwrmgr_domain_config_t pwrmgr_domain_cfg;
+static dif_rv_plic_t plic;
+
+static plic_isr_ctx_t plic_ctx = {.rv_plic = &plic, .hart_id = kPlicTarget};
+static pwrmgr_isr_ctx_t pwrmgr_isr_ctx = {
+    .pwrmgr = &pwrmgr,
+    .plic_pwrmgr_start_irq_id = kTopMatchaPlicIrqIdPwrmgrAonWakeup,
+    .expected_irq = kDifPwrmgrIrqWakeup,
+    .is_only_irq = true};
+
+// SV randomizes the round of entering/exiting sleep then set this volatile
+// variable via backdoor_overwrite.
+static volatile const uint8_t kRounds = 2;
+
+// SW testcode randomly chooses the value for 8 GPIO pins (pins are fixed) then
+// invert the value for retention. SW will sends the value to SV testbench via
+// LOG_INFO().
+static const uint8_t kGpioVal = 0x00;
+
+// To wakeup and maintain GPIO, for now test enters to normal sleep only.
+static const bool deepPowerdown = false;
+
+// Num of GPIO Pads to test
+enum { kNumGpioPads = 8 };
+
+/**
+ * External interrupt handler.
+ */
+void ottf_external_isr(void) {
+  dif_pwrmgr_irq_t irq_id;
+  top_matcha_plic_peripheral_t peripheral;
+
+  isr_testutils_pwrmgr_isr(plic_ctx, pwrmgr_isr_ctx, &peripheral, &irq_id);
+
+  // Check that both the peripheral and the irq id is correct
+  CHECK(peripheral == kTopMatchaPlicPeripheralPwrmgrAon,
+        "IRQ peripheral: %d is incorrect", peripheral);
+  CHECK(irq_id == kDifPwrmgrIrqWakeup, "IRQ ID: %d is incorrect", irq_id);
+
+  // Clear PINMUX WKUP_CAUSE reg
+  CHECK_DIF_OK(dif_pinmux_wakeup_cause_clear(&pinmux));
+}
+
+/**
+ * A round of GPIO[7:0] retention value test.
+ *
+ * The test sequence is:
+ *
+ * 1. Randomly choose GPIO[7:0] value using rand_testutils.
+ * 2. Drive GPIO with the chosen value.
+ * 3. Send the chosen values to SV via LOG_INFO.
+ * 4. Configure PINMUX Retention value opposit to the chosen value for
+ *    GPIO[7:0].
+ * 5. Initiate sleep mode (assuming pinmux pin wake up has been configured.)
+ * 6. WFI()
+ * 7. At this point, chip has been waken up by DV. Send a log to DV that chip
+ *    has waken up.
+ *
+ * DV env checks all PIN value. SW simply drives the GPIO and invert the value
+ * for retention.
+ */
+void gpio_test(dif_pwrmgr_t *pwrmgr, dif_pinmux_t *pinmux, dif_gpio_t *gpio,
+               int round) {
+  uint8_t gpio_val = 0;
+  dif_pinmux_pad_kind_t pad_kind;
+  dif_pinmux_sleep_mode_t pad_mode;
+
+  LOG_INFO("Current Test Round: %1d", round);
+
+  // 1. Randomly choose GPIO value
+  gpio_val = rand_testutils_gen32_range(0, 255);
+
+  // 2. Drive GPIO with the chosen value.
+  CHECK_DIF_OK(dif_gpio_write_masked(gpio, (dif_gpio_mask_t)0x000000FF,
+                                     (dif_gpio_state_t)gpio_val));
+
+  // 3. Send the chosen value to SV via LOG_INFO.
+  //
+  // The format is:
+  //
+  //     Chosen GPIO value: %2x
+  LOG_INFO("Chosen GPIO value: %2x", gpio_val);
+
+  // 4. Configure PINMUX Retention value opposite to the chosen value.
+  pad_kind = kDifPinmuxPadKindMio;
+  for (int i = 0; i < kNumGpioPads; i++) {
+    // GPIO are assigned starting from MIO0
+    pad_mode = ((gpio_val >> i) & 0x1) ? kDifPinmuxSleepModeLow
+                                       : kDifPinmuxSleepModeHigh;
+    CHECK_DIF_OK(dif_pinmux_pad_sleep_enable(
+        pinmux, kTopMatchaPinmuxMioOutIoa0 + i, pad_kind, pad_mode));
+  }
+
+  // 5. Initiate sleep mode
+  pwrmgr_testutils_enable_low_power(pwrmgr, kDifPwrmgrWakeupRequestSourceThree,
+                                    pwrmgr_domain_cfg);
+  // 6. WFI()
+  LOG_INFO("Entering low power mode.");
+  wait_for_interrupt();
+
+  // 7. Turn-off retention.
+  for (int i = 0; i < kNumGpioPads; i++) {
+    CHECK_DIF_OK(dif_pinmux_pad_sleep_clear_state(
+        pinmux, kTopMatchaPinmuxMioOutIoa0 + i, pad_kind));
+  }
+}
+
+/**
+ * Configure GPIO
+ *
+ * gpio_init() configures first 8 MIO PADs to GPIO[7:0].
+ */
+void gpio_init(const dif_pinmux_t *pinmux, const dif_gpio_t *gpio) {
+  // Drive GPIO first
+  CHECK_DIF_OK(
+      dif_gpio_output_set_enabled_all(gpio, (dif_gpio_state_t)0x000000FFu));
+  CHECK_DIF_OK(dif_gpio_write_masked(gpio, (dif_gpio_mask_t)0x000000FF,
+                                     (dif_gpio_state_t)0x00000000));
+
+  // Configure PINMUX to GPIO
+  for (int i = 0; i < kNumGpioPads; i++) {
+    CHECK_DIF_OK(dif_pinmux_input_select(
+        pinmux, kTopMatchaPinmuxPeripheralInGpioGpio0 + i,
+        kTopMatchaPinmuxInselIoa0 + i));
+    CHECK_DIF_OK(dif_pinmux_output_select(pinmux,
+                                          kTopMatchaPinmuxMioOutIoa0 + i,
+                                          kTopMatchaPinmuxOutselGpioGpio0 + i));
+  }
+}
+
+bool test_main(void) {
+  bool result = true;
+
+  dif_pinmux_index_t detector;
+  dif_pinmux_wakeup_config_t wakeup_cfg;
+
+  // Default Deep Power Down
+
+  // Enable global and external IRQ at Ibex.
+  irq_global_ctrl(true);
+  irq_external_ctrl(true);
+
+  // Initialize power manager
+  CHECK_DIF_OK(dif_pwrmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_PWRMGR_AON_BASE_ADDR), &pwrmgr));
+  CHECK_DIF_OK(dif_rv_plic_init(
+      mmio_region_from_addr(TOP_MATCHA_RV_PLIC_BASE_ADDR), &plic));
+  CHECK_DIF_OK(dif_pinmux_init(
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+  CHECK_DIF_OK(
+      dif_gpio_init(mmio_region_from_addr(TOP_MATCHA_GPIO_BASE_ADDR), &gpio));
+
+  // Enable all the AON interrupts used in this test.
+  rv_plic_testutils_irq_range_enable(&plic, kPlicTarget,
+                                     kTopMatchaPlicIrqIdPwrmgrAonWakeup,
+                                     kTopMatchaPlicIrqIdPwrmgrAonWakeup);
+  // Enable pwrmgr interrupt
+  CHECK_DIF_OK(dif_pwrmgr_irq_set_enabled(&pwrmgr, 0, kDifToggleEnabled));
+
+  // Wakeup configs
+  wakeup_cfg.mode = kDifPinmuxWakeupModePositiveEdge;
+  wakeup_cfg.signal_filter = false;
+  wakeup_cfg.pad_type = 0;                            // MIO
+  wakeup_cfg.pad_select = kTopMatchaPinmuxInselIoa8;  // MIO08
+
+  // Configure Wakeup Detector 0
+  CHECK_DIF_OK(dif_pinmux_wakeup_detector_enable(&pinmux, 0, wakeup_cfg));
+
+  if (deepPowerdown == false) {
+    // Configure Normal Sleep
+    pwrmgr_domain_cfg = kDifPwrmgrDomainOptionMainPowerInLowPower |
+                        kDifPwrmgrDomainOptionUsbClockInActivePower;
+  }
+
+  LOG_INFO("Num Rounds: %3d", kRounds);
+
+  // Select IOA0:IOA7 to GPIO
+  gpio_init(&pinmux, &gpio);
+
+  // Set wakeup condition. Always use GPIO[8] for Pinmux PIN Wakeup.
+
+  for (int i = kRounds - 1; i >= 0; i--) {
+    gpio_test(&pwrmgr, &pinmux, &gpio, i);
+  }
+
+  return result;
+}
diff --git a/util/topgen_matcha/templates/chiplevel.sv.tpl b/util/topgen_matcha/templates/chiplevel.sv.tpl
index 1c0daf1..87945c3 100644
--- a/util/topgen_matcha/templates/chiplevel.sv.tpl
+++ b/util/topgen_matcha/templates/chiplevel.sv.tpl
@@ -697,15 +697,19 @@
     .clk_src_usb_o         ( ast_base_clks.clk_usb ),
     .clk_src_usb_val_o     ( ast_base_pwr.usb_clk_val ),
     // smc source clock
+    .clk_src_smc_en_i      ( base_ast_pwr.smc_clk_en ),
     .clk_src_smc_o         ( ast_base_clks.clk_smc ),
     .clk_src_smc_val_o     ( ast_base_pwr.smc_clk_val),
     // ml source clock
+    .clk_src_ml_en_i       ( base_ast_pwr.ml_clk_en ),
     .clk_src_ml_o          ( ast_base_clks.clk_ml ),
     .clk_src_ml_val_o      ( ast_base_pwr.ml_clk_val),
     // video source clock
+    .clk_src_video_en_i    ( base_ast_pwr.video_clk_en ),
     .clk_src_video_o       ( ast_base_clks.clk_video ),
     .clk_src_video_val_o   ( ast_base_pwr.video_clk_val),
     // audio source clock
+    .clk_src_audio_en_i    ( base_ast_pwr.audio_clk_en ),
     .clk_src_audio_o       ( ast_base_clks.clk_audio ),
     .clk_src_audio_val_o   ( ast_base_pwr.audio_clk_val),
     // adc