Add chip_sw_sleep_pwm_pulses to edacloud

  - Add chip_sw_sleep_pwm_pulses
  - Temporarily remove chip_sw_sleep_pin_wake from edacloud_nightly

Change-Id: I75717311114209018d0ac6496125003ca64191bd
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson
index 1fbdabb..9486b91 100644
--- a/hw/top_matcha/dv/chip_sim_cfg.hjson
+++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -675,7 +675,7 @@
     {
       name: chip_sw_sleep_pwm_pulses
       uvm_test_seq: chip_sw_pwm_pulses_vseq
-      sw_images: ["//sw/device/tests:sleep_pwm_pulses_test:1"]
+      sw_images: ["//sw/device/tests:sleep_pwm_pulses_test:1:matcha"]
       en_run_modes: ["sw_test_mode_test_rom"]
     }
     {
@@ -2112,7 +2112,7 @@
         "chip_sw_sensor_ctrl_status",
         "chip_sw_sleep_pin_mio_dio_val",
         "chip_sw_sleep_pin_retention",
-        "chip_sw_sleep_pin_wake",
+        "chip_sw_sleep_pwm_pulses",
         "chip_sw_smc_cam_irq_test",
         "chip_sw_smc_ctrl_test",
         "chip_sw_smc_env_test",
@@ -2206,6 +2206,7 @@
         "chip_sw_sleep_pin_mio_dio_val",
         "chip_sw_sleep_pin_retention",
         "chip_sw_sleep_pin_wake",
+        "chip_sw_sleep_pwm_pulses",
         "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_if.sv b/hw/top_matcha/dv/env/chip_if.sv
index 6663de3..a5efa22 100644
--- a/hw/top_matcha/dv/env/chip_if.sv
+++ b/hw/top_matcha/dv/env/chip_if.sv
@@ -569,7 +569,7 @@
   // Functional (muxed) interface: PWM.
   localparam int AssignedPwmIos[NUM_PWM_CHANNELS] = {
       top_matcha_pkg::MioPadIob10, top_matcha_pkg::MioPadIob11, top_matcha_pkg::MioPadIob12,
-      top_matcha_pkg::MioPadIoc10, top_matcha_pkg::MioPadIoc11, top_matcha_pkg::MioPadIoc12
+      top_matcha_pkg::MioPadIod2, top_matcha_pkg::MioPadIod3, top_matcha_pkg::MioPadIoc12
   };
 
   for (genvar i = 0; i < NUM_PWM_CHANNELS; i++) begin : gen_pwm_if_conn
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index d24b5a5..5c0339f 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -977,6 +977,22 @@
     ],
 )
 
+matcha_dv_test(
+    name = "sleep_pwm_pulses_test",
+    srcs = ["sleep_pwm_pulses_test.c"],
+    deps = [
+        ":test_dv_lib",
+        "//sw/device/lib/dif:pinmux",
+        "//sw/device/lib/dif:rstmgr",
+        "@lowrisc_opentitan//sw/device/lib/dif:aon_timer",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwm",
+        "@lowrisc_opentitan//sw/device/lib/dif:pwrmgr",
+        "@lowrisc_opentitan//sw/device/lib/testing:aon_timer_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:pwrmgr_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing:rstmgr_testutils",
+    ],
+)
+
 # Smoke tests
 matcha_dv_test(
     name = "aes_smoketest",
diff --git a/sw/device/tests/sleep_pwm_pulses_test.c b/sw/device/tests/sleep_pwm_pulses_test.c
new file mode 100644
index 0000000..7e94c98
--- /dev/null
+++ b/sw/device/tests/sleep_pwm_pulses_test.c
@@ -0,0 +1,209 @@
+// 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 "pwm_regs.h"
+#include "sw/device/lib/base/mmio.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_pinmux.h"
+#include "sw/device/lib/dif/dif_pwm.h"
+#include "sw/device/lib/dif/dif_pwrmgr.h"
+#include "sw/device/lib/dif/dif_rstmgr.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/aon_timer_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"
+
+/**
+ * SLEEP PWM PULSES test
+ *
+ * This test configure 6 pwm channels with a fixed duty cycle
+ * then kicks power manager sleep mode to see pwm pluses are
+ * not affected by power down event.
+ * pwm out --> pinmux setup is chosen arbitrary as below
+ *      pwmout[0] -> IOB10
+ *      pwmout[1] -> IOB11
+ *      pwmout[2] -> IOB12
+ *      pwmout[3] -> IOD2
+ *      pwmout[4] -> IOD3
+ *      pwmout[5] -> IOC12
+ *
+ * Since purpose of this test is to check pwm -> pinmux
+ * connectivity and pulse integrity under sleep event,
+ * Fixed pwm configuration, mode and 0 phase delay are chosen.
+ */
+
+OTTF_DEFINE_TEST_CONFIG();
+
+static const dif_pinmux_index_t kPinmuxOutsel[PWM_PARAM_N_OUTPUTS] = {
+    kTopMatchaPinmuxOutselPwmAonPwm0, kTopMatchaPinmuxOutselPwmAonPwm1,
+    kTopMatchaPinmuxOutselPwmAonPwm2, kTopMatchaPinmuxOutselPwmAonPwm3,
+    kTopMatchaPinmuxOutselPwmAonPwm4, kTopMatchaPinmuxOutselPwmAonPwm5,
+};
+
+static const dif_pinmux_index_t kPinmuxMioOut[PWM_PARAM_N_OUTPUTS] = {
+    kTopMatchaPinmuxMioOutIob10, kTopMatchaPinmuxMioOutIob11,
+    kTopMatchaPinmuxMioOutIob12, kTopMatchaPinmuxMioOutIod2,
+    kTopMatchaPinmuxMioOutIod3,  kTopMatchaPinmuxMioOutIoc12,
+};
+
+static const dif_pwm_channel_t kPwmChannel[PWM_PARAM_N_OUTPUTS] = {
+    kDifPwmChannel0, kDifPwmChannel1, kDifPwmChannel2,
+    kDifPwmChannel3, kDifPwmChannel4, kDifPwmChannel5,
+};
+
+// Duty cycle in the unit of beat
+// These are random numbers betwen [1,beats_per_pulse_cycle)
+// make 'static volatile' to overwrite from
+// hw/top_matcha/dv/env/seq_lib/chip_sw_pwm_pulses_vseq.sv
+// via backdoor
+static volatile const uint16_t kPwmDutycycle[PWM_PARAM_N_OUTPUTS] = {
+    6, 11, 27, 8, 17, 7,
+};
+
+static const dif_pwm_config_t config_ = {
+    // set beat period to 3
+    .clock_divisor = 2,
+
+    // upper 5bits of phase cntr only matter
+    // and total(on+off) beats per cycle will be 32
+    .beats_per_pulse_cycle = 32,
+};
+
+// This is initial value of config variable
+static const dif_pwm_channel_config_t default_ch_cfg_ = {
+    .duty_cycle_a = 0,
+    .duty_cycle_b = 0,
+    .phase_delay = 0,
+    .mode = kDifPwmModeFirmware,
+    .polarity = kDifPwmPolarityActiveHigh,
+    .blink_parameter_x = 0,
+    .blink_parameter_y = 0,
+};
+
+// Configure pwm channel register for all 6 channels.
+// This also contain disable and enable each channel.
+void config_pwm_channels(dif_pwm_t *pwm) {
+  dif_pwm_channel_config_t channel_config_ = default_ch_cfg_;
+
+  for (int i = 0; i < PWM_PARAM_N_OUTPUTS; ++i) {
+    CHECK_DIF_OK(
+        dif_pwm_channel_set_enabled(pwm, kPwmChannel[i], kDifToggleDisabled));
+    channel_config_.duty_cycle_a = kPwmDutycycle[i];
+    CHECK_DIF_OK(
+        dif_pwm_configure_channel(pwm, kPwmChannel[i], channel_config_));
+    CHECK_DIF_OK(
+        dif_pwm_channel_set_enabled(pwm, kPwmChannel[i], kDifToggleEnabled));
+  }
+}
+
+bool test_main(void) {
+  dif_pwrmgr_t pwrmgr;
+  dif_rstmgr_t rstmgr;
+
+  // Issue a wakeup signal in ~150us through the AON timer.
+  //
+  // At 200kHz, threshold of 30 is equal to 150us. There is an additional
+  // ~4 cycle overhead for the CSR value to synchronize with the AON clock.
+  // We should expect the wake up to trigger in ~170us. This is sufficient
+  // time to allow pwrmgr config and the low power entry on WFI to complete.
+  //
+  // Adjust the threshold for Verilator since it runs on different clock
+  // frequencies.
+  uint32_t wakeup_threshold = 30;
+  if (kDeviceType == kDeviceSimVerilator) {
+    wakeup_threshold = 300;
+  }
+
+  // Initialize 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.
+  CHECK_DIF_OK(dif_rstmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_RSTMGR_AON_BASE_ADDR), &rstmgr));
+
+  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));
+
+  // Assuming the chip hasn't slept yet, wakeup reason should be empty.
+
+  // Notice we are clearing rstmgr's RESET_INFO, so after the aon wakeup there
+  // is only one bit set.
+  if (pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) {
+    dif_pwm_t pwm;
+    dif_pinmux_t pinmux;
+    // Initialize pwm
+    CHECK_DIF_OK(dif_pwm_init(
+        mmio_region_from_addr(TOP_MATCHA_PWM_AON_BASE_ADDR), &pwm));
+
+    // Update pwm.CFG
+    CHECK_DIF_OK(dif_pwm_configure(&pwm, config_));
+
+    // Update all 6 pwm channels
+    config_pwm_channels(&pwm);
+
+    // enable phase count to make the change effective
+    CHECK_DIF_OK(dif_pwm_phase_cntr_set_enabled(&pwm, kDifToggleEnabled));
+
+    // Initialize pinmux - this assigns PwmAonPwm[0..5] to
+    // IOB10..12, IOD2, IOD3 and IOC12
+    // LOG_INFO is used to indicate pwmout is available to
+    // SV pwm_monitor
+    CHECK_DIF_OK(dif_pinmux_init(
+        mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
+
+    LOG_INFO("pinmux_init begin");
+    for (int i = 0; i < PWM_PARAM_N_OUTPUTS; ++i) {
+      CHECK_DIF_OK(dif_pinmux_output_select(&pinmux, kPinmuxMioOut[i],
+                                            kPinmuxOutsel[i]));
+    }
+    LOG_INFO("pinmux_init end");
+
+    // Add 1ms to initial pulses go through before sleep event
+    busy_spin_micros(1 * 1000);
+
+    LOG_INFO("POR reset");
+    CHECK(rstmgr_testutils_reset_info_any(&rstmgr, kDifRstmgrResetInfoPor));
+
+    // Prepare rstmgr for a reset.
+    rstmgr_testutils_pre_reset(&rstmgr);
+
+    aon_timer_testutils_wakeup_config(&aon_timer, wakeup_threshold);
+    // Deep sleep.
+    pwrmgr_testutils_enable_low_power(&pwrmgr,
+                                      kDifPwrmgrWakeupRequestSourceFive, 0);
+
+    // Enter low power mode.
+    LOG_INFO("Issue WFI to enter sleep");
+    wait_for_interrupt();
+
+  } else if (pwrmgr_testutils_is_wakeup_reason(
+                 &pwrmgr, kDifPwrmgrWakeupRequestSourceFive)) {
+    LOG_INFO("Wakeup reset");
+
+    CHECK(rstmgr_testutils_is_reset_info(&rstmgr,
+                                         kDifRstmgrResetInfoLowPowerExit));
+    LOG_INFO("Aon timer wakeup detected");
+    rstmgr_testutils_post_reset(&rstmgr, kDifRstmgrResetInfoLowPowerExit, 0, 0,
+                                0, 0);
+
+    // add another 2ms to give more time to pwm pulses sequences
+    busy_spin_micros(2 * 1000);
+
+    return true;
+  } else {
+    dif_pwrmgr_wakeup_reason_t wakeup_reason;
+    CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
+    LOG_ERROR("Unexpected wakeup detected: type = %d, request_source = %d",
+              wakeup_reason.types, wakeup_reason.request_sources);
+    return false;
+  }
+
+  return false;
+}