From 68cd3ac9f23437f6dce6afdea023d90625fce63f Mon Sep 17 00:00:00 2001 From: Guillermo Maturana Date: Fri, 29 Sep 2023 17:43:20 +0000 Subject: [PATCH] [pwrmgr,ipgen] Remove the old and use the ipgen files Both hw/ip/pwrmgr and hw/top_earlgrey/ip/pwrmgr are removed. Various hjson and BUILD files and some docs are changed to use the ip_autogen directory. Signed-off-by: Guillermo Maturana --- hw/ip/BUILD | 1 - hw/ip/pwrmgr/BUILD | 12 - hw/ip/pwrmgr/README.md | 37 - hw/ip/pwrmgr/data/BUILD | 10 - hw/ip/pwrmgr/data/pwrmgr.hjson | 577 ------- hw/ip/pwrmgr/data/pwrmgr.hjson.tpl | 807 --------- .../pwrmgr/data/pwrmgr_sec_cm_testplan.hjson | 216 --- hw/ip/pwrmgr/data/pwrmgr_testplan.hjson | 353 ---- hw/ip/pwrmgr/doc/checklist.md | 266 --- hw/ip/pwrmgr/doc/interfaces.md | 67 - hw/ip/pwrmgr/doc/programmers_guide.md | 63 - hw/ip/pwrmgr/doc/pwrmgr_connectivity.svg | 1 - hw/ip/pwrmgr/doc/pwrmgr_fsms.svg | 1 - hw/ip/pwrmgr/doc/registers.md | 435 ----- hw/ip/pwrmgr/doc/theory_of_operation.md | 302 ---- hw/ip/pwrmgr/dv/README.md | 256 --- hw/ip/pwrmgr/dv/cov/pwrmgr_cov_bind.sv | 33 - hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el | 34 - hw/ip/pwrmgr/dv/doc/tb.svg | 1 - hw/ip/pwrmgr/dv/env/pwrmgr_env.core | 53 - hw/ip/pwrmgr/dv/env/pwrmgr_env.sv | 57 - hw/ip/pwrmgr/dv/env/pwrmgr_env_cfg.sv | 52 - hw/ip/pwrmgr/dv/env/pwrmgr_env_cov.sv | 193 --- hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv | 89 - hw/ip/pwrmgr/dv/env/pwrmgr_if.sv | 219 --- hw/ip/pwrmgr/dv/env/pwrmgr_scoreboard.sv | 339 ---- .../pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv | 14 - .../seq_lib/pwrmgr_aborted_low_power_vseq.sv | 124 -- .../pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv | 809 --------- .../dv/env/seq_lib/pwrmgr_common_vseq.sv | 113 -- ...pwrmgr_disable_rom_integrity_check_vseq.sv | 130 -- .../pwrmgr_esc_clk_rst_malfunc_vseq.sv | 42 - .../dv/env/seq_lib/pwrmgr_glitch_vseq.sv | 42 - .../dv/env/seq_lib/pwrmgr_global_esc_vseq.sv | 63 - .../seq_lib/pwrmgr_lowpower_invalid_vseq.sv | 140 -- .../pwrmgr_lowpower_wakeup_race_vseq.sv | 141 -- .../pwrmgr_repeat_wakeup_reset_vseq.sv | 79 - .../env/seq_lib/pwrmgr_reset_invalid_vseq.sv | 129 -- .../dv/env/seq_lib/pwrmgr_reset_vseq.sv | 77 - .../pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv | 38 - .../dv/env/seq_lib/pwrmgr_smoke_vseq.sv | 90 - .../dv/env/seq_lib/pwrmgr_stress_all_vseq.sv | 42 - .../dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv | 54 - .../pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv | 22 - .../env/seq_lib/pwrmgr_wakeup_reset_vseq.sv | 170 -- .../dv/env/seq_lib/pwrmgr_wakeup_vseq.sv | 126 -- hw/ip/pwrmgr/dv/pwrmgr_sim.core | 29 - hw/ip/pwrmgr/dv/pwrmgr_sim_cfg.hjson | 154 -- hw/ip/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv | 145 -- hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv | 87 - .../dv/sva/pwrmgr_clock_enables_sva_if.sv | 59 - hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core | 19 - hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv | 49 - hw/ip/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv | 102 -- .../dv/sva/pwrmgr_sec_cm_checker_assert.sv | 132 -- hw/ip/pwrmgr/dv/sva/pwrmgr_sva.core | 43 - hw/ip/pwrmgr/dv/tb.sv | 143 -- hw/ip/pwrmgr/dv/tests/pwrmgr_base_test.sv | 20 - hw/ip/pwrmgr/dv/tests/pwrmgr_test.core | 19 - hw/ip/pwrmgr/dv/tests/pwrmgr_test_pkg.sv | 22 - hw/ip/pwrmgr/lint/pwrmgr.vlt | 5 - hw/ip/pwrmgr/lint/pwrmgr.waiver | 5 - hw/ip/pwrmgr/lint/pwrmgr_pkg.vlt | 12 - hw/ip/pwrmgr/pwrmgr.core | 80 - hw/ip/pwrmgr/pwrmgr_pkg.core | 29 - hw/ip/pwrmgr/pwrmgr_reg.core | 21 - hw/ip/pwrmgr/rtl/pwrmgr.sv | 719 -------- hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv | 333 ---- hw/ip/pwrmgr/rtl/pwrmgr_cdc_pulse.sv | 91 - hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv | 542 ------ hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv | 282 ---- hw/ip/pwrmgr/rtl/pwrmgr_reg_pkg.sv | 215 --- hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv | 950 ----------- hw/ip/pwrmgr/rtl/pwrmgr_slow_fsm.sv | 358 ---- hw/ip/pwrmgr/rtl/pwrmgr_wake_info.sv | 74 - hw/ip/pwrmgr/util/reg_pwrmgr.py | 42 - hw/ip_templates/pwrmgr/BUILD | 4 +- hw/ip_templates/pwrmgr/data/BUILD | 9 + .../pwrmgr/data/pwrmgr_testplan.hjson | 2 +- hw/ip_templates/pwrmgr/dv/env/pwrmgr_env.core | 3 +- .../pwrmgr/dv/pwrmgr_sim_cfg.hjson | 7 +- hw/ip_templates/pwrmgr/dv/sva/pwrmgr_sva.core | 4 +- hw/ip_templates/pwrmgr/pwrmgr.core | 7 +- hw/ip_templates/pwrmgr/pwrmgr_reg.core | 5 +- .../data/autogen/top_earlgrey.gen.hjson | 2 +- hw/top_earlgrey/data/top_earlgrey.hjson | 3 +- .../dv/top_earlgrey_sim_cfgs.hjson | 2 +- hw/top_earlgrey/ip/BUILD | 2 +- hw/top_earlgrey/ip/pwrmgr/BUILD | 12 - hw/top_earlgrey/ip/pwrmgr/data/BUILD | 12 - hw/top_earlgrey/ip/pwrmgr/data/autogen/BUILD | 19 - .../ip/pwrmgr/data/autogen/pwrmgr.hjson | 875 ---------- .../data/autogen/pwrmgr_sec_cm_testplan.hjson | 219 --- hw/top_earlgrey/ip/pwrmgr/pwrmgr_reg.core | 20 - .../ip/pwrmgr/rtl/autogen/pwrmgr_reg_pkg.sv | 279 --- .../ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv | 1490 ----------------- hw/top_earlgrey/ip_autogen/pwrmgr/BUILD | 4 +- hw/top_earlgrey/ip_autogen/pwrmgr/data/BUILD | 9 + .../pwrmgr/data/pwrmgr_testplan.hjson | 2 +- .../ip_autogen/pwrmgr/dv/env/pwrmgr_env.core | 3 +- .../ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson | 7 +- .../ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core | 4 +- hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr.core | 7 +- .../ip_autogen/pwrmgr/pwrmgr_reg.core | 5 +- sw/device/lib/dif/BUILD | 2 +- sw/device/lib/dif/dif_pwrmgr.md | 2 +- sw/device/silicon_creator/lib/BUILD | 2 +- sw/device/silicon_creator/lib/drivers/BUILD | 4 +- sw/device/silicon_creator/rom/BUILD | 2 +- sw/device/silicon_creator/rom/e2e/BUILD | 2 +- sw/device/tests/sim_dv/BUILD | 8 +- sw/device/tock/BUILD | 2 +- util/ipgen/README.md | 36 +- 113 files changed, 82 insertions(+), 14695 deletions(-) delete mode 100644 hw/ip/pwrmgr/BUILD delete mode 100644 hw/ip/pwrmgr/README.md delete mode 100644 hw/ip/pwrmgr/data/BUILD delete mode 100644 hw/ip/pwrmgr/data/pwrmgr.hjson delete mode 100644 hw/ip/pwrmgr/data/pwrmgr.hjson.tpl delete mode 100644 hw/ip/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson delete mode 100644 hw/ip/pwrmgr/data/pwrmgr_testplan.hjson delete mode 100644 hw/ip/pwrmgr/doc/checklist.md delete mode 100644 hw/ip/pwrmgr/doc/interfaces.md delete mode 100644 hw/ip/pwrmgr/doc/programmers_guide.md delete mode 100644 hw/ip/pwrmgr/doc/pwrmgr_connectivity.svg delete mode 100644 hw/ip/pwrmgr/doc/pwrmgr_fsms.svg delete mode 100644 hw/ip/pwrmgr/doc/registers.md delete mode 100644 hw/ip/pwrmgr/doc/theory_of_operation.md delete mode 100644 hw/ip/pwrmgr/dv/README.md delete mode 100644 hw/ip/pwrmgr/dv/cov/pwrmgr_cov_bind.sv delete mode 100644 hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el delete mode 100644 hw/ip/pwrmgr/dv/doc/tb.svg delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_env.core delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_env.sv delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_env_cfg.sv delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_env_cov.sv delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_if.sv delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_scoreboard.sv delete mode 100644 hw/ip/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv delete mode 100644 hw/ip/pwrmgr/dv/pwrmgr_sim.core delete mode 100644 hw/ip/pwrmgr/dv/pwrmgr_sim_cfg.hjson delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv delete mode 100644 hw/ip/pwrmgr/dv/sva/pwrmgr_sva.core delete mode 100644 hw/ip/pwrmgr/dv/tb.sv delete mode 100644 hw/ip/pwrmgr/dv/tests/pwrmgr_base_test.sv delete mode 100644 hw/ip/pwrmgr/dv/tests/pwrmgr_test.core delete mode 100644 hw/ip/pwrmgr/dv/tests/pwrmgr_test_pkg.sv delete mode 100644 hw/ip/pwrmgr/lint/pwrmgr.vlt delete mode 100644 hw/ip/pwrmgr/lint/pwrmgr.waiver delete mode 100644 hw/ip/pwrmgr/lint/pwrmgr_pkg.vlt delete mode 100644 hw/ip/pwrmgr/pwrmgr.core delete mode 100644 hw/ip/pwrmgr/pwrmgr_pkg.core delete mode 100644 hw/ip/pwrmgr/pwrmgr_reg.core delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_cdc_pulse.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_reg_pkg.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_slow_fsm.sv delete mode 100644 hw/ip/pwrmgr/rtl/pwrmgr_wake_info.sv delete mode 100755 hw/ip/pwrmgr/util/reg_pwrmgr.py delete mode 100644 hw/top_earlgrey/ip/pwrmgr/BUILD delete mode 100644 hw/top_earlgrey/ip/pwrmgr/data/BUILD delete mode 100644 hw/top_earlgrey/ip/pwrmgr/data/autogen/BUILD delete mode 100644 hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson delete mode 100644 hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson delete mode 100644 hw/top_earlgrey/ip/pwrmgr/pwrmgr_reg.core delete mode 100644 hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_pkg.sv delete mode 100644 hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv diff --git a/hw/ip/BUILD b/hw/ip/BUILD index d1dc7be172c123..7825dd885bf77f 100644 --- a/hw/ip/BUILD +++ b/hw/ip/BUILD @@ -30,7 +30,6 @@ filegroup( "//hw/ip/prim_xilinx:all_files", "//hw/ip/prim_xilinx_ultrascale:all_files", "//hw/ip/pwm:all_files", - "//hw/ip/pwrmgr:all_files", "//hw/ip/rom_ctrl:all_files", "//hw/ip/rstmgr:all_files", "//hw/ip/rv_core_ibex:all_files", diff --git a/hw/ip/pwrmgr/BUILD b/hw/ip/pwrmgr/BUILD deleted file mode 100644 index 8b2c124557d7de..00000000000000 --- a/hw/ip/pwrmgr/BUILD +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "all_files", - srcs = glob(["**"]) + [ - "//hw/ip/pwrmgr/data:all_files", - ], -) diff --git a/hw/ip/pwrmgr/README.md b/hw/ip/pwrmgr/README.md deleted file mode 100644 index bd29b944ba8ca8..00000000000000 --- a/hw/ip/pwrmgr/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Power Manager HWIP Technical Specification - -[`pwrmgr`](https://reports.opentitan.org/hw/ip/pwrmgr/dv/latest/report.html): -![](https://dashboards.lowrisc.org/badges/dv/pwrmgr/test.svg) -![](https://dashboards.lowrisc.org/badges/dv/pwrmgr/passing.svg) -![](https://dashboards.lowrisc.org/badges/dv/pwrmgr/functional.svg) -![](https://dashboards.lowrisc.org/badges/dv/pwrmgr/code.svg) - -# Overview - -This document specifies the functionality of the OpenTitan power manager. - -## Features - -- Cold boot, low power entry / exit and reset support. -- 2 different low power modes. -- Software initiated low power entry and hardware requested low power exit. -- Peripheral reset requests -- Low power abort and low power fall-through support. -- ROM integrity check at power-up. -- Local checks for escalator and power stability. - -## Description - -The power manager sequences power, clocks, and reset resources of the design through cold boot, low power entry/exit and reset scenarios. - -Cold boot, also known as POR (power on reset) is the first reset state of the design. -The power manager sequences the design from a freshly reset state to an active state where software can be initialized. - -- Low power entry is the process in which the device enters one of two low power modes (sleep or deep sleep). -- Low power exit is the process in which the device exits low power mode and returns to active state. -- Low power entry is always initiated by software, while low power exit is always initiated by a previously setup hardware event such as pins or internal timers. -- The power manager processes the software and hardware requests to perform the appropriate actions. - -Reset scenarios refer to non-POR events that cause the device to reboot. -There are various stimuli that can cause such a reset, ranging from external user input to watchdog timeout. -The power manager processes the reset request and brings the device to an appropriate state. diff --git a/hw/ip/pwrmgr/data/BUILD b/hw/ip/pwrmgr/data/BUILD deleted file mode 100644 index 36beb77a655e78..00000000000000 --- a/hw/ip/pwrmgr/data/BUILD +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "all_files", - srcs = glob(["**"]), -) diff --git a/hw/ip/pwrmgr/data/pwrmgr.hjson b/hw/ip/pwrmgr/data/pwrmgr.hjson deleted file mode 100644 index 555e69b9003a75..00000000000000 --- a/hw/ip/pwrmgr/data/pwrmgr.hjson +++ /dev/null @@ -1,577 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// -// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - name: "pwrmgr", - human_name: "Power Manager", - one_line_desc: "Sequences on-chip power, clocks, and resets through different reset and power states", - one_paragraph_desc: ''' - Power Manager sequences on-chip power, clocks, and reset signals on power-on reset (aka cold boot), low power entry and exit, and non-power-on resets. - To this end, it can turn power domains on and off, control root resets with Reset Manager, and control root clock enables with AST and Clock Manager. - During power up, Power Manager is responsible for triggering OTP sensing, initiating Life Cycle Controller, coordinating with ROM Controller for the startup ROM check, and eventually releasing software to execute. - It features several countermeasures to deter fault injection (FI) attacks. - ''' - // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. - cip_id: "20", - design_spec: "../doc", - dv_doc: "../doc/dv", - hw_checklist: "../doc/checklist", - sw_checklist: "/sw/device/lib/dif/dif_pwrmgr", - revisions: [ - { - version: "0.1.0", - life_stage: "L1", - design_stage: "D1", - verification_stage: "V0", // this module is not verified at the block level - dif_stage: "S0", - commit_id: "b2abc989498f072d9a5530f8aab9b58c1f92c9fb" - } - { - version: "1.0.0", - life_stage: "L1", - design_stage: "D2S", - verification_stage: "V2S", - dif_stage: "S2", - } - ] - clocking: [ - {clock: "clk_i", reset: "rst_ni", primary: true}, - {reset: "rst_main_ni"}, - {clock: "clk_slow_i", reset: "rst_slow_ni"}, - {clock: "clk_lc_i", reset: "rst_lc_ni"}, - {clock: "clk_esc_i", reset: "rst_esc_ni"} - ] - bus_interfaces: [ - { protocol: "tlul", direction: "device" } - ], - interrupt_list: [ - { name: "wakeup", desc: "Wake from low power state. See wake info for more details" }, - ], - - inter_signal_list: [ - { struct: "pwr_ast", - type: "req_rsp", - name: "pwr_ast", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_rst", - type: "req_rsp", - name: "pwr_rst", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_clk", - type: "req_rsp", - name: "pwr_clk", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_otp", - type: "req_rsp", - name: "pwr_otp", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_lc", - type: "req_rsp", - name: "pwr_lc", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_flash", - type: "req_rsp", - name: "pwr_flash", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "esc_tx", - type: "uni", - name: "esc_rst_tx", - act: "rcv", - package: "prim_esc_pkg", - }, - - { struct: "esc_rx", - type: "uni", - name: "esc_rst_rx", - act: "req", - package: "prim_esc_pkg", - }, - - { struct: "pwr_cpu", - type: "uni", - name: "pwr_cpu", - act: "rcv", - package: "pwrmgr_pkg", - }, - - { struct: "logic", - width: 1, - type: "uni", - name: "wakeups", - act: "rcv", - package: "", - }, - - { struct: "logic", - width: 1, - type: "uni", - name: "rstreqs", - act: "rcv", - package: "", - }, - - ], - - param_list: [ - { name: "NumWkups", - desc: "Number of wakeups", - type: "int", - default: "1", - local: "true" - }, - { name: "NumRstReqs", - desc: "Number of reset requets", - type: "int", - default: "1", - local: "true" - }, - ], - - countermeasures: [ - { name: "BUS.INTEGRITY", - desc: "End-to-end bus integrity scheme." - } - { name: "LC_CTRL.INTERSIG.MUBI", - desc: "life cycle control / debug signals are multibit." - } - { name: "ROM_CTRL.INTERSIG.MUBI", - desc: "rom control done/good signals are multibit." - } - { name: "RSTMGR.INTERSIG.MUBI", - desc: "reset manager software request is multibit." - } - { name: "ESC_RX.CLK.BKGN_CHK", - desc: "Escalation receiver has a background timeout check" - } - { name: "ESC_RX.CLK.LOCAL_ESC", - desc: "Escalation receiver clock timeout has a local reset escalation" - } - { name: "FSM.SPARSE", - desc: "Sparse encoding for slow and fast state machines." - } - { name: "FSM.TERMINAL", - desc: "When FSMs reach a bad state, escalate directly and force user reset." - } - { name: "CTRL_FLOW.GLOBAL_ESC", - desc: "When global escalation is received, proceed directly to reset." - } - { name: "MAIN_PD.RST.LOCAL_ESC", - desc: "When main power domain reset glitches, proceed directly to reset." - } - { name: "CTRL.CONFIG.REGWEN", - desc: "Main control protected by regwen." - } - { name: "WAKEUP.CONFIG.REGWEN", - desc: "Wakeup configuration protected by regwen." - } - { name: "RESET.CONFIG.REGWEN", - desc: "Reset configuration protected by regwen." - } - - ] - - regwidth: "32", - registers: [ - - { name: "CTRL_CFG_REGWEN", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - desc: ''' - Controls the configurability of the !!CONTROL register. - - This register ensures the contents do not change once a low power hint and - WFI has occurred. - - It unlocks whenever a low power transition has completed (transition back to the - ACTIVE state) for any reason. - ''', - - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Configuration enable. - - This bit defaults to 1 and is set to 0 by hardware when low power entry is initiated. - When the device transitions back from low power state to active state, this bit is set - back to 1 to allow software configuration of !!CONTROL - ''', - resval: "1", - }, - ] - tags: [// This regwen is completely under HW management and thus cannot be manipulated - // by software. - "excl:CsrNonInitTests:CsrExclCheck"] - }, - - - { name: "CONTROL", - desc: "Control register", - swaccess: "rw", - hwaccess: "hro", - regwen: "CTRL_CFG_REGWEN", - fields: [ - { bits: "0", - hwaccess: "hrw", - name: "LOW_POWER_HINT", - desc: ''' - The low power hint to power manager. - The hint is an indication for how the manager should treat the next WFI. - Once the power manager begins a low power transition, or if a valid reset request is registered, - this bit is automatically cleared by HW. - ''' - resval: "0" - enum: [ - { value: "0", - name: "None", - desc: ''' - No low power intent - ''' - }, - { value: "1", - name: "Low Power", - desc: ''' - Next WFI should trigger low power entry - ''' - }, - ] - tags: [// The regwen for this reg is RO. CSR seq can't support to check this reg - "excl:CsrAllTests:CsrExclAll"] - }, - - { bits: "4", - name: "CORE_CLK_EN", - desc: "core clock enable during low power state", - resval: "0" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - Core clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - Core clock enabled during low power state - ''' - }, - ] - }, - - { bits: "5", - name: "IO_CLK_EN", - desc: "IO clock enable during low power state", - resval: "0" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - IO clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - IO clock enabled during low power state - ''' - }, - ] - }, - - { bits: "6", - name: "USB_CLK_EN_LP", - desc: "USB clock enable during low power state", - resval: "0", - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - USB clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - USB clock enabled during low power state - ''' - }, - ] - }, - - { bits: "7", - name: "USB_CLK_EN_ACTIVE", - desc: "USB clock enable during active power state", - resval: "1" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - USB clock disabled during active power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - USB clock enabled during active power state - ''' - }, - ] - tags: [// Turning off USB clock in active state impacts other CSRs - // at the chip level (in other blocks, such as clkmgr). - "excl:CsrNonInitTests:CsrExclWrite"] - }, - - { bits: "8", - name: "MAIN_PD_N", - desc: "Active low, main power domain power down", - resval: "1" - enum: [ - { value: "0", - name: "Power down", - desc: ''' - Main power domain is powered down during low power state - ''' - }, - { value: "1", - name: "Power up", - desc: ''' - Main power domain is kept powered during low power state - ''' - }, - ] - }, - - - ], - }, - - { name: "CFG_CDC_SYNC", - swaccess: "rw", - hwaccess: "hrw", - hwqe: "true", - desc: ''' - The configuration registers CONTROL, WAKEUP_EN, RESET_EN are all written in the - fast clock domain but used in the slow clock domain. - - The configuration are not propogated across the clock boundary until this - register is triggered and read. See fields below for more details - ''', - - fields: [ - { bits: "0", - name: "SYNC", - desc: ''' - Configuration sync. When this bit is written to 1, a sync pulse is generated. When - the sync completes, this bit then self clears. - - Software should write this bit to 1, wait for it to clear, before assuming the slow clock - domain has assumed the programmed values. - ''', - resval: "0", - }, - ] - tags: [// This bit triggers a payload synchronization and self clears when complete. - // Do not write this bit as there will be side effects and the value will not persist - "excl:CsrNonInitTests:CsrExclCheck"] - }, - - { name: "WAKEUP_EN_REGWEN", - desc: "Configuration enable for wakeup_en register", - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - resval: "1" - name: "EN", - desc: ''' - When 1, WAKEUP_EN register can be configured. - When 0, WAKEUP_EN register cannot be configured. - ''', - }, - ] - }, - - { multireg: - { name: "WAKEUP_EN", - desc: "Bit mask for enabled wakeups", - swaccess: "rw", - hwaccess: "hro", - regwen: "WAKEUP_EN_REGWEN", - resval: "0" - cname: "wakeup_en", - count: "NumWkups" - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Whenever a particular bit is set to 1, that wakeup is also enabled. - Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. - ''', - }, - ] - }, - }, - - { multireg: - { name: "WAKE_STATUS", - desc: "A read only register of all current wake requests post enable mask", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - cname: "wake_status", - count: "NumWkups", - tags: [// Cannot auto-predict current wake request status - "excl:CsrNonInitTests:CsrExclWriteCheck"], - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - Current value of wake requests - ''', - }, - ] - }, - }, - - { name: "RESET_EN_REGWEN", - desc: "Configuration enable for reset_en register", - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - resval: "1" - name: "EN", - desc: ''' - When 1, RESET_EN register can be configured. - When 0, RESET_EN register cannot be configured. - ''', - }, - ] - }, - - { multireg: - { name: "RESET_EN", - desc: "Bit mask for enabled reset requests", - swaccess: "rw", - hwaccess: "hro", - regwen: "RESET_EN_REGWEN", - resval: "0" - cname: "rstreq_en", - count: "NumRstReqs" - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Whenever a particular bit is set to 1, that reset request is enabled. - Whenever a particular bit is set to 0, that reset request cannot reset the device. - ''', - }, - ] - }, - }, - - { multireg: - { name: "RESET_STATUS", - desc: "A read only register of all current reset requests post enable mask", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - cname: "reset_status", - count: "NumRstReqs", - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - Current value of reset request - ''', - }, - ] - }, - }, - - { name: "WAKE_INFO_CAPTURE_DIS", - desc: "Disables capture by WAKE_INFO", - swaccess: "rw", - hwaccess: "hro", - resval: "0" - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - When written to 1, WAKE INFO capture is suppressed. - When written to 0, WAKE_INFO capture is controlled by HW. - ''', - }, - ] - }, - - { name: "WAKE_INFO", - desc: ''' - Indicates which functions caused the chip to wakeup. - - This register starts recording upon a valid low power entry with WAKE_INFO_CAPTURE_DIS off. - Capture continues until it is explicitly disabled by setting WAKE_INFO_CAPTURE_DIS. - This means it is possible to capture multiple wakeup reasons. - ''', - swaccess: "rw1c", - hwaccess: "hrw", - hwext: "true", - hwqe: "true", - resval: "0" - fields: [ - { bits: "0:0", - name: "REASONS", - desc: "Various peripheral wake reasons" - }, - { bits: "1", - name: "FALL_THROUGH", - desc: ''' - The fall through wakeup reason indicates that despite setting a WFI and providing a low power - hint, an interrupt arrived at just the right time to break the executing core out of WFI. - - The power manager detects this condition, halts low power entry and reports as a wakeup reason - ''', - }, - { bits: "2", - name: "ABORT", - desc: ''' - The abort wakeup reason indicates that despite setting a WFI and providing a low power - hint, an active flash / lifecycle / otp transaction was ongoing when the power controller - attempted to initiate low power entry. - - The power manager detects this condition, halts low power entry and reports as a wakeup reason - ''', - }, - ] - tags: [// This regwen is completely under HW management and thus cannot be manipulated - // by software. - "excl:CsrNonInitTests:CsrExclCheck"] - }, - ] -} diff --git a/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl b/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl deleted file mode 100644 index 51d96509afde1f..00000000000000 --- a/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl +++ /dev/null @@ -1,807 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -<% - # Additional reset - int_reset_reqs = rst_reqs["int"] - debug_reset_reqs = rst_reqs["debug"] -%>\ -{ - name: "pwrmgr", - human_name: "Power Manager", - one_line_desc: "Sequences on-chip power, clocks, and resets through different reset and power states", - one_paragraph_desc: ''' - Power Manager sequences on-chip power, clocks, and reset signals on power-on reset (aka cold boot), low power entry and exit, and non-power-on resets. - To this end, it can turn power domains on and off, control root resets with Reset Manager, and control root clock enables with AST and Clock Manager. - During power up, Power Manager is responsible for triggering OTP sensing, initiating Life Cycle Controller, coordinating with ROM Controller for the startup ROM check, and eventually releasing software to execute. - It features several countermeasures to deter fault injection (FI) attacks. - ''' - // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. - cip_id: "20", - design_spec: "../doc", - dv_doc: "../doc/dv", - hw_checklist: "../doc/checklist", - sw_checklist: "/sw/device/lib/dif/dif_pwrmgr", - revisions: [ - { - version: "0.1.0", - life_stage: "L1", - design_stage: "D1", - verification_stage: "V0", // this module is not verified at the block level - dif_stage: "S0", - commit_id: "b2abc989498f072d9a5530f8aab9b58c1f92c9fb" - } - { - version: "1.0.0", - life_stage: "L1", - design_stage: "D2S", - verification_stage: "V2S", - dif_stage: "S2", - } - ] - clocking: [ - {clock: "clk_i", reset: "rst_ni", primary: true}, - {reset: "rst_main_ni"}, - {clock: "clk_slow_i", reset: "rst_slow_ni"}, - {clock: "clk_lc_i", reset: "rst_lc_ni"}, - {clock: "clk_esc_i", reset: "rst_esc_ni"} - ] - bus_interfaces: [ - { protocol: "tlul", direction: "device" } - ], - interrupt_list: [ - { name: "wakeup", desc: "Wake from low power state. See wake info for more details" }, - ], - alert_list: [ - { name: "fatal_fault", - desc: ''' - This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. - ''' - } - ], - features: [ - { name: "PWRMGR.STARTUP.LIFE_CYCLE_INITIALIZATION", - desc: "Wait completion of Life Cycle initialization." - } - { name: "PWRMGR.CLOCK_CONTROL.IO_IN_LOW_POWER", - desc: '''Controls whether the IO clock remains active in - low power mode. - ''' - } - { name: "PWRMGR.CLOCK_CONTROL.MAIN_IN_LOW_POWER", - desc: '''Controls whether the MAIN clock remains active in - low power mode. - ''' - } - { name: "PWRMGR.CLOCK_CONTROL.USB_IN_LOW_POWER", - desc: '''Controls whether the USB clock remains active in - low power mode. - ''' - } - { name: "PWRMGR.CLOCK_CONTROL.USB_WHEN_ACTIVE", - desc: "Controls whether the USB clock is enabled in active state." - } - { name: "PWRMGR.LOW_POWER.ENTRY", - desc: '''Controls of low power entry, and cases when low power is - not entered due to interrupts or specific units getting busy. - ''' - } - { name: "PWRMGR.LOW_POWER.DISABLE_POWER" - desc: '''Controls whether power is turned off for non-AON domains when - in low power. - ''' - } -% for wkup in Wkups: -<% - wakeup_name = wkup["module"].upper() + "_" + wkup["name"].upper() -%>\ - { name: "PWRMGR.LOW_POWER.${wakeup_name}_WAKEUP_ENABLE" - desc: "Enable wakeup request ${wkup["name"]} from ${wkup["module"]}." - } - { name: "PWRMGR.LOW_POWER.${wakeup_name}_WAKEUP_REQUEST" - desc: "Wakeup request ${wkup["name"]} from ${wkup["module"]}." - } -% endfor - { name: "PWRMGR.LOW_POWER.WAKE_INFO" - desc: "Record what caused the chip to wakeup from low power." - } - { name: "PWRMGR.RESET.CHECK_ROM_INTEGRITY", - desc: "Wait for successful completion of ROM integrity checks." - } -% for reset in rst_reqs["peripheral"]: -<% - description = reset["desc"] - reset_name = reset["module"].upper() + "_" + reset["name"].upper() - description = description[:1].upper() + description[1:].rstrip(".") -%>\ - { name: "PWRMGR.RESET.${reset_name}_ENABLE", - desc: "Enable reset request from ${reset["module"]}." - } - { name: "PWRMGR.RESET.${reset_name}_REQUEST", - desc: "Reset request from ${reset["module"]}." - } -% endfor - { name: "PWRMGR.RESET.ESCALATION_REQUEST", - desc: "Trigger reset in response to incoming escalation requests." - } - { name: "PWRMGR.RESET.ESCALATION_TIMEOUT", - desc: "Trigger reset in response to non-responsive escalation network." - } - { name: "PWRMGR.RESET.SW_RST_REQUEST", - desc: "Trigger reset in response to rstmgr's sw reset request." - } - { name: "PWRMGR.RESET.MAIN_POWER_GLITCH_RESET", - desc: "Trigger reset in response to glitch in main power." - } - { name: "PWRMGR.RESET.NDM_RESET_REQUEST", - desc: "Trigger reset in response to RV_DM ndm reset." - } - { name: "PWRMGR.RESET.POR_REQUEST", - desc: "Trigger reset in response to POR_N pin." - } - ] - - inter_signal_list: [ - { struct: "pwr_ast", - type: "req_rsp", - name: "pwr_ast", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_rst", - type: "req_rsp", - name: "pwr_rst", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_clk", - type: "req_rsp", - name: "pwr_clk", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_otp", - type: "req_rsp", - name: "pwr_otp", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_lc", - type: "req_rsp", - name: "pwr_lc", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_flash", - type: "uni", - name: "pwr_flash", - act: "rcv", - package: "pwrmgr_pkg", - }, - - { struct: "esc_tx", - type: "uni", - name: "esc_rst_tx", - act: "rcv", - package: "prim_esc_pkg", - }, - - { struct: "esc_rx", - type: "uni", - name: "esc_rst_rx", - act: "req", - package: "prim_esc_pkg", - }, - - { struct: "pwr_cpu", - type: "uni", - name: "pwr_cpu", - act: "rcv", - package: "pwrmgr_pkg", - }, - - { struct: "logic", - width: ${NumWkups}, - type: "uni", - name: "wakeups", - act: "rcv", - package: "", - }, - - { struct: "logic", - width: ${NumRstReqs}, - type: "uni", - name: "rstreqs", - act: "rcv", - package: "", - }, - - { struct: "logic", - type: "uni", - name: "ndmreset_req", - act: "rcv", - }, - - { struct: "logic", - type: "uni", - name: "strap", - act: "req", - package: "", - }, - - { struct: "logic", - type: "uni", - name: "low_power", - act: "req", - package: "", - }, - - { struct: "pwrmgr_data", - type: "uni", - name: "rom_ctrl", - act: "rcv", - package: "rom_ctrl_pkg", - }, - - { struct: "lc_tx", - type: "uni", - name: "fetch_en", - act: "req", - package: "lc_ctrl_pkg", - }, - - { struct: "lc_tx", - type: "uni", - name: "lc_dft_en", - act: "rcv", - package: "lc_ctrl_pkg", - }, - - { struct: "lc_tx", - type: "uni", - name: "lc_hw_debug_en", - act: "rcv", - package: "lc_ctrl_pkg", - }, - - { struct: "mubi4", - type: "uni", - name: "sw_rst_req", - act: "rcv", - package: "prim_mubi_pkg", - }, - ], - - param_list: [ - { name: "NumWkups", - desc: "Number of wakeups", - type: "int", - default: "${NumWkups}", - local: "true" - }, - - % for wkup in Wkups: - { name: "${wkup['module'].upper()}_${wkup['name'].upper()}_IDX", - desc: "Vector index for ${wkup['module']} ${wkup['name']}, applies for WAKEUP_EN, WAKE_STATUS and WAKE_INFO", - type: "int", - default: "${loop.index}", - local: "true" - }, - - % endfor - - { name: "NumRstReqs", - desc: "Number of peripheral reset requets", - type: "int", - default: "${NumRstReqs}", - local: "true" - }, - - { name: "NumIntRstReqs", - desc: "Number of pwrmgr internal reset requets", - type: "int", - default: "${len(int_reset_reqs)}", - local: "true" - }, - - { name: "NumDebugRstReqs", - desc: "Number of debug reset requets", - type: "int", - default: "${len(debug_reset_reqs)}", - local: "true" - }, - - % for req in int_reset_reqs + debug_reset_reqs: - { name: "${f"Reset{req['name']}Idx"}", - desc: "Reset req idx for ${req['name']}", - type: "int", - default: "${loop.index + NumRstReqs}", - local: "true" - }, - % endfor - - ], - countermeasures: [ - { name: "BUS.INTEGRITY", - desc: "End-to-end bus integrity scheme." - } - { name: "LC_CTRL.INTERSIG.MUBI", - desc: "life cycle control / debug signals are multibit." - } - { name: "ROM_CTRL.INTERSIG.MUBI", - desc: "rom control done/good signals are multibit." - } - { name: "RSTMGR.INTERSIG.MUBI", - desc: "reset manager software request is multibit." - } - { name: "ESC_RX.CLK.BKGN_CHK", - desc: "Escalation receiver has a background timeout check" - } - { name: "ESC_RX.CLK.LOCAL_ESC", - desc: "Escalation receiver clock timeout has a local reset escalation" - } - { name: "FSM.SPARSE", - desc: "Sparse encoding for slow and fast state machines." - } - { name: "FSM.TERMINAL", - desc: ''' - When FSMs reach a bad state, go into a terminate state that does not - recover without user or external host intervention. - ''' - } - { name: "CTRL_FLOW.GLOBAL_ESC", - desc: "When global escalation is received, proceed directly to reset." - } - { name: "MAIN_PD.RST.LOCAL_ESC", - desc: "When main power domain reset glitches, proceed directly to reset." - } - { name: "CTRL.CONFIG.REGWEN", - desc: "Main control protected by regwen." - } - { name: "WAKEUP.CONFIG.REGWEN", - desc: "Wakeup configuration protected by regwen." - } - { name: "RESET.CONFIG.REGWEN", - desc: "Reset configuration protected by regwen." - } - - ] - - regwidth: "32", - registers: [ - - { name: "CTRL_CFG_REGWEN", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - desc: ''' - Controls the configurability of the !!CONTROL register. - - This register ensures the contents do not change once a low power hint and - WFI has occurred. - - It unlocks whenever a low power transition has completed (transition back to the - ACTIVE state) for any reason. - ''', - - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Configuration enable. - - This bit defaults to 1 and is set to 0 by hardware when low power entry is initiated. - When the device transitions back from low power state to active state, this bit is set - back to 1 to allow software configuration of !!CONTROL - ''', - resval: "1", - }, - ] - tags: [// This regwen is completely under HW management and thus cannot be manipulated - // by software. - "excl:CsrNonInitTests:CsrExclCheck"] - }, - - - { name: "CONTROL", - desc: "Control register", - swaccess: "rw", - hwaccess: "hro", - regwen: "CTRL_CFG_REGWEN", - tags: [// Turning off USB clock in active state impacts other CSRs - // at the chip level (in other blocks, such as clkmgr), - // so we exclude writing from this register. - "excl:CsrAllTests:CsrExclWrite"] - fields: [ - { bits: "0", - hwaccess: "hrw", - name: "LOW_POWER_HINT", - desc: ''' - The low power hint to power manager. - The hint is an indication for how the manager should treat the next WFI. - Once the power manager begins a low power transition, or if a valid reset request is registered, - this bit is automatically cleared by HW. - ''' - resval: "0" - enum: [ - { value: "0", - name: "None", - desc: ''' - No low power intent - ''' - }, - { value: "1", - name: "Low Power", - desc: ''' - Next WFI should trigger low power entry - ''' - }, - ] - tags: [// The regwen for this reg is RO. CSR seq can't support to check this reg - "excl:CsrAllTests:CsrExclAll"] - }, - - { bits: "4", - name: "CORE_CLK_EN", - desc: "core clock enable during low power state", - resval: "0" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - Core clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - Core clock enabled during low power state - ''' - }, - ] - }, - - { bits: "5", - name: "IO_CLK_EN", - desc: "IO clock enable during low power state", - resval: "0" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - IO clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - IO clock enabled during low power state - ''' - }, - ] - }, - - { bits: "6", - name: "USB_CLK_EN_LP", - desc: "USB clock enable during low power state", - resval: "0", - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - USB clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - USB clock enabled during low power state. - - However, if !!CONTROL.MAIN_PD_N is 0, USB clock is disabled - during low power state. - ''' - }, - ] - }, - - { bits: "7", - name: "USB_CLK_EN_ACTIVE", - desc: "USB clock enable during active power state", - resval: "1" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - USB clock disabled during active power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - USB clock enabled during active power state - ''' - }, - ] - }, - - { bits: "8", - name: "MAIN_PD_N", - desc: "Active low, main power domain power down", - resval: "1" - enum: [ - { value: "0", - name: "Power down", - desc: ''' - Main power domain is powered down during low power state. - ''' - }, - { value: "1", - name: "Power up", - desc: ''' - Main power domain is kept powered during low power state - ''' - }, - ] - }, - - - ], - }, - - { name: "CFG_CDC_SYNC", - swaccess: "rw", - hwaccess: "hrw", - hwqe: "true", - desc: ''' - The configuration registers CONTROL, WAKEUP_EN, RESET_EN are all written in the - fast clock domain but used in the slow clock domain. - - The configuration are not propagated across the clock boundary until this - register is triggered and read. See fields below for more details - ''', - - fields: [ - { bits: "0", - name: "SYNC", - desc: ''' - Configuration sync. When this bit is written to 1, a sync pulse is generated. When - the sync completes, this bit then self clears. - - Software should write this bit to 1, wait for it to clear, before assuming the slow clock - domain has accepted the programmed values. - ''', - resval: "0", - }, - ] - tags: [// This bit triggers a payload synchronization and self clears when complete. - // Do not write this bit as there will be side effects and the value will not persist - "excl:CsrNonInitTests:CsrExclWrite"] - }, - - { name: "WAKEUP_EN_REGWEN", - desc: "Configuration enable for wakeup_en register", - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - resval: "1" - name: "EN", - desc: ''' - When 1, WAKEUP_EN register can be configured. - When 0, WAKEUP_EN register cannot be configured. - ''', - }, - ] - }, - - { multireg: - { name: "WAKEUP_EN", - desc: "Bit mask for enabled wakeups", - swaccess: "rw", - hwaccess: "hro", - regwen: "WAKEUP_EN_REGWEN", - resval: "0" - cname: "wakeup_en", - count: "NumWkups" - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Whenever a particular bit is set to 1, that wakeup is also enabled. - Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. - ''', - }, - ] - }, - }, - - { multireg: - { name: "WAKE_STATUS", - desc: "A read only register of all current wake requests post enable mask", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - cname: "wake_status", - count: "NumWkups", - tags: [// Cannot auto-predict current wake request status - "excl:CsrNonInitTests:CsrExclWriteCheck"], - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - Current value of wake requests - ''', - }, - ] - }, - }, - - { name: "RESET_EN_REGWEN", - desc: "Configuration enable for reset_en register", - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - resval: "1" - name: "EN", - desc: ''' - When 1, RESET_EN register can be configured. - When 0, RESET_EN register cannot be configured. - ''', - }, - ] - }, - - { multireg: - { name: "RESET_EN", - desc: "Bit mask for enabled reset requests", - swaccess: "rw", - hwaccess: "hro", - regwen: "RESET_EN_REGWEN", - resval: "0" - cname: "rstreq_en", - count: "NumRstReqs" - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Whenever a particular bit is set to 1, that reset request is enabled. - Whenever a particular bit is set to 0, that reset request cannot reset the device. - ''', - }, - ] - tags: [// Self resets should never be triggered by automated tests - "excl:CsrAllTests:CsrExclWrite"] - }, - }, - - { multireg: - { name: "RESET_STATUS", - desc: "A read only register of all current reset requests post enable mask", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - cname: "reset_status", - count: "NumRstReqs", - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - Current value of reset request - ''', - }, - ] - }, - }, - - { name: "ESCALATE_RESET_STATUS", - desc: "A read only register of escalation reset request", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - When 1, an escalation reset has been seen. - When 0, there is no escalation reset. - ''', - }, - ] - }, - - { name: "WAKE_INFO_CAPTURE_DIS", - desc: "Indicates which functions caused the chip to wakeup", - swaccess: "rw", - hwaccess: "hro", - resval: "0" - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - When written to 1, this actively suppresses the wakeup info capture. - When written to 0, wakeup info capture timing is controlled by HW. - ''', - }, - ] - }, - - { name: "WAKE_INFO", - desc: ''' - Indicates which functions caused the chip to wakeup. - The wake info recording begins whenever the device begins a valid low power entry. - - This capture is continued until it is explicitly disabled through WAKE_INFO_CAPTURE_DIS. - This means it is possible to capture multiple wakeup reasons. - ''', - swaccess: "rw1c", - hwaccess: "hrw", - hwext: "true", - hwqe: "true", - resval: "0" - fields: [ - { bits: "${NumWkups-1}:0", - name: "REASONS", - desc: "Various peripheral wake reasons" - }, - { bits: "${NumWkups}", - name: "FALL_THROUGH", - desc: ''' - The fall through wakeup reason indicates that despite setting a WFI and providing a low power - hint, an interrupt arrived at just the right time to break the executing core out of WFI. - - The power manager detects this condition, halts low power entry and reports as a wakeup reason - ''', - }, - { bits: "${NumWkups+1}", - name: "ABORT", - desc: ''' - The abort wakeup reason indicates that despite setting a WFI and providing a low power - hint, an active flash / lifecycle / otp transaction was ongoing when the power controller - attempted to initiate low power entry. - - The power manager detects this condition, halts low power entry and reports as a wakeup reason - ''', - }, - ] - tags: [// This regwen is completely under HW management and thus cannot be manipulated - // by software. - "excl:CsrNonInitTests:CsrExclCheck"] - }, - - { name: "FAULT_STATUS", - desc: "A read only register that shows the existing faults", - swaccess: "ro", - hwaccess: "hrw", - sync: "clk_lc_i", - resval: "0" - fields: [ - { bits: "0", - name: "REG_INTG_ERR", - desc: ''' - When 1, an integrity error has occurred. - ''', - }, - - { bits: "1", - name: "ESC_TIMEOUT", - desc: ''' - When 1, an escalation clock / reset timeout has occurred. - ''', - }, - - { bits: "2", - name: "MAIN_PD_GLITCH", - desc: ''' - When 1, unexpected power glitch was observed on main PD. - ''', - }, - ] - }, - ] -} diff --git a/hw/ip/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson b/hw/ip/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson deleted file mode 100644 index f5c6aa33f41fc9..00000000000000 --- a/hw/ip/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Security countermeasures testplan extracted from the IP Hjson using reggen. -// -// This testplan is auto-generated only the first time it is created. This is -// because this testplan needs to be hand-editable. It is possible that these -// testpoints can go out of date if the spec is updated with new -// countermeasures. When `reggen` is invoked when this testplan already exists, -// It checks if the list of testpoints is up-to-date and enforces the user to -// make further manual updates. -// -// These countermeasures and their descriptions can be found here: -// .../pwrmgr/data/pwrmgr.hjson -// -// It is possible that the testing of some of these countermeasures may already -// be covered as a testpoint in a different testplan. This duplication is ok - -// the test would have likely already been developed. We simply map those tests -// to the testpoints below using the `tests` key. -// -// Please ensure that this testplan is imported in: -// .../pwrmgr/data/pwrmgr_testplan.hjson -{ - testpoints: [ - { - name: sec_cm_bus_integrity - desc: '''Verify the countermeasure(s) BUS.INTEGRITY. - This entry is covered by tl_access_test - (hw/dv/tools/dvsim/tests/tl_access_tests.hjson) - This will not trigger rst_req, but - send fatal alert - ''' - stage: V2S - tests: ["pwrmgr_tl_intg_err"] - } - { - name: sec_cm_lc_ctrl_intersig_mubi - desc: '''Verify the countermeasure(s) LC_CTRL.INTERSIG.MUBI. - - **Stimulus**: - - Use comprehensive stimulus - reset and wakeup - - as background traffic to ensure this counter measure - is valid for various states of fast and slow state. - - Drive lc_hw_debug_en_i and lc_dft_en_i with - mixed valid and invalid values. - - **Check**: - - Collect coverage by binding cip_mubi_cov_if to - tb.dut.lc_hw_debug_en_i and tb.dut.lc_dft_en_i - - Add assertion to check whether rom_intg_chk_dis - is set to '1' only when lc_dft_en_i or lc_hw_debug_en_i - is high. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_lc_ctrl_intersig_mubi"] - } - { - name: sec_cm_rom_ctrl_intersig_mubi - desc: '''Verify the countermeasure(s) ROM_CTRL.INTERSIG.MUBI. - - **Stimulus**: - - Use comprehensive stimulus - reset and wakeup - - as background traffic to ensure this counter measure - is valid for various states of fast and slow fsm. - - Drive rom_ctrl_i with mixed valid and invalid values. - - **Check**: - - Collect coverage by binding cip_mubi_cov_if to - tb.dut.rom_ctrl_i - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_rom_ctrl_intersig_mubi"] - } - { - name: sec_cm_rstmgr_intersig_mubi - desc: '''Verify the countermeasure(s) RSTMGR.INTERSIG.MUBI. - - **Stimulus**: - - Drive tb.dut.sw_rst_req_i with mixed valid and invalid values - - **Check**: - - See sw rst only happens when dut gets valid value. - - Collect coverage by binding cip_mubi_cov_if to - tb.dut.sw_rst_req_i - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_rstmgr_intersig_mubi"] - } - { - name: sec_cm_esc_rx_clk_bkgn_chk - desc: '''Verify the countermeasure(s) ESC_RX.CLK.BKGN_CHK. - - **Stimulus**: - - At FastPwrStateActive state, create escalation clock - or reset failure by stopping clock or asserting reset. - - **Check**: - - Expecting esc_timeout event and trigger rstreqs[ResetEscIdx] - and fatal alert event. After alert agent process - the alert by asserting escalation reset, see if dut - is back to normal operation state. - - ''' - stage: V2S - tests: ["pwrmgr_esc_clk_rst_malfunc"] - } - { - name: sec_cm_esc_rx_clk_local_esc - desc: '''Verify the countermeasure(s) ESC_RX.CLK.LOCAL_ESC. - - This is triggered by common cm primitives (SecCmPrimCount). - (https://github.com/lowRISC/opentitan/blob/master - /hw/dv/sv/cip_lib/doc/index.md#security-verification - -for-common-countermeasure-primitives) - - **Check**: - - Detect fast state transition to FastPwrStateResetPrep. - And this will trigger rstreqs[ResetEscIdx]. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm"] - } - { - name: sec_cm_fsm_sparse - desc: '''Verify the countermeasure(s) FSM.SPARSE. - This is triggered by common cm primitives (SecCmPrimSparseFsmFlop). - (https://github.com/lowRISC/opentitan/blob/master - /hw/dv/sv/cip_lib/doc/index.md#security-verification - -for-common-countermeasure-primitives) - ''' - stage: V2S - tests: ["pwrmgr_sec_cm"] - } - { - name: sec_cm_fsm_terminal - desc: '''Verify the countermeasure(s) FSM.TERMINAL. - - This is caused by any invalid (slow|fast) state. - - **Check**: - If slow state is invalid, fast state becomes FastPwrStateInvalid, - pwr_ast_o.pwr_clamp =1 and pwr_ast_o.main_pd_n = 0. - If fast state is invalid, pwr_rst_o.rst_lc_req = 3, - pwr_rst_o.rst_sys_req = 3 and pwr_clk_o = 0. - Dut should be recovered by asserting rst_n = 0. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm"] - } - { - name: sec_cm_ctrl_flow_global_esc - desc: '''Verify the countermeasure(s) CTRL_FLOW.GLOBAL_ESC. - - **Stimulus**: - - Send escalation request to esc_rst_tx_i. - - **Check**: - - Check fast state transition to FastPwrStateResetPrep - and get pwr_rst_req. - ''' - stage: V2S - tests: ["pwrmgr_global_esc"] - } - { - name: sec_cm_main_pd_rst_local_esc - desc: '''Verify the countermeasure(s) MAIN_PD.RST.LOCAL_ESC. - - **Stimulus**: - - Create power reset glitch by setting 'tb.dut.rst_main_ni' to 0. - - **Check**: - - Check fast state transition to FastPwrStateResetPrep - and get pwr_rst_req. - ''' - stage: V2S - tests: ["pwrmgr_glitch"] - } - { - name: sec_cm_ctrl_config_regwen - desc: '''Verify the countermeasure(s) CTRL.CONFIG.REGWEN. - - **Stimulus**: - - Initiate low power transition by setting - PWRMGR.CONTROL.LOW_POWER_HINT to 1. Wait for a few cycle - to ensure the csr value propagates to slow clock domain. - Then issue csr write to PWRMGR.CONTROL - - **Check**: - - After the csr update under PWRMGR.CTRL_CFG_REGWEN = 0, - read back and check the value is not updated by - the csr udate attempt. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_ctrl_config_regwen"] - } - { - name: sec_cm_wakeup_config_regwen - desc: '''Verify the countermeasure(s) WAKEUP.CONFIG.REGWEN. - - This is covered by auto csr test. - ''' - stage: V2S - tests: ["pwrmgr_csr_rw"] - } - { - name: sec_cm_reset_config_regwen - desc: '''Verify the countermeasure(s) RESET.CONFIG.REGWEN. - - This is covered by auto csr test. - ''' - stage: V2S - tests: ["pwrmgr_csr_rw"] - } - ] -} diff --git a/hw/ip/pwrmgr/data/pwrmgr_testplan.hjson b/hw/ip/pwrmgr/data/pwrmgr_testplan.hjson deleted file mode 100644 index 4d0ddde515167d..00000000000000 --- a/hw/ip/pwrmgr/data/pwrmgr_testplan.hjson +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - name: "pwrmgr" - // TODO: remove the common testplans if not applicable - import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", - "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", - "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", - "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", - "hw/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson", - "hw/dv/tools/dvsim/testplans/sec_cm_fsm_testplan.hjson", - // TODO: Top-level specific Hjson imported here. This will likely be resolved - // once we move to IPgen flow. - "hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson"] - testpoints: [ - { - name: smoke - desc: ''' - Smoke test exercising the pwrmgr state transitions. - - - Brings pwrmgr out of POR. - - Enables wakeup. - - Triggers SW initiated low power transition with reset settings - in `control` CSR. - - Triggers wakeup. - - Enables and triggers a reset. - - Waits for pwrmgr to be out of reset. - - **Stimulus**: - - CSR writes to `wakeup_en`, `reset_en`, and `low_power_hint`. - - Needs many input pins to line up correctly in order to prevent the - pwrmgr from waiting forever. Most of these are set in response - to outputs, and are checked by SVA. - - **Checks**: - - The fast fsm becomes active when `fetch_en_o` output rises. - - The wakeup and reset causes are as expected reading CSRs - `wake_status` and `reset_status`. - - The output `pwr_rst_req.reset_cause` matches a low power or - reset cause. - - The output `pwr_rst_req.rstreqs` matches the enabled resets. - ''' - stage: V1 - tests: ["pwrmgr_smoke"] - } - { - name: wakeup - desc: ''' - Test random wakeup, wakeup_en, wake_info_capture_dis, and - interrupt. - - The different wakeup inputs can be disabled via bits in the - `wakeup_en` CSR. Update of `wakeup_info` can be disabled - via the `wake_info_capture_dis` CSR. Any wakeup causes an - interrupt unless interrupts are disabled. - - **Stimulus**: - - Sets `wakeup_en` randomly but don't set it to zero, or the - test will timeout. - - Set `wake_info_capture_dis` randomly on and off. - - Bring pwrmgr to low power. - - Set `wakeups_i` inputs randomly. - - Set `intr_enable` randomly. - - **Checks**: - - The fast fsm becomes active when `fetch_en_o` output rises. - - Depending on `wakeups_i`: - - If all wakeups are disabled, wait some time checking the - state remains inactive. - - Set `wakeups_i` so at least one is enabled. - - Checks `wakeup_status` CSR during transition to active state - since the reset involved will clear the wakeups_i input. - - Checks the `wake_info` CSR. - - Checks the output `pwr_rst_req.reset_cause` is `LowPwrEntry`. - - Check that `intr_wakeup_o` is set according to `intr_enable` CSR. - - Coverage collected by `wakeup_cg` and `wakeup_intr_cg`. - ''' - stage: V2 - tests: ["pwrmgr_wakeup"] - } - { - name: control_clks - desc: ''' - Test CSR control of peripheral clocks during low power. - - The peripheral clocks can be configured to remain on or be turned - off during low power with bits in the `control` CSR register. The - usb clock can also be configured off in active mode. - - **Stimulus**: - - Sets these control bits at random. - - Cause a low power transition and wakeup. - - **Checks**: - - The clock enable outputs to the AST clocks during a low - power transition match the control bits. - - The usb clock enable is also checked during active mode against - the control register. - ''' - stage: V2 - tests: ["pwrmgr_wakeup"] - } - { - name: aborted_low_power - desc: ''' - Test aborted low power transitions. - - Low power transitions can be aborted in two cases: - - The processor gets an interrupt soon after a low power entry is - triggered. - - OTP, LC, or FLASH are not idle. - This test aborts low power transitions, and disables any wakeups, - so the test would timeout if low power was entered. - - **Stimulus**: - - Bring pwrmgr to low power. - - Either disable `pwr_cpu.core_sleeping` or keep some of `lc_idle`, - `otp_idle`, or `flash_idle` inputs off. - - Disable all wakeup enables. - - Randomly set `wakeup_info_capture_dis` CSR. - - **Checks**: - - The `ctrl_cfg_regwen` CSR reads as 1 on the first attempt. - - Checks the output `pwr_rst_req.reset_cause` doesn't change for - a bounded amount of time. - - Check that the `wakeup_info` CSR flags either `fall_through` or - `abort` events when capture is enabled. - ''' - stage: V2 - tests: ["pwrmgr_aborted_low_power", "pwrmgr_lowpower_invalid"] - } - { - name: reset - desc: ''' - Test random reset and reset_en. - - Conditional reset inputs can be disabled via bits in the `reset_en` - CSR, while escalation and main power are unconditional. Resets can - be triggered either in active or low power state. - - **Stimulus**: - - Sets `reset_en` randomly. - - Randomly choose whether to put the unit in low power mode. - - Generate resets randomly in value and time: - - Conditionals via rstreqs_i, - - Main power glitch via rst_main_ni. - - Escalation via `esc_rst_tx_i`. - - Sw reset from rstmgr via `sw_rst_req_i`. - - **Checks**: - - The fast fsm becomes active when `fetch_en_o` output rises. - - Checks the `reset_status` CSRs. - - Checks `ip_clk_en` output has a low transition. - - SVA that when `pwr_rst_req.reset_cause` is HwReq, and the output - `pwr_rst_req.rstreqs` matches the unconditional and enabled - conditional resets inputs. - ''' - stage: V2 - tests: ["pwrmgr_reset", "pwrmgr_reset_invalid"] - } - { - name: main_power_glitch_reset - desc: ''' - Test reset due to a glitch in main power. - - A power glitch causes an unconditional reset. - - **Stimulus**: - - Set the rst_main_ni input low indicating a main power glitch. - - **Checks**: - - The fast fsm becomes active when `fetch_en_o` output rises. - - Checks the `reset_status` CSRs. - - Checks `ip_clk_en` output has a low transition. - - Checks the output `pwr_rst_req.reset_cause` matches HwReq. - - Checks the output `pwr_rst_req.rstreqs` matches power glitch. - ''' - stage: V2 - tests: ["pwrmgr_reset"] - } - { - name: reset_wakeup_race - desc: ''' - Test wakeup from low power and reset request almost coinciding. - - If a wakeup from low power and a reset occur at nearly the same time - the system handles them one at a time. - - **Stimulus**: - - Trigger reset and wakeup from low power as described for other - testpoints. - - Issue reset and wakeup a random number of cycles after the slow - state machine is in LowPower state. - - This also checks them coinciding. - - **Check**: - - Similar tests as for the wakeup and reset testpoints, except - making sure they happen per the triggering order. - ''' - stage: V2 - tests: ["pwrmgr_wakeup_reset"] - } - { - name: lowpower_wakeup_race - desc: ''' - Test wakeups coming close to lowpower entry. - - If low power entry and a wakeup are closely aligned the hardware - could get confused. Notice this is very unlikely, since wakeup is - only sensed when the slow fsm is in LowPower state. - - **Stimulus**: - - Trigger low power entry as described for other testpoints. - - Have all wakeups enabled. - - Assert wakeups_i in the temporal neighborhood of low power - entry. - - **Check**: - - No timeout occurs. - - Either pwrmgr remains active or a full low power cycle occurs. - ''' - stage: V2 - tests: ["pwrmgr_lowpower_wakeup_race"] - } - { - name: disable_rom_integrity_check - desc: ''' - Test rom integrity check is disabled under life cycle test states. - - While running a series of reset event, at FastPwrStateRomCheck - state, - - Drive lc_hw_debug_en_i and lc_dft_en_i to random value - excluding {lc_ctrl_pkg::On, lc_ctrl_pkg::On} for both ports. - - Set rom_ctrl_i.good = Mubi4False. - - Wait for a while to make sure fsm state check is not FastPwrStateActive. - - Then, - - Drive lc_hw_debug_en_i and lc_dft_en_i to {lc_ctrl_pkg::On, lc_ctrl_pkg::On} - - Check test finish gracefully. - - Try these steps with different lc_ctrl inputs. - ''' - stage: V2 - tests: ["pwrmgr_disable_rom_integrity_check"] - } - { - name: stress_all - desc: '''This runs random sequences in succession. - - Randomly chooses from the following sequences: - - pwrmgr_aborted_low_power_vseq - - pwrmgr_lowpower_wakeup_race_vseq - - pwrmgr_reset_vseq - - pwrmgr_smoke_vseq - - pwrmgr_wakeup_reset_vseq - - pwrmgr_wakeup_vseq - ''' - stage: V2 - tests: ["pwrmgr_stress_all"] - } - ] - - covergroups: [ - { - name: wakeup_ctrl_cg - desc: ''' - Collects coverage on wakeup enable and capture functionality. - - This is collected per individual wakeup bit. Covergroup contains - coverpoints for the `wakeup_en` CSR bit, `wakeup_info_capture_dis` - CSR, `wakeups_i` input bit, and `wakeup_status` CSR bit, and their - cross. - ''' - } - { - name: wakeup_intr_cg - desc: ''' - Collects coverage on interrupts for wakeup functionality. - - This is collected per individual wakeup bit. Covergroup contains - coverpoints for the `intr_en` CSR, the `wakeup_status` CSR bit, - the `intr_status` CSR, the output `intr_wakeup` port, and their - cross. - ''' - } - { - name: control_cg - desc: ''' - Collects coverage on clock and power bits from `control` CSR during - a lowpower transition and active state. - ''' - } - { - name: hw_reset_0_cg - desc: ''' - Collects coverage related to external reset `0`. - - Covergroup contains coverpoints for the `rstreqs_i[0]` external - reset input, its corresponding bit in `reset_en` CSR, and whether - this reset is asserted during low power state, and suitable crosses. - ''' - } - { - name: hw_reset_1_cg - desc: ''' - Collects coverage related to external reset `1`. - - Covergroup contains coverpoints for the `rstreqs_i[1]` external - reset input, its corresponding bit in `reset_en` CSR, and whether - this reset is asserted during low power state, and suitable crosses. - ''' - } - { - name: rstmgr_sw_reset_cg - desc: ''' - Collects coverage on the software reset from rstmgr. - - Covergroup contains a coverpoint for the input `sw_rst_req_i` from - rstmgr. - ''' - } - { - name: main_power_reset_cg - desc: ''' - Collects coverage on resets due to a main power glitch. - - Covergroup contains a coverpoint for the input `rst_main_i` that - triggers a power glitch reset, and whether this reset is asserted - during low power state. - ''' - } - { - name: esc_reset_cg - desc: ''' - Collects coverage on resets due to escalation. - - Covergroup contains a coverpoint for the input `esc_rst_tx_i` that - triggers an escalation reset, and whether this reset is asserted - during low power state. - ''' - } - { - name: reset_wakeup_distance_cg - desc: ''' - Covergroup contains a coverpoint for the difference between the - cycles when the reset and the wakeup were received in the inputs. - The difference is positive when reset happened after wakeup, and - zero when the two happened at the same clock cycle. - ''' - } - ] -} diff --git a/hw/ip/pwrmgr/doc/checklist.md b/hw/ip/pwrmgr/doc/checklist.md deleted file mode 100644 index d62e27011cb3de..00000000000000 --- a/hw/ip/pwrmgr/doc/checklist.md +++ /dev/null @@ -1,266 +0,0 @@ -# PWRMGR Checklist - -This checklist is for [Hardware Stage](../../../../doc/project_governance/development_stages.md) transitions for the [PWRMGR peripheral.](../README.md) -All checklist items refer to the content in the [Checklist.](../../../../doc/project_governance/checklist/README.md) - -## Design Checklist - -### D1 - -Type | Item | Resolution | Note/Collaterals ---------------|--------------------------------|-------------|------------------ -Documentation | [SPEC_COMPLETE][] | Done |[PWRMGR Design Spec](../README.md) -Documentation | [CSR_DEFINED][] | Done | -RTL | [CLKRST_CONNECTED][] | Done | -RTL | [IP_TOP][] | Done | -RTL | [IP_INSTANTIABLE][] | Done | -RTL | [PHYSICAL_MACROS_DEFINED_80][] | N/A | -RTL | [FUNC_IMPLEMENTED][] | Done | -RTL | [ASSERT_KNOWN_ADDED][] | Done | -Code Quality | [LINT_SETUP][] | Done | - -[SPEC_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#spec_complete -[CSR_DEFINED]: ../../../../doc/project_governance/checklist/README.md#csr_defined -[CLKRST_CONNECTED]: ../../../../doc/project_governance/checklist/README.md#clkrst_connected -[IP_TOP]: ../../../../doc/project_governance/checklist/README.md#ip_top -[IP_INSTANTIABLE]: ../../../../doc/project_governance/checklist/README.md#ip_instantiable -[PHYSICAL_MACROS_DEFINED_80]: ../../../../doc/project_governance/checklist/README.md#physical_macros_defined_80 -[FUNC_IMPLEMENTED]: ../../../../doc/project_governance/checklist/README.md#func_implemented -[ASSERT_KNOWN_ADDED]: ../../../../doc/project_governance/checklist/README.md#assert_known_added -[LINT_SETUP]: ../../../../doc/project_governance/checklist/README.md#lint_setup - -### D2 - -Type | Item | Resolution | Note/Collaterals ---------------|---------------------------|-------------|------------------ -Documentation | [NEW_FEATURES][] | Done | -Documentation | [BLOCK_DIAGRAM][] | Done | -Documentation | [DOC_INTERFACE][] | Done | -Documentation | [DOC_INTEGRATION_GUIDE][] | Waived | This checklist item has been added retrospectively. -Documentation | [MISSING_FUNC][] | Done | -Documentation | [FEATURE_FROZEN][] | Done | -RTL | [FEATURE_COMPLETE][] | Done | -RTL | [PORT_FROZEN][] | Done | -RTL | [ARCHITECTURE_FROZEN][] | Done | -RTL | [REVIEW_TODO][] | Done | -RTL | [STYLE_X][] | Done | -RTL | [CDC_SYNCMACRO][] | N/A | -Code Quality | [LINT_PASS][] | Done | -Code Quality | [CDC_SETUP][] | Waived | No block-level flow available - waived to top-level signoff. -Code Quality | [RDC_SETUP][] | Waived | No block-level flow available - waived to top-level signoff. -Code Quality | [AREA_CHECK][] | Done | -Code Quality | [TIMING_CHECK][] | Done | -Security | [SEC_CM_DOCUMENTED][] | Done | - -[NEW_FEATURES]: ../../../../doc/project_governance/checklist/README.md#new_features -[BLOCK_DIAGRAM]: ../../../../doc/project_governance/checklist/README.md#block_diagram -[DOC_INTERFACE]: ../../../../doc/project_governance/checklist/README.md#doc_interface -[DOC_INTEGRATION_GUIDE]: ../../../../doc/project_governance/checklist/README.md#doc_integration_guide -[MISSING_FUNC]: ../../../../doc/project_governance/checklist/README.md#missing_func -[FEATURE_FROZEN]: ../../../../doc/project_governance/checklist/README.md#feature_frozen -[FEATURE_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#feature_complete -[PORT_FROZEN]: ../../../../doc/project_governance/checklist/README.md#port_frozen -[ARCHITECTURE_FROZEN]: ../../../../doc/project_governance/checklist/README.md#architecture_frozen -[REVIEW_TODO]: ../../../../doc/project_governance/checklist/README.md#review_todo -[STYLE_X]: ../../../../doc/project_governance/checklist/README.md#style_x -[CDC_SYNCMACRO]: ../../../../doc/project_governance/checklist/README.md#cdc_syncmacro -[LINT_PASS]: ../../../../doc/project_governance/checklist/README.md#lint_pass -[CDC_SETUP]: ../../../../doc/project_governance/checklist/README.md#cdc_setup -[RDC_SETUP]: ../../../../doc/project_governance/checklist/README.md#rdc_setup -[AREA_CHECK]: ../../../../doc/project_governance/checklist/README.md#area_check -[TIMING_CHECK]: ../../../../doc/project_governance/checklist/README.md#timing_check -[SEC_CM_DOCUMENTED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_documented - -### D2S - - Type | Item | Resolution | Note/Collaterals ---------------|------------------------------|-------------|------------------ -Security | [SEC_CM_ASSETS_LISTED][] | Done | -Security | [SEC_CM_IMPLEMENTED][] | Done | -Security | [SEC_CM_RND_CNST][] | N/A | -Security | [SEC_CM_NON_RESET_FLOPS][] | Done | -Security | [SEC_CM_SHADOW_REGS][] | Done | -Security | [SEC_CM_RTL_REVIEWED][] | Done | -Security | [SEC_CM_COUNCIL_REVIEWED][] | Done | - -[SEC_CM_ASSETS_LISTED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_assets_listed -[SEC_CM_IMPLEMENTED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_implemented -[SEC_CM_RND_CNST]: ../../../../doc/project_governance/checklist/README.md#sec_cm_rnd_cnst -[SEC_CM_NON_RESET_FLOPS]: ../../../../doc/project_governance/checklist/README.md#sec_cm_non_reset_flops -[SEC_CM_SHADOW_REGS]: ../../../../doc/project_governance/checklist/README.md#sec_cm_shadow_regs -[SEC_CM_RTL_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_rtl_reviewed -[SEC_CM_COUNCIL_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_council_reviewed - -### D3 - - Type | Item | Resolution | Note/Collaterals ---------------|-------------------------|-------------|------------------ -Documentation | [NEW_FEATURES_D3][] | Not Started | -RTL | [TODO_COMPLETE][] | Not Started | -Code Quality | [LINT_COMPLETE][] | Not Started | -Code Quality | [CDC_COMPLETE][] | Not Started | -Code Quality | [RDC_COMPLETE][] | Not Started | -Review | [REVIEW_RTL][] | Not Started | -Review | [REVIEW_DELETED_FF][] | Not Started | -Review | [REVIEW_SW_CHANGE][] | Not Started | -Review | [REVIEW_SW_ERRATA][] | Not Started | -Review | Reviewer(s) | Not Started | -Review | Signoff date | Not Started | - -[NEW_FEATURES_D3]: ../../../../doc/project_governance/checklist/README.md#new_features_d3 -[TODO_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#todo_complete -[LINT_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#lint_complete -[CDC_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#cdc_complete -[RDC_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#rdc_complete -[REVIEW_RTL]: ../../../../doc/project_governance/checklist/README.md#review_rtl -[REVIEW_DELETED_FF]: ../../../../doc/project_governance/checklist/README.md#review_deleted_ff -[REVIEW_SW_CHANGE]: ../../../../doc/project_governance/checklist/README.md#review_sw_change -[REVIEW_SW_ERRATA]: ../../../../doc/project_governance/checklist/README.md#review_sw_errata - -## Verification Checklist - -### V1 - - Type | Item | Resolution | Note/Collaterals ---------------|---------------------------------------|-------------|------------------ -Documentation | [DV_DOC_DRAFT_COMPLETED][] | Done | [PWRMGR DV document](../dv/README.md) -Documentation | [TESTPLAN_COMPLETED][] | Done | [PWRMGR testplan](../dv/README.md#testplan) -Testbench | [TB_TOP_CREATED][] | Done | -Testbench | [PRELIMINARY_ASSERTION_CHECKS_ADDED][]| Done | -Testbench | [SIM_TB_ENV_CREATED][] | Done | -Testbench | [SIM_RAL_MODEL_GEN_AUTOMATED][] | Done | -Testbench | [CSR_CHECK_GEN_AUTOMATED][] | Done | -Testbench | [TB_GEN_AUTOMATED][] | Done | -Tests | [SIM_SMOKE_TEST_PASSING][] | Done | -Tests | [SIM_CSR_MEM_TEST_SUITE_PASSING][] | Done | Block has no mem -Tests | [FPV_MAIN_ASSERTIONS_PROVEN][] | N/A | -Tool Setup | [SIM_ALT_TOOL_SETUP][] | Done | Xcelium -Regression | [SIM_SMOKE_REGRESSION_SETUP][] | Done | -Regression | [SIM_NIGHTLY_REGRESSION_SETUP][] | Done | -Regression | [FPV_REGRESSION_SETUP][] | N/A | -Coverage | [SIM_COVERAGE_MODEL_ADDED][] | Done | -Code Quality | [TB_LINT_SETUP][] | Done | -Integration | [PRE_VERIFIED_SUB_MODULES_V1][] | Done | -Review | [DESIGN_SPEC_REVIEWED][] | Done | -Review | [TESTPLAN_REVIEWED][] | Done | -Review | [STD_TEST_CATEGORIES_PLANNED][] | Done | Exceptions: debug, power, performance -Review | [V2_CHECKLIST_SCOPED][] | Done | - -[DV_DOC_DRAFT_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#dv_doc_draft_completed -[TESTPLAN_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#testplan_completed -[TB_TOP_CREATED]: ../../../../doc/project_governance/checklist/README.md#tb_top_created -[PRELIMINARY_ASSERTION_CHECKS_ADDED]: ../../../../doc/project_governance/checklist/README.md#preliminary_assertion_checks_added -[SIM_TB_ENV_CREATED]: ../../../../doc/project_governance/checklist/README.md#sim_tb_env_created -[SIM_RAL_MODEL_GEN_AUTOMATED]: ../../../../doc/project_governance/checklist/README.md#sim_ral_model_gen_automated -[CSR_CHECK_GEN_AUTOMATED]: ../../../../doc/project_governance/checklist/README.md#csr_check_gen_automated -[TB_GEN_AUTOMATED]: ../../../../doc/project_governance/checklist/README.md#tb_gen_automated -[SIM_SMOKE_TEST_PASSING]: ../../../../doc/project_governance/checklist/README.md#sim_smoke_test_passing -[SIM_CSR_MEM_TEST_SUITE_PASSING]: ../../../../doc/project_governance/checklist/README.md#sim_csr_mem_test_suite_passing -[FPV_MAIN_ASSERTIONS_PROVEN]: ../../../../doc/project_governance/checklist/README.md#fpv_main_assertions_proven -[SIM_ALT_TOOL_SETUP]: ../../../../doc/project_governance/checklist/README.md#sim_alt_tool_setup -[SIM_SMOKE_REGRESSION_SETUP]: ../../../../doc/project_governance/checklist/README.md#sim_smoke_regression_setup -[SIM_NIGHTLY_REGRESSION_SETUP]: ../../../../doc/project_governance/checklist/README.md#sim_nightly_regression_setup -[FPV_REGRESSION_SETUP]: ../../../../doc/project_governance/checklist/README.md#fpv_regression_setup -[SIM_COVERAGE_MODEL_ADDED]: ../../../../doc/project_governance/checklist/README.md#sim_coverage_model_added -[TB_LINT_SETUP]: ../../../../doc/project_governance/checklist/README.md#tb_lint_setup -[PRE_VERIFIED_SUB_MODULES_V1]: ../../../../doc/project_governance/checklist/README.md#pre_verified_sub_modules_v1 -[DESIGN_SPEC_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#design_spec_reviewed -[TESTPLAN_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#testplan_reviewed -[STD_TEST_CATEGORIES_PLANNED]: ../../../../doc/project_governance/checklist/README.md#std_test_categories_planned -[V2_CHECKLIST_SCOPED]: ../../../../doc/project_governance/checklist/README.md#v2_checklist_scoped - -### V2 - - Type | Item | Resolution | Note/Collaterals ---------------|-----------------------------------------|-------------|------------------ -Documentation | [DESIGN_DELTAS_CAPTURED_V2][] | Done | -Documentation | [DV_DOC_COMPLETED][] | Done | -Testbench | [FUNCTIONAL_COVERAGE_IMPLEMENTED][] | Done | -Testbench | [ALL_INTERFACES_EXERCISED][] | Done | -Testbench | [ALL_ASSERTION_CHECKS_ADDED][] | Done | -Testbench | [SIM_TB_ENV_COMPLETED][] | Done | -Tests | [SIM_ALL_TESTS_PASSING][] | Done | -Tests | [FPV_ALL_ASSERTIONS_WRITTEN][] | NA | -Tests | [FPV_ALL_ASSUMPTIONS_REVIEWED][] | NA | -Tests | [SIM_FW_SIMULATED][] | Done | -Regression | [SIM_NIGHTLY_REGRESSION_V2][] | Done | -Coverage | [SIM_CODE_COVERAGE_V2][] | Done | -Coverage | [SIM_FUNCTIONAL_COVERAGE_V2][] | Done | -Coverage | [FPV_CODE_COVERAGE_V2][] | NA | -Coverage | [FPV_COI_COVERAGE_V2][] | NA | -Integration | [PRE_VERIFIED_SUB_MODULES_V2][] | Done | -Issues | [NO_HIGH_PRIORITY_ISSUES_PENDING][] | Done | -Issues | [ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED][] | Done | -Review | [DV_DOC_TESTPLAN_REVIEWED][] | Done | -Review | [V3_CHECKLIST_SCOPED][] | Done | - -[DESIGN_DELTAS_CAPTURED_V2]: ../../../../doc/project_governance/checklist/README.md#design_deltas_captured_v2 -[DV_DOC_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#dv_doc_completed -[FUNCTIONAL_COVERAGE_IMPLEMENTED]: ../../../../doc/project_governance/checklist/README.md#functional_coverage_implemented -[ALL_INTERFACES_EXERCISED]: ../../../../doc/project_governance/checklist/README.md#all_interfaces_exercised -[ALL_ASSERTION_CHECKS_ADDED]: ../../../../doc/project_governance/checklist/README.md#all_assertion_checks_added -[SIM_TB_ENV_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#sim_tb_env_completed -[SIM_ALL_TESTS_PASSING]: ../../../../doc/project_governance/checklist/README.md#sim_all_tests_passing -[FPV_ALL_ASSERTIONS_WRITTEN]: ../../../../doc/project_governance/checklist/README.md#fpv_all_assertions_written -[FPV_ALL_ASSUMPTIONS_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#fpv_all_assumptions_reviewed -[SIM_FW_SIMULATED]: ../../../../doc/project_governance/checklist/README.md#sim_fw_simulated -[SIM_NIGHTLY_REGRESSION_V2]: ../../../../doc/project_governance/checklist/README.md#sim_nightly_regression_v2 -[SIM_CODE_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#sim_code_coverage_v2 -[SIM_FUNCTIONAL_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#sim_functional_coverage_v2 -[FPV_CODE_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#fpv_code_coverage_v2 -[FPV_COI_COVERAGE_V2]: ../../../../doc/project_governance/checklist/README.md#fpv_coi_coverage_v2 -[PRE_VERIFIED_SUB_MODULES_V2]: ../../../../doc/project_governance/checklist/README.md#pre_verified_sub_modules_v2 -[NO_HIGH_PRIORITY_ISSUES_PENDING]: ../../../../doc/project_governance/checklist/README.md#no_high_priority_issues_pending -[ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED]:../../../../doc/project_governance/checklist/README.md#all_low_priority_issues_root_caused -[DV_DOC_TESTPLAN_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#dv_doc_testplan_reviewed -[V3_CHECKLIST_SCOPED]: ../../../../doc/project_governance/checklist/README.md#v3_checklist_scoped - -### V2S - - Type | Item | Resolution | Note/Collaterals ---------------|-----------------------------------------|-------------|------------------ -Documentation | [SEC_CM_TESTPLAN_COMPLETED][] | Done | -Tests | [FPV_SEC_CM_VERIFIED][] | Done | -Tests | [SIM_SEC_CM_VERIFIED][] | Done | -Coverage | [SIM_COVERAGE_REVIEWED][] | Done | UNR will be added after intra structure issue is resolved. -Review | [SEC_CM_DV_REVIEWED][] | Done | - -[SEC_CM_TESTPLAN_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_testplan_completed -[FPV_SEC_CM_VERIFIED]: ../../../../doc/project_governance/checklist/README.md#fpv_sec_cm_verified -[SIM_SEC_CM_VERIFIED]: ../../../../doc/project_governance/checklist/README.md#sim_sec_cm_verified -[SIM_COVERAGE_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sim_coverage_reviewed -[SEC_CM_DV_REVIEWED]: ../../../../doc/project_governance/checklist/README.md#sec_cm_dv_reviewed - -### V3 - - Type | Item | Resolution | Note/Collaterals ---------------|-----------------------------------|-------------|------------------ -Documentation | [DESIGN_DELTAS_CAPTURED_V3][] | Not Started | -Tests | [X_PROP_ANALYSIS_COMPLETED][] | Not Started | -Tests | [FPV_ASSERTIONS_PROVEN_AT_V3][] | Not Started | -Regression | [SIM_NIGHTLY_REGRESSION_AT_V3][] | Not Started | -Coverage | [SIM_CODE_COVERAGE_AT_100][] | Not Started | -Coverage | [SIM_FUNCTIONAL_COVERAGE_AT_100][]| Not Started | -Coverage | [FPV_CODE_COVERAGE_AT_100][] | Not Started | -Coverage | [FPV_COI_COVERAGE_AT_100][] | Not Started | -Code Quality | [ALL_TODOS_RESOLVED][] | Not Started | -Code Quality | [NO_TOOL_WARNINGS_THROWN][] | Not Started | -Code Quality | [TB_LINT_COMPLETE][] | Not Started | -Integration | [PRE_VERIFIED_SUB_MODULES_V3][] | Not Started | -Issues | [NO_ISSUES_PENDING][] | Not Started | -Review | Reviewer(s) | Not Started | -Review | Signoff date | Not Started | - -[DESIGN_DELTAS_CAPTURED_V3]: ../../../../doc/project_governance/checklist/README.md#design_deltas_captured_v3 -[X_PROP_ANALYSIS_COMPLETED]: ../../../../doc/project_governance/checklist/README.md#x_prop_analysis_completed -[FPV_ASSERTIONS_PROVEN_AT_V3]: ../../../../doc/project_governance/checklist/README.md#fpv_assertions_proven_at_v3 -[SIM_NIGHTLY_REGRESSION_AT_V3]: ../../../../doc/project_governance/checklist/README.md#sim_nightly_regression_at_v3 -[SIM_CODE_COVERAGE_AT_100]: ../../../../doc/project_governance/checklist/README.md#sim_code_coverage_at_100 -[SIM_FUNCTIONAL_COVERAGE_AT_100]:../../../../doc/project_governance/checklist/README.md#sim_functional_coverage_at_100 -[FPV_CODE_COVERAGE_AT_100]: ../../../../doc/project_governance/checklist/README.md#fpv_code_coverage_at_100 -[FPV_COI_COVERAGE_AT_100]: ../../../../doc/project_governance/checklist/README.md#fpv_coi_coverage_at_100 -[ALL_TODOS_RESOLVED]: ../../../../doc/project_governance/checklist/README.md#all_todos_resolved -[NO_TOOL_WARNINGS_THROWN]: ../../../../doc/project_governance/checklist/README.md#no_tool_warnings_thrown -[TB_LINT_COMPLETE]: ../../../../doc/project_governance/checklist/README.md#tb_lint_complete -[PRE_VERIFIED_SUB_MODULES_V3]: ../../../../doc/project_governance/checklist/README.md#pre_verified_sub_modules_v3 -[NO_ISSUES_PENDING]: ../../../../doc/project_governance/checklist/README.md#no_issues_pending diff --git a/hw/ip/pwrmgr/doc/interfaces.md b/hw/ip/pwrmgr/doc/interfaces.md deleted file mode 100644 index 148b562c62ba9f..00000000000000 --- a/hw/ip/pwrmgr/doc/interfaces.md +++ /dev/null @@ -1,67 +0,0 @@ -# Hardware Interfaces - - -Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`pwrmgr`** has the following hardware interfaces defined -- Primary Clock: **`clk_i`** -- Other Clocks: **`clk_slow_i`**, **`clk_lc_i`**, **`clk_esc_i`** -- Bus Device Interfaces (TL-UL): **`tl`** -- Bus Host Interfaces (TL-UL): *none* -- Peripheral Pins for Chip IO: *none* - -## [Inter-Module Signals](https://opentitan.org/book/doc/contributing/hw/comportability/index.html#inter-signal-handling) - -| Port Name | Package::Struct | Type | Act | Width | Description | -|:---------------|:--------------------------|:--------|:------|--------:|:--------------| -| pwr_ast | pwrmgr_pkg::pwr_ast | req_rsp | req | 1 | | -| pwr_rst | pwrmgr_pkg::pwr_rst | req_rsp | req | 1 | | -| pwr_clk | pwrmgr_pkg::pwr_clk | req_rsp | req | 1 | | -| pwr_otp | pwrmgr_pkg::pwr_otp | req_rsp | req | 1 | | -| pwr_lc | pwrmgr_pkg::pwr_lc | req_rsp | req | 1 | | -| pwr_flash | pwrmgr_pkg::pwr_flash | uni | rcv | 1 | | -| esc_rst_tx | prim_esc_pkg::esc_tx | uni | rcv | 1 | | -| esc_rst_rx | prim_esc_pkg::esc_rx | uni | req | 1 | | -| pwr_cpu | pwrmgr_pkg::pwr_cpu | uni | rcv | 1 | | -| wakeups | logic | uni | rcv | 6 | | -| rstreqs | logic | uni | rcv | 2 | | -| ndmreset_req | logic | uni | rcv | 1 | | -| strap | logic | uni | req | 1 | | -| low_power | logic | uni | req | 1 | | -| rom_ctrl | rom_ctrl_pkg::pwrmgr_data | uni | rcv | 1 | | -| fetch_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | | -| lc_dft_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | -| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | -| sw_rst_req | prim_mubi_pkg::mubi4 | uni | rcv | 1 | | -| tl | tlul_pkg::tl | req_rsp | rsp | 1 | | - -## Interrupts - -| Interrupt Name | Type | Description | -|:-----------------|:-------|:----------------------------------------------------------| -| wakeup | Event | Wake from low power state. See wake info for more details | - -## Security Alerts - -| Alert Name | Description | -|:-------------|:----------------------------------------------------------------------------------| -| fatal_fault | This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. | - -## Security Countermeasures - -| Countermeasure ID | Description | -|:------------------------------|:-------------------------------------------------------------------------------------------------------------------------| -| PWRMGR.BUS.INTEGRITY | End-to-end bus integrity scheme. | -| PWRMGR.LC_CTRL.INTERSIG.MUBI | life cycle control / debug signals are multibit. | -| PWRMGR.ROM_CTRL.INTERSIG.MUBI | rom control done/good signals are multibit. | -| PWRMGR.RSTMGR.INTERSIG.MUBI | reset manager software request is multibit. | -| PWRMGR.ESC_RX.CLK.BKGN_CHK | Escalation receiver has a background timeout check | -| PWRMGR.ESC_RX.CLK.LOCAL_ESC | Escalation receiver clock timeout has a local reset escalation | -| PWRMGR.FSM.SPARSE | Sparse encoding for slow and fast state machines. | -| PWRMGR.FSM.TERMINAL | When FSMs reach a bad state, go into a terminate state that does not recover without user or external host intervention. | -| PWRMGR.CTRL_FLOW.GLOBAL_ESC | When global escalation is received, proceed directly to reset. | -| PWRMGR.MAIN_PD.RST.LOCAL_ESC | When main power domain reset glitches, proceed directly to reset. | -| PWRMGR.CTRL.CONFIG.REGWEN | Main control protected by regwen. | -| PWRMGR.WAKEUP.CONFIG.REGWEN | Wakeup configuration protected by regwen. | -| PWRMGR.RESET.CONFIG.REGWEN | Reset configuration protected by regwen. | - - - diff --git a/hw/ip/pwrmgr/doc/programmers_guide.md b/hw/ip/pwrmgr/doc/programmers_guide.md deleted file mode 100644 index b61e8168d7ae44..00000000000000 --- a/hw/ip/pwrmgr/doc/programmers_guide.md +++ /dev/null @@ -1,63 +0,0 @@ -# Programmer's Guide - -The process in which the power manager is used is highly dependent on the system's topology. -The following proposes one method for how this can be done. - -Assume first the system has the power states described [above](theory_of_operation.md#supported-low-power-modes). - -## Programmer Sequence for Entering Low Power - -1. Disable interrupts -2. Enable desired wakeup and reset sources in [`WAKEUP_EN`](registers.md#wakeup_en) and [`RESET_EN`](registers.md#reset_en). -3. Perform any system-specific low power entry steps, e.g. - - Interrupt checks (if something became pending prior to disable) -4. Configure low power mode in [`CONTROL`](registers.md#control). -5. Set low power hint in [`LOW_POWER_HINT`](registers.md#control--low_power_hint). -6. Set and poll [`CFG_CDC_SYNC`](registers.md#cfg_cdc_sync) to ensure above settings propagate across clock domains. -7. Execute wait-for-interrupt instruction on the processing host. - -### Possible Exits - -Once low power is initiated, the system may exit due to several reasons. -1. Graceful low power exit - This exit occurs when some source in the system gracefully wakes up the power manager. -2. System reset request - This exit occurs when either software or a peripheral requests the pwrmgr to reset the system. -3. [Fall through exit](theory_of_operation.md#fall-through-handling) - This exit occurs when an interrupt manages to break the wait-for-interrupt loop. -4. [Aborted entry](theory_of_operation.md#abort-handling) - This exit occurs when low power entry is attempted with an ongoing non-volatile transaction. - -In both fall through exit and aborted entry, the power manager does not actually enter low power. -Instead the low power entry is interrupted and the system restored to active state. - -## Programmer Sequence for Exiting Low Power - -There are two separate cases for low power exit. -One is exiting from deep sleep, and the other is exiting from normal sleep. - -### Exiting from Deep Sleep - -When exiting from deep sleep, the system begins execution in ROM. - -1. Complete normal preparation steps. -2. Check reset cause in [rstmgr](../../rstmgr/README.md) -3. Re-enable modules that have powered down. -4. Disable wakeup recording through [`WAKE_INFO_CAPTURE_DIS`](registers.md#wake_info_capture_dis). -5. Check which source woke up the system through [`WAKE_INFO`](registers.md#wake_info). -6. Take appropriate steps to handle the wake and resume normal operation. -7. Once wake is handled, clear the wake indication in [`WAKE_INFO`](registers.md#wake_info). - -### Exiting from Normal Sleep - -The handling for fall-through and abort are similar to normal sleep exit. -Since in these scenarios the system was not reset, software continues executing the instruction after the wait-for-interrupt invocation. - -1. Check exit condition to determine appropriate steps. -2. Clear low power hints and configuration in [`CONTROL`](registers.md#control). -3. Set and poll [`CFG_CDC_SYNC`](registers.md#cfg_cdc_sync) to ensure setting changes have propagated across clock boundaries. -4. Disable wakeup sources and stop recording. -5. Re-enable interrupts for normal operation and wakeup handling. -6. Once wake is handled, clear the wake indication in [`WAKE_INFO`](registers.md#wake_info). - -For an in-depth discussion, please see [power management programmers model](https://docs.google.com/document/d/1w86rmvylJgZVmmQ6Q1YBcCp2VFctkQT3zJ408SJMLPE/edit?usp=sharing) for additional details. - -## Device Interface Functions (DIFs) - -- [Device Interface Functions](../../../../sw/device/lib/dif/dif_pwrmgr.h) diff --git a/hw/ip/pwrmgr/doc/pwrmgr_connectivity.svg b/hw/ip/pwrmgr/doc/pwrmgr_connectivity.svg deleted file mode 100644 index b525330ca14082..00000000000000 --- a/hw/ip/pwrmgr/doc/pwrmgr_connectivity.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/pwrmgr/doc/pwrmgr_fsms.svg b/hw/ip/pwrmgr/doc/pwrmgr_fsms.svg deleted file mode 100644 index 962794cd0ab79c..00000000000000 --- a/hw/ip/pwrmgr/doc/pwrmgr_fsms.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/pwrmgr/doc/registers.md b/hw/ip/pwrmgr/doc/registers.md deleted file mode 100644 index e933e5bc9fd363..00000000000000 --- a/hw/ip/pwrmgr/doc/registers.md +++ /dev/null @@ -1,435 +0,0 @@ -# Registers - - -## Summary - -| Name | Offset | Length | Description | -|:---------------------------------------------------------|:---------|---------:|:--------------------------------------------------------------------------------| -| pwrmgr.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | -| pwrmgr.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | -| pwrmgr.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | -| pwrmgr.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | -| pwrmgr.[`CTRL_CFG_REGWEN`](#ctrl_cfg_regwen) | 0x10 | 4 | Controls the configurability of the !!CONTROL register. | -| pwrmgr.[`CONTROL`](#control) | 0x14 | 4 | Control register | -| pwrmgr.[`CFG_CDC_SYNC`](#cfg_cdc_sync) | 0x18 | 4 | The configuration registers CONTROL, WAKEUP_EN, RESET_EN are all written in the | -| pwrmgr.[`WAKEUP_EN_REGWEN`](#wakeup_en_regwen) | 0x1c | 4 | Configuration enable for wakeup_en register | -| pwrmgr.[`WAKEUP_EN`](#WAKEUP_EN) | 0x20 | 4 | Bit mask for enabled wakeups | -| pwrmgr.[`WAKE_STATUS`](#WAKE_STATUS) | 0x24 | 4 | A read only register of all current wake requests post enable mask | -| pwrmgr.[`RESET_EN_REGWEN`](#reset_en_regwen) | 0x28 | 4 | Configuration enable for reset_en register | -| pwrmgr.[`RESET_EN`](#RESET_EN) | 0x2c | 4 | Bit mask for enabled reset requests | -| pwrmgr.[`RESET_STATUS`](#RESET_STATUS) | 0x30 | 4 | A read only register of all current reset requests post enable mask | -| pwrmgr.[`ESCALATE_RESET_STATUS`](#escalate_reset_status) | 0x34 | 4 | A read only register of escalation reset request | -| pwrmgr.[`WAKE_INFO_CAPTURE_DIS`](#wake_info_capture_dis) | 0x38 | 4 | Indicates which functions caused the chip to wakeup | -| pwrmgr.[`WAKE_INFO`](#wake_info) | 0x3c | 4 | Indicates which functions caused the chip to wakeup. | -| pwrmgr.[`FAULT_STATUS`](#fault_status) | 0x40 | 4 | A read only register that shows the existing faults | - -## INTR_STATE -Interrupt State Register -- Offset: `0x0` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "wakeup", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:----------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw1c | 0x0 | wakeup | Wake from low power state. See wake info for more details | - -## INTR_ENABLE -Interrupt Enable Register -- Offset: `0x4` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "wakeup", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-----------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw | 0x0 | wakeup | Enable interrupt when [`INTR_STATE.wakeup`](#intr_state) is set. | - -## INTR_TEST -Interrupt Test Register -- Offset: `0x8` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "wakeup", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:----------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | wo | 0x0 | wakeup | Write 1 to force [`INTR_STATE.wakeup`](#intr_state) to 1. | - -## ALERT_TEST -Alert Test Register -- Offset: `0xc` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "fatal_fault", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:------------|:-------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | wo | 0x0 | fatal_fault | Write 1 to trigger one alert event of this kind. | - -## CTRL_CFG_REGWEN -Controls the configurability of the [`CONTROL`](#control) register. - -This register ensures the contents do not change once a low power hint and -WFI has occurred. - -It unlocks whenever a low power transition has completed (transition back to the -ACTIVE state) for any reason. -- Offset: `0x10` -- Reset default: `0x1` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "EN", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | ro | 0x1 | EN | Configuration enable. This bit defaults to 1 and is set to 0 by hardware when low power entry is initiated. When the device transitions back from low power state to active state, this bit is set back to 1 to allow software configuration of [`CONTROL`](#control) | - -## CONTROL -Control register -- Offset: `0x14` -- Reset default: `0x180` -- Reset mask: `0x1f1` -- Register enable: [`CTRL_CFG_REGWEN`](#ctrl_cfg_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "LOW_POWER_HINT", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 3}, {"name": "CORE_CLK_EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "IO_CLK_EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "USB_CLK_EN_LP", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "USB_CLK_EN_ACTIVE", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "MAIN_PD_N", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 190}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:-------------------------------------------------| -| 31:9 | | | Reserved | -| 8 | rw | 0x1 | [MAIN_PD_N](#control--main_pd_n) | -| 7 | rw | 0x1 | [USB_CLK_EN_ACTIVE](#control--usb_clk_en_active) | -| 6 | rw | 0x0 | [USB_CLK_EN_LP](#control--usb_clk_en_lp) | -| 5 | rw | 0x0 | [IO_CLK_EN](#control--io_clk_en) | -| 4 | rw | 0x0 | [CORE_CLK_EN](#control--core_clk_en) | -| 3:1 | | | Reserved | -| 0 | rw | 0x0 | [LOW_POWER_HINT](#control--low_power_hint) | - -### CONTROL . MAIN_PD_N -Active low, main power domain power down - -| Value | Name | Description | -|:--------|:-----------|:----------------------------------------------------------| -| 0x0 | Power down | Main power domain is powered down during low power state. | -| 0x1 | Power up | Main power domain is kept powered during low power state | - - -### CONTROL . USB_CLK_EN_ACTIVE -USB clock enable during active power state - -| Value | Name | Description | -|:--------|:---------|:---------------------------------------------| -| 0x0 | Disabled | USB clock disabled during active power state | -| 0x1 | Enabled | USB clock enabled during active power state | - - -### CONTROL . USB_CLK_EN_LP -USB clock enable during low power state - -| Value | Name | Description | -|:--------|:---------|:-------------------------------------------------------------------------------------------------------------------------------| -| 0x0 | Disabled | USB clock disabled during low power state | -| 0x1 | Enabled | USB clock enabled during low power state. However, if !!CONTROL.MAIN_PD_N is 0, USB clock is disabled during low power state. | - - -### CONTROL . IO_CLK_EN -IO clock enable during low power state - -| Value | Name | Description | -|:--------|:---------|:-----------------------------------------| -| 0x0 | Disabled | IO clock disabled during low power state | -| 0x1 | Enabled | IO clock enabled during low power state | - - -### CONTROL . CORE_CLK_EN -core clock enable during low power state - -| Value | Name | Description | -|:--------|:---------|:-------------------------------------------| -| 0x0 | Disabled | Core clock disabled during low power state | -| 0x1 | Enabled | Core clock enabled during low power state | - - -### CONTROL . LOW_POWER_HINT -The low power hint to power manager. -The hint is an indication for how the manager should treat the next WFI. -Once the power manager begins a low power transition, or if a valid reset request is registered, -this bit is automatically cleared by HW. - -| Value | Name | Description | -|:--------|:----------|:----------------------------------------| -| 0x0 | None | No low power intent | -| 0x1 | Low Power | Next WFI should trigger low power entry | - - -## CFG_CDC_SYNC -The configuration registers CONTROL, WAKEUP_EN, RESET_EN are all written in the -fast clock domain but used in the slow clock domain. - -The configuration are not propagated across the clock boundary until this -register is triggered and read. See fields below for more details -- Offset: `0x18` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "SYNC", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:----------------------------| -| 31:1 | | | Reserved | -| 0 | rw | 0x0 | [SYNC](#cfg_cdc_sync--sync) | - -### CFG_CDC_SYNC . SYNC -Configuration sync. When this bit is written to 1, a sync pulse is generated. When -the sync completes, this bit then self clears. - -Software should write this bit to 1, wait for it to clear, before assuming the slow clock -domain has accepted the programmed values. - -## WAKEUP_EN_REGWEN -Configuration enable for wakeup_en register -- Offset: `0x1c` -- Reset default: `0x1` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "EN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-----------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | EN | When 1, WAKEUP_EN register can be configured. When 0, WAKEUP_EN register cannot be configured. | - -## WAKEUP_EN -Bit mask for enabled wakeups -- Offset: `0x20` -- Reset default: `0x0` -- Reset mask: `0x3f` -- Register enable: [`WAKEUP_EN_REGWEN`](#wakeup_en_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "EN_0", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "EN_1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "EN_2", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "EN_3", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "EN_4", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "EN_5", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:6 | | | | Reserved | -| 5 | rw | 0x0 | EN_5 | Whenever a particular bit is set to 1, that wakeup is also enabled. Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. | -| 4 | rw | 0x0 | EN_4 | Whenever a particular bit is set to 1, that wakeup is also enabled. Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. | -| 3 | rw | 0x0 | EN_3 | Whenever a particular bit is set to 1, that wakeup is also enabled. Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. | -| 2 | rw | 0x0 | EN_2 | Whenever a particular bit is set to 1, that wakeup is also enabled. Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. | -| 1 | rw | 0x0 | EN_1 | Whenever a particular bit is set to 1, that wakeup is also enabled. Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. | -| 0 | rw | 0x0 | EN_0 | Whenever a particular bit is set to 1, that wakeup is also enabled. Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. | - -## WAKE_STATUS -A read only register of all current wake requests post enable mask -- Offset: `0x24` -- Reset default: `0x0` -- Reset mask: `0x3f` - -### Fields - -```wavejson -{"reg": [{"name": "VAL_0", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "VAL_1", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "VAL_2", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "VAL_3", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "VAL_4", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "VAL_5", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-------------------------------| -| 31:6 | | | | Reserved | -| 5 | ro | 0x0 | VAL_5 | Current value of wake requests | -| 4 | ro | 0x0 | VAL_4 | Current value of wake requests | -| 3 | ro | 0x0 | VAL_3 | Current value of wake requests | -| 2 | ro | 0x0 | VAL_2 | Current value of wake requests | -| 1 | ro | 0x0 | VAL_1 | Current value of wake requests | -| 0 | ro | 0x0 | VAL_0 | Current value of wake requests | - -## RESET_EN_REGWEN -Configuration enable for reset_en register -- Offset: `0x28` -- Reset default: `0x1` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "EN", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:---------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw0c | 0x1 | EN | When 1, RESET_EN register can be configured. When 0, RESET_EN register cannot be configured. | - -## RESET_EN -Bit mask for enabled reset requests -- Offset: `0x2c` -- Reset default: `0x0` -- Reset mask: `0x3` -- Register enable: [`RESET_EN_REGWEN`](#reset_en_regwen) - -### Fields - -```wavejson -{"reg": [{"name": "EN_0", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "EN_1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:---------------------------------------------------------------------------------------------------------------------------------------------------------| -| 31:2 | | | | Reserved | -| 1 | rw | 0x0 | EN_1 | Whenever a particular bit is set to 1, that reset request is enabled. Whenever a particular bit is set to 0, that reset request cannot reset the device. | -| 0 | rw | 0x0 | EN_0 | Whenever a particular bit is set to 1, that reset request is enabled. Whenever a particular bit is set to 0, that reset request cannot reset the device. | - -## RESET_STATUS -A read only register of all current reset requests post enable mask -- Offset: `0x30` -- Reset default: `0x0` -- Reset mask: `0x3` - -### Fields - -```wavejson -{"reg": [{"name": "VAL_0", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "VAL_1", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:-------------------------------| -| 31:2 | | | | Reserved | -| 1 | ro | 0x0 | VAL_1 | Current value of reset request | -| 0 | ro | 0x0 | VAL_0 | Current value of reset request | - -## ESCALATE_RESET_STATUS -A read only register of escalation reset request -- Offset: `0x34` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "VAL", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:---------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | ro | 0x0 | VAL | When 1, an escalation reset has been seen. When 0, there is no escalation reset. | - -## WAKE_INFO_CAPTURE_DIS -Indicates which functions caused the chip to wakeup -- Offset: `0x38` -- Reset default: `0x0` -- Reset mask: `0x1` - -### Fields - -```wavejson -{"reg": [{"name": "VAL", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:-------|:----------------------------------------------------------------------------------------------------------------------------------------| -| 31:1 | | | | Reserved | -| 0 | rw | 0x0 | VAL | When written to 1, this actively suppresses the wakeup info capture. When written to 0, wakeup info capture timing is controlled by HW. | - -## WAKE_INFO -Indicates which functions caused the chip to wakeup. -The wake info recording begins whenever the device begins a valid low power entry. - -This capture is continued until it is explicitly disabled through WAKE_INFO_CAPTURE_DIS. -This means it is possible to capture multiple wakeup reasons. -- Offset: `0x3c` -- Reset default: `0x0` -- Reset mask: `0xff` - -### Fields - -```wavejson -{"reg": [{"name": "REASONS", "bits": 6, "attr": ["rw1c"], "rotate": 0}, {"name": "FALL_THROUGH", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "ABORT", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 140}} -``` - -| Bits | Type | Reset | Name | -|:------:|:------:|:-------:|:-----------------------------------------| -| 31:8 | | | Reserved | -| 7 | rw1c | 0x0 | [ABORT](#wake_info--abort) | -| 6 | rw1c | 0x0 | [FALL_THROUGH](#wake_info--fall_through) | -| 5:0 | rw1c | 0x0 | [REASONS](#wake_info--reasons) | - -### WAKE_INFO . ABORT -The abort wakeup reason indicates that despite setting a WFI and providing a low power -hint, an active flash / lifecycle / otp transaction was ongoing when the power controller -attempted to initiate low power entry. - -The power manager detects this condition, halts low power entry and reports as a wakeup reason - -### WAKE_INFO . FALL_THROUGH -The fall through wakeup reason indicates that despite setting a WFI and providing a low power -hint, an interrupt arrived at just the right time to break the executing core out of WFI. - -The power manager detects this condition, halts low power entry and reports as a wakeup reason - -### WAKE_INFO . REASONS -Various peripheral wake reasons - -## FAULT_STATUS -A read only register that shows the existing faults -- Offset: `0x40` -- Reset default: `0x0` -- Reset mask: `0x7` - -### Fields - -```wavejson -{"reg": [{"name": "REG_INTG_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ESC_TIMEOUT", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "MAIN_PD_GLITCH", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 160}} -``` - -| Bits | Type | Reset | Name | Description | -|:------:|:------:|:-------:|:---------------|:----------------------------------------------------------| -| 31:3 | | | | Reserved | -| 2 | ro | 0x0 | MAIN_PD_GLITCH | When 1, unexpected power glitch was observed on main PD. | -| 1 | ro | 0x0 | ESC_TIMEOUT | When 1, an escalation clock / reset timeout has occurred. | -| 0 | ro | 0x0 | REG_INTG_ERR | When 1, an integrity error has occurred. | - - - diff --git a/hw/ip/pwrmgr/doc/theory_of_operation.md b/hw/ip/pwrmgr/doc/theory_of_operation.md deleted file mode 100644 index ec83f8daff3c3c..00000000000000 --- a/hw/ip/pwrmgr/doc/theory_of_operation.md +++ /dev/null @@ -1,302 +0,0 @@ -# Theory of Operation - -The power manager performs the following functions: -- Turn on/off power domain(s). -- Control root resets with the reset manager. -- Control root clock enables with AST and clock manager. -- Sequence various power up activities such as OTP sensing, life cycle initiation and releasing software to execute. - - -## Block Diagram - -See the below high level block diagram that illustrates the connections between the power manager and various system components. -Blocks outlined with a solid magenta line are always on; while blocks outlined with a dashed magenta line are a mix of components that are and those that are not. - -![Power Manager Connectivity Diagram](../doc/pwrmgr_connectivity.svg) - -## Overall Sequencing - -The power manager contains two state machines. -One operates on the always-on slow clock (this clock is always running and usually measured in KHz) and is responsible for turning faster clocks on and off and managing the power domains. -The other operates on a normal fixed clock (usually measured in MHz) and is responsible for everything else in the power sequence. - -The following diagram breaks down the general functionality of both. -The state machines are colored based on their clock domains. -The green state machine is clocked by the normal fixed domain, while the orange state machine is clocked by the slow domain. -Specific request / acknowledge signals are also highlighted in this color scheme to show where the two state machines communicate. - -![Power Manager FSMs](../doc/pwrmgr_fsms.svg) - - -Note, most of the states are transitional states, and only the following state combinations are resting states. - - -* Slow FSM `Idle` and fast FSM `Active` -* Slow FSM `Low Power` and fast FSM `Low Power` - -The slow FSM `Low Power` and fast FSM `Active` states specifically are concepts useful when examining [reset handling](#reset-request-handling). - - -## Slow Clock Domain FSM - -The slow clock domain FSM (referred to as the slow FSM from here on) resets to the Reset state. -This state is released by `por_rst_n`, which is supplied from the reset controller. -The `por_rst_n` signal is released when the reset controller detects the root power domains (`vcaon_pok` from AST) of the system are ready. -Please see the [ast](../../../top_earlgrey/ip/ast/README.md) for more details. - -The slow FSM requests the AST to power up the main domain and high speed clocks. -Once those steps are done, it requests the [fast FSM](#fast-clock-domain-fsm) to begin operation. -The slow FSM also handles power isolation controls as part of this process. - -Once the fast FSM acknowledges the power-up completion, the slow FSM transitions to `Idle` and waits for a power down request. -When a power down request is received, the slow FSM turns off AST clocks and power as directed by software configuration. -This means the clocks and power are not always turned off, but are rather controlled by software configurations in [`CONTROL`](registers.md#control) prior to low power entry . -Once these steps are complete, the slow FSM transitions to a low power state and awaits a wake request, which can come either as an actual wakeup, or a reset event (for example always on watchdog expiration). - -#### Sparse FSM - -Since the slow FSM is sparsely encoded, it is possible for the FSM to end up in an undefined state if attacked. -When this occurs, the slow FSM sends an `invalid` indication to the fast FSM and forcibly powers off and clamps everything. - -The clocks are kept on however to allow the fast FSM to operate if it is able to receive the `invalid` indication. -The slow FSM does not recover from this state until the system is reset by POR. - -Unlike [escalation resets](#escalation-reset-request), the system does not self reset. -Instead the system goes into a terminal non-responsive state where a user or host must directly intervene by toggling the power or asserting an external reset input. - -## Fast Clock Domain FSM - -The fast clock domain FSM (referred to as fast FSM from here on) resets to `Low Power` state and waits for a power-up request from the slow FSM. - -Once received, the fast FSM releases the life cycle reset stage (see [reset controller](../../rstmgr/README.md) for more details). -This allows the [OTP](../../otp_ctrl/README.md) to begin sensing. -Once OTP sensing completes, the life cycle controller is initialized. -The initialization of the life cycle controller puts the device into its allowed operating state (see [life cycle controller](../../lc_ctrl/README.md) for more details). - -Once life cycle initialization is done, the fast FSM enables all second level clock gating (see [clock controller](../../clkmgr/README.md) for more details) and initiates strap sampling. -For more details on what exactly the strap samples, please see [here](https://docs.google.com/spreadsheets/d/1pH8T1MhQ7TXtP_bFNT85T9jSVIHlxHAfbMnPbsMdjc0/edit?usp=sharing). - -Once strap sampling is complete, the system is ready to begin normal operations (note `flash_ctrl` initialization is explicitly not done here, please see [sections below](#flash-handling) for more details). -The fast FSM acknowledges the slow FSM (which made the original power up request) and releases the system reset stage - this enables the processor to begin operation. -Afterwards, the fast FSM transitions to `Active` state and waits for a software low power entry request. - -A low power request is initiated by software through a combination of WFI and software low power hint in [`CONTROL`](registers.md#control). -Specifically, this means if software issues only WFI, the power manager does not treat it as a power down request. -The notion of WFI is exported from the processor. -For Ibex, this is currently in the form of `core_sleeping_o`. - -In response to the low power entry request, the fast FSM disables all second level clock gating. -Before proceeding, the fast FSM explicitly separates the handling between a normal low power entry and a [reset request](#reset-request-handling). - -For low power entry, there are two cases, [fall through handling](#fall-through-handling) and [abort handling](#abort-handling). -If none of these exception cases are matched for low power entry, the fast FSM then asserts appropriate resets as necessary and requests the slow FSM to take over. - -For reset requests, fall through and aborts are not checked and the system simply resets directly. -Note in this scenario the slow FSM is not requested to take over. - -#### Sparse FSM - -Since the fast FSM is sparsely encoded, it is possible for the FSM to end up in an undefined state if attacked. -When this occurs, the fast FSM forcibly disables all clocks and holds the system in reset. - -The fast FSM does not recover from this state until the system is reset by POR. - - -### ROM Integrity Checks - -The power manager coordinates the [start up ROM check](../../rom_ctrl/README.md#the-startup-rom-check) with `rom_ctrl`. - -After every reset, the power manager sends an indication to the `rom_ctrl` to begin performing integrity checks. -When the `rom_ctrl` checks are finished, a `done` and `good` indication are sent back to the power manager. - -If the device is in life cycle test states (`TEST_UNLOCKED` or `RMA`), the `good` signal is ignored and the ROM contents are always allowed to execute. - -If the device is not in one of the test states, the `good` signal is used to determine ROM execution. -If `good` is true, ROM execution is allowed. -If `good` is false, ROM execution is disallowed. - -### Fall Through Handling - -A low power entry fall through occurs when some condition occurs that immediately de-assert the entry conditions right after the software requests it. - -This can happen if right after software asserts WFI, an interrupt is shown to the processor, thus breaking it out of its currently stopped state. -Whether this type of fall through happens is highly dependent on how the system handles interrupts during low power entry - some systems may choose to completely silence any interrupt not related to wakeup, others may choose to leave them all enabled. -The fall through handle is specifically catered to the latter category. - -For a normal low power entry, the fast FSM first checks that the low power entry conditions are still true. -If the entry conditions are no longer true, the fast FSM "falls through" the entry handling and returns the system to active state, thus terminating the entry process. - -### Abort Handling - -If the entry conditions are still true, the fast FSM then checks there are no ongoing non-volatile activities from `otp_ctrl`, `lc_ctrl` and `flash_ctrl`. -If any module is active, the fast FSM "aborts" entry handling and returns the system to active state, thus terminating the entry process. - -## Reset Request Handling - -There are 4 reset requests in the system -- peripheral requested reset such as watchdog. -- reset manager's software requested reset, which is functionally very similar to a peripheral requested reset. -- power manager's internal reset request. -- Non-debug module reset. - -Flash brownout is handled separately and described in [flash handling section](#flash-handling) below. - -Note that the non-debug module reset is handled similarly to a peripheral requested reset, except that the non-debug module reset won't affect the debug module state and associated TAP muxing logic inside the pinmux. - -The power controller only observes reset requests in two states - the slow FSM `Low Power` state and the fast FSM `Active` state. -When a reset request is received during slow FSM `Low Power` state, the system begins its usual power up sequence even if a wakeup has not been received. - -When a reset request is received during fast FSM `Active` state, the fast FSM asserts resets and transitions back to its `Low Power` state. -The normal power-up process described [above](#fast-clock-domain-fsm) is then followed to release the resets. -Note in this case, the slow FSM is "not activated" and remains in its `Idle` state. - -### Power Manager Internal Reset Requests - -In additional to external requests, the power manager maintains 2 internal reset requests: -* Escalation reset request -* Main power domain unstable reset request - -#### Escalation Reset Request - -Alert escalation resets in general behave similarly to peripheral requested resets. -However, peripheral resets are always handled gracefully and follow the normal FSM transition. - -Alert escalations can happen at any time and do not always obey normal rules. -As a result, upon alert escalation, the power manager makes a best case effort to transition directly into reset handling. - -This may not always be possible if the escalation happens while the FSM is in an invalid state. -In this scenario, the pwrmgr keeps everything powered off and silenced and requests escalation handling if the system ever wakes up. - -#### Escalation Clock Timeout - -Under normal behavior, the power manager can receive escalation requests from the system and handle them [appropriately](#escalation-reset-request). -However, if the escalation clock or reset are non-functional for any reason, the escalation request would not be serviced. - -To mitigate this, the power manager actively checks for escalation interface clock/reset timeout. -This is done by a continuous request / acknowledge interface between the power manager's local clock/reset and the escalate network's clock/reset. - -If the request / acknowledge interface does not respond within 128 power manager clock cycles, the escalate domain is assumed to be off. -When this happens, the power manager creates a local escalation request that behaves identically to the global escalation request. - - -#### Main Power Unstable Reset Requests -If the main power ever becomes unstable (the power okay indication is low even though it is powered on), the power manager requests an internal reset. -This reset behaves similarly to the escalation reset and transitions directly into reset handling. - -Note that under normal low power conditions, the main power may be turned off. -As a result of this, the main power unstable checks are valid only during states that power should be on and stable. -This includes any state where power manager has requested the power to be turned on. - - -### Reset Requests Received During Other States - -All other states in the slow / fast FSM are considered transitional states. -Resets are not observed in other states because the system will always be transitioning towards one of the steady states (the system is in the process of powering down or powering up). -Once a steady state is reached, reset requests are then observed and processed. - -### Reset Recording - -There are two ways in which the device is reset: -- The reset requests mentioned in [reset handling](#reset-request-handling) -- Low power entry (`sleep_req` in the state diagram) - -The power manager handles only one of these at a time (see state diagrams). -This means if reset request and low power entry collide, the power manager will handle them on a first come first served basis. -When the handling of the first is completed, the power manager handles the second pending request if it is still present. - -This is done because low power resets and peripheral requested resets lead to different behaviors. -When the power manager commits to handling a specific request, it informs the reset manager why it has reset the processor. - -For example, assume a low power entry request arrives slightly ahead of reset requests. -The power manager will: -- Transition the system into low power state. -- Inform the reset manager to record "low power exit" as the reset reason. -- Once in low state, transition the system to `Active` state by using the reset request as a wakeup indicator. -- Inform the reset manager to also record the peripheral that requested reset. -- Once in `Active` state, reset the system and begin normal power-up routines again. - -If reset requests arrive slightly ahead of a low power entry request, then power manager will: -- Reset the system and begin normal power-up routines. -- Inform the reset manager to record the peripheral that requested reset. -- Once in `Active` state, if the low power entry request is still present, transition to low power state. - - Inform the reset manager to also record "low power exit" as the reset reason. -- If the low power entry request was wiped out by reset, the system then stays in `Active` state and awaits software instructions. - -Ultimately when control is returned to software, it may see two reset reasons and must handle them accordingly. - - -## Wakeup Recording - -Similar to [reset handling](#reset-request-handling), wakeup signals are only observed during slow FSM `Low Power`; however their recording is continuous until explicitly disabled by software. - -Wakeup recording begins when the fast FSM transitions out of `Active` state and continues until explicitly disabled by software. -This ensures wakeup events are not missed until software has set up the appropriate peripherals. - -The software is also able to enable recording during `Active` state if it chooses to do so. The recording enables are OR’d together for hardware purposes. - - -## Flash Handling -For the section below, flash macro refers to the proprietary flash storage supplied by a vendor. -`flash_ctrl`, on the other hand, refers to the open source controller that manages access to the flash macro. - -### Power-Up Handling - -The [AST](../../../top_earlgrey/ip/ast/README.md) automatically takes the flash macro out of power down state as part of the power manager's power up request. - -Once flash macro is powered up and ready, an indication is sent to the `flash_ctrl`. - -Once the boot ROM is allowed to execute, it is expected to further initialize the `flash_ctrl` and flash macro prior to using it. -This involves the following steps: - -* Poll `flash_ctrl` register to ensure flash macro has powered up and completed internal initialization. -* Initialize `flash_ctrl` seed reading and scrambling. - -### Power-Down Handling - -Before the device enters low power, the pwrmgr first checks to ensure there are no ongoing transactions to the flash macro. -When the device enters deep sleep, the flash macro is automatically put into power down mode by the AST. -The AST places the flash macro into power down through direct signaling between AST and flash macro, the pwrmgr is not directly involved. - -When the device exits low power state, it is the responsibility of the boot ROM to poll for flash macro and `flash_ctrl` power-up complete similar to the above section. - -### Flash Brownout Handling - -When the external supply of the device dips below a certain threshold during a non-volatile flash macro operation (program or erase), the flash macro requires the operation to terminate in a pre-defined manner. -This sequence will be exclusively handled by the AST. - -The power manager is unaware of the difference between POR and flash brownout. -Because of this, the software also cannot distinguish between these two reset causes. - - -## Supported Low Power Modes - -This section details the various low power modes supported by OpenTitan. - - -### Deep Sleep or Standby - -This is the lowest power mode of the device (outside of full power down or device held in reset). -During this state: - -* All clocks other than the always-on slow clock are turned off at the source. -* All non-always-on digital domains are powered off. -* I/O power domains may or may not be off. - * The state of the IO power domain has no impact on the digital core’s power budget, e.g. the IO power being off does not cause the accompanying digital logic in pads or elsewhere to leak more. - - -### Normal Sleep - -This is a fast low power mode of the device that trades-off power consumption for resume latency. -During this state: - -* All clocks other than the KHz slow clock are turned off at the source. -* All power domains are kept on for fast resume. -* Sensor countermeasures can be opportunistically on. -* I/O power domains may or may not be off. - * The state of the IO power domain has no impact on the digital core’s power budget, e.g. the IO power being off does not cause the accompanying digital logic in pads or elsewhere to leak more. - -## Debug - -When performing TAP debug, it is important for the debugging software to prevent the system from going to low power. -If the system enters low power during live debug, the debug session will be broken. -There is currently no standardized way to do this, so it is up to the debugging agent to perform the correct steps. diff --git a/hw/ip/pwrmgr/dv/README.md b/hw/ip/pwrmgr/dv/README.md deleted file mode 100644 index 04490f51655023..00000000000000 --- a/hw/ip/pwrmgr/dv/README.md +++ /dev/null @@ -1,256 +0,0 @@ -# PWRMGR DV document - -## Goals -* **DV** - * Verify all PWRMGR IP features by running dynamic simulations with a SV/UVM based testbench. - * Develop and run all tests based on the [testplan](#testplan) below towards closing code and functional coverage on the IP and all of its sub-modules. -* **FPV** - * Verify TileLink device protocol compliance with an SVA based testbench. - -## Current status -* [Design & verification stage](../doc/checklist.md) - * [HW development stages](../../../../doc/project_governance/development_stages.md) -* [Simulation results](https://reports.opentitan.org/hw/ip/pwrmgr/dv/latest/report.html) - -## Design features -For detailed information on PWRMGR design features, please see the [PWRMGR HWIP technical specification](../README.md). - -## Testbench architecture -PWRMGR testbench has been constructed based on the [CIP testbench architecture](../../../dv/sv/cip_lib/README.md). - -### Block diagram -![Block diagram](./doc/tb.svg) - -### Top level testbench -Top level testbench is located at [`hw/ip/pwrmgr/dv/tb.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/dv/tb.sv). -It instantiates the PWRMGR DUT module [`hw/ip/pwrmgr/rtl/pwrmgr.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/rtl/pwrmgr.sv). -In addition, it instantiates the following interfaces, connects them to the DUT and sets their handle into `uvm_config_db`: -* [Clock and reset interface](../../../dv/sv/common_ifs/README.md) -* [TileLink host interface](../../../dv/sv/tl_agent/README.md) -* PWRMGR interface [`hw/ip/pwrmgr/dv/env/pwrmgr_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/dv/env/pwrmgr_if.sv). -* Interrupts ([`pins_if`](../../../dv/sv/common_ifs/README.md)) -* Alerts ([`alert_esc_if`](../../../dv/sv/alert_esc_agent/README.md)) -* Devmode ([`pins_if`](../../../dv/sv/common_ifs/README.md)) - -### Common DV utility components -The following utilities provide generic helper tasks and functions to perform activities that are common across the project: -* [dv_utils_pkg](../../../dv/sv/dv_utils/README.md) -* [csr_utils_pkg](../../../dv/sv/csr_utils/README.md) - -### Global types & methods -All common types and methods defined at the package level can be found in -[`pwrmgr_env_pkg`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv). -Some of them in use are: -```systemverilog - typedef enum int { - WakeupSysrst, - WakeupDbgCable, - WakeupPin, - WakeupUsb, - WakeupAonTimer, - WakeupSensorCtrl - } wakeup_e; - - typedef struct packed { - logic main_pd_n; - logic usb_clk_en_active; - logic usb_clk_en_lp; - logic io_clk_en; - logic core_clk_en; - } control_enables_t; - - typedef bit [pwrmgr_reg_pkg::NumWkups-1:0] wakeups_t; - typedef bit [pwrmgr_reg_pkg::NumRstReqs-1:0] resets_t; - - // This is used to send all resets to rstmgr. - typedef bit [pwrmgr_pkg::HwResetWidth-1:0] resets_out_t; -``` -### TL_agent -PWRMGR testbench instantiates (already handled in CIP base env) [tl_agent](../../../dv/sv/tl_agent/README.md) which provides the ability to drive and independently monitor random traffic via TL host interface into PWRMGR device. - -### UVM RAL Model -The PWRMGR RAL model is created with the [`ralgen`](../../../dv/tools/ralgen/README.md) FuseSoC generator script automatically when the simulation is at the build stage. - -It can be created manually by invoking [`regtool`](../../../../util/reggen/doc/setup_and_use.md). - -### Stimulus strategy -The sequences are closely related to the testplan's testpoints. -Testpoints and coverage are described in more detail in the [testplan](#testplan). -All test sequences reside in [`hw/ip/pwrmgr/dv/env/seq_lib`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/dv/env/seq_lib), and extend `pwrmgr_base_vseq`. -The `pwrmgr_base_vseq` virtual sequence is extended from `cip_base_vseq` and serves as a starting point. -It provides commonly used handles, variables, functions and tasks used by the test sequences. -Some of the most commonly used tasks and functions are as follows: -* task `wait_for_fast_fsm_active`: - Waits for the `fetch_en_o` output to become 1, indicating the fast fsm is active and the CPU can fetch instructions. - We wait for this before the tests can start, since any CSR accesses require the CPU to be running. - Due to complexities in the UVM sequences this task is called in the virtual post_apply_reset task of dv_base_vseq. -* task `wait_for_csr_to_propagate_to_slow_domain`: - Waits for `cfg_cdc_sync` CSR to be clear, indicating the CDC to the slow clock has completed. -* task `wait_for_reset_cause`: - Waits for the `pwr_rst_req.reset_cause` output to match an expected cause. -* task `check_wait_info`: - Checks the wake_info CSR matches expectations. -* task `check_reset_status`: - Checks the reset_status CSR matches expectations. -* task `check_and_clear_interrupt`: - Checks the interrupt enable, status, and output pin. - -In addition, the base sequence provides two tasks that provide expected inputs based on the pwrmgr outputs. -In the absence of these inputs the pwrmgr will be stuck waiting forever. -Being based on outputs means the inputs are in accordance to the implicit protocol. -The tasks in question are: -* task `slow_responder`: - Handles required input changes from AST for the slow state machine. - For the various `_en` outputs it changes the `_val` as required, for `core`, `io`, `main`, and `usb` clocks. -* task `fast_responder`: - Handles input changes for the fast state machine. - * Completes the handshake with rstmgr for lc and sys resets: some random cycles after an output reset is requested the corresponding reset src input must go low. - * Completes the handshake with clkmgr: the various `_status` inputs need to match the corresponding `_ip_clk_en` output after some cycles, for `io`, `main`, and `usb` clocks. - * Completes the handshake with lc and otp: both *_done inputs must match the corresponding *_init outputs after some cycles. - -These tasks are started by the parent sequence's `pre_start` task, and terminated gracefully in the parent sequence's `post_start` task. -### Test sequences -The test sequences besides the base are as follows: -* `pwrmgr_smoke_vseq` tests the pwrmgr through POR, entry and exit from software initiated low power and reset. -* `pwrmgr_wakeup_vseq` checks the transitions to low power and the wakeup settings. - It randomizes wakeup inputs, wakeup enables, the wakeup info capture enable, and the interrupt enable. -* `pwrmgr_aborted_low_power_vseq` creates scenarios that lead to aborting a low power transition. - The abort can be due to the processor waking up very soon, or otp, lc, or flash being busy. -* `pwrmgr_reset_vseq` checks the pwrmgr response to conditional resets and reset enables, and unconditional escalation and main power glitch resets. -* `pwrmgr_wakeup_reset_vseq` aligns reset and wakeup from low power. -* `pwrmgr_lowpower_wakeup_race_vseq` aligns a wakeup event coming in proximity to low power entry. - Notice the wakeup is not expected to impact low power entry, since it is not sampled at this time. - -### Functional coverage -To ensure high quality constrained random stimulus, it is necessary to develop a functional coverage model. -The following covergroups have been developed to prove that the test intent has been adequately met: -* `wakeup_ctrl_cg` covers wakeup and capture control. -* `wakeup_intr_cg` covers control of the interrupt due to a wakeup. -* `control_cg` covers clock controls. -* `hw_reset_0_cg` covers external reset via `rstreqs_i[0]`. -* `hw_reset_1_cg` covers external reset via `rstreqs_i[1]`. -* `rstmgr_sw_reset_cg` covers software initiated resets via rstmgr CSR. -* `main_power_reset_cg` covers resets due to a main power glitch. -* `esc_reset_cg` covers resets due to an incoming escalation. -* `reset_wakeup_distance_cg` covers the distance in clock cycles between a wakeup and a reset request. - -More details about these sequences and covergroups can be found at [testplan](#testplan). - -### Self-checking strategy -Many of the checks are performed via SVA, and are enabled for all test sequences. -Refer to the [assertions](#assertions) section below for details. - -#### Scoreboard -The `pwrmgr_scoreboard` is primarily used for end to end checking. - -Many inputs must have specific transitions to prevent the pwrmgr fsms from wait forever. -When possible the transitions are triggered by pwrmgr output changes. -These are described according to the unit that originates or is the recipient of the ports. -See also the test plan for specific ways these are driven to trigger different testpoints. - -##### AST -- Output `slow_clk_en` is always on. -- Input `slow_clk_val` is unused. -- Outputs `core_clk_en`, `io_clk_en`, and `usb_clk_en` reset low, and go high prior to the slow fsm requesting the fast fsm to wakeup. - Notice the usb clock can be programmed to stay low on wakeup via the `control` CSR. - These clock enables are cleared on reset, and should match their corresponding enables in the `control` CSR on low power transitions. - These clock enables are checked via SVAs in [`hw/ip/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv). - When slow fsm transitions to `SlowPwrStateReqPwrUp` the clock enables should be on (except usb should match `control.usb_clk_en_active`). - When slow fsm transitions to `SlowPwrStatePwrClampOn` the clock enables should match their bits in the `control` CSR. -- Inputs `core_clk_val`, `io_clk_val`, and `usb_clk_val` track the corresponding enables. - They are driven by `slow_responder`, which turn them off when their enables go off, and turn them back on a few random slow clock cycles after their enables go on. - Slow fsm waits for them to go high prior to requesting fast fsm wakeup. - Lack of a high transition when needed is detected via timeout. - Such timeout would be due to the corresponding enables being set incorrectly. - These inputs are checked via SVAs in [`hw/ip/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv). -- Output `main_pd_n` should go high when slow fsm transitions to `SlowPwrStateMainPowerOn`, and should match `control.main_pd_n` CSR when slow fsm transitions to `SlowPwrStateMainPowerOff`. -- Input `main_pok` should turn on for the slow fsm to start power up sequence. - This is also driven by `slow_responder`, which turn this off in response to `main_pd_n` going low, and turn it back on after a few random slow clock cycles from `main_pd_n` going high. - Lack of a high transition causes a timeout, and would point to `main_pd_n` being set incorrectly. -- Output transitions of `pwr_clamp_env` must always precede transitions of - `pwr_clamp` output. - Output transitions of `pwr_clamp` to active must always precede transitions - of `main_pd_n` output to active. - Output transitions of `pwr_clamp` to inactive must always follow transitions - of `main_pd_n` output to inactive. - -##### RSTMGR -- Output `rst_lc_req` resets to 1, also set on reset transition, and on low power transitions that turn off main clock. - Cleared early on during the steps to fast fsm active. -- Input `rst_lc_src_n` go low in response to `rst_lc_req` high, go high when `rst_lc_req` clears (and lc is reset). - Driven by `fast_responder` in response to `rst_lc_req`, waiting a few random cycles prior to transitions. - Fast fsm waits for it to go low before deactivating, and for it to go high before activating. - Checked implicitly by lack of timeout: a timeout would be due to `rst_lc_req` being set incorrectly, and by SVA as described below. -- Output `rst_sys_req` resets to 1, also set to on reset, and on low power transitions that turn off main clock. - Cleared right before the fast fsm goes active. -- Input `rst_sys_src_n` go low in response to `rst_sys_req` high. - Transitions go high when `rst_sysd_req` clears (and lc is reset). - Fast fsm waits for it to go low before deactivating. - Also driver by `fast_responder`. - Checked implicitly by lack of timeout, and by SVA. -- Output `rstreqs` correspond to the enabled pwrmgr rstreqs inputs plus main power glitch, escalation reset, and software reset request from RSTMGR. - Checked in scoreboard and SVA. -- Output `reset_cause` indicates a reset is due to low power entry or a reset request. - Checked in scoreboard. - -##### CLKMGR -- Outputs `pwr_clk_o._ip_clk_en` reset low, are driven high by fast fsm when going active, and driven low when going inactive. - The `` correspond to `io`, `main`, and `usb`. -- Inputs `pwr_clk_i._status` are expected to track `pwr_clk_o._ip_clk_en`. - Fast fsm waits for them going high prior to going active, and going low prior to deactivating. - These are controlled by the `control` CSR. - Driven by `fast_responder`, which turns them off when `_ip_clk_en` goes low, and turns them back on a few random cycles after `_ip_clk_en` goes high. - Checked by lack of a timeout: such timeout would be due to `ip_clk_en` being set incorrectly. - Also checked by SVA. - -##### OTP -- Output `otp_init` resets low, goes high when the fast fsm is going active, and low after the `otp_done` input goes high. -- Input `otp_done` is driven by `fast_responder`. - It is initialized low, and goes high some random cycles after `otp_init` goes high. - The sequencer will timeout if `otp_init` is not driven high. -- Input `otp_idle` normally set high, but is set low by the `pwrmgr_aborted_low_power_vseq` sequence. - -###### LC -The pins connecting to LC behave pretty much the same way as those to OTP. - -##### FLASH -- Input `flash_idle` is handled much like `lc_idle` and `otp_idle`. - -##### CPU -- Input `core_sleeping` is driven by sequences. - It is driven low to enable a transition to low power. - After the transition is under way it is a don't care. - The `pwrmgr_aborted_low_power_vseq` sequence sets it carefully to abort a low power entry soon after the attempt because the processor wakes up. - -##### Wakeups and Resets -There are a number of wakeup and reset requests. -They are driven by sequences as they need to. - -#### Assertions -The [`hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv) module binds a few modules containing assertions to the IP as follows: -* TLUL assertions: the `tlul_assert` [assertions](../../tlul/doc/TlulProtocolChecker.md) ensures TileLink interface protocol compliance. -* Clock enables assertions: - The `pwrmgr_clock_enables_sva_if` module contains assertions checking that the various clk_en outputs correspond to the settings in the `control` CSR. -* CLKMGR clk_en to status handshake assertions: - The `clkmgr_pwrmgr_sva_if` contains assertions checking the various `_status` inputs track the corresponding `_ip_clk_en` outputs. -* AST input/output handshake assertions: - The `pwrmgr_ast_sva_if` module contains assertions checking that the inputs from the AST respond to the pwrmgr outputs. -* RSTMGR input/output handshake assertions: - The `pwrmgr_rstmgr_sva_if` module contains assertions checking the following: - * The `rst_lc_src_n` input from RSTMGR respond to the `rst_lc_req` pwrmgr output. - * The `rst_sys_src_n` input from RSTMGR respond to the `rst_sys_req` pwrmgr output. - * The different `pwr_rst_o.rstreqs` output bits track the corresponding reset causes. - These include hardware, power glitch, escalation, and software resets. - -In addition, the RTL has assertions to ensure all outputs are initialized to known values after coming out of reset. - -## Building and running tests -We are using our in-house developed [regression tool](../../../../util/dvsim/README.md) for building and running our tests and regressions. -Please take a look at the link for detailed information on the usage, capabilities, features and known issues. -Here's how to run a smoke test: -```console -$ $REPO_TOP/util/dvsim/dvsim.py $REPO_TOP/hw/ip/pwrmgr/dv/pwrmgr_sim_cfg.hjson -i pwrmgr_smoke -``` - -## Testplan -[Testplan](../data/pwrmgr_testplan.hjson) diff --git a/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_bind.sv b/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_bind.sv deleted file mode 100644 index 6a444e73cb146c..00000000000000 --- a/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_bind.sv +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Description: -// Power manager coverage bindings for multi bus input -module pwrmgr_cov_bind; - - bind pwrmgr cip_lc_tx_cov_if u_lc_dft_en_mubi_cov_if ( - .rst_ni (rst_ni), - .val (lc_dft_en_i) - ); - - bind pwrmgr cip_lc_tx_cov_if u_lc_hw_debug_en_mubi_cov_if ( - .rst_ni (rst_ni), - .val (lc_hw_debug_en_i) - ); - - bind pwrmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_rom_ctrl_good_mubi_cov_if ( - .rst_ni (rst_ni), - .mubi (rom_ctrl_i.done) - ); - - bind pwrmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_rom_ctrl_done_mubi_cov_if ( - .rst_ni (rst_ni), - .mubi (rom_ctrl_i.good) - ); - - bind pwrmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_sw_rst_req_mubi_cov_if ( - .rst_ni (rst_ni), - .mubi (sw_rst_req_i) - ); -endmodule // pwrmgr_cov_bind diff --git a/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el b/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el deleted file mode 100644 index 202e253ca58da9..00000000000000 --- a/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -//================================================== -// This file contains the Excluded objects -// Generated By User: jdonjdon -// Format Version: 2 -// Date: Sun Sep 25 22:09:48 2022 -// ExclMode: default -//================================================== -CHECKSUM: "2301929872 963630968" -INSTANCE: tb.dut.u_esc_rx.u_prim_count -ANNOTATION: "[UNSUPPORTED] Ports are assigned constant by RTL." -Toggle step_i "net step_i[21:0]" -Toggle set_cnt_i "net set_cnt_i[21:0]" -CHECKSUM: "3681358461" -INSTANCE: tb.dut.u_esc_timeout.u_ref_timeout -ANNOTATION: "[UNR] Input req_chk_i is tied to constant 0 and src_req_i to constant 1" -Assert SyncReqAckHoldReq "assertion" -CHECKSUM: "2699797328" -INSTANCE: tb.dut.pwrmgr_ast_sva_if -ANNOTATION: "[UNR] por_d0_ni input is tied to constant 1" -Assert CoreClkGlitchToEnOff_A "assertion" -ANNOTATION: "[UNR] por_d0_ni input is tied to constant 1" -Assert UsbClkGlitchToValOff_A "assertion" -ANNOTATION: "[UNR] por_d0_ni input is tied to constant 1" -Assert UsbClkGlitchToEnOff_A "assertion" -ANNOTATION: "[UNR] por_d0_ni input is tied to constant 1" -Assert IoClkGlitchToValOff_A "assertion" -ANNOTATION: "[UNR] por_d0_ni input is tied to constant 1" -Assert IoClkGlitchToEnOff_A "assertion" -ANNOTATION: "[UNR] por_d0_ni input is tied to constant 1" -Assert CoreClkGlitchToValOff_A "assertion" diff --git a/hw/ip/pwrmgr/dv/doc/tb.svg b/hw/ip/pwrmgr/dv/doc/tb.svg deleted file mode 100644 index 285ef6948e4dc1..00000000000000 --- a/hw/ip/pwrmgr/dv/doc/tb.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_env.core b/hw/ip/pwrmgr/dv/env/pwrmgr_env.core deleted file mode 100644 index 8d737e00f3aed1..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_env.core +++ /dev/null @@ -1,53 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:pwrmgr_env:0.1" -description: "PWRMGR DV UVM environment" -filesets: - files_dv: - depend: - - lowrisc:dv:ralgen - - lowrisc:dv:cip_lib - files: - - pwrmgr_env_pkg.sv - - pwrmgr_env_cfg.sv: {is_include_file: true} - - pwrmgr_env_cov.sv: {is_include_file: true} - - pwrmgr_if.sv - - pwrmgr_virtual_sequencer.sv: {is_include_file: true} - - pwrmgr_scoreboard.sv: {is_include_file: true} - - pwrmgr_env.sv: {is_include_file: true} - - seq_lib/pwrmgr_vseq_list.sv: {is_include_file: true} - - seq_lib/pwrmgr_base_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_aborted_low_power_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_common_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_reset_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_smoke_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_stress_all_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_wakeup_reset_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_wakeup_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_sw_reset_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_global_esc_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_glitch_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_reset_invalid_vseq.sv: {is_include_file: true} - - seq_lib/pwrmgr_lowpower_invalid_vseq.sv: {is_include_file: true} - file_type: systemVerilogSource - -generate: - ral: - generator: ralgen - parameters: - name: pwrmgr - ip_hjson: ../../../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson - -targets: - default: - filesets: - - files_dv - generate: - - ral diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_env.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_env.sv deleted file mode 100644 index 7a02f2e39e467f..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_env.sv +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class pwrmgr_env extends cip_base_env #( - .CFG_T (pwrmgr_env_cfg), - .COV_T (pwrmgr_env_cov), - .VIRTUAL_SEQUENCER_T(pwrmgr_virtual_sequencer), - .SCOREBOARD_T (pwrmgr_scoreboard) -); - `uvm_component_utils(pwrmgr_env) - - alert_esc_agent m_esc_agent; - `uvm_component_new - - function void build_phase(uvm_phase phase); - super.build_phase(phase); - if (!uvm_config_db#(virtual clk_rst_if)::get( - this, "", "slow_clk_rst_vif", cfg.slow_clk_rst_vif - )) begin - `uvm_fatal(`gfn, "failed to get slow_clk_rst_vif from uvm_config_db") - end - if (!uvm_config_db#(virtual clk_rst_if)::get( - this, "", "esc_clk_rst_vif", cfg.esc_clk_rst_vif - )) begin - `uvm_fatal(`gfn, "failed to get esc_clk_rst_vif from uvm_config_db") - end - if (!uvm_config_db#(virtual clk_rst_if)::get( - this, "", "lc_clk_rst_vif", cfg.lc_clk_rst_vif - )) begin - `uvm_fatal(`gfn, "failed to get lc_clk_rst_vif from uvm_config_db") - end - if (!uvm_config_db#(virtual pwrmgr_if)::get(this, "", "pwrmgr_vif", cfg.pwrmgr_vif)) begin - `uvm_fatal(`gfn, "failed to get pwrmgr_vif from uvm_config_db") - end - if (!uvm_config_db#(virtual pwrmgr_clock_enables_sva_if)::get( - this, "", "pwrmgr_clock_enables_sva_vif", cfg.pwrmgr_clock_enables_sva_vif - )) begin - `uvm_fatal(`gfn, "failed to get pwrmgr_clock_enables_sva_vif from uvm_config_db") - end - if (!uvm_config_db#(virtual pwrmgr_rstmgr_sva_if)::get( - this, "", "pwrmgr_rstmgr_sva_vif", cfg.pwrmgr_rstmgr_sva_vif - )) begin - `uvm_fatal(`gfn, "failed to get pwrmgr_rstmgr_sva_vif from uvm_config_db") - end - - m_esc_agent = alert_esc_agent::type_id::create("m_esc_agent", this); - uvm_config_db#(alert_esc_agent_cfg)::set(this, "m_esc_agent", "cfg", cfg.m_esc_agent_cfg); - cfg.m_esc_agent_cfg.en_cov = cfg.en_cov; - - endfunction - - function void connect_phase(uvm_phase phase); - super.connect_phase(phase); - endfunction - -endclass diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_env_cfg.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_env_cfg.sv deleted file mode 100644 index 540aeb88187024..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_env_cfg.sv +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class pwrmgr_env_cfg extends cip_base_env_cfg #( - .RAL_T(pwrmgr_reg_block) -); - - // disable fault csr read check from scoreboard - bit disable_csr_rd_chk = 0; - - // Invalid state test. Used to disable interrupt check. - bit invalid_st_test = 0; - - // ext component cfgs - alert_esc_agent_cfg m_esc_agent_cfg; - - `uvm_object_utils_begin(pwrmgr_env_cfg) - `uvm_object_utils_end - - `uvm_object_new - - // ext interfaces - virtual clk_rst_if esc_clk_rst_vif; - virtual clk_rst_if lc_clk_rst_vif; - virtual clk_rst_if slow_clk_rst_vif; - virtual pwrmgr_if pwrmgr_vif; - virtual pwrmgr_clock_enables_sva_if pwrmgr_clock_enables_sva_vif; - virtual pwrmgr_rstmgr_sva_if pwrmgr_rstmgr_sva_vif; - - // The run_phase object, to deal with objections. - uvm_phase run_phase; - - virtual function void initialize(bit [31:0] csr_base_addr = '1); - list_of_alerts = pwrmgr_env_pkg::LIST_OF_ALERTS; - super.initialize(csr_base_addr); - num_interrupts = ral.intr_state.get_n_used_bits(); - `ASSERT_I(NumInstrMatch_A, num_interrupts == NUM_INTERRUPTS) - `uvm_info(`gfn, $sformatf("num_interrupts = %0d", num_interrupts), UVM_MEDIUM) - - // pwrmgr_tl_intg_err test uses default alert name "fata_fault" - // and it requires following field to be '1' - tl_intg_alert_fields[ral.fault_status.reg_intg_err] = 1; - m_tl_agent_cfg.max_outstanding_req = 1; - m_esc_agent_cfg = alert_esc_agent_cfg::type_id::create("m_esc_agent_cfg"); - `DV_CHECK_RANDOMIZE_FATAL(m_esc_agent_cfg) - m_esc_agent_cfg.is_alert = 0; - // Disable escalation ping coverage. - m_esc_agent_cfg.en_ping_cov = 0; - endfunction - -endclass diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_env_cov.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_env_cov.sv deleted file mode 100644 index 825d933f1c256f..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_env_cov.sv +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -/** - * Covergoups that are dependent on run-time parameters that may be available - * only in build_phase can be defined here. - * Covergroups may also be wrapped inside helper classes if needed. - */ - -`include "cip_macros.svh" - -// Wrapper class for wakeup control covergroup. -class pwrmgr_wakeup_ctrl_cg_wrap; - // This covers enable, capture, and status of wakeups. - covergroup wakeup_ctrl_cg(string name) with function sample (bit enable, bit capture, bit wakeup); - option.name = name; - option.per_instance = 1; - - enable_cp: coverpoint enable; - capture_cp: coverpoint capture; - wakeup_cp: coverpoint wakeup; - - wakeup_cross: cross enable_cp, capture_cp, wakeup_cp; - endgroup - - function new(string name); - wakeup_ctrl_cg = new(name); - endfunction - - function void sample (bit enable, bit capture, bit wakeup); - wakeup_ctrl_cg.sample(enable, capture, wakeup); - endfunction -endclass - -// Wrapper class for wakeup interrupt covergroup. -class pwrmgr_wakeup_intr_cg_wrap; - // This covers interrupts generated by wakeups. - covergroup wakeup_intr_cg( - string name - ) with function sample ( - bit wakeup, bit enable, bit status, bit interrupt - ); - option.name = name; - option.per_instance = 1; - - enable_cp: coverpoint enable; - status_cp: coverpoint status; - wakeup_cp: coverpoint wakeup; - interrupt_cp: coverpoint interrupt; - - interrupt_cross: cross enable_cp, status_cp, wakeup_cp, interrupt_cp{ - // An interrupt cannot happen unless wake_status is on. - ignore_bins no_wakeup = interrupt_cross with (!wakeup_cp && interrupt_cp); - // An interrupt cannot happen unless it is enabled. - ignore_bins disable_pin = interrupt_cross with (!enable_cp && interrupt_cp); - // An interrupt cannot happen if intr_status is off. - ignore_bins no_status_pin = interrupt_cross with (!status_cp && interrupt_cp); - // If all preconditions are satisfied there must be an interrupt. - ignore_bins missing_int = interrupt_cross with (enable_cp && status_cp && wakeup_cp && - !interrupt_cp); - } - endgroup - - function new(string name); - wakeup_intr_cg = new(name); - endfunction - - function void sample (bit enable, bit status, bit wakeup, bit interrupt); - wakeup_intr_cg.sample(wakeup, enable, status, interrupt); - endfunction -endclass - -class pwrmgr_env_cov extends cip_base_env_cov #( - .CFG_T(pwrmgr_env_cfg) -); - `uvm_component_utils(pwrmgr_env_cov) - - // the base class provides the following handles for use: - // pwrmgr_env_cfg: cfg - - // covergroups - pwrmgr_wakeup_ctrl_cg_wrap wakeup_ctrl_cg_wrap[pwrmgr_reg_pkg::NumWkups]; - pwrmgr_wakeup_intr_cg_wrap wakeup_intr_cg_wrap[pwrmgr_reg_pkg::NumWkups]; - - // This collects coverage on the clock and power control functionality. - covergroup control_cg with function sample (control_enables_t control_enables, bit sleep); - core_cp: coverpoint control_enables.core_clk_en; - io_cp: coverpoint control_enables.io_clk_en; - usb_lp_cp: coverpoint control_enables.usb_clk_en_lp; - usb_active_cp: coverpoint control_enables.usb_clk_en_active; - main_pd_n_cp: coverpoint control_enables.main_pd_n; - sleep_cp: coverpoint sleep; - - control_cross: cross core_cp, io_cp, usb_lp_cp, usb_active_cp, main_pd_n_cp, sleep_cp; - endgroup - - covergroup hw_reset_0_cg with function sample (logic reset, logic enable, bit sleep); - reset_cp: coverpoint reset; - enable_cp: coverpoint enable; - sleep_cp: coverpoint sleep; - reset_cross: cross reset_cp, enable_cp, sleep_cp { - // Reset and sleep are mutually exclusive. - illegal_bins illegal = reset_cross with (reset_cp && sleep_cp); - } - endgroup - - covergroup hw_reset_1_cg with function sample (logic reset, logic enable, bit sleep); - reset_cp: coverpoint reset; - enable_cp: coverpoint enable; - sleep_cp: coverpoint sleep; - reset_cross: cross reset_cp, enable_cp, sleep_cp { - // Reset and sleep are mutually exclusive. - illegal_bins illegal = reset_cross with (reset_cp && sleep_cp); - } - endgroup - - // This reset cannot be generated in low power state since it is triggered by software. - covergroup rstmgr_sw_reset_cg with function sample (logic sw_reset); - sw_reset_cp: coverpoint sw_reset; - endgroup - - covergroup main_power_reset_cg with function sample (logic main_power_reset, bit sleep); - main_power_reset_cp: coverpoint main_power_reset; - sleep_cp: coverpoint sleep; - reset_cross: cross main_power_reset_cp, sleep_cp { - // Any reset and sleep are mutually exclusive. - illegal_bins illegal = reset_cross with (main_power_reset_cp && sleep_cp); - } - endgroup - - covergroup esc_reset_cg with function sample (logic esc_reset, bit sleep); - esc_reset_cp: coverpoint esc_reset; - sleep_cp: coverpoint sleep; - reset_cross: cross esc_reset_cp, sleep_cp { - // Any reset and sleep are mutually exclusive. - illegal_bins illegal = reset_cross with (esc_reset_cp && sleep_cp); - } - endgroup - - // This measures the number of cycles between the reset and wakeup. - // It is positive when reset happened after wakeup, and zero when they coincided in time. - covergroup reset_wakeup_distance_cg with function sample (int cycles); - cycles_cp: coverpoint cycles { - bins close[] = {[-4 : 4]}; - bins far = default; - } - endgroup - - // This covers the rom inputs that should prevent entering the active state. - covergroup rom_active_blockers_cg with function sample ( - logic [3:0] done, logic [3:0] good, logic [3:0] dft, logic [3:0] debug - ); - done_cp: coverpoint done { - `DV_MUBI4_CP_BINS - } - good_cp: coverpoint good { - `DV_MUBI4_CP_BINS - } - dft_cp: coverpoint dft { - `DV_LC_TX_T_CP_BINS - } - debug_cp: coverpoint debug { - `DV_LC_TX_T_CP_BINS - } - blockers_cross: cross done_cp, good_cp, dft_cp, debug_cp; - endgroup - - function new(string name, uvm_component parent); - super.new(name, parent); - foreach (wakeup_ctrl_cg_wrap[i]) begin - pwrmgr_env_pkg::wakeup_e wakeup = pwrmgr_env_pkg::wakeup_e'(i); - wakeup_ctrl_cg_wrap[i] = new({wakeup.name, "_ctrl_cg"}); - wakeup_intr_cg_wrap[i] = new({wakeup.name, "_intr_cg"}); - end - control_cg = new(); - hw_reset_0_cg = new(); - hw_reset_1_cg = new(); - rstmgr_sw_reset_cg = new(); - main_power_reset_cg = new(); - esc_reset_cg = new(); - reset_wakeup_distance_cg = new(); - rom_active_blockers_cg = new(); - endfunction : new - - virtual function void build_phase(uvm_phase phase); - super.build_phase(phase); - // [or instantiate covergroups here] - // Please instantiate sticky_intr_cov array of objects for all interrupts that are sticky - // See cip_base_env_cov for details - endfunction - -endclass diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv deleted file mode 100644 index 6c684b9f0b3183..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_env_pkg.sv +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -package pwrmgr_env_pkg; - // dep packages - import uvm_pkg::*; - import top_pkg::*; - import dv_utils_pkg::*; - import dv_lib_pkg::*; - import tl_agent_pkg::*; - import cip_base_pkg::*; - import dv_base_reg_pkg::*; - import csr_utils_pkg::*; - import pwrmgr_ral_pkg::*; - import alert_esc_agent_pkg::*; - import pwrmgr_pkg::PowerDomains; - import prim_mubi_pkg::mubi4_t; - import prim_mubi_pkg::MuBi4False; - import prim_mubi_pkg::MuBi4True; - import prim_mubi_pkg::MuBi4Width; - import sec_cm_pkg::*; - // macro includes - `include "uvm_macros.svh" - `include "dv_macros.svh" - - // parameters - parameter int NUM_INTERRUPTS = 1; - - // clk enable disable delay - parameter uint MAIN_CLK_DELAY_MIN = 15; - parameter uint MAIN_CLK_DELAY_MAX = 258; - parameter uint ESC_CLK_DELAY_MIN = 1; - parameter uint ESC_CLK_DELAY_MAX = 10; - - // alerts - parameter uint NUM_ALERTS = 1; - parameter string LIST_OF_ALERTS[] = {"fatal_fault"}; - - // types - typedef enum int { - WakeupSysrst, - WakeupDbgCable, - WakeupPin, - WakeupUsb, - WakeupAonTimer, - WakeupSensorCtrl - } wakeup_e; - - typedef enum int { - PwrmgrMubiNone = 0, - PwrmgrMubiLcCtrl = 1, - PwrmgrMubiRomCtrl = 2 - } pwrmgr_mubi_e; - - typedef struct packed { - logic main_pd_n; - logic usb_clk_en_active; - logic usb_clk_en_lp; - logic io_clk_en; - logic core_clk_en; - } control_enables_t; - - typedef bit [pwrmgr_reg_pkg::NumWkups-1:0] wakeups_t; - typedef bit [pwrmgr_reg_pkg::NumRstReqs-1:0] resets_t; - - // This is used to send all resets to rstmgr. - typedef bit [pwrmgr_pkg::HwResetWidth-1:0] resets_out_t; - - // need a short name to avoid 100 line cut off - parameter int MUBI4W = prim_mubi_pkg::MuBi4Width; - - // functions - - // variables - bit [NUM_INTERRUPTS-1:0] exp_intr; - wakeups_t exp_wakeup_reasons; - control_enables_t control_enables; - logic low_power_hint; - - // package sources - `include "pwrmgr_env_cfg.sv" - `include "pwrmgr_env_cov.sv" - `include "pwrmgr_virtual_sequencer.sv" - `include "pwrmgr_scoreboard.sv" - `include "pwrmgr_env.sv" - `include "pwrmgr_vseq_list.sv" - -endpackage diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_if.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_if.sv deleted file mode 100644 index 7352322fab6d34..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_if.sv +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// pwrmgr interface. -// -// Samples some internal signals to help coverage collection: -interface pwrmgr_if ( - input logic clk, - input logic rst_n, - input logic clk_slow, - input logic rst_slow_n -); - import uvm_pkg::*; - import pwrmgr_env_pkg::*; - - // Ports to the dut side. - - logic rst_main_n; - - pwrmgr_pkg::pwr_ast_req_t pwr_ast_req; - pwrmgr_pkg::pwr_ast_rsp_t pwr_ast_rsp; - - pwrmgr_pkg::pwr_rst_req_t pwr_rst_req; - pwrmgr_pkg::pwr_rst_rsp_t pwr_rst_rsp; - - pwrmgr_pkg::pwr_clk_req_t pwr_clk_req; - pwrmgr_pkg::pwr_clk_rsp_t pwr_clk_rsp; - - pwrmgr_pkg::pwr_otp_req_t pwr_otp_req; - pwrmgr_pkg::pwr_otp_rsp_t pwr_otp_rsp; - - pwrmgr_pkg::pwr_lc_req_t pwr_lc_req; - pwrmgr_pkg::pwr_lc_rsp_t pwr_lc_rsp; - - pwrmgr_pkg::pwr_flash_t pwr_flash; - - pwrmgr_pkg::pwrmgr_cpu_t cpu_i; - pwrmgr_pkg::pwr_cpu_t pwr_cpu; - - lc_ctrl_pkg::lc_tx_t fetch_en; - lc_ctrl_pkg::lc_tx_t lc_hw_debug_en; - lc_ctrl_pkg::lc_tx_t lc_dft_en; - - logic [ pwrmgr_reg_pkg::NumWkups-1:0] wakeups_i; - logic [pwrmgr_reg_pkg::NumRstReqs-1:0] rstreqs_i; - - logic strap; - logic low_power; - rom_ctrl_pkg::pwrmgr_data_t rom_ctrl; - - prim_mubi_pkg::mubi4_t sw_rst_req_i; - - logic intr_wakeup; - - // Relevant CSR values. - logic wakeup_en_regwen; - logic [ pwrmgr_reg_pkg::NumWkups-1:0] wakeup_en; - logic [ pwrmgr_reg_pkg::NumWkups-1:0] wakeup_status; - logic wakeup_capture_en; - - logic [pwrmgr_reg_pkg::NumRstReqs-1:0] reset_en; - logic [pwrmgr_reg_pkg::NumRstReqs-1:0] reset_en_q; - logic [pwrmgr_reg_pkg::NumRstReqs-1:0] reset_status; - - logic lowpwr_cfg_wen; - pwrmgr_reg_pkg::pwrmgr_hw2reg_wake_info_reg_t wake_info; - - // Internal DUT signals. -`ifndef PATH_TO_DUT - `define PATH_TO_DUT tb.dut -`endif - - // Slow fsm state. - pwrmgr_pkg::slow_pwr_state_e slow_state; - always_comb slow_state = `PATH_TO_DUT.u_slow_fsm.state_q; - - // Fast fsm state. - pwrmgr_pkg::fast_pwr_state_e fast_state; - always_comb fast_state = `PATH_TO_DUT.u_fsm.state_q; - - // cfg regwen - always_comb lowpwr_cfg_wen = `PATH_TO_DUT.lowpwr_cfg_wen; - - // reset status - always_comb reset_status = {`PATH_TO_DUT.u_reg.reset_status_val_1_qs, - `PATH_TO_DUT.u_reg.reset_status_val_0_qs}; - always_comb reset_en_q = {`PATH_TO_DUT.u_reg.reset_en_en_1_qs, - `PATH_TO_DUT.u_reg.reset_en_en_0_qs}; - always_comb - wakeup_en = { - `PATH_TO_DUT.reg2hw.wakeup_en[5].q, - `PATH_TO_DUT.reg2hw.wakeup_en[4].q, - `PATH_TO_DUT.reg2hw.wakeup_en[3].q, - `PATH_TO_DUT.reg2hw.wakeup_en[2].q, - `PATH_TO_DUT.reg2hw.wakeup_en[1].q, - `PATH_TO_DUT.reg2hw.wakeup_en[0].q - }; - - // Wakeup_status ro CSR. - always_comb - wakeup_status = { - `PATH_TO_DUT.hw2reg.wake_status[5].d, - `PATH_TO_DUT.hw2reg.wake_status[4].d, - `PATH_TO_DUT.hw2reg.wake_status[3].d, - `PATH_TO_DUT.hw2reg.wake_status[2].d, - `PATH_TO_DUT.hw2reg.wake_status[1].d, - `PATH_TO_DUT.hw2reg.wake_status[0].d - }; - - always_comb wakeup_capture_en = !`PATH_TO_DUT.u_reg.wake_info_capture_dis_qs; - always_comb wake_info = `PATH_TO_DUT.i_wake_info.info_o; - - logic intr_enable; - always_comb intr_enable = `PATH_TO_DUT.reg2hw.intr_enable.q; - - logic intr_status; - always_comb intr_status = `PATH_TO_DUT.reg2hw.intr_state.q; - - // This is only used to determine if an interrupt will be set in case of a reset while in - // low power. tryIt is very hard to perdict if the reset or a wakeup happen first, so this - // signal is used to help instead. - pwrmgr_pkg::pwrup_cause_e pwrup_cause; - always_comb pwrup_cause = `PATH_TO_DUT.slow_pwrup_cause; - - // Used to disable assertions once with the first power glitch. - bit internal_assertion_disabled; - - function automatic void update_ast_main_pok(logic value); - pwr_ast_rsp.main_pok = value; - endfunction - - function automatic void update_otp_done(logic value); - pwr_otp_rsp.otp_done = value; - endfunction - - function automatic void update_otp_idle(logic value); - pwr_otp_rsp.otp_idle = value; - endfunction - - function automatic void update_lc_done(logic value); - pwr_lc_rsp.lc_done = value; - endfunction - - function automatic void update_lc_idle(logic value); - pwr_lc_rsp.lc_idle = value; - endfunction - - function automatic void update_flash_idle(logic value); - pwr_flash.flash_idle = value; - endfunction - - function automatic void update_cpu_sleeping(logic value); - pwr_cpu.core_sleeping = value; - endfunction - - function automatic void update_wakeups(logic [pwrmgr_reg_pkg::NumWkups-1:0] wakeups); - wakeups_i = wakeups; - endfunction - - function automatic void update_resets(logic [pwrmgr_reg_pkg::NumRstReqs-1:0] resets); - rstreqs_i = resets; - endfunction - - function automatic void update_reset_en( - logic [pwrmgr_reg_pkg::NumRstReqs-1:0] reset_en_value); - reset_en = reset_en_value; - endfunction - - function automatic void update_sw_rst_req(prim_mubi_pkg::mubi4_t value); - sw_rst_req_i = value; - endfunction - - // Sends a main power glitch and disables a design assertion that trips for power glitches. - task automatic glitch_power_reset(); - rst_main_n = 1'b0; - if (!internal_assertion_disabled) begin - internal_assertion_disabled = 1'b1; - `uvm_info("pwrmgr_if", "disabling power glitch related SVA", UVM_MEDIUM) - $assertoff(1, tb.dut.u_slow_fsm.IntRstReq_A); - end - repeat (2) @(posedge clk_slow); - rst_main_n = 1'b1; - endtask - - // FIXME Move all these initializations to sequences. - initial begin - // From AST. - pwr_ast_rsp = '{default: '0}; - pwr_rst_rsp = '{default: '0}; - pwr_clk_rsp = '{default: '0}; - pwr_otp_rsp = '{default: '0}; - pwr_lc_rsp = '{default: '0}; - pwr_flash = '{default: '0}; - pwr_cpu = pwrmgr_pkg::PWR_CPU_DEFAULT; - wakeups_i = pwrmgr_pkg::WAKEUPS_DEFAULT; - rstreqs_i = pwrmgr_pkg::RSTREQS_DEFAULT; - sw_rst_req_i = prim_mubi_pkg::MuBi4False; - rom_ctrl = rom_ctrl_pkg::PWRMGR_DATA_DEFAULT; - end - - clocking slow_cb @(posedge clk_slow); - input slow_state; - input pwr_ast_req; - output pwr_ast_rsp; - endclocking - - clocking fast_cb @(posedge clk); - input fast_state; - input pwr_rst_req; - output pwr_rst_rsp; - input pwr_clk_req; - output pwr_clk_rsp; - input pwr_lc_req; - output pwr_lc_rsp; - input pwr_otp_req; - output pwr_otp_rsp; - endclocking -endinterface diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_scoreboard.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_scoreboard.sv deleted file mode 100644 index d67dda13bd914d..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_scoreboard.sv +++ /dev/null @@ -1,339 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class pwrmgr_scoreboard extends cip_base_scoreboard #( - .CFG_T(pwrmgr_env_cfg), - .RAL_T(pwrmgr_reg_block), - .COV_T(pwrmgr_env_cov) -); - `uvm_component_utils(pwrmgr_scoreboard) - - // local variables - - // TLM agent fifos - - // local queues to hold incoming packets pending comparison - - `uvm_component_new - - function void build_phase(uvm_phase phase); - string common_seq_type; - super.build_phase(phase); - - void'($value$plusargs("run_%0s", common_seq_type)); - if (common_seq_type == "stress_all_with_rand_reset") do_alert_check = 0; - endfunction - - task run_phase(uvm_phase phase); - super.run_phase(phase); - cfg.run_phase = phase; - fork - monitor_power_glitch(); - monitor_escalation_timeout(); - reset_cip_helper(); - wakeup_ctrl_coverage_collector(); - wakeup_intr_coverage_collector(); - low_power_coverage_collector(); - reset_coverage_collector(); - rom_coverage_collector(); - join_none - endtask - - task monitor_power_glitch(); - fork - forever - @cfg.pwrmgr_vif.rst_main_n begin - if (cfg.pwrmgr_vif.rst_main_n == 1'b0 && `gmv(ral.control.main_pd_n)) begin - set_exp_alert("fatal_fault", 1, 500); - end - end - join - endtask - - // An escalation timeout is triggered in test sequences by stopping clk_esc_i or by driving - // rst_esc_ni active when the dut state is not expecting it. - task monitor_escalation_timeout(); - fork - forever - @(posedge cfg.esc_clk_rst_vif.clk_gate) begin - if (cfg.pwrmgr_vif.pwr_ast_req.io_clk_en && cfg.pwrmgr_vif.pwr_clk_req.io_ip_clk_en) begin - `uvm_info(`gfn, "Detected unexpected clk_esc_i stop", UVM_MEDIUM) - set_exp_alert("fatal_fault", 1, 500); - end - end - forever - @(negedge cfg.esc_clk_rst_vif.o_rst_n) begin - if (cfg.pwrmgr_vif.fetch_en == lc_ctrl_pkg::On) begin - `uvm_info(`gfn, "Detected unexpected rst_esc_ni active", UVM_MEDIUM) - set_exp_alert("fatal_fault", 1, 500); - end - end - join - endtask - - // We need to reset the cip scoreboard, since the alert handler responds - // to lc domain0 resets, yet the pwrmgr's clk_rst_vif is aon. So when a - // reset happens the cip scoreboard needs to be informed, both when reset - // starts and when it ends. - task reset_cip_helper(); - fork - forever - @cfg.pwrmgr_vif.pwr_rst_req.rst_lc_req begin - if (|cfg.pwrmgr_vif.pwr_rst_req.rst_lc_req) begin - // Start of d0 reset request. - `uvm_info(`gfn, "pwrmgr start reset in reset_cip_helper", UVM_MEDIUM) - cfg.under_reset = 1; - end - end - forever - @cfg.pwrmgr_vif.fetch_en begin - if (cfg.pwrmgr_vif.fetch_en == lc_ctrl_pkg::On) begin - // End of d0 reset request. - `uvm_info(`gfn, "pwrmgr end reset in reset_cip_helper", UVM_MEDIUM) - reset_alert_state(); - end - end - join - endtask - - task wakeup_ctrl_coverage_collector(); - forever - @(posedge (|cfg.pwrmgr_vif.wakeups_i)) begin - if (cfg.en_cov) begin - // Allow for synchronization delay. - cfg.slow_clk_rst_vif.wait_clks(2); - foreach (cov.wakeup_ctrl_cg_wrap[i]) begin - cov.wakeup_ctrl_cg_wrap[i].sample(cfg.pwrmgr_vif.wakeup_en[i], - cfg.pwrmgr_vif.wakeup_capture_en, - cfg.pwrmgr_vif.wakeups_i[i]); - end - end - end - endtask - - task wakeup_intr_coverage_collector(); - forever - @(posedge (cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateRomCheckDone)) begin - if (cfg.en_cov) begin - foreach (cov.wakeup_intr_cg_wrap[i]) begin - cov.wakeup_intr_cg_wrap[i].sample( - cfg.pwrmgr_vif.wakeup_status[i], cfg.pwrmgr_vif.intr_enable, - cfg.pwrmgr_vif.intr_status, cfg.pwrmgr_vif.intr_wakeup); - end - end - end - endtask - - task low_power_coverage_collector(); - forever - @(posedge cfg.pwrmgr_vif.pwr_rst_req.reset_cause == pwrmgr_pkg::LowPwrEntry) begin - if (cfg.en_cov) begin - // At this point pwrmgr is asleep. - cov.control_cg.sample(control_enables, 1'b1); - end - end - endtask - - local task sample_reset_coverage(bit sleep); - cov.hw_reset_0_cg.sample(cfg.pwrmgr_vif.rstreqs_i[0], cfg.pwrmgr_vif.reset_en[0], sleep); - cov.hw_reset_1_cg.sample(cfg.pwrmgr_vif.rstreqs_i[1], cfg.pwrmgr_vif.reset_en[1], sleep); - cov.rstmgr_sw_reset_cg.sample(cfg.pwrmgr_vif.sw_rst_req_i == prim_mubi_pkg::MuBi4True); - cov.main_power_reset_cg.sample( - cfg.pwrmgr_vif.pwr_rst_req.rstreqs[pwrmgr_reg_pkg::ResetMainPwrIdx], sleep); - cov.esc_reset_cg.sample(cfg.pwrmgr_vif.pwr_rst_req.rstreqs[pwrmgr_reg_pkg::ResetEscIdx], sleep); - `uvm_info(`gfn, $sformatf( - { - "reset_cg sample with hw_resets=%b, hw_resets_en=%b, ", - "esc_rst=%b, main_pwr_rst=%b, sw_rst=%b, sleep=%b" - }, - cfg.pwrmgr_vif.rstreqs_i, - cfg.pwrmgr_vif.reset_en, - cfg.pwrmgr_vif.pwr_rst_req.rstreqs[pwrmgr_reg_pkg::ResetEscIdx], - cfg.pwrmgr_vif.pwr_rst_req.rstreqs[pwrmgr_reg_pkg::ResetMainPwrIdx], - cfg.pwrmgr_vif.sw_rst_req_i == prim_mubi_pkg::MuBi4True, - sleep - ), UVM_MEDIUM) - endtask - - task reset_coverage_collector(); - fork - forever - @(posedge cfg.pwrmgr_vif.pwr_rst_req.reset_cause == pwrmgr_pkg::HwReq) begin - if (cfg.en_cov) begin - sample_reset_coverage(.sleep(1'b0)); - end - end - forever - @(posedge cfg.pwrmgr_vif.slow_state == pwrmgr_pkg::SlowPwrStateLowPower) begin - if (cfg.en_cov) begin - sample_reset_coverage(.sleep(1'b1)); - end - end - join_none - endtask - - task rom_coverage_collector(); - forever - @(cfg.pwrmgr_vif.rom_ctrl or cfg.pwrmgr_vif.lc_hw_debug_en or cfg.pwrmgr_vif.lc_dft_en) begin - if (cfg.en_cov) begin - cov.rom_active_blockers_cg.sample(cfg.pwrmgr_vif.rom_ctrl.done, - cfg.pwrmgr_vif.rom_ctrl.good, cfg.pwrmgr_vif.lc_dft_en, - cfg.pwrmgr_vif.lc_hw_debug_en); - end - end - endtask - - virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name); - uvm_reg csr; - bit do_read_check = ~(cfg.disable_csr_rd_chk); - bit skip_intr_chk = cfg.invalid_st_test; - bit write = item.is_write(); - uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr); - - bit addr_phase_read = (!write && channel == AddrChannel); - bit addr_phase_write = (write && channel == AddrChannel); - bit data_phase_read = (!write && channel == DataChannel); - bit data_phase_write = (write && channel == DataChannel); - - // if access was to a valid csr, get the csr handle - if (csr_addr inside {cfg.ral_models[ral_name].csr_addrs}) begin - csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr); - `DV_CHECK_NE_FATAL(csr, null) - end else begin - `uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr)) - end - - // if incoming access is a write to a valid csr, then make updates right away - if (addr_phase_write) begin - `uvm_info(`gfn, $sformatf("Writing 0x%x to %s", item.a_data, csr.get_full_name()), UVM_MEDIUM) - void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask))); - end - - // process the csr req - // for write, update local variable and fifo at address phase - // for read, update predication at address phase and compare at data phase - case (csr.get_name()) - // add individual case item for each csr - "intr_state": begin - if (skip_intr_chk) return; - if (data_phase_write) begin - exp_intr &= ~item.a_data; - end else if (data_phase_read) begin - bit [TL_DW-1:0] intr_en = ral.intr_enable.get_mirrored_value(); - foreach (exp_intr[i]) begin - if (cfg.en_cov) begin - cov.intr_cg.sample(i, intr_en[i], exp_intr[i]); - cov.intr_pins_cg.sample(i, cfg.intr_vif.pins[i]); - end - `DV_CHECK_EQ(item.d_data[i], exp_intr[i], $sformatf("Interrupt bit %0d", i)); - `DV_CHECK_CASE_EQ(cfg.intr_vif.pins[i], (intr_en[i] & exp_intr[i]), $sformatf( - "Interrupt_pin bit %0d", i)); - end - end - // rw1c: write 1 clears, write 0 is no-op. - do_read_check = 1'b0; - end - "intr_enable", "alert_test": begin - // Do nothing - end - "intr_test": begin - if (data_phase_write) begin - bit [TL_DW-1:0] intr_en = ral.intr_enable.get_mirrored_value(); - exp_intr |= item.a_data; - if (cfg.en_cov) begin - foreach (exp_intr[i]) begin - cov.intr_test_cg.sample(i, item.a_data[i], intr_en[i], exp_intr[i]); - end - end - end - // Write-only, so it can't be read. - do_read_check = 1'b0; - end - "ctrl_cfg_regwen": begin - // Read-only. Hardware clears this bit when going to low power mode, - // and sets it in active mode. - do_read_check = 1'b0; - end - "control": begin - // Only some bits can be checked on reads. Bit 0 is cleared by hardware - // on low power transition or when registering a valid reset. - if (data_phase_write) begin - low_power_hint = get_field_val(ral.control.low_power_hint, item.a_data); - control_enables = '{ - core_clk_en: get_field_val(ral.control.core_clk_en, item.a_data), - io_clk_en: get_field_val(ral.control.io_clk_en, item.a_data), - usb_clk_en_lp: get_field_val(ral.control.usb_clk_en_lp, item.a_data), - usb_clk_en_active: get_field_val(ral.control.usb_clk_en_active, item.a_data), - main_pd_n: get_field_val(ral.control.main_pd_n, item.a_data) - }; - `uvm_info(`gfn, $sformatf("Writing low power hint=%b", low_power_hint), UVM_MEDIUM) - `uvm_info(`gfn, $sformatf("Writing control_enables=%p", control_enables), UVM_MEDIUM) - if (cfg.en_cov) begin - // At this point the processor is not asleep. - cov.control_cg.sample(control_enables, 1'b0); - end - end - end - "cfg_cdc_sync": begin - // rw1c: When written to 1 this bit self-clears when the slow clock domain - // syncs. - do_read_check = 1'b0; - end - "wakeup_en_regwen": begin - end - "wakeup_en": begin - end - "wake_status": begin - // Read-only. - do_read_check = 1'b0; - end - "reset_en_regwen": begin - // rw0c, so writing a 1 is a no-op. - end - "reset_en": begin - if (data_phase_write) begin - cfg.pwrmgr_vif.update_reset_en(item.a_data); - end - end - "reset_status": begin - // Read-only. - do_read_check = 1'b0; - end - "escalate_reset_status": begin - // Read-only. - do_read_check = 1'b0; - end - "wake_info_capture_dis": begin - end - "wake_info": begin - // rw1c: write 1 clears, write 0 is no-op. - do_read_check = 1'b0; - end - default: begin - `uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name())) - end - endcase - - // On reads, if do_read_check, is set, then check mirrored_value against item.d_data - if (data_phase_read) begin - `uvm_info(`gfn, $sformatf("Reading 0x%x from %s", item.d_data, csr.get_full_name()), UVM_LOW) - if (do_read_check) begin - `DV_CHECK_EQ(csr.get_mirrored_value(), item.d_data, $sformatf( - "reg name: %0s", csr.get_full_name())) - end - void'(csr.predict(.value(item.d_data), .kind(UVM_PREDICT_READ))); - end - endtask - - virtual function void reset(string kind = "HARD"); - super.reset(kind); - // reset local fifos queues and variables - endfunction - - function void check_phase(uvm_phase phase); - super.check_phase(phase); - // post test checks - ensure that all local fifos and queues are empty - endfunction - -endclass diff --git a/hw/ip/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv b/hw/ip/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv deleted file mode 100644 index 70b34c98ff3d3e..00000000000000 --- a/hw/ip/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class pwrmgr_virtual_sequencer extends cip_base_virtual_sequencer #( - .CFG_T(pwrmgr_env_cfg), - .COV_T(pwrmgr_env_cov) -); - `uvm_component_utils(pwrmgr_virtual_sequencer) - - - `uvm_component_new - -endclass diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv deleted file mode 100644 index df82f2424e8e60..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// The aborted low power test causes low power transitions to abort for CPU interrupts and nvms not -// idle. It randomly enables wakeups, info capture, and interrupts, and sends wakeups at random -// times, and causes a test failure if they are not aborted. -class pwrmgr_aborted_low_power_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_aborted_low_power_vseq) - - `uvm_object_new - - // If set causes an abort because the CPU gets an interrupt, which shows up as - // pwr_cpu.core_sleeping being low when the fast FSM is in FastPwrStateFallThrough. - rand bit cpu_interrupt; - - constraint cpu_interrupt_c { - cpu_interrupt dist { - 1 := 2, - 0 := 6 - }; - } - - rand bit flash_idle; - rand bit lc_idle; - rand bit otp_idle; - - constraint idle_c { - solve cpu_interrupt before flash_idle, lc_idle, otp_idle; - if (!cpu_interrupt) {(flash_idle && lc_idle && otp_idle) == 1'b0;} - } - - constraint wakeups_c {wakeups != 0;} - - constraint wakeup_en_c { - solve wakeups before wakeups_en; - |(wakeups_en & wakeups) == 1'b1; - } - - // Make sure wakeup capture is enabled to check the abort happened. - constraint enable_wakeup_capture_c {disable_wakeup_capture == 1'b0;} - - task body(); - logic [TL_DW-1:0] value; - wakeups_t enabled_wakeups; - wait_for_fast_fsm_active(); - - check_wake_status('0); - set_nvms_idle(); - for (int i = 0; i < num_trans; ++i) begin - `uvm_info(`gfn, "Starting new round", UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - // Enable wakeups. - enabled_wakeups = wakeups_en & wakeups; - `DV_CHECK(enabled_wakeups, $sformatf( - "Some wakeup must be enabled: wkups=%b, wkup_en=%b", wakeups, wakeups_en)) - `uvm_info(`gfn, $sformatf( - "Enabled wakeups=0x%x (wkups=%x wkup_en=%x)", enabled_wakeups, wakeups, wakeups_en - ), UVM_MEDIUM) - csr_wr(.ptr(ral.wakeup_en[0]), .value(wakeups_en)); - `uvm_info(`gfn, $sformatf("%0sabling wakeup capture", disable_wakeup_capture ? "Dis" : "En"), - UVM_MEDIUM) - csr_wr(.ptr(ral.wake_info_capture_dis), .value(disable_wakeup_capture)); - low_power_hint = 1'b1; - - // Put CPU to sleep even before the control registers are fully written to avoid - // unexpected failures to abort due to delicate timing. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); - - fork - begin - update_control_csr(); - `uvm_info(`gfn, $sformatf("After update_control_csr exp_intr=%b", exp_intr), UVM_MEDIUM) - end - begin - // Prepare for an abort ahead of time. - `DV_WAIT(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive) - // Wait one more cycle for update_control_csr called above to predict the interrupt - // based on the value of cpu_sleeping right after the transition out of active state. - // There is enough time for this since it takes time to disable the clocks. - cfg.clk_rst_vif.wait_clks(1); - if (cpu_interrupt) begin - `uvm_info(`gfn, "Expecting a fall through (0x40)", UVM_MEDIUM) - cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); - end else begin - `uvm_info(`gfn, $sformatf( - "Expecting an abort (0x80): fi=%b, li=%b, oi=%b", - flash_idle, - lc_idle, - otp_idle - ), UVM_MEDIUM) - set_nvms_idle(flash_idle, lc_idle, otp_idle); - end - end - join - wait_for_fast_fsm_active(); - - `uvm_info(`gfn, "Back from sleep attempt", UVM_MEDIUM) - @cfg.clk_rst_vif.cb; - - // No wakeups, but check abort and fall_through. - fork - begin - fast_check_reset_status(0); - end - begin - fast_check_wake_info(.reasons('0), .fall_through(cpu_interrupt), .abort(~cpu_interrupt)); - end - join - - clear_wake_info(); - - // And check interrupt is set. - check_and_clear_interrupt(.expected(1'b1)); - - // Get ready for another round. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); - set_nvms_idle(); - end - `uvm_info(`gfn, "Test done", UVM_MEDIUM) - endtask - -endclass : pwrmgr_aborted_low_power_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv deleted file mode 100644 index 79702d98056f65..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv +++ /dev/null @@ -1,809 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class pwrmgr_base_vseq extends cip_base_vseq #( - .RAL_T (pwrmgr_reg_block), - .CFG_T (pwrmgr_env_cfg), - .COV_T (pwrmgr_env_cov), - .VIRTUAL_SEQUENCER_T(pwrmgr_virtual_sequencer) -); - `uvm_object_utils(pwrmgr_base_vseq) - - `uvm_object_new - - localparam int ActiveTimeoutInNanoSeconds = 10_000; - localparam int PropagationToSlowTimeoutInNanoSeconds = 15_000; - localparam int FetchEnTimeoutNs = 40_000; - - localparam int MaxCyclesBeforeEnable = 12; - - // Random wakeups and resets. - rand wakeups_t wakeups; - rand wakeups_t wakeups_en; - rand resets_t resets; - rand resets_t resets_en; - rand bit power_glitch_reset; - rand bit escalation_reset; - rand bit ndm_reset; - - rand bit en_intr; - - constraint resets_en_c { - solve resets, power_glitch_reset, escalation_reset, ndm_reset before resets_en; - |{resets_en & resets, power_glitch_reset, escalation_reset, ndm_reset} == 1'b1; - } - - rand bit disable_wakeup_capture; - - // Random control enables. - rand control_enables_t control_enables; - - // Random delays. - rand int cycles_before_clks_ok; - rand int cycles_between_clks_ok; - rand int cycles_before_io_status; - rand int cycles_before_main_status; - rand int cycles_before_usb_status; - rand int cycles_before_rst_lc_src; - rand int cycles_before_rst_sys_src; - rand int cycles_before_otp_done; - rand int cycles_before_lc_done; - rand int cycles_before_wakeup; - rand int cycles_before_reset; - - // Slow responder delays. - rand int cycles_before_core_clk_en; - rand int cycles_before_io_clk_en; - rand int cycles_before_usb_clk_en; - rand int cycles_before_main_pok; - - // This tracks the local objection count from these responders. We do not use UVM - // objections because uvm_objection::wait_for(UVM_ALL_DROPPED, this) seems to wait - // for all objections to be dropped, not just those raised by this. - local int fast_objection_count = 0; - local int slow_objection_count = 0; - - constraint cycles_before_clks_ok_c {cycles_before_clks_ok inside {[3 : 10]};} - constraint cycles_between_clks_ok_c {cycles_between_clks_ok inside {[3 : 10]};} - constraint cycles_before_io_status_c {cycles_before_io_status inside {[0 : 4]};} - constraint cycles_before_main_status_c {cycles_before_main_status inside {[0 : 4]};} - constraint cycles_before_usb_status_c {cycles_before_usb_status inside {[0 : 4]};} - constraint cycles_before_rst_lc_src_base_c {cycles_before_rst_lc_src inside {[0 : 4]};} - constraint cycles_before_rst_sys_src_base_c {cycles_before_rst_sys_src inside {[0 : 4]};} - constraint cycles_before_otp_done_base_c {cycles_before_otp_done inside {[0 : 4]};} - constraint cycles_before_lc_done_base_c {cycles_before_lc_done inside {[0 : 4]};} - constraint cycles_before_wakeup_c {cycles_before_wakeup inside {[2 : 6]};} - constraint cycles_before_reset_c {cycles_before_reset inside {[2 : 6]};} - constraint cycles_before_core_clk_en_c { - cycles_before_core_clk_en inside {[1 : MaxCyclesBeforeEnable]}; - } - constraint cycles_before_io_clk_en_c { - cycles_before_io_clk_en inside {[1 : MaxCyclesBeforeEnable - 2]}; - } - constraint cycles_before_usb_clk_en_c { - cycles_before_usb_clk_en inside {[1 : MaxCyclesBeforeEnable]}; - } - constraint cycles_before_main_pok_c {cycles_before_main_pok inside {[2 : MaxCyclesBeforeEnable]};} - - // This is used to trigger a software reset, as per rstmgr's `reset_req` CSR. - prim_mubi_pkg::mubi4_t sw_rst_from_rstmgr = prim_mubi_pkg::MuBi4False; - - bit do_pwrmgr_init = 1'b1; - // This static variable is incremented in each pre_start and decremented in each post_start. - // It is used to start and stop the responders when the parent sequence starts and ends. - local static int sequence_depth = 0; - pwrmgr_mubi_e mubi_mode; - - // This stops randomizing cycles counts that select from a pipeline, since - // changes can lead to missing or unexpected transitions. - task stop_randomizing_cycles(); - cycles_before_core_clk_en.rand_mode(0); - cycles_before_io_clk_en.rand_mode(0); - cycles_before_usb_clk_en.rand_mode(0); - cycles_before_main_pok.rand_mode(0); - endtask - - // Disable exclusions for CONTROL.USB_CLK_EN_ACTIVE and RESET_EN: they are meant for full-chip only. - function void disable_unnecessary_exclusions(); - csr_excl_item csr_excl = ral.get_excl_item(); - `uvm_info(`gfn, "Dealing with exclusions", UVM_MEDIUM) - csr_excl.enable_excl(.obj("pwrmgr_reg_block.control"), .enable(1'b0)); - csr_excl.enable_excl(.obj("pwrmgr_reg_block.reset_en"), .enable(1'b0)); - csr_excl.print_exclusions(UVM_MEDIUM); - endfunction - - virtual task pre_start(); - cfg.pwrmgr_vif.lc_hw_debug_en = lc_ctrl_pkg::Off; - cfg.pwrmgr_vif.lc_dft_en = lc_ctrl_pkg::Off; - mubi_mode = PwrmgrMubiNone; - `DV_GET_ENUM_PLUSARG(pwrmgr_mubi_e, mubi_mode, pwrmgr_mubi_mode) - `uvm_info(`gfn, $sformatf("pwrmgr mubi mode : %s", mubi_mode.name()), UVM_MEDIUM) - - if (do_pwrmgr_init) pwrmgr_init(); - disable_unnecessary_exclusions(); - cfg.slow_clk_rst_vif.wait_for_reset(.wait_negedge(0)); - stop_randomizing_cycles(); - fork - // Deactivate rst_main_n to make sure the slow fsm won't be confused into thinking - // a power glitch occurred, and wait some cycles so testing doesn't start until any - // side-effects are cleared. This confusion can arise if a sequence with random resets - // gets reset while sending a power glitch. - begin - cfg.pwrmgr_vif.rst_main_n = 1'b1; - cfg.slow_clk_rst_vif.wait_clks(7); - end - begin - if (sequence_depth == 0) begin - `uvm_info(`gfn, "Starting responders", UVM_MEDIUM) - slow_responder(); - fast_responder(); - end - ++sequence_depth; - super.pre_start(); - end - join - endtask : pre_start - - task post_apply_reset(string reset_kind = "HARD"); - super.post_apply_reset(reset_kind); - if (reset_kind == "HARD") begin - // Undo any pending resets. - cfg.pwrmgr_vif.rst_main_n = 1'b1; - cfg.pwrmgr_vif.update_resets(0); - end - - `uvm_info(`gfn, "waiting for fast active after applying reset", UVM_MEDIUM) - - // There is tb lock up case - // when reset come while rom_ctrl = {false, false}. - // So we need rom_ctrl driver runs in parallel with - // wait_for_fast_fsm_active - fork - wait_for_fast_fsm_active(); - init_rom_response(); - join - // And drive the cpu not sleeping. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); - endtask - - task post_start(); - super.post_start(); - --sequence_depth; - if (sequence_depth == 0) begin - `uvm_info(`gfn, $sformatf( - "Waiting for all objections done with fast=%0d, slow=%0d", - fast_objection_count, - slow_objection_count - ), UVM_MEDIUM) - `DV_WAIT(fast_objection_count == 0 && slow_objection_count == 0) - `uvm_info(`gfn, "all local objections are done", UVM_LOW) - control_assertions(0); - `uvm_info(`gfn, "Stopping responders", UVM_MEDIUM) - disable slow_responder; - disable fast_responder; - end - endtask - - virtual task dut_init(string reset_kind = "HARD"); - super.dut_init(); - endtask - - virtual task dut_shutdown(); - // There are no known checks to perform here. - endtask - - virtual task apply_reset(string kind = "HARD"); - `uvm_info(`gfn, $sformatf("At apply_reset kind='%0s'", kind), UVM_MEDIUM) - fork - super.apply_reset(kind); - if (kind == "HARD") begin - // A short slow clock reset should suffice. - cfg.slow_clk_rst_vif.apply_reset(.pre_reset_dly_clks(0), .reset_width_clks(5)); - end - cfg.esc_clk_rst_vif.apply_reset(); - cfg.lc_clk_rst_vif.apply_reset(); - // Escalation resets are cleared when reset goes active. - clear_escalation_reset(); - clear_ndm_reset(); - join - // And wait until the responders settle with all okay from the AST. - `DV_WAIT( - cfg.pwrmgr_vif.pwr_ast_rsp.main_pok && - cfg.pwrmgr_vif.pwr_ast_rsp.core_clk_val && - cfg.pwrmgr_vif.pwr_ast_rsp.io_clk_val) - `uvm_info(`gfn, $sformatf("Out of apply_reset kind='%0s'", kind), UVM_MEDIUM) - endtask - - virtual task apply_resets_concurrently(int reset_duration_ps = 0); - cfg.slow_clk_rst_vif.drive_rst_pin(0); - cfg.esc_clk_rst_vif.drive_rst_pin(0); - cfg.lc_clk_rst_vif.drive_rst_pin(0); - super.apply_resets_concurrently(cfg.slow_clk_rst_vif.clk_period_ps); - cfg.esc_clk_rst_vif.drive_rst_pin(1); - cfg.lc_clk_rst_vif.drive_rst_pin(1); - cfg.slow_clk_rst_vif.drive_rst_pin(1); - endtask - - // setup basic pwrmgr features - virtual task pwrmgr_init(); - // The fast clock frequency is set by ral. - // The real slow clock rate is 200kHz, but that slows testing down. - // Increasing its frequency improves DV efficiency without compromising quality. - cfg.slow_clk_rst_vif.set_freq_mhz(7); - `uvm_info(`gfn, $sformatf( - "slow clock freq=%fMHz, period=%0dns", - cfg.slow_clk_rst_vif.clk_freq_mhz, - cfg.slow_clk_rst_vif.clk_period_ps - ), UVM_MEDIUM) - cfg.esc_clk_rst_vif.set_freq_mhz(cfg.clk_rst_vif.clk_freq_mhz); - cfg.lc_clk_rst_vif.set_freq_mhz(cfg.clk_rst_vif.clk_freq_mhz); - set_ndmreset_req('0); - control_assertions(0); - endtask - - virtual task setup_interrupt(bit enable); - csr_wr(.ptr(ral.intr_enable.wakeup), .value(enable)); - `uvm_info(`gfn, $sformatf("Wakeup interrupt is %0sabled", enable ? "en" : "dis"), UVM_MEDIUM) - endtask - - // May check intr_state.wakeup CSR against expected, and regardless, it checks that the - // interrupt output matches intr_state && intr_enable. The first check is disabled if - // check_expected is off, which is used when a reset and an interrupt come in close - // temporal proximity. - virtual task check_and_clear_interrupt(bit expected, bit check_expected = 1'b1); - bit enable; - `uvm_info(`gfn, "Checking and clearing interrupt", UVM_MEDIUM) - if (check_expected) begin - csr_rd_check(.ptr(ral.intr_state.wakeup), .compare_value(expected), - .err_msg("interrupt mismatch")); - end else begin - csr_rd(.ptr(ral.intr_state.wakeup), .value(expected)); - end - csr_rd(.ptr(ral.intr_enable.wakeup), .value(enable)); - `DV_CHECK_EQ(cfg.pwrmgr_vif.intr_wakeup, expected && enable) - csr_wr(.ptr(ral.intr_state.wakeup), .value(1'b1)); - endtask - - local function void raise_fast_objection(string label); - ++fast_objection_count; - `uvm_info(`gfn, $sformatf("Raising fast objection to %0d for %0s", fast_objection_count, label), - UVM_HIGH) - endfunction - - local function void drop_fast_objection(string label); - --fast_objection_count; - `uvm_info(`gfn, $sformatf("Dropping fast objection to %0d for %0s", fast_objection_count, label - ), UVM_HIGH) - endfunction - - local function void raise_slow_objection(string label); - ++slow_objection_count; - `uvm_info(`gfn, $sformatf("Raising slow objection to %0d for %0s", slow_objection_count, label), - UVM_MEDIUM) - endfunction - - local function void drop_slow_objection(string label); - --slow_objection_count; - `uvm_info(`gfn, $sformatf("Dropping slow objection to %0d for %0s", slow_objection_count, label - ), UVM_MEDIUM) - endfunction - - virtual function void set_ndmreset_req(logic value); - cfg.pwrmgr_vif.cpu_i.ndmreset_req = value; - endfunction - - // Generates expected responses for the slow fsm. - // - Completes the clock handshake with the ast: when a clk_en output changes, after a few - // cycles the ast is expected to set the corresponding clk_val input to the same value. - // - It is possible changes occur in fast succession, so the side-effect is pipelined. - // Uses macros because VCS flags an error for assignments to automatic variables, - // even if the variable is a ref to an interface variable. - - `define SLOW_DETECT(rsp_name_, req_) \ - forever \ - @req_ begin \ - raise_slow_objection(rsp_name_); \ - `uvm_info(`gfn, $sformatf( \ - "slow_responder: Will drive %0s to %b", rsp_name_, req_), UVM_MEDIUM) \ - end - - `define SLOW_SHIFT_SR(req_, rsp_sr_) \ - forever \ - @cfg.slow_clk_rst_vif.cb begin \ - rsp_sr_ = {rsp_sr_[MaxCyclesBeforeEnable-1:0], req_}; \ - end - - `define SLOW_ASSIGN(rsp_name_, cycles_, rsp_sr_, rsp_) \ - forever \ - @(rsp_sr_[cycles_]) begin \ - `uvm_info(`gfn, $sformatf( \ - "slow_responder: Driving %0s to %b after %0d AON cycles.", \ - rsp_name_, \ - rsp_sr_[cycles_], \ - cycles_ \ - ), UVM_MEDIUM) \ - rsp_ <= rsp_sr_[cycles_]; \ - drop_slow_objection(rsp_name_); \ - end - - task slow_responder(); - logic [MaxCyclesBeforeEnable:0] core_clk_val_sr; - logic [MaxCyclesBeforeEnable:0] io_clk_val_sr; - logic [MaxCyclesBeforeEnable:0] usb_clk_val_sr; - logic [MaxCyclesBeforeEnable:0] main_pd_val_sr; - fork - `SLOW_DETECT("core_clk_val", cfg.pwrmgr_vif.slow_cb.pwr_ast_req.core_clk_en) - `SLOW_SHIFT_SR(cfg.pwrmgr_vif.slow_cb.pwr_ast_req.core_clk_en, core_clk_val_sr) - `SLOW_ASSIGN("core_clk_val", cycles_before_core_clk_en, core_clk_val_sr, - cfg.pwrmgr_vif.slow_cb.pwr_ast_rsp.core_clk_val) - - `SLOW_DETECT("io_clk_val", cfg.pwrmgr_vif.slow_cb.pwr_ast_req.io_clk_en) - `SLOW_SHIFT_SR(cfg.pwrmgr_vif.slow_cb.pwr_ast_req.io_clk_en, io_clk_val_sr) - // Notice this splits updates due to io_clk_en in two processes: with a single process - // and a wait inside a quick sequence of changes would cause skipping some update, per - // SV scheduling semantics. - forever - @(io_clk_val_sr[cycles_before_io_clk_en]) begin - logic new_value = io_clk_val_sr[cycles_before_io_clk_en]; - `uvm_info(`gfn, $sformatf( - "slow_responder: Driving %0s to %b after %0d AON cycles.", - "io_clk_val", - new_value, - cycles_before_io_clk_en - ), UVM_MEDIUM) - if (new_value == 1) begin - cfg.clk_rst_vif.start_clk(); - cfg.lc_clk_rst_vif.start_clk(); - cfg.esc_clk_rst_vif.start_clk(); - end else begin - cfg.clk_rst_vif.stop_clk(); - cfg.lc_clk_rst_vif.stop_clk(); - cfg.esc_clk_rst_vif.stop_clk(); - end - end - forever - @(io_clk_val_sr[cycles_before_io_clk_en+2]) begin - logic new_value = io_clk_val_sr[cycles_before_io_clk_en+2]; - cfg.pwrmgr_vif.slow_cb.pwr_ast_rsp.io_clk_val <= new_value; - drop_slow_objection("io_clk_val"); - end - - `SLOW_DETECT("usb_clk_val", cfg.pwrmgr_vif.slow_cb.pwr_ast_req.usb_clk_en) - `SLOW_SHIFT_SR(cfg.pwrmgr_vif.slow_cb.pwr_ast_req.usb_clk_en, usb_clk_val_sr) - `SLOW_ASSIGN("usb_clk_val", cycles_before_usb_clk_en, usb_clk_val_sr, - cfg.pwrmgr_vif.slow_cb.pwr_ast_rsp.usb_clk_val) - - `SLOW_DETECT("main_pok", cfg.pwrmgr_vif.slow_cb.pwr_ast_req.main_pd_n) - `SLOW_SHIFT_SR(cfg.pwrmgr_vif.slow_cb.pwr_ast_req.main_pd_n, main_pd_val_sr) - `SLOW_ASSIGN("main_pok", cycles_before_main_pok, main_pd_val_sr, - cfg.pwrmgr_vif.slow_cb.pwr_ast_rsp.main_pok) - join_none - endtask : slow_responder - `undef SLOW_DETECT - `undef SLOW_SHIFT_SR - `undef SLOW_ASSIGN - - // Generates expected responses for the fast fsm. - // - Completes the reset handshake with the rstmgr for lc and sys resets: soon after a - // reset is requested the corresponding active low reset src must go low. - // - Completes the handshake with the clkmgr for io, main, and usb clocks: - // each status input needs to track the corresponding ip_clk_en output. - // - Completes handshake with lc and otp: *_done needs to track *_init. - // Macros for the same reason as the slow responder. - - `define FAST_RESPONSE_ACTION(rsp_name, rsp, req, cycles) \ - `uvm_info(`gfn, $sformatf( \ - "fast_responder %s: Will drive %0s to %b in %0d fast clock cycles", \ - rsp_name, rsp_name, req, cycles), UVM_HIGH) \ - cfg.clk_rst_vif.wait_clks(cycles); \ - rsp <= req; \ - `uvm_info(`gfn, $sformatf("fast_responder %s: Driving %0s to %b", rsp_name, rsp_name, req), UVM_HIGH) \ - - - task fast_responder(); - fork - forever - @cfg.pwrmgr_vif.fast_cb.pwr_rst_req.rst_lc_req begin - `uvm_info(`gfn, $sformatf( - "fast responder got rst_lc_req change to 0x%x", - cfg.pwrmgr_vif.fast_cb.pwr_rst_req.rst_lc_req - ), UVM_HIGH) - raise_fast_objection("rst_lc_src_n"); - `FAST_RESPONSE_ACTION("rst_lc_src_n", cfg.pwrmgr_vif.fast_cb.pwr_rst_rsp.rst_lc_src_n, - ~cfg.pwrmgr_vif.fast_cb.pwr_rst_req.rst_lc_req, - cycles_before_rst_lc_src) - if (cfg.pwrmgr_vif.fast_cb.pwr_rst_req.rst_lc_req[1] == 1'b0) begin - cfg.esc_clk_rst_vif.drive_rst_pin(1); - cfg.lc_clk_rst_vif.drive_rst_pin(1); - end else begin - // And clear all reset requests when rst_lc_req[1] goes high, because when - // peripherals are reset they should drop their reset requests. - cfg.esc_clk_rst_vif.drive_rst_pin(0); - cfg.lc_clk_rst_vif.drive_rst_pin(0); - clear_escalation_reset(); - clear_ndm_reset(); - cfg.pwrmgr_vif.update_resets('0); - cfg.pwrmgr_vif.update_sw_rst_req(prim_mubi_pkg::MuBi4False); - `uvm_info(`gfn, "Clearing resets", UVM_MEDIUM) - end - drop_fast_objection("rst_lc_src_n"); - `uvm_info(`gfn, "fast responder done with rst_lc_req change", UVM_HIGH) - end - forever - @cfg.pwrmgr_vif.fast_cb.pwr_rst_req.rst_sys_req begin - raise_fast_objection("rst_sys_src_n"); - `FAST_RESPONSE_ACTION("rst_sys_src_n", cfg.pwrmgr_vif.fast_cb.pwr_rst_rsp.rst_sys_src_n, - ~cfg.pwrmgr_vif.fast_cb.pwr_rst_req.rst_sys_req, - cycles_before_rst_sys_src) - drop_fast_objection("rst_sys_src_n"); - end - - forever - @cfg.pwrmgr_vif.fast_cb.pwr_clk_req.io_ip_clk_en begin - logic new_value = cfg.pwrmgr_vif.fast_cb.pwr_clk_req.io_ip_clk_en; - raise_fast_objection("io_status"); - `uvm_info(`gfn, $sformatf( - "fast_responder: Will drive %0s to %b in %0d fast clock cycles", - "io_status", - new_value, - cycles_before_io_status - ), UVM_HIGH) - cfg.clk_rst_vif.wait_clks(cycles_before_io_status); - if (new_value) cfg.esc_clk_rst_vif.start_clk(); - else cfg.esc_clk_rst_vif.stop_clk(); - cfg.clk_rst_vif.wait_clks(2); - cfg.pwrmgr_vif.fast_cb.pwr_clk_rsp.io_status <= new_value; - `uvm_info(`gfn, $sformatf( - "fast_responder: Driving %0s to %b", - "io_status", - cfg.pwrmgr_vif.fast_cb.pwr_clk_req.io_ip_clk_en - ), UVM_HIGH) - drop_fast_objection("io_status"); - end - - forever - @cfg.pwrmgr_vif.fast_cb.pwr_clk_req.main_ip_clk_en begin - raise_fast_objection("main_status"); - `FAST_RESPONSE_ACTION("main_status", cfg.pwrmgr_vif.fast_cb.pwr_clk_rsp.main_status, - cfg.pwrmgr_vif.fast_cb.pwr_clk_req.main_ip_clk_en, - cycles_before_main_status) - drop_fast_objection("main_status"); - end - forever - @cfg.pwrmgr_vif.fast_cb.pwr_clk_req.usb_ip_clk_en begin - raise_fast_objection("usb_status"); - `FAST_RESPONSE_ACTION("usb_status", cfg.pwrmgr_vif.fast_cb.pwr_clk_rsp.usb_status, - cfg.pwrmgr_vif.fast_cb.pwr_clk_req.usb_ip_clk_en, - cycles_before_usb_status) - drop_fast_objection("usb_status"); - end - forever - @cfg.pwrmgr_vif.fast_cb.pwr_lc_req.lc_init begin - raise_fast_objection("lc_done"); - `FAST_RESPONSE_ACTION("lc_done", cfg.pwrmgr_vif.fast_cb.pwr_lc_rsp.lc_done, - cfg.pwrmgr_vif.fast_cb.pwr_lc_req.lc_init, cycles_before_lc_done) - drop_fast_objection("lc_done"); - end - forever - @cfg.pwrmgr_vif.fast_cb.pwr_otp_req.otp_init begin - raise_fast_objection("otp_done"); - `FAST_RESPONSE_ACTION("otp_done", cfg.pwrmgr_vif.fast_cb.pwr_otp_rsp.otp_done, - cfg.pwrmgr_vif.fast_cb.pwr_otp_req.otp_init, cycles_before_otp_done) - drop_fast_objection("otp_done"); - end - join_none - endtask : fast_responder - `undef FAST_RESPONSE_ACTION - - function void control_assertions(bit enable); - `uvm_info(`gfn, $sformatf("%0sabling assertions", enable ? "En" : "Dis"), UVM_MEDIUM) - cfg.pwrmgr_clock_enables_sva_vif.disable_sva = !enable; - cfg.pwrmgr_rstmgr_sva_vif.disable_sva = !enable; - endfunction - - local task wait_for_fall_through(); - `DV_WAIT(!cfg.pwrmgr_vif.pwr_cpu.core_sleeping) - exp_intr = 1'b1; - `uvm_info(`gfn, "wait_for_fall_through succeeds", UVM_MEDIUM) - endtask - - local task wait_for_abort(); - `DV_WAIT( - !cfg.pwrmgr_vif.pwr_flash.flash_idle || !cfg.pwrmgr_vif.pwr_otp_rsp.otp_idle || - !cfg.pwrmgr_vif.pwr_lc_rsp.lc_idle) - exp_intr = 1'b1; - `uvm_info(`gfn, "wait_for_abort succeeds", UVM_MEDIUM) - endtask - - local task wait_for_low_power_transition(); - wait_for_reset_cause(pwrmgr_pkg::LowPwrEntry); - exp_wakeup_reasons = wakeups & wakeups_en; - exp_intr = 1'b1; - `uvm_info(`gfn, "Setting expected interrupt", UVM_MEDIUM) - endtask - - task process_low_power_hint(); - `uvm_info(`gfn, "Entering process_low_power_hint", UVM_MEDIUM) - // Timeout if the low power transition waits too long for WFI. - `DV_WAIT(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive) - `uvm_info(`gfn, "In process_low_power_hint pre forks", UVM_MEDIUM) - // Clear expectations. - exp_wakeup_reasons = 1'b0; - fork - begin : isolation_fork - fork - wait_for_fall_through(); - wait_for_abort(); - wait_for_low_power_transition(); - join_any - disable fork; - end - join - // At this point we know the low power transition went through or was aborted. - // If it went through, determine if the transition to active state is for a reset, and - // cancel the expected interrupt. - if (exp_wakeup_reasons) begin - `DV_WAIT(cfg.pwrmgr_vif.slow_state == pwrmgr_pkg::SlowPwrStateMainPowerOn) - if (cfg.pwrmgr_vif.pwrup_cause == pwrmgr_pkg::Reset) begin - `uvm_info(`gfn, "Cancelling expected interrupt", UVM_MEDIUM) - exp_intr = 1'b0; - end - end - endtask - - // Updates control CSR. - task update_control_csr(); - fork - begin - ral.control.core_clk_en.set(control_enables.core_clk_en); - ral.control.io_clk_en.set(control_enables.io_clk_en); - ral.control.usb_clk_en_lp.set(control_enables.usb_clk_en_lp); - ral.control.usb_clk_en_active.set(control_enables.usb_clk_en_active); - ral.control.main_pd_n.set(control_enables.main_pd_n); - ral.control.low_power_hint.set(low_power_hint); - // Disable assertions when main power is down. - control_assertions(control_enables.main_pd_n); - `uvm_info(`gfn, $sformatf( - "Setting control CSR to 0x%x, enables=%p, low_power_hint=%b", - ral.control.get(), - control_enables, - low_power_hint - ), UVM_MEDIUM) - csr_update(.csr(ral.control)); - end - // Predict the effect of the potential low power transition. - if (low_power_hint) process_low_power_hint(); - join_any - endtask : update_control_csr - - // This enables the fast fsm to transition to low power when all nvms are idle after the - // transition is enabled by software and cpu WFI. When not all are idle the transition is - // aborted. - virtual task set_nvms_idle(logic flash_idle = 1'b1, logic lc_idle = 1'b1, logic otp_idle = 1'b1); - `uvm_info(`gfn, $sformatf( - "Setting nvms idle: flash=%b, lc=%b, otp=%b", flash_idle, lc_idle, otp_idle), - UVM_MEDIUM) - cfg.pwrmgr_vif.update_flash_idle(flash_idle); - cfg.pwrmgr_vif.update_lc_idle(lc_idle); - cfg.pwrmgr_vif.update_otp_idle(otp_idle); - endtask - - // Waits for the fast fsm becoming active after SW initiated low power, indicated by the - // fetch_en output going high. - task wait_for_fast_fsm_active(); - `uvm_info(`gfn, "starting wait for pwrmgr fast fsm active", UVM_MEDIUM) - `DV_SPINWAIT(wait (cfg.pwrmgr_vif.fetch_en == lc_ctrl_pkg::On);, - "timeout waiting for the CPU to be active", FetchEnTimeoutNs) - `uvm_info(`gfn, "pwrmgr fast fsm is active", UVM_MEDIUM) - endtask - - task wait_for_reset_cause(pwrmgr_pkg::reset_cause_e cause); - `DV_WAIT(cfg.pwrmgr_vif.pwr_rst_req.reset_cause == cause) - `uvm_info(`gfn, $sformatf("Observed reset cause_match 0x%x", cause), UVM_MEDIUM) - endtask - - virtual task wait_for_csr_to_propagate_to_slow_domain(); - csr_wr(.ptr(ral.cfg_cdc_sync), .value(1'b1)); - csr_spinwait(.ptr(ral.cfg_cdc_sync), .exp_data(1'b0), - .timeout_ns(PropagationToSlowTimeoutInNanoSeconds)); - `uvm_info(`gfn, "CSR updates made it to the slow domain", UVM_MEDIUM) - endtask - - // Checks the reset_status CSR matches expectations. - task check_reset_status(resets_t expected_resets); - csr_rd_check(.ptr(ral.reset_status[0]), .compare_value(expected_resets), - .err_msg("reset_status")); - endtask - - task fast_check_reset_status(resets_t expected_resets); - logic [pwrmgr_reg_pkg::NumRstReqs-1:0] init_reset_status; - `uvm_info(`gfn, "init reset status", UVM_MEDIUM); - // Wait to get out of low power state, since all reset status should have settled. - if (cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateLowPower) begin - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateLowPower);, - "fast state out of low power for reset timeout", 15_000) - end - - init_reset_status = cfg.pwrmgr_vif.reset_status; - if (expected_resets == init_reset_status) begin - // This is a success, so nothing more to do. - return; - end else begin - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.reset_status != init_reset_status);, $sformatf( - "reset_status wait timeout exp:%x init:%x", expected_resets, init_reset_status), - 15_000) - // The various bits of reset_status could have different sync delays, wait some more. - cfg.clk_rst_vif.wait_clks(2); - `DV_CHECK_EQ(cfg.pwrmgr_vif.reset_status, expected_resets) - end - endtask - - // Checks the wake_status CSR matches expectations. - task check_wake_status(wakeups_t expected_wakeups); - csr_rd_check(.ptr(ral.wake_status[0]), .compare_value(expected_wakeups), - .err_msg("wake_status")); - endtask - - task fast_check_wake_status(wakeups_t expected_wakeups); - logic [pwrmgr_reg_pkg::NumWkups-1:0] init_wakeup_status; - `uvm_info(`gfn, "init wakeup", UVM_MEDIUM); - init_wakeup_status = cfg.pwrmgr_vif.wakeup_status; - - // Wait to get out of low power state, since all wake status should have settled - if (cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateLowPower) begin - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateLowPower);, - "fast state out of low power for wakeup timeout", 15_000) - end - - if (expected_wakeups == init_wakeup_status) begin - // This is a success, so nothing more to do. - return; - end else begin - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.wakeup_status != init_wakeup_status);, $sformatf( - "wakeup_status wait timeout exp:%x init:%x", expected_wakeups, init_wakeup_status - ), 15_000) - // The various bits of wakeup_status could have different sync delays, so wait some more. - cfg.clk_rst_vif.wait_clks(2); - `DV_CHECK_EQ(cfg.pwrmgr_vif.wakeup_status, expected_wakeups) - end - endtask - - task fast_check_wake_info(wakeups_t reasons, wakeups_t prior_reasons = '0, bit fall_through, - bit prior_fall_through = '0, bit abort, bit prior_abort = '0); - pwrmgr_reg_pkg::pwrmgr_hw2reg_wake_info_reg_t initial_value, exp_value; - initial_value = cfg.pwrmgr_vif.wake_info; - - if (disable_wakeup_capture) begin - exp_value.reasons = prior_reasons; - exp_value.fall_through = prior_fall_through; - exp_value.abort = prior_abort; - end else begin - exp_value.reasons = (reasons | prior_reasons); - exp_value.fall_through = (fall_through | prior_fall_through); - exp_value.abort = (abort | prior_abort); - end - if (exp_value != initial_value) begin - // The various bits of wake_info could have different sync delays, so wait some more. - cfg.clk_rst_vif.wait_clks(1); - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.wake_info != initial_value);, $sformatf( - "wake info wait timeout exp:%p init:%p", exp_value, initial_value), 15_000) - end - endtask : fast_check_wake_info - - // Checks the wake_info CSR matches expectations depending on capture disable. - // The per-field "prior_" arguments support cases where the wake_info register was not - // cleared and may contain residual values. - task check_wake_info(wakeups_t reasons, wakeups_t prior_reasons = '0, bit fall_through, - bit prior_fall_through = '0, bit abort, bit prior_abort = '0); - if (disable_wakeup_capture) begin - csr_rd_check(.ptr(ral.wake_info.reasons), .compare_value(prior_reasons), - .err_msg("With capture disabled")); - csr_rd_check(.ptr(ral.wake_info.fall_through), .compare_value(prior_fall_through), - .err_msg("With capture disabled")); - csr_rd_check(.ptr(ral.wake_info.abort), .compare_value(prior_abort), - .err_msg("With capture disabled")); - end else begin - csr_rd_check(.ptr(ral.wake_info.reasons), .compare_value(reasons | prior_reasons), - .err_msg("With capture enabled")); - csr_rd_check(.ptr(ral.wake_info.fall_through), - .compare_value(fall_through | prior_fall_through), - .err_msg("With capture enabled")); - csr_rd_check(.ptr(ral.wake_info.abort), .compare_value(abort | prior_abort), - .err_msg("With capture enabled")); - end - endtask : check_wake_info - - task clear_wake_info(); - // To clear wake_info, capture must be disabled. - csr_wr(.ptr(ral.wake_info_capture_dis), .value(1'b1)); - csr_wr(.ptr(ral.wake_info), .value('1)); - endtask - - function void send_escalation_reset(); - `uvm_info(`gfn, "Sending escalation reset", UVM_MEDIUM) - cfg.m_esc_agent_cfg.vif.sender_cb.esc_tx_int <= 2'b10; - endfunction - - function void clear_escalation_reset(); - `uvm_info(`gfn, "Clearing escalation reset", UVM_MEDIUM) - cfg.m_esc_agent_cfg.vif.sender_cb.esc_tx_int <= 2'b01; - endfunction - - function void send_ndm_reset(); - `uvm_info(`gfn, "Sending ndm reset", UVM_MEDIUM) - cfg.pwrmgr_vif.cpu_i.ndmreset_req = 1'b1; - endfunction - - function void clear_ndm_reset(); - `uvm_info(`gfn, "Clearing ndm reset", UVM_MEDIUM) - cfg.pwrmgr_vif.cpu_i.ndmreset_req = 1'b0; - endfunction - - task send_power_glitch(); - // Create glitch by 'glitch_power_reset'. An outgoing alert is only possible - // when main power is up. - if (control_enables.main_pd_n) expect_fatal_alerts = 1; - else expect_fatal_alerts = 0; - `uvm_info(`gfn, $sformatf( - "Sending power glitch, expecting %0s alert", expect_fatal_alerts ? "an" : "no"), - UVM_MEDIUM) - cfg.pwrmgr_vif.glitch_power_reset(); - endtask - - // bad_bits = {done, good} - task add_rom_rsp_noise(); - bit [MUBI4W*2-1:0] bad_bits; - int delay; - - repeat (10) begin - delay = $urandom_range(5, 10); - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(bad_bits, - bad_bits[MUBI4W*2-1:MUBI4W] != prim_mubi_pkg::MuBi4True; - bad_bits[MUBI4W*2-1:MUBI4W] != prim_mubi_pkg::MuBi4False; - bad_bits[MUBI4W-1:0] != prim_mubi_pkg::MuBi4False; - bad_bits[MUBI4W-1:0] != prim_mubi_pkg::MuBi4True;) - `uvm_info(`gfn, $sformatf("add_rom_rsp_noise to 0x%x", bad_bits), UVM_HIGH) - cfg.pwrmgr_vif.rom_ctrl = bad_bits; - #(delay * 10ns); - end - endtask : add_rom_rsp_noise - - // Drive rom_ctrl at post reset stage - virtual task init_rom_response(); - if (cfg.pwrmgr_vif.rom_ctrl.done != prim_mubi_pkg::MuBi4True) begin - cfg.pwrmgr_vif.rom_ctrl.good = get_rand_mubi4_val( - .t_weight(1), .f_weight(1), .other_weight(1) - ); - cfg.pwrmgr_vif.rom_ctrl.done = get_rand_mubi4_val( - .t_weight(0), .f_weight(1), .other_weight(1) - ); - `DV_WAIT(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateRomCheckDone) - cfg.pwrmgr_vif.rom_ctrl.good = get_rand_mubi4_val( - .t_weight(1), .f_weight(1), .other_weight(1) - ); - cfg.pwrmgr_vif.rom_ctrl.done = get_rand_mubi4_val( - .t_weight(0), .f_weight(1), .other_weight(1) - ); - cfg.slow_clk_rst_vif.wait_clks(10); - cfg.pwrmgr_vif.rom_ctrl.good = get_rand_mubi4_val( - .t_weight(1), .f_weight(1), .other_weight(1) - ); - cfg.pwrmgr_vif.rom_ctrl.done = get_rand_mubi4_val( - .t_weight(0), .f_weight(1), .other_weight(1) - ); - cfg.slow_clk_rst_vif.wait_clks(5); - cfg.pwrmgr_vif.rom_ctrl.good = get_rand_mubi4_val( - .t_weight(1), .f_weight(1), .other_weight(1) - ); - cfg.pwrmgr_vif.rom_ctrl.done = get_rand_mubi4_val( - .t_weight(0), .f_weight(1), .other_weight(1) - ); - cfg.slow_clk_rst_vif.wait_clks(5); - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4True; - cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4True; - end - `uvm_info(`gfn, "Set rom response to MuBi4True", UVM_MEDIUM) - endtask - -endclass : pwrmgr_base_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv deleted file mode 100644 index 7347b8f195e6bc..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class pwrmgr_common_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_common_vseq) - - constraint num_trans_c {num_trans inside {[1 : 2]};} - `uvm_object_new - - parameter int STATE_TRANSITION_NS = 50000; - - virtual task pre_start(); - csr_excl_item csr_excl = ral.get_excl_item(); - super.pre_start(); - // In pwrmgr, random reset event can be regarded as power glitch in tb. - // Since glitch is marked as fatal and creates alert after PR#12072, - // exclude pwrmgr_reg_block.fault_status from the random reset tests - // to avoid spurious test failure. - if (common_seq_type inside {"csr_mem_rw_with_rand_reset", "stress_all_with_rand_reset"}) begin - csr_excl.add_excl("pwrmgr_reg_block.fault_status", CsrExclCheck); - expect_fatal_alerts = 1; - end - endtask - - virtual task body(); - run_common_vseq_wrapper(num_trans); - `uvm_info(`gfn, "Done with body", UVM_HIGH) - endtask : body - - task rand_reset_eor_clean_up(); - // clear wakeup at the beginning - cfg.pwrmgr_vif.update_wakeups('0); - cfg.clk_rst_vif.wait_clks(2); - - // clear interrupt - csr_wr(.ptr(ral.intr_state), .value(1)); - endtask : rand_reset_eor_clean_up - - // pwrmgr has three alert events - // REG_INTG_ERR, ESC_TIMEOUT and MAIN_PD_GLITCH - // all others will trigger only reset. - // So disable wait_alert by skipping super.check_sec_cm_fi_resp() - virtual task check_sec_cm_fi_resp(sec_cm_base_if_proxy if_proxy); - string slow_st_to, fast_st_to, msg; - // to avoid 100 column cut off - slow_st_to = { - "slow state local esc chk timeout:", - "fast_state %s, pwr_ast_req.pwr_clamp %0d, pwr_ast_req.main_pd_n %0d" - }; - fast_st_to = { - "fast state local esc chk timeout:", - "pwr_rst_req.rst_lc_req %0d, pwr_rst_req.rst_sys_req %0d, pwr_clk_req %0d" - }; - - `uvm_info(`gfn, $sformatf("sec_cm_type %s", if_proxy.sec_cm_type.name), UVM_MEDIUM) - - case (if_proxy.sec_cm_type) - SecCmPrimSparseFsmFlop: begin - // if slow state is unknown, - // wait for - // fast_state == FastPwrStateInvalid - // tb.dut.pwr_ast_o.pwr_clamp == 1 - // tb.dut.pwr_ast_o.main_pd_n == 0 - // - // if fast state is unknown, - // wait for - // tb.dut.pwr_rst_o.rst_lc_req == 2'b11 - // tb.dut.pwr_rst_o.rst_sys_req == 2'b11 - // tb.dut.pwr_clk_o == 3'b0 - if (!uvm_re_match("*.u_slow_fsm.*", if_proxy.path)) begin - `uvm_info(`gfn, "detect unknown slow state", UVM_MEDIUM) - msg = $sformatf( - slow_st_to, - cfg.pwrmgr_vif.fast_state.name, - cfg.pwrmgr_vif.pwr_ast_req.pwr_clamp, - cfg.pwrmgr_vif.pwr_ast_req.main_pd_n - ); - - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateInvalid && - cfg.pwrmgr_vif.pwr_ast_req.pwr_clamp == 1 && - cfg.pwrmgr_vif.pwr_ast_rsp.main_pok == 0);, msg, STATE_TRANSITION_NS) - end - if (!uvm_re_match("*.u_fsm.*", if_proxy.path)) begin - `uvm_info(`gfn, "detect unknown fast state", UVM_MEDIUM) - msg = $sformatf( - fast_st_to, - cfg.pwrmgr_vif.pwr_rst_req.rst_lc_req, - cfg.pwrmgr_vif.pwr_rst_req.rst_sys_req, - cfg.pwrmgr_vif.pwr_clk_req - ); - - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.pwr_rst_req.rst_lc_req == 2'b11 && - cfg.pwrmgr_vif.pwr_rst_req.rst_sys_req == 2'b11 && - cfg.pwrmgr_vif.pwr_clk_req == 3'h0);, msg, 5000) - end - end - SecCmPrimCount: begin - // wait for fast state to be FastPwrStateResetPrep - // before assert reset - `uvm_info(`gfn, "check rx_clk local esc", UVM_MEDIUM) - msg = $sformatf( - "rx clk loc esc chk timeout : fast_state %s", cfg.pwrmgr_vif.fast_state.name - ); - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateResetPrep);, msg, - STATE_TRANSITION_NS) - end - default: `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name)) - endcase // case (if_proxy.sec_cm_type) - // This makes sure errors are not injected too close together to avoid confusion. - cfg.slow_clk_rst_vif.wait_clks(10); - endtask : check_sec_cm_fi_resp -endclass diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv deleted file mode 100644 index f25046d2e8f3a2..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Test multiple resets with setting lc_* inputs with random value. -class pwrmgr_disable_rom_integrity_check_vseq extends pwrmgr_base_vseq; - - `uvm_object_utils(pwrmgr_disable_rom_integrity_check_vseq) - `uvm_object_new - - rand bit release_by_good; - - constraint wakeups_c {wakeups == 0;} - constraint wakeups_en_c {wakeups_en == 0;} - - function void post_randomize(); - sw_rst_from_rstmgr = get_rand_mubi4_val(.t_weight(8), .f_weight(4), .other_weight(4)); - super.post_randomize(); - endfunction - - local task detect_block(output bit blocked); - blocked = 1; - repeat (20) begin - @cfg.slow_clk_rst_vif.cb; - if (cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateActive) begin - blocked = 0; - break; - end - end - endtask - - task body(); - resets_t enabled_resets; - wait_for_fast_fsm_active(); - check_reset_status('0); - - for (int i = 0; i < 5; ++i) begin - `uvm_info(`gfn, $sformatf("Starting new round %0d", i), UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - - // set lc ctrl input to random value - cfg.pwrmgr_vif.lc_hw_debug_en = get_rand_lc_tx_val( - .t_weight(1), .f_weight(3), .other_weight(1) - ); - cfg.pwrmgr_vif.lc_dft_en = get_rand_lc_tx_val(.t_weight(1), .f_weight(3), .other_weight(1)); - cfg.pwrmgr_vif.rom_ctrl.done = get_rand_mubi4_val( - .t_weight(1), .f_weight(3), .other_weight(1)); - cfg.pwrmgr_vif.rom_ctrl.good = get_rand_mubi4_val( - .t_weight(1), .f_weight(3), .other_weight(1)); - - `uvm_info(`gfn, $sformatf( - "Set done 0x%x, good 0x%x", cfg.pwrmgr_vif.rom_ctrl.done, - cfg.pwrmgr_vif.rom_ctrl.good), UVM_MEDIUM) - - enabled_resets = resets_en & resets; - `uvm_info(`gfn, $sformatf( - "Enabled resets=0x%x, power_reset=%b, escalation=%b, sw_reset=%b, ndm_reset=%b", - enabled_resets, - power_glitch_reset, - escalation_reset, - sw_rst_from_rstmgr == prim_mubi_pkg::MuBi4True, - ndm_reset - ), UVM_MEDIUM) - - csr_wr(.ptr(ral.reset_en[0]), .value(resets_en)); - // This is necessary to propagate reset_en. - wait_for_csr_to_propagate_to_slow_domain(); - - // Trigger resets. The glitch is sent prior to the externals since if it is delayed - // it will cause a separate reset after the externals, which complicates the checks. - if (power_glitch_reset) send_power_glitch(); - cfg.clk_rst_vif.wait_clks(cycles_before_reset); - - `uvm_info(`gfn, $sformatf("Sending resets=0x%x", resets), UVM_MEDIUM) - cfg.pwrmgr_vif.update_resets(resets); - `uvm_info(`gfn, $sformatf("Sending sw reset from rstmgr=%b", sw_rst_from_rstmgr), UVM_MEDIUM) - if (escalation_reset) send_escalation_reset(); - cfg.pwrmgr_vif.update_sw_rst_req(sw_rst_from_rstmgr); - if (ndm_reset) send_ndm_reset(); - - `uvm_info(`gfn, "Wait for Fast State NE FastPwrStateActive", UVM_MEDIUM) - `DV_WAIT(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive) - - if (cfg.pwrmgr_vif.rom_ctrl.done != prim_mubi_pkg::MuBi4True) begin - // Check fast state is not FastPwrStateActive for a while - repeat (20) begin - @cfg.slow_clk_rst_vif.cb; - `DV_CHECK_NE(cfg.pwrmgr_vif.fast_state, pwrmgr_pkg::FastPwrStateActive) - end - - // Set done to True. - `uvm_info(`gfn, "Set rom_ctrl.done input True", UVM_MEDIUM) - cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4True; - cfg.slow_clk_rst_vif.wait_clks(2); - end - - if (cfg.pwrmgr_vif.rom_ctrl.good != prim_mubi_pkg::MuBi4True) begin - bit blocked = 0; - detect_block(blocked); - if (blocked) begin - if (release_by_good) begin - // Set to good. - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4True; - end else begin - // Disable rom checks. - `uvm_info(`gfn, "Set lc ctrl inputs On", UVM_MEDIUM) - cfg.pwrmgr_vif.lc_hw_debug_en = lc_ctrl_pkg::On; - cfg.pwrmgr_vif.lc_dft_en = lc_ctrl_pkg::On; - end - end // if (blocked) - cfg.slow_clk_rst_vif.wait_clks(2); - end - wait(cfg.pwrmgr_vif.pwr_clk_req.main_ip_clk_en == 1'b1); - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "Back from reset", UVM_MEDIUM) - - check_wake_info(.reasons('0), .fall_through(1'b0), .abort(1'b0)); - - cfg.slow_clk_rst_vif.wait_clks(4); - check_reset_status('0); - - // And check interrupt is not set. - check_and_clear_interrupt(.expected(1'b0)); - end - clear_wake_info(); - endtask - -endclass : pwrmgr_disable_rom_integrity_check_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv deleted file mode 100644 index c64a096e71443f..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Description: -// This sequence creates escalation clock and reset malfunction at FastPwrStateActive state. -// This event will trigger timeout counter and assert timeout signal -// when timeout counter reaches EscTimeOutCnt value. -// Once the timeout occurs, it will create fatal alert and alert agent(tb) will set esc rst. -// The pass or failure status is determined in the cip scoreboard. -class pwrmgr_esc_clk_rst_malfunc_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_esc_clk_rst_malfunc_vseq) - - `uvm_object_new - constraint num_trans_c {num_trans inside {[1 : 3]};} - - virtual task body(); - wait_for_fast_fsm_active(); - // Wait some time so the stimulus is sent after the fast fsm becoming active. - cfg.clk_rst_vif.wait_clks(4); - expect_fatal_alerts = 1; - trigger_escalation_timeout(); - wait_for_fast_fsm_active(); - endtask : body - - // Trigers an escalation timeout fault, either stopping clk_esc_i or driving rst_esc_ni. - // - // Randomly set a bit to 0 or 1: if 0 stop clk_esc_i, if 1 make rst_esc_ni active. - task trigger_escalation_timeout(); - int which = $urandom_range(0, 1); - `uvm_info(`gfn, $sformatf("Triggering escalation via %0s", which ? "rst" : "clk"), UVM_MEDIUM) - if (which == 0) cfg.esc_clk_rst_vif.stop_clk(); - else cfg.esc_clk_rst_vif.drive_rst_pin(1'b0); - - // Wait for cpu fetch to be disabled, as an indication a reset is triggered. - `DV_SPINWAIT(wait (cfg.pwrmgr_vif.fetch_en != lc_ctrl_pkg::On);, - "timeout waiting for the CPU to be inactive", FetchEnTimeoutNs) - `uvm_info(`gfn, "Releasing trigger", UVM_MEDIUM) - if (which == 0) cfg.esc_clk_rst_vif.start_clk(); - else cfg.esc_clk_rst_vif.drive_rst_pin(1'b1); - endtask : trigger_escalation_timeout -endclass diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv deleted file mode 100644 index f41663f5ae61e5..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// Description: -// This test asserts glitch to power_reset and see -// dut can recover gracefully. -class pwrmgr_glitch_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_glitch_vseq) - - `uvm_object_new - - int trans_cnt = 0; - constraint num_trans_c {num_trans inside {[1 : 5]};} - - virtual task body(); - expect_fatal_alerts = 1; - for (int i = 0; i < num_trans; ++i) begin - wait_for_fast_fsm_active(); - cfg.clk_rst_vif.wait_clks(4); - - fork - send_power_glitch(); - begin - cfg.pwrmgr_vif.update_ast_main_pok(0); - cfg.slow_clk_rst_vif.wait_clks(2); - cfg.pwrmgr_vif.update_ast_main_pok(1); - end - join - - cfg.clk_rst_vif.wait_clks(cycles_before_reset); - - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateResetPrep && - cfg.pwrmgr_vif.pwr_rst_req.rstreqs[2] == 1);, $sformatf( - "checker timeout : fast_state %s, pwr_rst_req 0x%x", - cfg.pwrmgr_vif.fast_state.name, - cfg.pwrmgr_vif.pwr_rst_req.rstreqs - ), 10000) - - dut_init(); - end - endtask : body -endclass diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv deleted file mode 100644 index dd4b7010d9684e..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// Description: -// This test asserts global escalation reset to dut -// and check glocal escalation request is handled by -// dut properly. -class pwrmgr_global_esc_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_global_esc_vseq) - - `uvm_object_new - - int trans_cnt = 0; - constraint num_trans_c {num_trans inside {[1 : 5]};} - - virtual task body(); - fork - send_esc(); - check_rst_req(); - join - endtask : body - - task send_esc(); - int cycle; - for (int i = 0; i < num_trans; ++i) begin - wait_for_fast_fsm_active(); - cycle = $urandom_range(50, 300); - send_escalation_reset(); - repeat (cycle) @(cfg.clk_rst_vif.cb); - clear_escalation_reset(); - end - endtask : send_esc - - task check_rst_req(); - bit dut_init_done = -1; - - while (trans_cnt < num_trans) begin - @(cfg.clk_rst_vif.cb); - wait(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive && - cfg.pwrmgr_vif.pwr_rst_req.rstreqs[3] == 1'b1); - trans_cnt++; - - // Make sure previous dut_init is done - if (dut_init_done > -1) begin - wait(dut_init_done == 1); - end - // Spawning dut_init thread then go to - // wait reset state - fork - begin - dut_init_done = 0; - dut_init(); - dut_init_done = 1; - end - begin - cfg.clk_rst_vif.wait_clks(10); - end - join_any - end - wait(dut_init_done == 1); - endtask : check_rst_req - -endclass diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv deleted file mode 100644 index 5d52ca0c393a59..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// The test to create transition to invalid state from any lowpower transitions. -class pwrmgr_lowpower_invalid_vseq extends pwrmgr_base_vseq; - - `uvm_object_utils(pwrmgr_lowpower_invalid_vseq) - `uvm_object_new - - // Create enum to map rtl local sparse state - // to continuous dv state. - typedef enum bit [3:0] { - DVWaitDisClks = 0, - DVWaitFallThrough = 1, - DVWaitNvmIdleChk = 2, - DVWaitLowPowerPrep = 3, - DVWaitReqPwrDn = 4, - DVWaitLowPower = 5, - DVWaitEnableClocks = 6, - DVWaitReleaseLcRst = 7, - DVWaitOtpInit = 8, - DVWaitLcInit = 9, - DVWaitAckPwrUp = 10, - DVWaitRomCheck = 11, - DVWaitStrap = 12, - DVWaitActive = 13, - DVWaitInvalid = 14 - } reset_index_e; - - constraint wakeups_c {wakeups != 0;} - constraint wakeup_en_c { - solve wakeups before wakeups_en; - |(wakeups_en & wakeups) == 1'b1; - } - - task body(); - reset_index_e reset_index; - resets_t enabled_resets; - string path = "tb.dut.u_fsm.fsm_invalid_i"; - int num_of_target_states = 4; - - // Spurious interrupt check can be executed by - // residue of lowpower task. Since we cannot kill csr op - // by disable fork, we have to disable spurious interrup check. - cfg.invalid_st_test = 1; - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "At body start", UVM_MEDIUM) - check_wake_status('0); - reset_index = DVWaitFallThrough; - - for (int i = 0; i < num_of_target_states; ++i) begin - `uvm_info(`gfn, $sformatf("Starting new round%0d %s", i, reset_index.name), UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - fork - start_lowpower_transition(); - begin - int wait_time_ns = 10000; - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state == dv2rtl_st(reset_index));, $sformatf( - "Timed out waiting for state %s", reset_index.name), wait_time_ns) - - @cfg.clk_rst_vif.cbn; - `DV_CHECK(uvm_hdl_force(path, 1)) - `uvm_info(`gfn, "Injected invalid slow state", UVM_MEDIUM) - @cfg.clk_rst_vif.cb; - end - join_any - @cfg.clk_rst_vif.cb; - `DV_CHECK(uvm_hdl_release(path)) - `DV_CHECK(cfg.pwrmgr_vif.fast_state, pwrmgr_pkg::FastPwrStateInvalid) - - repeat (10) @cfg.clk_rst_vif.cb; - - apply_reset(); - reset_index=reset_index.next(); - wait_for_fast_fsm_active(); - end // for (int i = 0; i < 4; ++i) - endtask - - task start_lowpower_transition(); - wakeups_t enabled_wakeups = wakeups_en & wakeups; - `DV_CHECK(enabled_wakeups, $sformatf( - "Some wakeup must be enabled: wkups=%b, wkup_en=%b", wakeups, wakeups_en)) - `uvm_info(`gfn, $sformatf("Enabled wakeups=0x%x", enabled_wakeups), UVM_MEDIUM) - csr_wr(.ptr(ral.wakeup_en[0]), .value(wakeups_en)); - low_power_hint = 1; - update_control_csr(); - - wait_for_csr_to_propagate_to_slow_domain(); - `uvm_info(`gfn, $sformatf("Enabled wakeups=0x%x", enabled_wakeups), UVM_MEDIUM) - - // Initiate low power transition. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); - set_nvms_idle(); - - `DV_WAIT(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive) - - if (ral.control.main_pd_n.get_mirrored_value() == 1'b0) begin - wait_for_reset_cause(pwrmgr_pkg::LowPwrEntry); - end - - // Now bring it back. - cfg.clk_rst_vif.wait_clks(cycles_before_wakeup); - cfg.pwrmgr_vif.update_wakeups(wakeups); - - wait(cfg.pwrmgr_vif.pwr_clk_req.main_ip_clk_en == 1'b1); - - // wakeups should be registered. - cfg.pwrmgr_vif.update_wakeups('1); - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "Back from wakeup", UVM_MEDIUM) - endtask : start_lowpower_transition - - function pwrmgr_pkg::fast_pwr_state_e dv2rtl_st(reset_index_e idx); - case (idx) - DVWaitDisClks: return pwrmgr_pkg::FastPwrStateDisClks; - DVWaitFallThrough: return pwrmgr_pkg::FastPwrStateFallThrough; - DVWaitNvmIdleChk: return pwrmgr_pkg::FastPwrStateNvmIdleChk; - DVWaitLowPowerPrep: return pwrmgr_pkg::FastPwrStateLowPowerPrep; - DVWaitReqPwrDn: return pwrmgr_pkg::FastPwrStateReqPwrDn; - DVWaitLowPower: return pwrmgr_pkg::FastPwrStateLowPower; - DVWaitEnableClocks: return pwrmgr_pkg::FastPwrStateEnableClocks; - DVWaitReleaseLcRst: return pwrmgr_pkg::FastPwrStateReleaseLcRst; - DVWaitOtpInit: return pwrmgr_pkg::FastPwrStateOtpInit; - DVWaitLcInit: return pwrmgr_pkg::FastPwrStateLcInit; - DVWaitAckPwrUp: return pwrmgr_pkg::FastPwrStateAckPwrUp; - DVWaitRomCheck: return pwrmgr_pkg::FastPwrStateRomCheckDone; - DVWaitStrap: return pwrmgr_pkg::FastPwrStateStrap; - DVWaitActive: return pwrmgr_pkg::FastPwrStateActive; - DVWaitInvalid: return pwrmgr_pkg::FastPwrStateInvalid; - default: begin - `uvm_error("dv2rma_st", $sformatf("unknown index:%0d", idx)) - end - endcase - endfunction : dv2rtl_st - -endclass : pwrmgr_lowpower_invalid_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv deleted file mode 100644 index 600fdeb2aca906..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// The lowpower_wakeup race test randomly enables wakeups, info capture, and interrupts, -// and sends wakeups in the temporal vecinity of low power entry. It also sends wakeups -// after wakeup processing starts. -class pwrmgr_lowpower_wakeup_race_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_lowpower_wakeup_race_vseq) - - `uvm_object_new - - constraint wakeups_c {wakeups != 0;} - - rand bit keep_prior_wake_info; - - constraint wakeup_en_c { - solve wakeups before wakeups_en; - |(wakeups_en & wakeups) == 1'b1; - } - - rand int cycles_before_early_wakeup; - rand int cycles_before_transition; - constraint cycles_racing_c { - cycles_before_early_wakeup inside {[2 : 8]}; - cycles_before_transition inside {[2 : 8]}; - } - - task body(); - logic [TL_DW-1:0] value; - wakeups_t prior_reasons = '0; - bit prior_fall_through = '0; - bit prior_abort = '0; - wait_for_fast_fsm_active(); - - check_wake_status('0); - for (int i = 0; i < num_trans; ++i) begin - `uvm_info(`gfn, "Starting new round", UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - - csr_wr(.ptr(ral.wakeup_en[0]), .value(wakeups_en)); - `uvm_info(`gfn, $sformatf("Enabled wakeups=0x%x", wakeups_en & wakeups), UVM_MEDIUM) - - if (keep_prior_wake_info) begin - csr_rd(.ptr(ral.wake_info.reasons), .value(prior_reasons)); - csr_rd(.ptr(ral.wake_info.fall_through), .value(prior_fall_through)); - csr_rd(.ptr(ral.wake_info.abort), .value(prior_abort)); - end else begin - clear_wake_info(); - prior_reasons = '0; - prior_fall_through = '0; - prior_abort = '0; - end - `uvm_info(`gfn, $sformatf( - "Prior wake_info: reasons=0x%x, fall_through=%b, abort=%b", - prior_reasons, - prior_fall_through, - prior_abort - ), UVM_MEDIUM) - - `uvm_info(`gfn, $sformatf("%0sabling wakeup capture", disable_wakeup_capture ? "Dis" : "En"), - UVM_MEDIUM) - csr_wr(.ptr(ral.wake_info_capture_dis), .value(disable_wakeup_capture)); - - low_power_hint = 1'b1; - update_control_csr(); - - wait_for_csr_to_propagate_to_slow_domain(); - set_nvms_idle(); - - // This will send the wakeup and trigger low power entry so they almost coincide. - fork - begin - cfg.clk_rst_vif.wait_clks(cycles_before_transition); - // Initiate low power transition. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); - end - begin - cfg.clk_rst_vif.wait_clks(cycles_before_early_wakeup); - // Send the wakeups. - cfg.pwrmgr_vif.update_wakeups(wakeups); - end - join - - if (ral.control.main_pd_n.get_mirrored_value() == 1'b0) begin - wait_for_reset_cause(pwrmgr_pkg::LowPwrEntry); - end - - // Now bring it back. - cfg.clk_rst_vif.wait_clks(cycles_before_wakeup); - - // Check wake_status prior to wakeup, or the unit requesting wakeup will have been reset. - // This read will not work in the chip, since the processor will be asleep. - cfg.slow_clk_rst_vif.wait_clks(5); - check_wake_status(wakeups & wakeups_en); - `uvm_info(`gfn, $sformatf("Got wake_status=0x%x", wakeups & wakeups_en), UVM_MEDIUM) - wait(cfg.pwrmgr_vif.pwr_clk_req.main_ip_clk_en == 1'b1); - - // Send more wakeups to make sure they are reported in CSRs. With this all enabled - // wakeups should be registered. - cfg.pwrmgr_vif.update_wakeups('1); - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "Back from wakeup", UVM_MEDIUM) - - // make this check parallel. - // to avoid csr rd blocking later status read request and - // miss status update window. - @cfg.clk_rst_vif.cb; - fork - begin - fast_check_reset_status(0); - end - begin - fast_check_wake_info(.reasons(wakeups_en), .prior_reasons(prior_reasons), - .fall_through(1'b0), .abort(1'b0), - .prior_fall_through(prior_fall_through), .prior_abort(prior_abort)); - end - join - // This is the expected side-effect of the low power entry reset, since the source of the - // non-aon wakeup sources will deassert it as a consequence of their reset. - // Some aon wakeups may remain active until software clears them. If they didn't, such wakeups - // will remain active, preventing the device from going to sleep. - cfg.pwrmgr_vif.update_wakeups('0); - cfg.slow_clk_rst_vif.wait_clks(10); - cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); - - // wait for clock is on - cfg.clk_rst_vif.wait_clks(10); - - check_wake_status('0); - - // Wait for interrupt to be generated whether or not it is enabled. - cfg.slow_clk_rst_vif.wait_clks(10); - check_and_clear_interrupt(.expected(1'b1)); - end - clear_wake_info(); - endtask - -endclass : pwrmgr_lowpower_wakeup_race_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv deleted file mode 100644 index 9d8a3f3b6650b5..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// Description: -// The wakeup_reset test randomly enables wakeups and resets, info capture, and interrupts, -// and sends wakeups and resets in close temporal proximity at random times. -class pwrmgr_repeat_wakeup_reset_vseq extends pwrmgr_wakeup_reset_vseq; - `uvm_object_utils(pwrmgr_repeat_wakeup_reset_vseq) - - `uvm_object_new - - bit [lc_ctrl_pkg::TxWidth-1:0] bad_lc_tx; - - int cycles_from_reset; - int micros_to_release; - - bit super_sequence_done; - - // add invalid value to rom_ctrl - virtual task twirl_rom_response(); - add_rom_rsp_noise(); - cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4False; - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4False; - cfg.clk_rst_vif.wait_clks(5); - add_rom_rsp_noise(); - wait(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateRomCheckDone); - add_rom_rsp_noise(); - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4True; - cfg.clk_rst_vif.wait_clks(5); - cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4True; - endtask - - task body(); - num_trans_c.constraint_mode(0); - num_trans = 50; - super_sequence_done = 0; - - disable_assert(); - fork - begin - super.body(); - super_sequence_done = 1; - end - drv_stim(mubi_mode); - join - endtask : body - - function void disable_assert(); - $assertoff(0, "tb.dut.u_cdc.u_sync_rom_ctrl"); - endfunction : disable_assert - - task drv_stim(pwrmgr_mubi_e mubi_mode); - if (mubi_mode == PwrmgrMubiLcCtrl) drv_lc_ctrl(); - endtask : drv_stim - - task drv_lc_ctrl(); - int delay; - - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(cycles_from_reset, cycles_from_reset inside {[2 : 8]};) - `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(micros_to_release, micros_to_release inside {[2 : 4]};) - - repeat (50) begin - wait(cfg.esc_clk_rst_vif.rst_n); - cfg.clk_rst_vif.wait_clks(cycles_from_reset); - if (super_sequence_done) break; - `uvm_info(`gfn, "Injection to lc_hw_debug_en", UVM_MEDIUM) - cfg.pwrmgr_vif.lc_hw_debug_en = get_rand_lc_tx_val( - .t_weight(1), .f_weight(1), .other_weight(2) - ); - #(micros_to_release * 1us); - `uvm_info(`gfn, "Injection to lc_dft_en", UVM_MEDIUM) - if (super_sequence_done) break; - cfg.pwrmgr_vif.lc_dft_en = get_rand_lc_tx_val(.t_weight(1), .f_weight(1), .other_weight(2)); - #(micros_to_release * 1us); - end // repeat (50) - `uvm_info(`gfn, "ended drv_lc_ctrl", UVM_MEDIUM) - endtask : drv_lc_ctrl - -endclass : pwrmgr_repeat_wakeup_reset_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv deleted file mode 100644 index 4344105627e79f..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// The test to create transition to invalid state from any reset transitions. -class pwrmgr_reset_invalid_vseq extends pwrmgr_base_vseq; - - `uvm_object_utils(pwrmgr_reset_invalid_vseq) - `uvm_object_new - - // Create enum to map rtl local sparse state - // to continuous dv state. - typedef enum bit [3:0] { - DVWaitDisClks = 0, - DVWaitNvmShutDown = 1, - DVWaitResetPrep = 2, - DVWaitLowPower = 3, - DVWaitEnableClocks = 4, - DVWaitReleaseLcRst = 5, - DVWaitOtpInit = 6, - DVWaitLcInit = 7, - DVWaitAckPwrUp = 8, - DVWaitRomCheck = 9, - DVWaitStrap = 10, - DVWaitActive = 11, - DVWaitInvalid = 12 - } reset_index_e; - - constraint wakeups_c {wakeups == 0;} - constraint wakeups_en_c {wakeups_en == 0;} - - function void post_randomize(); - sw_rst_from_rstmgr = get_rand_mubi4_val(.t_weight(8), .f_weight(4), .other_weight(4)); - super.post_randomize(); - endfunction - - task body(); - reset_index_e reset_index; - resets_t enabled_resets; - string path = "tb.dut.u_fsm.fsm_invalid_i"; - int num_of_target_states = 11; - - wait_for_fast_fsm_active(); - check_reset_status('0); - $assertoff(0, "tb.dut.u_cdc.u_clr_reqack.SyncReqAckHoldReq"); - - for (int i = 0; i < num_of_target_states; ++i) begin - `uvm_info(`gfn, $sformatf("Starting new round %0d", i), UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - - fork - create_any_reset_event(); - begin - int wait_time_ns = 20000; - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state == dv2rtl_st(reset_index));, $sformatf( - "Timed out waiting for state %s", reset_index.name), wait_time_ns) - - @cfg.clk_rst_vif.cbn; - `uvm_info(`gfn, $sformatf("Will cause invalid state forcing %s = 1", path), UVM_MEDIUM) - `DV_CHECK(uvm_hdl_force(path, 1)) - @cfg.clk_rst_vif.cb; - end - join - @cfg.clk_rst_vif.cb; - `DV_CHECK(uvm_hdl_release(path)) - `DV_CHECK(cfg.pwrmgr_vif.fast_state, pwrmgr_pkg::FastPwrStateInvalid) - `uvm_info(`gfn, "All good, resetting for next round", UVM_MEDIUM) - repeat (10) @cfg.clk_rst_vif.cb; - apply_reset(); - reset_index=reset_index.next(); - wait_for_fast_fsm_active(); - end - endtask - - task create_any_reset_event(); - resets_t enabled_resets = resets_t'(resets_en & resets); - `uvm_info(`gfn, $sformatf( - "Enabled resets=0x%x, power_reset=%b, escalation=%b, sw_reset=%b, ndm_reset=%b", - enabled_resets, - power_glitch_reset, - escalation_reset, - sw_rst_from_rstmgr == prim_mubi_pkg::MuBi4True, - ndm_reset - ), UVM_MEDIUM) - - `uvm_info(`gfn, "Trying to write to reset_en CSR", UVM_MEDIUM) - csr_wr(.ptr(ral.reset_en[0]), .value(resets_en)); - // This is necessary to propagate reset_en. - wait_for_csr_to_propagate_to_slow_domain(); - - // Trigger resets. The glitch is sent prior to the externals since if it is delayed - // it will cause a separate reset after the externals, which complicates the checks. - if (power_glitch_reset) send_power_glitch(); - cfg.clk_rst_vif.wait_clks(cycles_before_reset); - - if (cycles_before_reset == 0) enabled_resets = 0; - - `uvm_info(`gfn, $sformatf("Sending resets=0x%x", resets), UVM_MEDIUM) - cfg.pwrmgr_vif.update_resets(resets); - `uvm_info(`gfn, $sformatf("Sending sw reset from rstmgr=%b", sw_rst_from_rstmgr), UVM_MEDIUM) - if (escalation_reset) send_escalation_reset(); - if (ndm_reset) send_ndm_reset(); - cfg.pwrmgr_vif.update_sw_rst_req(sw_rst_from_rstmgr); - - endtask : create_any_reset_event - - function pwrmgr_pkg::fast_pwr_state_e dv2rtl_st(reset_index_e idx); - case (idx) - DVWaitDisClks: return pwrmgr_pkg::FastPwrStateDisClks; - DVWaitNvmShutDown: return pwrmgr_pkg::FastPwrStateNvmShutDown; - DVWaitResetPrep: return pwrmgr_pkg::FastPwrStateResetPrep; - DVWaitLowPower: return pwrmgr_pkg::FastPwrStateLowPower; - DVWaitEnableClocks: return pwrmgr_pkg::FastPwrStateEnableClocks; - DVWaitReleaseLcRst: return pwrmgr_pkg::FastPwrStateReleaseLcRst; - DVWaitOtpInit: return pwrmgr_pkg::FastPwrStateOtpInit; - DVWaitLcInit: return pwrmgr_pkg::FastPwrStateLcInit; - DVWaitAckPwrUp: return pwrmgr_pkg::FastPwrStateAckPwrUp; - DVWaitRomCheck: return pwrmgr_pkg::FastPwrStateRomCheckDone; - DVWaitStrap: return pwrmgr_pkg::FastPwrStateStrap; - DVWaitActive: return pwrmgr_pkg::FastPwrStateActive; - DVWaitInvalid: return pwrmgr_pkg::FastPwrStateInvalid; - default: begin - `uvm_error("dv2rma_st", $sformatf("unknown index:%0d", idx)) - end - endcase - endfunction : dv2rtl_st - -endclass : pwrmgr_reset_invalid_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv deleted file mode 100644 index c40683c770cd11..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// The reset test randomly introduces external resets, ndm resets, power glitches, and escalation -// resets. -class pwrmgr_reset_vseq extends pwrmgr_base_vseq; - - `uvm_object_utils(pwrmgr_reset_vseq) - `uvm_object_new - - constraint wakeups_c {wakeups == 0;} - constraint wakeups_en_c {wakeups_en == 0;} - - function void post_randomize(); - sw_rst_from_rstmgr = get_rand_mubi4_val(.t_weight(8), .f_weight(4), .other_weight(4)); - super.post_randomize(); - endfunction - - task body(); - logic [TL_DW-1:0] value; - resets_t enabled_resets; - wait_for_fast_fsm_active(); - - check_reset_status('0); - for (int i = 0; i < num_trans; ++i) begin - `uvm_info(`gfn, "Starting new round", UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - enabled_resets = resets_en & resets; - `uvm_info(`gfn, $sformatf( - "Enabled resets=0x%x, power_reset=%b, escalation=%b, sw_reset=%b, ndm_reset=%b", - enabled_resets, - power_glitch_reset, - escalation_reset, - sw_rst_from_rstmgr == prim_mubi_pkg::MuBi4True, - ndm_reset - ), UVM_MEDIUM) - - csr_wr(.ptr(ral.reset_en[0]), .value(resets_en)); - // This is necessary to propagate reset_en. - wait_for_csr_to_propagate_to_slow_domain(); - - // Trigger resets. The glitch is sent prior to the externals since if it is delayed - // it will cause a separate reset after the externals, which complicates the checks. - if (power_glitch_reset) send_power_glitch(); - cfg.clk_rst_vif.wait_clks(cycles_before_reset); - - `uvm_info(`gfn, $sformatf("Sending resets=0x%x", resets), UVM_MEDIUM) - cfg.pwrmgr_vif.update_resets(resets); - `uvm_info(`gfn, $sformatf("Sending sw reset from rstmgr=%b", sw_rst_from_rstmgr), UVM_MEDIUM) - if (escalation_reset) begin - send_escalation_reset(); - // Wait for the alert to propagate to fault_status? - end - cfg.pwrmgr_vif.update_sw_rst_req(sw_rst_from_rstmgr); - if (ndm_reset) send_ndm_reset(); - - // Expect to start reset. - `DV_WAIT(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive) - `uvm_info(`gfn, "Started to process reset", UVM_MEDIUM) - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "Back from reset", UVM_MEDIUM) - - check_wake_info(.reasons('0), .fall_through(1'b0), .abort(1'b0)); - - cfg.slow_clk_rst_vif.wait_clks(4); - check_reset_status('0); - - // And check interrupt is not set. - check_and_clear_interrupt(.expected(1'b0)); - end - clear_wake_info(); - endtask - -endclass : pwrmgr_reset_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv deleted file mode 100644 index 0145e71062f677..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// Decription: -// Create low power transition and wakeup a few times. -// When PWRMGR.CONTROL.LOW_POWER_HINT is set, -// issue random write to PWRMGR.CONTROL and check -// PWRMGR.CONTROL value is not changed. -class pwrmgr_sec_cm_ctrl_config_regwen_vseq extends pwrmgr_wakeup_vseq; - `uvm_object_utils(pwrmgr_sec_cm_ctrl_config_regwen_vseq) - - `uvm_object_new - - virtual task pre_start(); - super.pre_start(); - cfg.disable_csr_rd_chk = 1; - endtask : pre_start - - task proc_illegal_ctrl_access(); - uvm_reg_data_t wdata, expdata; - cfg.clk_rst_vif.wait_clks(1); - wait(cfg.pwrmgr_vif.lowpwr_cfg_wen == 0); - - repeat ($urandom_range(1, 5)) begin - `DV_CHECK_STD_RANDOMIZE_FATAL(wdata) - expdata = ral.control.get(); - `uvm_info(`gfn, $sformatf("csr start %x", ral.control.get()), UVM_HIGH) - csr_wr(.ptr(ral.control), .value(wdata)); - csr_rd_check(.ptr(ral.control), .compare_value(expdata)); - `uvm_info(`gfn, "csr done", UVM_HIGH) - end - endtask : proc_illegal_ctrl_access - - virtual task wait_for_csr_to_propagate_to_slow_domain(); - proc_illegal_ctrl_access(); - super.wait_for_csr_to_propagate_to_slow_domain(); - endtask -endclass : pwrmgr_sec_cm_ctrl_config_regwen_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv deleted file mode 100644 index 3f33e9c10cde94..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// The smoke test brings the pwrmgr through a POR reset, followed by a low -// power sequence, followed by reset. - -// smoke test vseq -class pwrmgr_smoke_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_smoke_vseq) - - `uvm_object_new - constraint cycles_before_rst_lc_src_c {cycles_before_rst_lc_src inside {[1 : 2]};} - constraint cycles_before_otp_done_c {cycles_before_otp_done inside {[1 : 2]};} - constraint cycles_before_lc_done_c {cycles_before_lc_done inside {[1 : 2]};} - - constraint wakeups_c {wakeups != 0;} - constraint resets_c {resets != 0;} - - constraint control_enables_c { - control_enables.core_clk_en == ral.control.core_clk_en.get_reset(); - control_enables.io_clk_en == ral.control.io_clk_en.get_reset(); - control_enables.usb_clk_en_lp == ral.control.usb_clk_en_lp.get_reset(); - control_enables.usb_clk_en_active == ral.control.usb_clk_en_active.get_reset(); - control_enables.main_pd_n == ral.control.main_pd_n.get_reset(); - } - - task body(); - logic [TL_DW-1:0] value; - wakeups_t wakeup_en; - resets_t reset_en; - wait_for_fast_fsm_active(); - set_nvms_idle(); - setup_interrupt(.enable(1'b1)); - - check_wake_status('0); - check_reset_status('0); - - // Enable all wakeups so any peripheral can cause a wakeup. - wakeup_en = '1; - csr_wr(.ptr(ral.wakeup_en[0]), .value(wakeup_en)); - low_power_hint = 1'b1; - update_control_csr(); - wait_for_csr_to_propagate_to_slow_domain(); - - // Initiate low power transition. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); - wait_for_reset_cause(pwrmgr_pkg::LowPwrEntry); - - // Now bring it back. - cfg.clk_rst_vif.wait_clks(cycles_before_wakeup); - cfg.pwrmgr_vif.update_wakeups(wakeups); - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "smoke back from wakeup", UVM_MEDIUM) - - check_wake_status(wakeups & wakeup_en); - check_reset_status('0); - // And make the cpu active. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); - - cfg.pwrmgr_vif.update_wakeups('0); - check_and_clear_interrupt(.expected(1'b1)); - - // Enable resets. - reset_en = '1; - csr_wr(.ptr(ral.reset_en[0]), .value(reset_en)); - wait_for_csr_to_propagate_to_slow_domain(); - - // Trigger a reset. - cfg.pwrmgr_vif.update_resets(resets); - cfg.slow_clk_rst_vif.wait_clks(2); - wait_for_reset_cause(pwrmgr_pkg::HwReq); - - // Now bring it back: the slow fsm doesn't participate on this, so we cannot - // rely on the ctrl_cfg_regwen CSR. Wait for the reset status to clear. - wait_for_fast_fsm_active(); - - // The reset_status CSR should be clear since the unit requesting reset - // should have been reset, so the incoming reset should have cleared. - check_reset_status('0); - check_wake_status('0); - clear_wake_info(); - - // Wait for interrupt to be generated whether or not it is enabled. - cfg.slow_clk_rst_vif.wait_clks(10); - check_and_clear_interrupt(.expected(1'b0)); - endtask - -endclass : pwrmgr_smoke_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv deleted file mode 100644 index f54bd502e55b46..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// combine all pwrmgr seqs (except below seqs) in one seq to run sequentially -// 1. csr seq, which requires scb to be disabled -class pwrmgr_stress_all_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_stress_all_vseq) - - `uvm_object_new - - task body(); - string seq_names[] = { - "pwrmgr_aborted_low_power_vseq", - "pwrmgr_lowpower_wakeup_race_vseq", - "pwrmgr_reset_vseq", - "pwrmgr_smoke_vseq", - "pwrmgr_wakeup_reset_vseq", - "pwrmgr_wakeup_vseq" - }; - - for (int i = 1; i <= num_trans; i++) begin - uvm_sequence seq; - pwrmgr_base_vseq pwrmgr_vseq; - uint seq_idx = $urandom_range(0, seq_names.size - 1); - - seq = create_seq_by_name(seq_names[seq_idx]); - `downcast(pwrmgr_vseq, seq) - - pwrmgr_vseq.do_apply_reset = 1; - pwrmgr_vseq.set_sequencer(p_sequencer); - `DV_CHECK_RANDOMIZE_FATAL(pwrmgr_vseq) - `uvm_info(`gfn, $sformatf("seq_idx = %0d, sequence is %0s", seq_idx, pwrmgr_vseq.get_name()), - UVM_MEDIUM) - - pwrmgr_vseq.start(p_sequencer); - `uvm_info(`gfn, $sformatf( - "End of sequence %0s with seq_idx = %0d", pwrmgr_vseq.get_name(), seq_idx), - UVM_MEDIUM) - end - endtask : body -endclass diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv deleted file mode 100644 index c1b1ce188c2205..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// Description: -// The reset test randomly introduces external resets. -class pwrmgr_sw_reset_vseq extends pwrmgr_base_vseq; - - `uvm_object_utils(pwrmgr_sw_reset_vseq) - `uvm_object_new - - constraint wakeups_c {wakeups == 0;} - constraint wakeups_en_c {wakeups_en == 0;} - - task body(); - int exp_rst; - wait_for_fast_fsm_active(); - - check_reset_status('0); - num_trans_c.constraint_mode(0); - num_trans = 30; - for (int i = 0; i < num_trans; ++i) begin - `uvm_info(`gfn, "Starting new round", UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - - cfg.pwrmgr_vif.sw_rst_req_i = prim_mubi_pkg::mubi4_t'($urandom_range(0, 15)); - exp_rst = (cfg.pwrmgr_vif.sw_rst_req_i == prim_mubi_pkg::MuBi4True); - cfg.slow_clk_rst_vif.wait_clks(4); - - // sw reset causes fast state machine transition to lowpower state - if (exp_rst == 1) begin - `DV_SPINWAIT(wait(cfg.pwrmgr_vif.fast_state != pwrmgr_pkg::FastPwrStateActive);, - "timeout waiting for non fast-active state", 1000) - end - - // This read is not always possible since the CPU may be off. - - wait(cfg.pwrmgr_vif.pwr_clk_req.main_ip_clk_en == 1'b1); - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "Back from reset", UVM_MEDIUM) - - check_wake_info(.reasons('0), .fall_through(1'b0), .abort(1'b0)); - - cfg.slow_clk_rst_vif.wait_clks(4); - check_reset_status('0); - - // And check interrupt is not set. - check_and_clear_interrupt(.expected(1'b0)); - end - clear_wake_info(); - endtask - -endclass : pwrmgr_sw_reset_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv deleted file mode 100644 index 233a711f3b4229..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -`include "pwrmgr_base_vseq.sv" -`include "pwrmgr_aborted_low_power_vseq.sv" -`include "pwrmgr_lowpower_wakeup_race_vseq.sv" -`include "pwrmgr_reset_vseq.sv" -`include "pwrmgr_smoke_vseq.sv" -`include "pwrmgr_stress_all_vseq.sv" -`include "pwrmgr_wakeup_reset_vseq.sv" -`include "pwrmgr_wakeup_vseq.sv" -`include "pwrmgr_common_vseq.sv" -`include "pwrmgr_repeat_wakeup_reset_vseq.sv" -`include "pwrmgr_sw_reset_vseq.sv" -`include "pwrmgr_esc_clk_rst_malfunc_vseq.sv" -`include "pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv" -`include "pwrmgr_global_esc_vseq.sv" -`include "pwrmgr_glitch_vseq.sv" -`include "pwrmgr_disable_rom_integrity_check_vseq.sv" -`include "pwrmgr_reset_invalid_vseq.sv" -`include "pwrmgr_lowpower_invalid_vseq.sv" diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv deleted file mode 100644 index 5e2f2c89eba099..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// The wakeup_reset test randomly enables wakeups and resets, info capture, and interrupts, -// and sends wakeups and resets in close temporal proximity at random times. -// Notice it makes no sense to send escalation reset requests while in low -// power, when the clocks are stopped, or while the system is already in reset -// since escalation should not be triggered with reset active. -class pwrmgr_wakeup_reset_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_wakeup_reset_vseq) - - `uvm_object_new - - constraint wakeups_c {wakeups != 0;} - - constraint wakeup_en_c { - solve wakeups before wakeups_en; - (wakeups_en & wakeups) != 0; - } - constraint disable_wakeup_capture_c {disable_wakeup_capture == 1'b0;} - - // Disabling escalation resets per comment above. - constraint escalation_reset_c {escalation_reset == 0;} - - // Cause some delays for the rom_ctrl done and good inputs. Simple, enough to hold the - // transition to active state. - // ICEBOX(lowrisc/opentitan#18236) Consider adding checks to monitor fast state transitions are - // compliant with "ROM Integrity Checks" at - // https://opentitan.org/book/hw/ip/pwrmgr/doc/theory_of_operation.html#rom-integrity-checks - virtual task twirl_rom_response(); - cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4False; - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4False; - @(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateAckPwrUp); - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4True; - @(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateRomCheckDone); - cfg.clk_rst_vif.wait_clks(10); - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4False; - cfg.clk_rst_vif.wait_clks(5); - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4True; - cfg.clk_rst_vif.wait_clks(5); - cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4True; - endtask - - task body(); - logic [TL_DW-1:0] value; - resets_t enabled_resets; - wakeups_t enabled_wakeups; - - wait_for_fast_fsm_active(); - - check_reset_status('0); - check_wake_status('0); - for (int i = 0; i < num_trans; ++i) begin - `uvm_info(`gfn, "Starting new round", UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - setup_interrupt(.enable(en_intr)); - - // Enable resets. - enabled_resets = resets_en & resets; - `uvm_info(`gfn, $sformatf( - "Enabled resets=0x%x, power_reset=%b, sw_reset=%b", - enabled_resets, - power_glitch_reset, - sw_rst_from_rstmgr - ), UVM_MEDIUM) - csr_wr(.ptr(ral.reset_en[0]), .value(resets_en)); - - // Enable wakeups. - enabled_wakeups = wakeups_en & wakeups; - `DV_CHECK(enabled_wakeups, $sformatf( - "Some wakeup must be enabled: wkups=%b, wkup_en=%b", wakeups, wakeups_en)) - `uvm_info(`gfn, $sformatf("Enabled wakeups=0x%x", enabled_wakeups), UVM_MEDIUM) - csr_wr(.ptr(ral.wakeup_en[0]), .value(wakeups_en)); - - clear_wake_info(); - - `uvm_info(`gfn, $sformatf("%0sabling wakeup capture", disable_wakeup_capture ? "Dis" : "En"), - UVM_MEDIUM) - csr_wr(.ptr(ral.wake_info_capture_dis), .value(disable_wakeup_capture)); - - low_power_hint = 1'b1; - update_control_csr(); - wait_for_csr_to_propagate_to_slow_domain(); - - // Initiate low power transition. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); - set_nvms_idle(); - // Wait for the slow state machine to be in low power. - wait(cfg.pwrmgr_vif.slow_state == pwrmgr_pkg::SlowPwrStateLowPower); - // This will send the wakeup and reset so they almost coincide. - // at low power state, do not use clk_rst_vif, cause it is off. - fork - begin - cfg.slow_clk_rst_vif.wait_clks(cycles_before_reset); - cfg.pwrmgr_vif.update_resets(resets); - - if (power_glitch_reset) begin - send_power_glitch(); - enabled_resets = 0; - end - `uvm_info(`gfn, $sformatf("Sending reset=%b, power_glitch=%b", resets, power_glitch_reset - ), UVM_MEDIUM) - end - - begin - cfg.slow_clk_rst_vif.wait_clks(cycles_before_wakeup); - cfg.pwrmgr_vif.update_wakeups(wakeups); - `uvm_info(`gfn, $sformatf("Sending wakeup=%b", wakeups), UVM_MEDIUM) - end - join - - if (cfg.en_cov) begin - cov.reset_wakeup_distance_cg.sample(cycles_before_reset - cycles_before_wakeup); - end - // twirl_rom_response has some waits, and so does the code to check wake_status, - // so we fork them to avoid conflicts. - - fork - begin - // At lowpower state, wait for clock comes back before check any csr - @cfg.clk_rst_vif.cb; - // Check wake_status prior to wakeup, or the unit requesting wakeup will have been reset. - // This read will not work in the chip, since the processor will be asleep. - // Reset status cannot be reliably checked here since it is cleared when reset goes active. - fast_check_wake_status(enabled_wakeups); - `uvm_info(`gfn, $sformatf("Got wake_status=0x%x", enabled_wakeups), UVM_MEDIUM) - end - twirl_rom_response(); - join - - wait_for_fast_fsm_active(); - - check_reset_status('0); - - check_wake_info(.reasons(enabled_wakeups), .prior_reasons(1'b0), .fall_through(1'b0), - .prior_fall_through(1'b0), .abort(1'b0), .prior_abort(1'b0)); - - if (mubi_mode == PwrmgrMubiRomCtrl) begin - add_rom_rsp_noise(); - cfg.pwrmgr_vif.rom_ctrl.good = prim_mubi_pkg::MuBi4True; - cfg.clk_rst_vif.wait_clks(5); - cfg.pwrmgr_vif.rom_ctrl.done = prim_mubi_pkg::MuBi4True; - end - - // This is the expected side-effect of the low power entry reset, since the source of the - // non-aon wakeup sources will deassert it as a consequence of their reset. - // Some aon wakeups may remain active until software clears them. If they didn't, such wakeups - // will remain active, preventing the device from going to sleep. - cfg.pwrmgr_vif.update_wakeups('0); - cfg.slow_clk_rst_vif.wait_clks(10); - check_reset_status('0); - check_wake_status('0); - - cfg.slow_clk_rst_vif.wait_clks(10); - // An interrupt will be generated depending on the exact timing of the slow fsm getting - // the reset and wakeup. We choose not to predict it here (it is checked on other tests). - // Instead, we just check if the interrupt status is asserted and it is enabled the - // output interrupt is active. - check_and_clear_interrupt(.expected(1'b1), .check_expected('0)); - // Clear hardware resets: if they are enabled they are cleared when rst_lc_req[1] goes active, - // but this makes sure they are cleared even if none is enabled for the next round. - cfg.pwrmgr_vif.update_resets('0); - // And make the cpu active. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); - end - clear_wake_info(); - endtask - -endclass : pwrmgr_wakeup_reset_vseq diff --git a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv b/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv deleted file mode 100644 index 43dce86c83df8f..00000000000000 --- a/hw/ip/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// The wakeup test randomly enables wakeups, info capture, and interrupts, -// and sends wakeups at random times. -class pwrmgr_wakeup_vseq extends pwrmgr_base_vseq; - `uvm_object_utils(pwrmgr_wakeup_vseq) - - `uvm_object_new - - constraint wakeups_c {wakeups != 0;} - - rand bit keep_prior_wake_info; - - constraint wakeup_en_c { - solve wakeups before wakeups_en; - |(wakeups_en & wakeups) == 1'b1; - } - - task body(); - logic [TL_DW-1:0] value; - wakeups_t enabled_wakeups; - wakeups_t prior_reasons = '0; - bit prior_fall_through = '0; - bit prior_abort = '0; - - wait_for_fast_fsm_active(); - check_wake_status('0); - for (int i = 0; i < num_trans; ++i) begin - `uvm_info(`gfn, "Starting new round", UVM_MEDIUM) - `DV_CHECK_RANDOMIZE_FATAL(this) - - // Instrument interrupts. - setup_interrupt(en_intr); - - // Enable wakeups. - enabled_wakeups = wakeups_en & wakeups; - `DV_CHECK(enabled_wakeups, $sformatf( - "Some wakeup must be enabled: wkups=%b, wkup_en=%b", wakeups, wakeups_en)) - `uvm_info(`gfn, $sformatf("Enabled wakeups=0x%x", enabled_wakeups), UVM_MEDIUM) - csr_wr(.ptr(ral.wakeup_en[0]), .value(wakeups_en)); - - if (keep_prior_wake_info) begin - csr_rd(.ptr(ral.wake_info.reasons), .value(prior_reasons)); - csr_rd(.ptr(ral.wake_info.fall_through), .value(prior_fall_through)); - csr_rd(.ptr(ral.wake_info.abort), .value(prior_abort)); - end else begin - clear_wake_info(); - prior_reasons = '0; - prior_fall_through = '0; - prior_abort = '0; - end - `uvm_info(`gfn, $sformatf( - "Prior wake_info: reasons=0x%x, fall_through=%b, abort=%b", - prior_reasons, - prior_fall_through, - prior_abort - ), UVM_MEDIUM) - - `uvm_info(`gfn, $sformatf("%0sabling wakeup capture", disable_wakeup_capture ? "Dis" : "En"), - UVM_MEDIUM) - csr_wr(.ptr(ral.wake_info_capture_dis), .value(disable_wakeup_capture)); - - low_power_hint = 1'b1; - update_control_csr(); - - wait_for_csr_to_propagate_to_slow_domain(); - - // Initiate low power transition. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); - set_nvms_idle(); - - if (ral.control.main_pd_n.get_mirrored_value() == 1'b0) begin - wait_for_reset_cause(pwrmgr_pkg::LowPwrEntry); - end - - // Now bring it back. - cfg.clk_rst_vif.wait_clks(cycles_before_wakeup); - cfg.pwrmgr_vif.update_wakeups(wakeups); - // Check wake_status prior to wakeup, or the unit requesting wakeup will have been reset. - // This read will not work in the chip, since the processor will be asleep. - cfg.slow_clk_rst_vif.wait_clks(4); - // wait for clock is on - cfg.clk_rst_vif.wait_clks(10); - - check_wake_status(enabled_wakeups); - `uvm_info(`gfn, $sformatf("Got wake_status=0x%x", enabled_wakeups), UVM_MEDIUM) - wait(cfg.pwrmgr_vif.pwr_clk_req.main_ip_clk_en == 1'b1); - - wait_for_fast_fsm_active(); - `uvm_info(`gfn, "Back from wakeup", UVM_MEDIUM) - - @cfg.clk_rst_vif.cb; - fork - begin - fast_check_reset_status(0); - end - begin - fast_check_wake_info(.reasons(enabled_wakeups), .prior_reasons(prior_reasons), - .fall_through(1'b0), .abort(1'b0), - .prior_fall_through(prior_fall_through), .prior_abort(prior_abort)); - end - join - // This is the expected side-effect of the low power entry reset, since the source of the - // non-aon wakeup sources will deassert it as a consequence of their reset. - // Some aon wakeups may remain active until software clears them. If they didn't, such wakeups - // will remain active, preventing the device from going to sleep. - cfg.pwrmgr_vif.update_wakeups('0); - cfg.slow_clk_rst_vif.wait_clks(10); - - // if clock is off, we need to wait until it is resumed. - cfg.clk_rst_vif.wait_clks(5); - check_wake_status('0); - - // And make the cpu active. - cfg.pwrmgr_vif.update_cpu_sleeping(1'b0); - - // Wait for interrupt to be generated whether or not it is enabled. - cfg.slow_clk_rst_vif.wait_clks(10); - check_and_clear_interrupt(.expected(1'b1)); - end - clear_wake_info(); - endtask - -endclass : pwrmgr_wakeup_vseq diff --git a/hw/ip/pwrmgr/dv/pwrmgr_sim.core b/hw/ip/pwrmgr/dv/pwrmgr_sim.core deleted file mode 100644 index 9eaa8fd0db4d5a..00000000000000 --- a/hw/ip/pwrmgr/dv/pwrmgr_sim.core +++ /dev/null @@ -1,29 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:pwrmgr_sim:0.1" -description: "PWRMGR DV sim target" -filesets: - files_rtl: - depend: - - lowrisc:ip:pwrmgr - files_dv: - depend: - - lowrisc:dv:pwrmgr_test - - lowrisc:dv:pwrmgr_sva - files: - - tb.sv - - cov/pwrmgr_cov_bind.sv - file_type: systemVerilogSource - -targets: - sim: &sim_target - toplevel: tb - filesets: - - files_rtl - - files_dv - default_tool: vcs - - lint: - <<: *sim_target diff --git a/hw/ip/pwrmgr/dv/pwrmgr_sim_cfg.hjson b/hw/ip/pwrmgr/dv/pwrmgr_sim_cfg.hjson deleted file mode 100644 index baebf306caf276..00000000000000 --- a/hw/ip/pwrmgr/dv/pwrmgr_sim_cfg.hjson +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - // Name of the sim cfg - typically same as the name of the DUT. - name: pwrmgr - - // Top level dut name (sv module). - dut: pwrmgr - - // Top level testbench name (sv module). - tb: tb - - // Simulator used to sign off this block - tool: vcs - - // Fusesoc core file used for building the file list. - fusesoc_core: lowrisc:dv:pwrmgr_sim:0.1 - - // Testplan hjson file. - testplan: "{proj_root}/hw/ip/pwrmgr/data/pwrmgr_testplan.hjson" - - // RAL spec - used to generate the RAL model. - ral_spec: "{proj_root}/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson" - - // Import additional common sim cfg files. - import_cfgs: [// Project wide common sim cfg file - "{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson", - // Common CIP test lists - "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/stress_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", - "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson"] - - // Overrides - overrides: [ - { - name: design_level - value: "top" - } - ] - - // Exclusion files - vcs_cov_excl_files: ["{proj_root}/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el"] - - // Add additional tops for simulation. - sim_tops: ["pwrmgr_bind", - "pwrmgr_cov_bind", - "sec_cm_prim_count_bind", - "sec_cm_prim_sparse_fsm_flop_bind", - "sec_cm_prim_onehot_check_bind"] - - // Default iterations for all tests - each test entry can override this. - reseed: 50 - - // Default UVM test and seq class name. - uvm_test: pwrmgr_base_test - uvm_test_seq: pwrmgr_base_vseq - - // Enable cdc instrumentation. - run_opts: ["+cdc_instrumentation_enabled=1"] - - // List of test specifications. - tests: [ - { - name: pwrmgr_smoke - uvm_test_seq: pwrmgr_smoke_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_reset - uvm_test_seq: pwrmgr_reset_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_lowpower_wakeup_race - uvm_test_seq: pwrmgr_lowpower_wakeup_race_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_wakeup - uvm_test_seq: pwrmgr_wakeup_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_wakeup_reset - uvm_test_seq: pwrmgr_wakeup_reset_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_aborted_low_power - uvm_test_seq: pwrmgr_aborted_low_power_vseq - } - { - name: pwrmgr_sec_cm_lc_ctrl_intersig_mubi - uvm_test_seq: pwrmgr_repeat_wakeup_reset_vseq - run_opts: ["+test_timeout_ns=3000000", "+pwrmgr_mubi_mode=PwrmgrMubiLcCtrl"] - } - { - name: pwrmgr_sec_cm_rom_ctrl_intersig_mubi - uvm_test_seq: pwrmgr_repeat_wakeup_reset_vseq - run_opts: ["+test_timeout_ns=4000000", "+pwrmgr_mubi_mode=PwrmgrMubiRomCtrl"] - } - { - name: pwrmgr_sec_cm_rstmgr_intersig_mubi - uvm_test_seq: pwrmgr_sw_reset_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_esc_clk_rst_malfunc - uvm_test_seq: pwrmgr_esc_clk_rst_malfunc_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_sec_cm_ctrl_config_regwen - uvm_test_seq: pwrmgr_sec_cm_ctrl_config_regwen_vseq - run_opts: ["+test_timeout_ns=50000000"] - } - { - name: pwrmgr_global_esc - uvm_test_seq: pwrmgr_global_esc_vseq - run_opts: ["+test_timeout_ns=1000000000"] - } - { - name: pwrmgr_glitch - uvm_test_seq: pwrmgr_glitch_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_disable_rom_integrity_check - uvm_test_seq: pwrmgr_disable_rom_integrity_check_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_reset_invalid - uvm_test_seq: pwrmgr_reset_invalid_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - { - name: pwrmgr_lowpower_invalid - uvm_test_seq: pwrmgr_lowpower_invalid_vseq - run_opts: ["+test_timeout_ns=1000000"] - } - ] - - // List of regressions. - regressions: [ - { - name: smoke - tests: ["pwrmgr_smoke"] - } - ] -} diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv deleted file mode 100644 index d8c7c53b93519e..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This has some assertions that check the inputs from ast react according to -// the pwrmgr outputs. The ast inputs are generated by the base sequences, but -// these assertions will also be useful at full chip level. -interface pwrmgr_ast_sva_if #( - parameter bit CheckClocks = 1'b0 -) ( - input logic clk_slow_i, - input logic rst_slow_ni, - input logic clk_main_i, - input logic clk_io_i, - input logic clk_usb_i, - input logic por_d0_ni, - // The pwrmgr outputs. - input pwrmgr_pkg::pwr_ast_req_t pwr_ast_o, - // The pwrmgr inputs. - input pwrmgr_pkg::pwr_ast_rsp_t pwr_ast_i -); - - // These numbers of cycles are meant to match both the randomization in - // pwrmgr_base_vseq, and the actual cycle counts from full chip. - // Notice the expectation for full chip is that deassertion of *clk_val - // takes 0 cycles, and assertion takes a 2 cycle synchronizer delay on - // the slow clock; deassertion of main_pok takes one cycle, and assertion - // not more than 2 cycles. - localparam int MIN_CLK_WAIT_CYCLES = 0; - localparam int MIN_PDN_WAIT_CYCLES = 0; - localparam int MAX_CLK_WAIT_CYCLES = 60; - localparam int MAX_PDN_WAIT_CYCLES = 110; - - bit disable_sva; - bit reset_or_disable; - - always_comb reset_or_disable = !rst_slow_ni || disable_sva; - - `define CLK_WAIT_BOUNDS ##[MIN_CLK_WAIT_CYCLES:MAX_CLK_WAIT_CYCLES] - `define PDN_WAIT_BOUNDS ##[MIN_PDN_WAIT_CYCLES:MAX_PDN_WAIT_CYCLES] - - // Clock enable-valid. - - // Changes triggered by por_d0_ni only affect clk_val. - `ASSERT(CoreClkGlitchToValOff_A, $fell(por_d0_ni) |-> ##[0:1] !pwr_ast_i.core_clk_val, clk_slow_i, - reset_or_disable) - `ASSERT(CoreClkGlitchToValOn_A, - $rose(por_d0_ni) && pwr_ast_o.core_clk_en |-> ##[0:2] pwr_ast_i.core_clk_val, clk_slow_i, - reset_or_disable) - `ASSERT(IoClkGlitchToValOff_A, $fell(por_d0_ni) |-> ##[0:1] !pwr_ast_i.io_clk_val, clk_slow_i, - reset_or_disable) - `ASSERT(IoClkGlitchToValOn_A, - $rose(por_d0_ni) && pwr_ast_o.io_clk_en |-> ##[0:2] pwr_ast_i.io_clk_val, clk_slow_i, - reset_or_disable) - `ASSERT(UsbClkGlitchToValOff_A, $fell(por_d0_ni) |-> ##[0:5] !pwr_ast_i.usb_clk_val, clk_slow_i, - reset_or_disable) - `ASSERT(UsbClkGlitchToValOn_A, - $rose(por_d0_ni) && pwr_ast_o.usb_clk_en |-> ##[0:5] pwr_ast_i.usb_clk_val, clk_slow_i, - reset_or_disable) - - // Changes not triggered by por_d0_ni - `ASSERT(CoreClkHandshakeOn_A, - $rose(pwr_ast_o.core_clk_en) && por_d0_ni |-> `CLK_WAIT_BOUNDS - pwr_ast_i.core_clk_val || !por_d0_ni, clk_slow_i, reset_or_disable) - `ASSERT(CoreClkHandshakeOff_A, - $fell(pwr_ast_o.core_clk_en) |-> `CLK_WAIT_BOUNDS !pwr_ast_i.core_clk_val, clk_slow_i, - reset_or_disable) - - `ASSERT(IoClkHandshakeOn_A, - $rose(pwr_ast_o.io_clk_en) && por_d0_ni |-> `CLK_WAIT_BOUNDS - pwr_ast_i.io_clk_val || !por_d0_ni, clk_slow_i, reset_or_disable) - `ASSERT(IoClkHandshakeOff_A, - $fell(pwr_ast_o.io_clk_en) |-> `CLK_WAIT_BOUNDS !pwr_ast_i.io_clk_val, clk_slow_i, - reset_or_disable) - - // Usb is a bit different: apparently usb_clk_val can stay low after a power glitch, so it may - // already be low when usb_clk_en drops. - `ASSERT(UsbClkHandshakeOn_A, - $rose(pwr_ast_o.usb_clk_en) && por_d0_ni && $past(por_d0_ni, 1) |-> `CLK_WAIT_BOUNDS - pwr_ast_i.usb_clk_val || !por_d0_ni, clk_slow_i, reset_or_disable) - `ASSERT(UsbClkHandshakeOff_A, - $fell(pwr_ast_o.usb_clk_en) |-> `CLK_WAIT_BOUNDS !pwr_ast_i.usb_clk_val, clk_slow_i, - reset_or_disable) - - if (CheckClocks) begin : gen_check_clock - int main_clk_cycles, io_clk_cycles, usb_clk_cycles; - always_ff @(posedge clk_main_i) main_clk_cycles++; - always_ff @(posedge clk_io_i) io_clk_cycles++; - always_ff @(posedge clk_usb_i) usb_clk_cycles++; - - `ASSERT(MainClkStopped_A, - $fell( - pwr_ast_i.core_clk_val - ) |=> ($stable( - main_clk_cycles - ) || pwr_ast_i.core_clk_val) [* 1 : $], - clk_slow_i, reset_or_disable) - `ASSERT(MainClkRun_A, - $rose( - pwr_ast_i.core_clk_val - ) |=> (!$stable( - main_clk_cycles - ) || !pwr_ast_i.core_clk_val) [* 1 : $], - clk_slow_i, reset_or_disable) - - `ASSERT(IOClkStopped_A, - $fell( - pwr_ast_i.io_clk_val - ) |=> ($stable( - io_clk_cycles - ) || pwr_ast_i.io_clk_val) [* 1 : $], - clk_slow_i, reset_or_disable) - `ASSERT(IOClkRun_A, - $rose( - pwr_ast_i.io_clk_val - ) |=> (!$stable( - io_clk_cycles - ) || !pwr_ast_i.io_clk_val) [* 1 : $], - clk_slow_i, reset_or_disable) - - `ASSERT(USBClkStopped_A, - $fell( - pwr_ast_i.usb_clk_val - ) |=> ($stable( - usb_clk_cycles - ) || pwr_ast_i.usb_clk_val) [* 1 : $], - clk_slow_i, reset_or_disable) - `ASSERT(USBClkRun_A, - $rose( - pwr_ast_i.usb_clk_val - ) |=> (!$stable( - usb_clk_cycles - ) || !pwr_ast_i.usb_clk_val) [* 1 : $], - clk_slow_i, reset_or_disable) - end - - // Main pd-pok - `ASSERT(MainPdHandshakeOn_A, pwr_ast_o.main_pd_n |-> `PDN_WAIT_BOUNDS pwr_ast_i.main_pok, - clk_slow_i, reset_or_disable) - `ASSERT(MainPdHandshakeOff_A, !pwr_ast_o.main_pd_n |-> `PDN_WAIT_BOUNDS !pwr_ast_i.main_pok, - clk_slow_i, reset_or_disable) - - `undef CLK_WAIT_BOUNDS - `undef PDN_WAIT_BOUNDS -endinterface diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv deleted file mode 100644 index 30791fbab57df6..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_bind.sv +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -module pwrmgr_bind; -`ifndef GATE_LEVEL - bind pwrmgr tlul_assert #( - .EndpointType("Device") - ) tlul_assert_device (.clk_i, .rst_ni, .h2d(tl_i), .d2h(tl_o)); - - // In top-level testbench, do not bind the csr_assert_fpv to reduce simulation time. -`ifndef TOP_LEVEL_DV - bind pwrmgr pwrmgr_csr_assert_fpv pwrmgr_csr_assert (.clk_i, .rst_ni, .h2d(tl_i), .d2h(tl_o)); -`endif - - // Clock control assertions. - bind pwrmgr pwrmgr_clock_enables_sva_if pwrmgr_clock_enables_sva_if ( - .clk_i(clk_slow_i), - .rst_ni(rst_slow_ni), - .fast_state(u_fsm.state_q), - .slow_state(u_slow_fsm.state_q), - // The synchronized control CSR bits. - .main_pd_ni(slow_main_pd_n), - .core_clk_en_i(slow_core_clk_en), - .io_clk_en_i(slow_io_clk_en), - .usb_clk_en_lp_i(slow_usb_clk_en_lp), - .usb_clk_en_active_i(slow_usb_clk_en_active), - .usb_ip_clk_status_i(usb_ip_clk_status), - // The main power control. - .main_pd_n(pwr_ast_o.main_pd_n), - // The output enables. - .core_clk_en(pwr_ast_o.core_clk_en), - .io_clk_en(pwr_ast_o.io_clk_en), - .usb_clk_en(pwr_ast_o.usb_clk_en) - ); - - bind pwrmgr pwrmgr_rstmgr_sva_if pwrmgr_rstmgr_sva_if ( - .clk_i, - .rst_ni, - .clk_slow_i, - .rst_slow_ni, - // The outputs from pwrmgr. - .rst_lc_req(pwr_rst_o.rst_lc_req), - .rst_sys_req(pwr_rst_o.rst_sys_req), - // The inputs from rstmgr. - .rst_lc_src_n(pwr_rst_i.rst_lc_src_n), - .rst_sys_src_n(pwr_rst_i.rst_sys_src_n) - ); - - bind pwrmgr clkmgr_pwrmgr_sva_if clkmgr_pwrmgr_sva_if ( - .clk_i, - .rst_ni, - .io_clk_en(pwr_clk_o.io_ip_clk_en), - .io_status(pwr_clk_i.io_status), - .main_clk_en(pwr_clk_o.main_ip_clk_en), - .main_status(pwr_clk_i.main_status), - .usb_clk_en(pwr_clk_o.usb_ip_clk_en), - .usb_status(pwr_clk_i.usb_status) - ); - - bind pwrmgr pwrmgr_sec_cm_checker_assert pwrmgr_sec_cm_checker_assert ( - .clk_i, - .rst_ni, - .clk_lc_i, - .rst_lc_ni, - .clk_esc_i, - .rst_esc_ni, - .clk_slow_i, - .rst_slow_ni, - .rst_main_ni, - .pwr_rst_o, - .slow_esc_rst_req(slow_peri_reqs.rstreqs[3]), - .slow_mp_rst_req(slow_peri_reqs.rstreqs[2]), - .slow_fsm_invalid, - .fast_fsm_invalid(u_fsm.u_state_regs.unused_err_o), - .rom_intg_chk_dis(u_fsm.rom_intg_chk_dis), - .rom_intg_chk_done(u_fsm.rom_intg_chk_done), - .rom_intg_chk_good(u_fsm.rom_intg_chk_good), - .fast_state(u_fsm.state_q), - .lc_dft_en_i(u_fsm.lc_dft_en_i), - .lc_hw_debug_en_i(u_fsm.lc_hw_debug_en_i), - .main_pd_ni(u_slow_fsm.main_pd_ni), - .rom_ctrl_done_i(u_fsm.rom_ctrl_done_i), - .rom_ctrl_good_i(u_fsm.rom_ctrl_good_i) - ); -`endif -endmodule diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv deleted file mode 100644 index 70304aad0d375e..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This has some assertions that check that the output clock enables correspond -// to the control CSR when transitioning into or out of the active state. In -// addition, the usb clock can change anytime when in the active state. -interface pwrmgr_clock_enables_sva_if ( - input logic clk_i, - input logic rst_ni, - input pwrmgr_pkg::fast_pwr_state_e fast_state, - input pwrmgr_pkg::slow_pwr_state_e slow_state, - // The synchronized control CSR bits. - input logic main_pd_ni, - input logic io_clk_en_i, - input logic core_clk_en_i, - input logic usb_clk_en_lp_i, - input logic usb_clk_en_active_i, - input logic usb_ip_clk_status_i, - // The output enables. - input logic main_pd_n, - input logic io_clk_en, - input logic core_clk_en, - input logic usb_clk_en -); - - bit disable_sva; - bit reset_or_disable; - - always_comb reset_or_disable = !rst_ni || disable_sva; - - sequence transitionUp_S; slow_state == pwrmgr_pkg::SlowPwrStateReqPwrUp; endsequence - - sequence transitionDown_S; slow_state == pwrmgr_pkg::SlowPwrStatePwrClampOn; endsequence - - bit fast_is_active; - always_comb fast_is_active = fast_state == pwrmgr_pkg::FastPwrStateActive; - - // This allows the usb enable to be slower since it also depends on usb clk_status. - sequence usbActiveTransition_S; - ##[0:7] !fast_is_active || usb_clk_en == (usb_clk_en_active_i | usb_ip_clk_status_i); - endsequence - - `ASSERT(CoreClkPwrUp_A, transitionUp_S |=> core_clk_en == 1'b1, clk_i, reset_or_disable) - `ASSERT(IoClkPwrUp_A, transitionUp_S |=> io_clk_en == 1'b1, clk_i, reset_or_disable) - `ASSERT(UsbClkPwrUp_A, transitionUp_S |=> usb_clk_en == usb_clk_en_active_i, clk_i, - reset_or_disable) - - // This deals with transitions while the fast fsm is active. - `ASSERT(UsbClkActive_A, fast_is_active && $changed(usb_clk_en_active_i) |=> usbActiveTransition_S, - clk_i, reset_or_disable) - - `ASSERT(CoreClkPwrDown_A, transitionDown_S |=> core_clk_en == (core_clk_en_i && main_pd_ni), - clk_i, reset_or_disable) - `ASSERT(IoClkPwrDown_A, transitionDown_S |=> io_clk_en == (io_clk_en_i && main_pd_ni), clk_i, - reset_or_disable) - `ASSERT(UsbClkPwrDown_A, transitionDown_S |=> usb_clk_en == (usb_clk_en_lp_i && main_pd_ni), - clk_i, reset_or_disable) -endinterface diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core b/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core deleted file mode 100644 index 79631950495e26..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.core +++ /dev/null @@ -1,19 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:pwrmgr_rstmgr_sva_if:0.1" -description: "PWRMGR to RSTMGR assertion interface." -filesets: - files_dv: - depend: - - lowrisc:ip:pwrmgr_pkg - - lowrisc:prim:assert - files: - - pwrmgr_rstmgr_sva_if.sv - file_type: systemVerilogSource - -targets: - default: - filesets: - - files_dv diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv deleted file mode 100644 index 34e60d34a7d267..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This has some assertions that check the inputs from rstmgr react according to -// the pwrmgr outputs. The rstmgr inputs are generated by the base sequences, but -// these assertions will also be useful at full chip level. -interface pwrmgr_rstmgr_sva_if - import pwrmgr_pkg::*, pwrmgr_reg_pkg::*; -( - input logic clk_i, - input logic rst_ni, - input logic clk_slow_i, - input logic rst_slow_ni, - - // The inputs from pwrmgr. - input logic [PowerDomains-1:0] rst_lc_req, - input logic [PowerDomains-1:0] rst_sys_req, - - // The inputs from rstmgr. - input logic [PowerDomains-1:0] rst_lc_src_n, - input logic [PowerDomains-1:0] rst_sys_src_n -); - - // Number of cycles for the LC/SYS reset handshake. - localparam int MIN_LC_SYS_CYCLES = 0; - localparam int MAX_LC_SYS_CYCLES = 150; - `define LC_SYS_CYCLES ##[MIN_LC_SYS_CYCLES:MAX_LC_SYS_CYCLES] - - bit disable_sva; - bit reset_or_disable; - - always_comb reset_or_disable = !rst_slow_ni || disable_sva; - - // Lc and Sys handshake: pwrmgr rst_*_req causes rstmgr rst_*_src_n - for (genvar pd = 0; pd < PowerDomains; ++pd) begin : gen_assertions_per_power_domains - `ASSERT(LcHandshakeOn_A, rst_lc_req[pd] |-> `LC_SYS_CYCLES !rst_lc_req[pd] || !rst_lc_src_n[pd], - clk_i, reset_or_disable) - `ASSERT(LcHandshakeOff_A, $fell(rst_lc_req[pd]) - |-> `LC_SYS_CYCLES rst_lc_req[pd] || rst_lc_src_n[pd], clk_i, reset_or_disable) - `ASSERT(SysHandshakeOn_A, - rst_sys_req[pd] |-> `LC_SYS_CYCLES !rst_sys_req[pd] || !rst_sys_src_n[pd], clk_i, - reset_or_disable) - `ASSERT(SysHandshakeOff_A, - !rst_sys_req[pd] |-> `LC_SYS_CYCLES rst_sys_req[pd] || rst_sys_src_n[pd], clk_i, - reset_or_disable) - end : gen_assertions_per_power_domains - `undef LC_SYS_CYCLES -endinterface diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv deleted file mode 100644 index f66da95433cfcb..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// This has some assertions that check the pwrmgr rstreqs and reset_cause output is set per the -// reset requests the pwrmgr receives or generates. -interface pwrmgr_rstreqs_sva_if - import pwrmgr_pkg::*, pwrmgr_reg_pkg::*; -( - input logic clk_i, - input logic rst_ni, - input logic clk_slow_i, - input logic rst_slow_ni, - - // Input causes resets. - input logic [ NumRstReqs-1:0] rstreqs_i, - input logic [ NumRstReqs-1:0] reset_en, - input logic sw_rst_req_i, - input logic main_rst_req_i, - input logic esc_rst_req_i, - input logic ndm_rst_req_i, - // outputs - input logic main_pd_n, - input reset_cause_e reset_cause, - input logic [HwResetWidth-1:0] rstreqs -); - - // output reset cycle with a clk enable disable - localparam int MIN_MAIN_RST_CYCLES = 0; - localparam int MAX_MAIN_RST_CYCLES = 400; - `define MAIN_RST_CYCLES ##[MIN_MAIN_RST_CYCLES:MAX_MAIN_RST_CYCLES] - - // The timing of the escalation reset is determined by the slow clock, but will not propagate if - // the non-slow clock is off. We use the regular clock and multiply the clock cycles times the - // clock ratio. - localparam int FAST_TO_SLOW_FREQ_RATIO = 120; - - localparam int MIN_ESC_RST_CYCLES = 0; - localparam int MAX_ESC_RST_CYCLES = 4 * FAST_TO_SLOW_FREQ_RATIO; - `define ESC_RST_CYCLES ##[MIN_ESC_RST_CYCLES:MAX_ESC_RST_CYCLES] - - bit disable_sva; - bit reset_or_disable; - - always_comb reset_or_disable = !rst_ni || !rst_slow_ni || disable_sva; - - // Reset ins to outs. - for (genvar rst = 0; rst < NumRstReqs; ++rst) begin : gen_hw_resets - `ASSERT(HwResetOn_A, - $rose( - rstreqs_i[rst] && reset_en[rst] - ) |-> `MAIN_RST_CYCLES rstreqs[rst] && reset_cause == HwReq, clk_slow_i, - reset_or_disable) - `ASSERT(HwResetOff_A, - $fell( - rstreqs_i[rst] && reset_en[rst] - ) |-> `MAIN_RST_CYCLES !rstreqs[rst] && reset_cause != HwReq, clk_slow_i, - reset_or_disable) - end - - // This is used to ignore main_rst_req_i (wired to rst_main_n) if it happens during low power, - // since as part of deep sleep rst_main_n will trigger and not because of a power glitch. - logic rst_main_n_ignored_for_main_pwr_rst; - always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin - if (!rst_slow_ni) begin - rst_main_n_ignored_for_main_pwr_rst <= 0; - end else if (!main_pd_n && reset_cause == LowPwrEntry) begin - rst_main_n_ignored_for_main_pwr_rst <= 1; - end else if (reset_cause != LowPwrEntry) begin - rst_main_n_ignored_for_main_pwr_rst <= 0; - end - end - - `ASSERT(MainPwrRstOn_A, - $rose( - main_rst_req_i && !rst_main_n_ignored_for_main_pwr_rst - ) |-> `MAIN_RST_CYCLES rstreqs[ResetMainPwrIdx], clk_slow_i, - reset_or_disable) - `ASSERT(MainPwrRstOff_A, - $fell( - main_rst_req_i - ) |-> `MAIN_RST_CYCLES !rstreqs[ResetMainPwrIdx], clk_slow_i, - reset_or_disable) - - // Signals in EscRstOn_A and EscRstOff_A are sampled with slow and fast clock. - // Since fast clock can be gated, use fast clock to evaluate cycle delay - // to avoid spurious failure. - `ASSERT(EscRstOn_A, - $rose( - esc_rst_req_i - ) |-> `ESC_RST_CYCLES rstreqs[ResetEscIdx], clk_i, reset_or_disable) - `ASSERT(EscRstOff_A, - $fell( - esc_rst_req_i - ) |-> `ESC_RST_CYCLES !rstreqs[ResetEscIdx], clk_i, reset_or_disable) - - // Software initiated resets do not affect rstreqs since rstmgr generates them. - `ASSERT(SwResetSetCause_A, - $rose(sw_rst_req_i) |-> MAIN_RST_CYCLES (reset_cause == HwReq), clk_i, - reset_or_disable) - -endinterface diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv b/hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv deleted file mode 100644 index d91eaf7b6e31db..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// add description here TBD -module pwrmgr_sec_cm_checker_assert - import pwrmgr_reg_pkg::*; -( - input clk_i, - input rst_ni, - input clk_lc_i, - input rst_lc_ni, - input clk_esc_i, - input rst_esc_ni, - input rst_main_ni, - input clk_slow_i, - input rst_slow_ni, - input pwrmgr_pkg::pwr_rst_req_t pwr_rst_o, - input slow_fsm_invalid, - input fast_fsm_invalid, - input prim_mubi_pkg::mubi4_t rom_intg_chk_dis, - input prim_mubi_pkg::mubi4_t rom_intg_chk_done, - input prim_mubi_pkg::mubi4_t rom_intg_chk_good, - input pwrmgr_pkg::fast_pwr_state_e fast_state, - input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, - input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, - input slow_esc_rst_req, - input slow_mp_rst_req, - input main_pd_ni, - input prim_mubi_pkg::mubi4_t rom_ctrl_done_i, - input prim_mubi_pkg::mubi4_t rom_ctrl_good_i -); - - bit disable_sva; - bit reset_or_disable; - bit esc_reset_or_disable; - bit slow_reset_or_disable; - - always_comb reset_or_disable = !rst_ni || disable_sva; - always_comb esc_reset_or_disable = !rst_esc_ni || disable_sva; - always_comb slow_reset_or_disable = !rst_slow_ni || disable_sva; - - // rom_intg_chk_dis only allows two states. - // Note that lc_dft_en_i and lc_hw_debug_en_i are already synchronized to clk_i at this - // hierarchy level. - `ASSERT(RomIntgChkDisTrue_A, - rom_intg_chk_dis == prim_mubi_pkg::MuBi4True |-> - (lc_dft_en_i == lc_ctrl_pkg::On && - lc_hw_debug_en_i == lc_ctrl_pkg::On), - clk_i, - reset_or_disable) - - `ASSERT(RomIntgChkDisFalse_A, - rom_intg_chk_dis == prim_mubi_pkg::MuBi4False |-> - (lc_dft_en_i !== lc_ctrl_pkg::On || - lc_hw_debug_en_i !== lc_ctrl_pkg::On), - clk_i, - reset_or_disable) - - // For any assertions involving state transitions, also allow cases where the fsm - // transitions to an invalid state, since we inject invalid encodings at random. - - // Check that unless rom_intg_chk_done is mubi true the fast state machine will - // stay in FastPwrStateRomCheckDone. - `ASSERT(RomBlockCheckGoodState_A, - rom_intg_chk_done != prim_mubi_pkg::MuBi4True && - fast_state == pwrmgr_pkg::FastPwrStateRomCheckDone |=> - fast_state == pwrmgr_pkg::FastPwrStateRomCheckDone || - fast_state == pwrmgr_pkg::FastPwrStateInvalid, - clk_i, - reset_or_disable) - - `ASSERT(RomAllowCheckGoodState_A, - rom_intg_chk_done == prim_mubi_pkg::MuBi4True && - fast_state == pwrmgr_pkg::FastPwrStateRomCheckDone |=> - fast_state == pwrmgr_pkg::FastPwrStateRomCheckGood || - fast_state == pwrmgr_pkg::FastPwrStateInvalid, - clk_i, - reset_or_disable) - - // Check that unless rom_intg_chk_good is mubi true or rom_intg_chk_dis is mubi true - // the fast state machine will stay in FastPwrStateRomCheckGood. - `ASSERT(RomBlockActiveState_A, - rom_intg_chk_good != prim_mubi_pkg::MuBi4True && - rom_intg_chk_dis != prim_mubi_pkg::MuBi4True && - fast_state == pwrmgr_pkg::FastPwrStateRomCheckGood |=> - fast_state == pwrmgr_pkg::FastPwrStateRomCheckGood || - fast_state == pwrmgr_pkg::FastPwrStateInvalid, - clk_i, - reset_or_disable) - - `ASSERT(RomAllowActiveState_A, - (rom_intg_chk_good == prim_mubi_pkg::MuBi4True || - rom_intg_chk_dis == prim_mubi_pkg::MuBi4True) && - fast_state == pwrmgr_pkg::FastPwrStateRomCheckGood |=> - fast_state == pwrmgr_pkg::FastPwrStateActive || - fast_state == pwrmgr_pkg::FastPwrStateInvalid, - clk_i, - reset_or_disable) - - // pwr_rst_o.rstreqs checker - // sec_cm_esc_rx_clk_bkgn_chk, sec_cm_esc_rx_clk_local_esc - // if esc_timeout, rstreqs[ResetEscIdx] should be asserted - `ASSERT(RstreqChkEsctimeout_A, - $rose( - slow_esc_rst_req - ) ##1 slow_esc_rst_req |-> ##[0:10] pwr_rst_o.rstreqs[ResetEscIdx], - clk_i, reset_or_disable) - -// sec_cm_fsm_terminal -// if slow_fsm or fast_fsm is invalid, -// both pwr_rst_o.rst_lc_req and pwr_rst_o.rst_sys_req should be set - - `ASSERT(RstreqChkFsmterm_A, - $rose(slow_fsm_invalid) || $rose(fast_fsm_invalid) - |-> ##[0:10] $rose(pwr_rst_o.rst_lc_req & pwr_rst_o.rst_sys_req), - clk_i, reset_or_disable) - -// sec_cm_ctrl_flow_global_esc -// if esc_rst_req is set, pwr_rst_o.rstreqs[ResetEscIdx] should be asserted. - `ASSERT(RstreqChkGlbesc_A, - $rose(slow_esc_rst_req) ##1 slow_esc_rst_req |-> - ##[0:10] (pwr_rst_o.rstreqs[ResetEscIdx] | !rst_esc_ni), - clk_i, reset_or_disable) - -// sec_cm_main_pd_rst_local_esc -// if power is up and rst_main_ni goes low, pwr_rst_o.rstreqs[ResetMainPwrIdx] should be asserted - `ASSERT(RstreqChkMainpd_A, - slow_mp_rst_req |-> ##[0:5] pwr_rst_o.rstreqs[ResetMainPwrIdx], clk_i, - reset_or_disable) - -endmodule // pwrmgr_sec_cm_checker_assert diff --git a/hw/ip/pwrmgr/dv/sva/pwrmgr_sva.core b/hw/ip/pwrmgr/dv/sva/pwrmgr_sva.core deleted file mode 100644 index a3491ab7871a37..00000000000000 --- a/hw/ip/pwrmgr/dv/sva/pwrmgr_sva.core +++ /dev/null @@ -1,43 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:pwrmgr_sva:0.1" -description: "PWRMGR assertion modules and bind file." -filesets: - files_dv: - depend: - - lowrisc:tlul:headers - - lowrisc:fpv:csr_assert_gen - - lowrisc:ip:pwrmgr - - lowrisc:dv:clkmgr_pwrmgr_sva_if - - lowrisc:dv:pwrmgr_rstmgr_sva_if - files: - - pwrmgr_bind.sv - - pwrmgr_clock_enables_sva_if.sv - - pwrmgr_rstreqs_sva_if.sv - - pwrmgr_sec_cm_checker_assert.sv - file_type: systemVerilogSource - - files_formal: - depend: - - lowrisc:ip:pwrmgr - -generate: - csr_assert_gen: - generator: csr_assert_gen - parameters: - spec: ../../../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson - -targets: - default: &default_target - filesets: - - files_dv - generate: - - csr_assert_gen - formal: - <<: *default_target - filesets: - - files_formal - - files_dv - toplevel: pwrmgr diff --git a/hw/ip/pwrmgr/dv/tb.sv b/hw/ip/pwrmgr/dv/tb.sv deleted file mode 100644 index 9fb11d5a7329c4..00000000000000 --- a/hw/ip/pwrmgr/dv/tb.sv +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -module tb; - // dep packages - import uvm_pkg::*; - import dv_utils_pkg::*; - import pwrmgr_env_pkg::*; - import pwrmgr_test_pkg::*; - - // macro includes - `include "uvm_macros.svh" - `include "dv_macros.svh" - - wire clk, rst_n; - wire clk_esc, rst_esc_n; - wire clk_lc, rst_lc_n; - wire clk_slow, rst_slow_n; - wire devmode; - wire [NUM_MAX_INTERRUPTS-1:0] interrupts; - - // interfaces - clk_rst_if clk_rst_if ( - .clk (clk), - .rst_n(rst_n) - ); - clk_rst_if lc_clk_rst_if ( - .clk (clk_lc), - .rst_n(rst_lc_n) - ); - clk_rst_if esc_clk_rst_if ( - .clk (clk_esc), - .rst_n(rst_esc_n) - ); - clk_rst_if slow_clk_rst_if ( - .clk (clk_slow), - .rst_n(rst_slow_n) - ); - pins_if #(NUM_MAX_INTERRUPTS) intr_if (interrupts); - alert_esc_if esc_if ( - .clk (clk), - .rst_n(rst_n) - ); - pins_if #(1) devmode_if (devmode); - tl_if tl_if ( - .clk (clk), - .rst_n(rst_n) - ); - - assign interrupts[0] = pwrmgr_if.intr_wakeup; - - pwrmgr_if pwrmgr_if ( - .clk, - .rst_n, - .clk_slow, - .rst_slow_n - ); - - `DV_ALERT_IF_CONNECT(clk_lc, rst_lc_n) - - // dut - pwrmgr dut ( - .clk_i (clk), - .rst_ni (rst_n), - .clk_slow_i (clk_slow), - .rst_slow_ni(rst_slow_n), - .rst_main_ni(pwrmgr_if.rst_main_n), - .clk_lc_i (clk_lc), - .rst_lc_ni (rst_lc_n), - .clk_esc_i (clk_esc), - .rst_esc_ni (rst_esc_n), - - .tl_i(tl_if.h2d), - .tl_o(tl_if.d2h), - - .alert_rx_i(alert_rx), - .alert_tx_o(alert_tx), - - .pwr_ast_i(pwrmgr_if.pwr_ast_rsp), - .pwr_ast_o(pwrmgr_if.pwr_ast_req), - - .pwr_rst_i(pwrmgr_if.pwr_rst_rsp), - .pwr_rst_o(pwrmgr_if.pwr_rst_req), - - .pwr_clk_i(pwrmgr_if.pwr_clk_rsp), - .pwr_clk_o(pwrmgr_if.pwr_clk_req), - - .pwr_otp_i(pwrmgr_if.pwr_otp_rsp), - .pwr_otp_o(pwrmgr_if.pwr_otp_req), - - .pwr_lc_i(pwrmgr_if.pwr_lc_rsp), - .pwr_lc_o(pwrmgr_if.pwr_lc_req), - - .pwr_flash_i(pwrmgr_if.pwr_flash), - .pwr_cpu_i (pwrmgr_if.pwr_cpu), - - .fetch_en_o(pwrmgr_if.fetch_en), - .wakeups_i (pwrmgr_if.wakeups_i), - .rstreqs_i (pwrmgr_if.rstreqs_i), - .ndmreset_req_i(pwrmgr_if.cpu_i.ndmreset_req), - - .lc_dft_en_i (pwrmgr_if.lc_dft_en), - .lc_hw_debug_en_i(pwrmgr_if.lc_hw_debug_en), - - .strap_o (pwrmgr_if.strap), - .low_power_o(pwrmgr_if.low_power), - - .rom_ctrl_i(pwrmgr_if.rom_ctrl), - - .sw_rst_req_i(pwrmgr_if.sw_rst_req_i), - - .esc_rst_tx_i(esc_if.esc_tx), - .esc_rst_rx_o(esc_if.esc_rx), - - .intr_wakeup_o(pwrmgr_if.intr_wakeup) - ); - - initial begin - // drive clk and rst_n from clk_if - clk_rst_if.set_active(); - esc_clk_rst_if.set_active(); - lc_clk_rst_if.set_active(); - slow_clk_rst_if.set_active(); - - uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if); - uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "esc_clk_rst_vif", esc_clk_rst_if); - uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "lc_clk_rst_vif", lc_clk_rst_if); - uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "slow_clk_rst_vif", slow_clk_rst_if); - uvm_config_db#(devmode_vif)::set(null, "*.env", "devmode_vif", devmode_if); - uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if); - uvm_config_db#(virtual alert_esc_if)::set(null, "*.env.m_esc_agent*", "vif", esc_if); - uvm_config_db#(virtual pwrmgr_if)::set(null, "*.env", "pwrmgr_vif", pwrmgr_if); - uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if); - uvm_config_db#(virtual pwrmgr_clock_enables_sva_if)::set( - null, "*.env", "pwrmgr_clock_enables_sva_vif", dut.pwrmgr_clock_enables_sva_if); - uvm_config_db#(virtual pwrmgr_rstmgr_sva_if)::set(null, "*.env", "pwrmgr_rstmgr_sva_vif", - dut.pwrmgr_rstmgr_sva_if); - $timeformat(-12, 0, " ps", 12); - run_test(); - end // initial begin - -endmodule diff --git a/hw/ip/pwrmgr/dv/tests/pwrmgr_base_test.sv b/hw/ip/pwrmgr/dv/tests/pwrmgr_base_test.sv deleted file mode 100644 index 8538a4c02319ce..00000000000000 --- a/hw/ip/pwrmgr/dv/tests/pwrmgr_base_test.sv +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -class pwrmgr_base_test extends cip_base_test #( - .CFG_T(pwrmgr_env_cfg), - .ENV_T(pwrmgr_env) -); - - `uvm_component_utils(pwrmgr_base_test) - `uvm_component_new - - // the base class dv_base_test creates the following instances: - // pwrmgr_env_cfg: cfg - // pwrmgr_env: env - - // the base class also looks up UVM_TEST_SEQ plusarg to create and run that seq in - // the run_phase; as such, nothing more needs to be done - -endclass : pwrmgr_base_test diff --git a/hw/ip/pwrmgr/dv/tests/pwrmgr_test.core b/hw/ip/pwrmgr/dv/tests/pwrmgr_test.core deleted file mode 100644 index f48439ee72c65f..00000000000000 --- a/hw/ip/pwrmgr/dv/tests/pwrmgr_test.core +++ /dev/null @@ -1,19 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:dv:pwrmgr_test:0.1" -description: "PWRMGR DV UVM test" -filesets: - files_dv: - depend: - - lowrisc:dv:pwrmgr_env - files: - - pwrmgr_test_pkg.sv - - pwrmgr_base_test.sv: {is_include_file: true} - file_type: systemVerilogSource - -targets: - default: - filesets: - - files_dv diff --git a/hw/ip/pwrmgr/dv/tests/pwrmgr_test_pkg.sv b/hw/ip/pwrmgr/dv/tests/pwrmgr_test_pkg.sv deleted file mode 100644 index bec41c713f1d1f..00000000000000 --- a/hw/ip/pwrmgr/dv/tests/pwrmgr_test_pkg.sv +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -package pwrmgr_test_pkg; - // dep packages - import uvm_pkg::*; - import cip_base_pkg::*; - import pwrmgr_env_pkg::*; - - // macro includes - `include "uvm_macros.svh" - `include "dv_macros.svh" - - // local types - - // functions - - // package sources - `include "pwrmgr_base_test.sv" - -endpackage diff --git a/hw/ip/pwrmgr/lint/pwrmgr.vlt b/hw/ip/pwrmgr/lint/pwrmgr.vlt deleted file mode 100644 index dc237ec0da12dc..00000000000000 --- a/hw/ip/pwrmgr/lint/pwrmgr.vlt +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// waiver file for Power Manager diff --git a/hw/ip/pwrmgr/lint/pwrmgr.waiver b/hw/ip/pwrmgr/lint/pwrmgr.waiver deleted file mode 100644 index bb053b8678f830..00000000000000 --- a/hw/ip/pwrmgr/lint/pwrmgr.waiver +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -# -# waiver file for Power Manager diff --git a/hw/ip/pwrmgr/lint/pwrmgr_pkg.vlt b/hw/ip/pwrmgr/lint/pwrmgr_pkg.vlt deleted file mode 100644 index 4e837583611fb9..00000000000000 --- a/hw/ip/pwrmgr/lint/pwrmgr_pkg.vlt +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// waiver file for the pwrmgr_pkg - -`verilator_config - -// Waive the SYMRSVDWORD warning in pwrmgr_reg_pkg: we have a field in -// the WAKE_INFO register called "abort", which means pwrmgr_reg_pkg -// defines a struct with that name, clashing with a C++ reserved word. -lint_off -rule SYMRSVDWORD -file "*/pwrmgr_reg_pkg.sv" -match "*common word: 'abort'" diff --git a/hw/ip/pwrmgr/pwrmgr.core b/hw/ip/pwrmgr/pwrmgr.core deleted file mode 100644 index af706a346f7146..00000000000000 --- a/hw/ip/pwrmgr/pwrmgr.core +++ /dev/null @@ -1,80 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:ip:pwrmgr:0.1" -description: "Power manager component without the generated portions" - -filesets: - files_rtl: - depend: - - lowrisc:ip:tlul - - lowrisc:prim:esc - - lowrisc:prim:lc_sync - - lowrisc:prim:lc_sender - - lowrisc:prim:all - - lowrisc:ip:rom_ctrl_pkg - - lowrisc:ip:lc_ctrl_pkg - - lowrisc:ip:pwrmgr_pkg - - lowrisc:prim:sparse_fsm - - lowrisc:prim:mubi - - lowrisc:prim:clock_buf - - lowrisc:prim:measure - - lowrisc:ip_interfaces:alert_handler_reg - files: - - rtl/pwrmgr.sv - - rtl/pwrmgr_cdc.sv - - rtl/pwrmgr_slow_fsm.sv - - rtl/pwrmgr_fsm.sv - - rtl/pwrmgr_wake_info.sv - file_type: systemVerilogSource - - files_verilator_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/pwrmgr.vlt - file_type: vlt - - files_ascentlint_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/pwrmgr.waiver - file_type: waiver - - files_veriblelint_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - -parameters: - SYNTHESIS: - datatype: bool - paramtype: vlogdefine - - -targets: - default: &default_target - filesets: - - tool_verilator ? (files_verilator_waiver) - - tool_ascentlint ? (files_ascentlint_waiver) - - tool_veriblelint ? (files_veriblelint_waiver) - - files_rtl - toplevel: pwrmgr - - lint: - <<: *default_target - default_tool: verilator - parameters: - - SYNTHESIS=true - tools: - verilator: - mode: lint-only - verilator_options: - - "-Wall" diff --git a/hw/ip/pwrmgr/pwrmgr_pkg.core b/hw/ip/pwrmgr/pwrmgr_pkg.core deleted file mode 100644 index 3e83cde44fd128..00000000000000 --- a/hw/ip/pwrmgr/pwrmgr_pkg.core +++ /dev/null @@ -1,29 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:ip:pwrmgr_pkg:0.1" -description: "Power manager package" - -filesets: - files_rtl: - depend: - - lowrisc:ip:pwrmgr_reg - files: - - rtl/pwrmgr_pkg.sv - file_type: systemVerilogSource - - files_verilator_waiver: - depend: - # common waivers - - lowrisc:lint:common - - lowrisc:lint:comportable - files: - - lint/pwrmgr_pkg.vlt - file_type: vlt - -targets: - default: - filesets: - - tool_verilator ? (files_verilator_waiver) - - files_rtl diff --git a/hw/ip/pwrmgr/pwrmgr_reg.core b/hw/ip/pwrmgr/pwrmgr_reg.core deleted file mode 100644 index 93eaf5bd351846..00000000000000 --- a/hw/ip/pwrmgr/pwrmgr_reg.core +++ /dev/null @@ -1,21 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:ip:pwrmgr_reg:0.1" -description: "Power manager registers" - -filesets: - files_rtl: - depend: - - lowrisc:tlul:headers - - lowrisc:prim:subreg - - "!fileset_topgen ? (lowrisc:systems:pwrmgr_reg)" - - "fileset_topgen ? (lowrisc:systems:topgen-reg-only)" - files: - file_type: systemVerilogSource - -targets: - default: - filesets: - - files_rtl diff --git a/hw/ip/pwrmgr/rtl/pwrmgr.sv b/hw/ip/pwrmgr/rtl/pwrmgr.sv deleted file mode 100644 index 721540404190f5..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr.sv +++ /dev/null @@ -1,719 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Power Manager -// - -`include "prim_assert.sv" - -module pwrmgr - import pwrmgr_pkg::*; - import pwrmgr_reg_pkg::*; -#( - parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}} -) ( - // Clocks and resets - input clk_slow_i, - input clk_i, - input rst_slow_ni, - input rst_ni, - input rst_main_ni, - input clk_lc_i, - input rst_lc_ni, - input clk_esc_i, - input rst_esc_ni, - - // Bus Interface - input tlul_pkg::tl_h2d_t tl_i, - output tlul_pkg::tl_d2h_t tl_o, - - // Alerts - input prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i, - output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o, - - // AST interface - input pwr_ast_rsp_t pwr_ast_i, - output pwr_ast_req_t pwr_ast_o, - - // rstmgr interface - input pwr_rst_rsp_t pwr_rst_i, - output pwr_rst_req_t pwr_rst_o, - - // clkmgr interface - output pwr_clk_req_t pwr_clk_o, - input pwr_clk_rsp_t pwr_clk_i, - - // otp interface - input pwr_otp_rsp_t pwr_otp_i, - output pwr_otp_req_t pwr_otp_o, - - // life cycle interface - input pwr_lc_rsp_t pwr_lc_i, - output pwr_lc_req_t pwr_lc_o, - - // flash interface - input pwr_flash_t pwr_flash_i, - - // processor interface - input pwr_cpu_t pwr_cpu_i, - // SEC_CM: LC_CTRL.INTERSIG.MUBI - output lc_ctrl_pkg::lc_tx_t fetch_en_o, - input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, - input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, - - // peripherals wakeup and reset requests - input [NumWkups-1:0] wakeups_i, - input [NumRstReqs-1:0] rstreqs_i, - - // cpu related inputs - input ndmreset_req_i, - - // pinmux and other peripherals - output logic strap_o, - output logic low_power_o, - - // rom_ctrl interface - // SEC_CM: ROM_CTRL.INTERSIG.MUBI - input rom_ctrl_pkg::pwrmgr_data_t rom_ctrl_i, - - // software issued reset request - // SEC_CM: RSTMGR.INTERSIG.MUBI - input prim_mubi_pkg::mubi4_t sw_rst_req_i, - - // escalation interface - input prim_esc_pkg::esc_tx_t esc_rst_tx_i, - output prim_esc_pkg::esc_rx_t esc_rst_rx_o, - - output intr_wakeup_o - -); - //////////////////////////////////////////////////// - // Input handling // - //////////////////////////////////////////////////// - - logic ndmreset_req_q; - logic ndm_req_valid; - - prim_flop_2sync #( - .Width(1), - .ResetValue('0) - ) u_ndm_sync ( - .clk_i, - .rst_ni, - .d_i(ndmreset_req_i), - .q_o(ndmreset_req_q) - ); - - assign ndm_req_valid = ndmreset_req_q; - - //////////////////////////// - /// escalation detections - //////////////////////////// - - logic clk_lc; - logic rst_lc_n; - assign clk_lc = clk_lc_i; - assign rst_lc_n = rst_lc_ni; - - logic clk_esc; - logic rst_esc_n; - prim_clock_buf #( - .NoFpgaBuf(1'b1) - ) u_esc_clk_buf ( - .clk_i(clk_esc_i), - .clk_o(clk_esc) - ); - - prim_clock_buf #( - .NoFpgaBuf(1'b1) - ) u_esc_rst_buf ( - .clk_i(rst_esc_ni), - .clk_o(rst_esc_n) - ); - - logic esc_rst_req_d, esc_rst_req_q; - prim_esc_receiver #( - .N_ESC_SEV (alert_handler_reg_pkg::N_ESC_SEV), - .PING_CNT_DW (alert_handler_reg_pkg::PING_CNT_DW) - ) u_esc_rx ( - .clk_i(clk_esc), - .rst_ni(rst_esc_n), - .esc_req_o(esc_rst_req_d), - .esc_rx_o(esc_rst_rx_o), - .esc_tx_i(esc_rst_tx_i) - ); - - // These assertions use formal or simulation to prove that once esc_rst_req is latched, we expect - // to see the lc reset requests in pwr_rst_o. The one exception is when escalation requests are - // cancelled while the CPU fetch is disabled, meaning the fast fsm is inactive. -`ifdef SIMULATION - // In simulation mode, the prim_cdc_rand_delay module inserts a random one cycle delay to the - // two flop synchronizers. There are two CDCs in the path from escalation reset to the fast fsm - // receiving it, one to the slow clock, and one back to the fast one. And there are additional - // cycles in the fast fsm to generate outputs. However, esc_rst_req_q can be dropped due to - // rst_lc_n. - `ASSERT(PwrmgrSecCmEscToSlowResetReq_A, - esc_rst_req_q |-> ##[1:5] !esc_rst_req_q || slow_peri_reqs_masked.rstreqs[ResetEscIdx], - clk_slow_i, !rst_slow_ni) - `ASSERT(PwrmgrSecCmFsmEscToResetReq_A, - slow_peri_reqs_masked.rstreqs[ResetEscIdx] |-> ##[1:4] u_fsm.reset_reqs_i[ResetEscIdx], - clk_i, !rst_ni) -`else - `ASSERT(PwrmgrSecCmEscToSlowResetReq_A, - esc_rst_req_d |-> ##[2:3] ( - (!esc_rst_req_d && lc_ctrl_pkg::lc_tx_test_false_loose(fetch_en_o)) || - slow_peri_reqs_masked.rstreqs[ResetEscIdx] - ), clk_slow_i, !rst_slow_ni) - `ASSERT(PwrmgrSlowResetReqToFsmResetReq_A, - slow_peri_reqs_masked.rstreqs[ResetEscIdx] |-> ##1 u_fsm.reset_reqs_i[ResetEscIdx], - clk_i, !rst_ni) -`endif - - `ASSERT(PwrmgrSecCmEscToLCReset_A, u_fsm.reset_reqs_i[ResetEscIdx] && - u_fsm.state_q == FastPwrStateActive |-> ##4 pwr_rst_o.rst_lc_req == 2'b11, - clk_i, !rst_ni) - - always_ff @(posedge clk_lc or negedge rst_lc_n) begin - if (!rst_lc_n) begin - esc_rst_req_q <= '0; - end else if (esc_rst_req_d) begin - // once latched, do not clear until reset - esc_rst_req_q <= 1'b1; - end - end - - localparam int EscTimeOutCnt = 128; - logic esc_timeout; - // SEC_CM: ESC_RX.CLK.BKGN_CHK, ESC_RX.CLK.LOCAL_ESC - prim_clock_timeout #( - .TimeOutCnt(EscTimeOutCnt) - ) u_esc_timeout ( - .clk_chk_i(clk_esc), - .rst_chk_ni(rst_esc_n), - .clk_i, - .rst_ni, - // if any ip clock enable is turned on, then the escalation - // clocks are also enabled. - .en_i(|pwr_clk_o), - .timeout_o(esc_timeout) - ); - - - //////////////////////////// - /// async declarations - //////////////////////////// - pwr_peri_t peri_reqs_raw; - logic slow_rst_req; - - assign peri_reqs_raw.wakeups = wakeups_i; - assign peri_reqs_raw.rstreqs[NumRstReqs-1:0] = rstreqs_i; - assign peri_reqs_raw.rstreqs[ResetMainPwrIdx] = slow_rst_req; - // SEC_CM: ESC_RX.CLK.LOCAL_ESC, CTRL_FLOW.GLOBAL_ESC - assign peri_reqs_raw.rstreqs[ResetEscIdx] = esc_rst_req_q | esc_timeout; - assign peri_reqs_raw.rstreqs[ResetNdmIdx] = ndm_req_valid; - - //////////////////////////// - /// Software reset request - //////////////////////////// - logic sw_rst_req; - prim_buf #( - .Width(1) - ) u_sw_req_buf ( - .in_i(prim_mubi_pkg::mubi4_test_true_strict(sw_rst_req_i)), - .out_o(sw_rst_req) - ); - - assign peri_reqs_raw.rstreqs[ResetSwReqIdx] = sw_rst_req; - - //////////////////////////// - /// clk_i domain declarations - //////////////////////////// - - pwrmgr_reg2hw_t reg2hw; - pwrmgr_hw2reg_t hw2reg; - pwr_peri_t peri_reqs_masked; - - logic req_pwrup; - logic ack_pwrup; - logic req_pwrdn; - logic ack_pwrdn; - logic fsm_invalid; - logic clr_slow_req; - logic usb_ip_clk_en; - logic usb_ip_clk_status; - pwrup_cause_e pwrup_cause; - - logic low_power_fall_through; - logic low_power_abort; - - pwr_flash_t flash_rsp; - pwr_otp_rsp_t otp_rsp; - - prim_mubi_pkg::mubi4_t rom_ctrl_done; - prim_mubi_pkg::mubi4_t rom_ctrl_good; - - logic core_sleeping; - - //////////////////////////// - /// clk_slow_i domain declarations - //////////////////////////// - - // Captured signals - // These signals, though on clk_i domain, are safe for clk_slow_i to use - logic [NumWkups-1:0] slow_wakeup_en; - logic [NumRstReqs-1:0] slow_reset_en; - - pwr_ast_rsp_t slow_ast; - pwr_peri_t slow_peri_reqs, slow_peri_reqs_masked; - - pwrup_cause_e slow_pwrup_cause; - logic slow_pwrup_cause_toggle; - logic slow_req_pwrup; - logic slow_ack_pwrup; - logic slow_req_pwrdn; - logic slow_ack_pwrdn; - logic slow_fsm_invalid; - logic slow_main_pd_n; - logic slow_io_clk_en; - logic slow_core_clk_en; - logic slow_usb_clk_en_lp; - logic slow_usb_clk_en_active; - logic slow_clr_req; - logic slow_usb_ip_clk_en; - logic slow_usb_ip_clk_status; - - - - //////////////////////////// - /// Register module - //////////////////////////// - logic [NumAlerts-1:0] alert_test, alerts; - logic low_power_hint; - logic lowpwr_cfg_wen; - logic clr_hint; - logic wkup; - logic clr_cfg_lock; - logic reg_intg_err; - - // SEC_CM: BUS.INTEGRITY - // SEC_CM: CTRL.CONFIG.REGWEN, WAKEUP.CONFIG.REGWEN, RESET.CONFIG.REGWEN - pwrmgr_reg_top u_reg ( - .clk_i, - .rst_ni, - .clk_lc_i (clk_lc ), - .rst_lc_ni (rst_lc_n), - .tl_i, - .tl_o, - .reg2hw, - .hw2reg, - .intg_err_o (reg_intg_err), - .devmode_i (1'b1) - ); - - // whenever low power entry begins, wipe the hint - assign hw2reg.control.low_power_hint.d = 1'b0; - assign hw2reg.control.low_power_hint.de = clr_hint; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - lowpwr_cfg_wen <= 1'b1; - end else if (!lowpwr_cfg_wen && (clr_cfg_lock || wkup)) begin - lowpwr_cfg_wen <= 1'b1; - end else if (low_power_hint) begin - lowpwr_cfg_wen <= 1'b0; - end - end - - assign hw2reg.ctrl_cfg_regwen.d = lowpwr_cfg_wen; - - assign hw2reg.fault_status.reg_intg_err.de = reg_intg_err; - assign hw2reg.fault_status.reg_intg_err.d = 1'b1; - assign hw2reg.fault_status.esc_timeout.de = esc_timeout; - assign hw2reg.fault_status.esc_timeout.d = 1'b1; - - // The main power domain glitch automatically causes a reset, so regsitering - // an alert is functionally pointless. However, if an attacker somehow manages/ - // to silence the reset, this gives us one potential back-up path through alert_handler. - // Allow capture of main_pd fault status whenever the system is live. - assign hw2reg.fault_status.main_pd_glitch.de = pwr_clk_o.main_ip_clk_en; - assign hw2reg.fault_status.main_pd_glitch.d = peri_reqs_masked.rstreqs[ResetMainPwrIdx] | - reg2hw.fault_status.main_pd_glitch.q; - - `ASSERT(GlitchStatusPersist_A, $rose(reg2hw.fault_status.main_pd_glitch.q) |-> - reg2hw.fault_status.main_pd_glitch.q until !rst_lc_ni) - - //////////////////////////// - /// alerts - //////////////////////////// - - // the logic below assumes there is only one alert, so make an - // explicit assertion check for it. - `ASSERT_INIT(AlertNumCheck_A, NumAlerts == 1) - - assign alert_test = { - reg2hw.alert_test.q & - reg2hw.alert_test.qe - }; - - assign alerts[0] = reg2hw.fault_status.reg_intg_err.q | - reg2hw.fault_status.esc_timeout.q | - reg2hw.fault_status.main_pd_glitch.q; - - for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx - prim_alert_sender #( - .AsyncOn(AlertAsyncOn[i]), - .IsFatal(1'b1) - ) u_prim_alert_sender ( - .clk_i ( clk_lc ), - .rst_ni ( rst_lc_n ), - .alert_test_i ( alert_test[i] ), - .alert_req_i ( alerts[i] ), - .alert_ack_o ( ), - .alert_state_o ( ), - .alert_rx_i ( alert_rx_i[i] ), - .alert_tx_o ( alert_tx_o[i] ) - ); - end - - //////////////////////////// - /// cdc handling - //////////////////////////// - - pwrmgr_cdc u_cdc ( - .clk_i, - .rst_ni, - .clk_slow_i, - .rst_slow_ni, - - // slow domain signals - .slow_req_pwrup_i(slow_req_pwrup), - .slow_ack_pwrdn_i(slow_ack_pwrdn), - .slow_fsm_invalid_i(slow_fsm_invalid), - .slow_pwrup_cause_toggle_i(slow_pwrup_cause_toggle), - .slow_pwrup_cause_i(slow_pwrup_cause), - .slow_wakeup_en_o(slow_wakeup_en), - .slow_reset_en_o(slow_reset_en), - .slow_main_pd_no(slow_main_pd_n), - .slow_io_clk_en_o(slow_io_clk_en), - .slow_core_clk_en_o(slow_core_clk_en), - .slow_usb_clk_en_lp_o(slow_usb_clk_en_lp), - .slow_usb_clk_en_active_o(slow_usb_clk_en_active), - .slow_req_pwrdn_o(slow_req_pwrdn), - .slow_ack_pwrup_o(slow_ack_pwrup), - .slow_ast_o(slow_ast), - .slow_peri_reqs_o(slow_peri_reqs), - .slow_peri_reqs_masked_i(slow_peri_reqs_masked), - .slow_clr_req_o(slow_clr_req), - .slow_usb_ip_clk_en_i(slow_usb_ip_clk_en), - .slow_usb_ip_clk_status_o(slow_usb_ip_clk_status), - - // fast domain signals - .req_pwrdn_i(req_pwrdn), - .ack_pwrup_i(ack_pwrup), - .cfg_cdc_sync_i(reg2hw.cfg_cdc_sync.qe & reg2hw.cfg_cdc_sync.q), - .cdc_sync_done_o(hw2reg.cfg_cdc_sync.de), - .wakeup_en_i(reg2hw.wakeup_en), - .reset_en_i(reg2hw.reset_en), - .main_pd_ni(reg2hw.control.main_pd_n.q), - .io_clk_en_i(reg2hw.control.io_clk_en.q), - .core_clk_en_i(reg2hw.control.core_clk_en.q), - .usb_clk_en_lp_i(reg2hw.control.usb_clk_en_lp.q), - .usb_clk_en_active_i(reg2hw.control.usb_clk_en_active.q), - .ack_pwrdn_o(ack_pwrdn), - .fsm_invalid_o(fsm_invalid), - .req_pwrup_o(req_pwrup), - .pwrup_cause_o(pwrup_cause), - .peri_reqs_o(peri_reqs_masked), - .clr_slow_req_i(clr_slow_req), - .usb_ip_clk_en_o(usb_ip_clk_en), - .usb_ip_clk_status_i(usb_ip_clk_status), - - // AST signals - .ast_i(pwr_ast_i), - - // peripheral signals - .peri_i(peri_reqs_raw), - - // flash handshake - .flash_i(pwr_flash_i), - .flash_o(flash_rsp), - - // OTP signals - .otp_i(pwr_otp_i), - .otp_o(otp_rsp), - - // rom_ctrl signals - .rom_ctrl_done_i(rom_ctrl_i.done), - .rom_ctrl_done_o(rom_ctrl_done), - - // core sleeping - .core_sleeping_i(pwr_cpu_i.core_sleeping), - .core_sleeping_o(core_sleeping) - - ); - // rom_ctrl_i.good is not synchronized as it acts as a "payload" signal - // to "done". Good is only observed if "done" is high. - assign rom_ctrl_good = rom_ctrl_i.good; - assign hw2reg.cfg_cdc_sync.d = 1'b0; - - //////////////////////////// - /// Wakup and reset capture - //////////////////////////// - - // reset and wakeup requests are captured into the slow clock domain and then - // fanned out to other domains as necessary. This ensures there is not a huge - // time gap between when the slow clk domain sees the signal vs when the fast - // clock domains see it. This creates redundant syncing but keeps the time - // scale approximately the same across all domains. - // - // This also implies that these signals must be at least 1 clk_slow pulse long - // - // Since resets are not latched inside pwrmgr, there exists a corner case where - // non-always-on reset requests may get wiped out by a graceful low power entry - // It's not clear if this is really an issue at the moment, but something to keep - // in mind if future changes are needed. - // - // Latching the reset requests is not difficult, but the bigger question is who - // should clear it and when that should happen. If the clearing does not work - // correctly, it is possible for the device to end up in a permanent reset loop, - // and that would be very undesirable. - - assign slow_peri_reqs_masked.wakeups = slow_peri_reqs.wakeups & slow_wakeup_en; - // msb is software request - // the internal requests include escalation and internal requests - // the lsbs are the software enabled peripheral requests. - assign slow_peri_reqs_masked.rstreqs = slow_peri_reqs.rstreqs & - {{NumSwRstReq{1'b1}}, - {NumDebugRstReqs{1'b1}}, - {NumIntRstReqs{1'b1}}, - slow_reset_en}; - - for (genvar i = 0; i < NumWkups; i++) begin : gen_wakeup_status - assign hw2reg.wake_status[i].de = 1'b1; - assign hw2reg.wake_status[i].d = peri_reqs_masked.wakeups[i]; - end - - for (genvar i = 0; i < NumRstReqs; i++) begin : gen_reset_status - assign hw2reg.reset_status[i].de = 1'b1; - assign hw2reg.reset_status[i].d = peri_reqs_masked.rstreqs[i]; - end - - assign hw2reg.escalate_reset_status.de = 1'b1; - assign hw2reg.escalate_reset_status.d = peri_reqs_masked.rstreqs[NumRstReqs]; - - - //////////////////////////// - /// clk_slow FSM - //////////////////////////// - - pwrmgr_slow_fsm u_slow_fsm ( - .clk_i (clk_slow_i), - .rst_ni (rst_slow_ni), - .rst_main_ni (rst_main_ni), - .wakeup_i (|slow_peri_reqs_masked.wakeups), - .reset_req_i (|slow_peri_reqs_masked.rstreqs), - .ast_i (slow_ast), - .req_pwrup_o (slow_req_pwrup), - .pwrup_cause_o (slow_pwrup_cause), - .pwrup_cause_toggle_o (slow_pwrup_cause_toggle), - .ack_pwrup_i (slow_ack_pwrup), - .req_pwrdn_i (slow_req_pwrdn), - .ack_pwrdn_o (slow_ack_pwrdn), - .rst_req_o (slow_rst_req), - .fsm_invalid_o (slow_fsm_invalid), - .clr_req_i (slow_clr_req), - .usb_ip_clk_en_o (slow_usb_ip_clk_en), - .usb_ip_clk_status_i (slow_usb_ip_clk_status), - - .main_pd_ni (slow_main_pd_n), - .io_clk_en_i (slow_io_clk_en), - .core_clk_en_i (slow_core_clk_en), - .usb_clk_en_lp_i (slow_usb_clk_en_lp), - .usb_clk_en_active_i (slow_usb_clk_en_active), - - // outputs to AST - These are on the slow clock domain - // TBD - need to check this with partners - .ast_o (pwr_ast_o) - ); - - lc_ctrl_pkg::lc_tx_t lc_dft_en; - prim_lc_sync u_prim_lc_sync_dft_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_dft_en_i), - .lc_en_o({lc_dft_en}) - ); - - lc_ctrl_pkg::lc_tx_t lc_hw_debug_en; - prim_lc_sync u_prim_lc_sync_hw_debug_en ( - .clk_i, - .rst_ni, - .lc_en_i(lc_hw_debug_en_i), - .lc_en_o({lc_hw_debug_en}) - ); - - //////////////////////////// - /// clk FSM - //////////////////////////// - - assign low_power_hint = reg2hw.control.low_power_hint.q == LowPower; - - pwrmgr_fsm u_fsm ( - .clk_i, - .rst_ni, - .clk_slow_i, - .rst_slow_ni, - - // interface with slow_fsm - .req_pwrup_i (req_pwrup), - .pwrup_cause_i (pwrup_cause), // por, wake or reset request - .ack_pwrup_o (ack_pwrup), - .req_pwrdn_o (req_pwrdn), - .ack_pwrdn_i (ack_pwrdn), - .low_power_entry_i (core_sleeping & low_power_hint), - .reset_reqs_i (peri_reqs_masked.rstreqs), - .fsm_invalid_i (fsm_invalid), - .clr_slow_req_o (clr_slow_req), - .usb_ip_clk_en_i (usb_ip_clk_en), - .usb_ip_clk_status_o (usb_ip_clk_status), - - // cfg - .main_pd_ni (reg2hw.control.main_pd_n.q), - - // consumed in pwrmgr - .wkup_o (wkup), - .clr_cfg_lock_o (clr_cfg_lock), - .fall_through_o (low_power_fall_through), - .abort_o (low_power_abort), - .clr_hint_o (clr_hint), - - // rstmgr - .pwr_rst_o (pwr_rst_o), - .pwr_rst_i (pwr_rst_i), - - // clkmgr - .ips_clk_en_o (pwr_clk_o), - .clk_en_status_i (pwr_clk_i), - - // otp - .otp_init_o (pwr_otp_o.otp_init), - .otp_done_i (otp_rsp.otp_done), - .otp_idle_i (otp_rsp.otp_idle), - - // lc - .lc_init_o (pwr_lc_o.lc_init), - .lc_done_i (pwr_lc_i.lc_done), - .lc_idle_i (pwr_lc_i.lc_idle), - .lc_dft_en_i (lc_dft_en), - .lc_hw_debug_en_i (lc_hw_debug_en), - - // flash - .flash_idle_i (flash_rsp.flash_idle), - - // rom_ctrl - .rom_ctrl_done_i (rom_ctrl_done), - .rom_ctrl_good_i (rom_ctrl_good), - - // processing element - .fetch_en_o, - - // pinmux and other peripherals - .strap_o, - .low_power_o - ); - - //////////////////////////// - /// Wakeup Info Capture - //////////////////////////// - - logic wake_info_wen; - logic [TotalWakeWidth-1:0] wake_info_data; - - assign wake_info_wen = reg2hw.wake_info.abort.qe | - reg2hw.wake_info.fall_through.qe | - reg2hw.wake_info.reasons.qe; - - assign wake_info_data = {reg2hw.wake_info.abort.q, - reg2hw.wake_info.fall_through.q, - reg2hw.wake_info.reasons.q}; - - pwrmgr_wake_info i_wake_info ( - .clk_i, - .rst_ni, - .wr_i (wake_info_wen), - .data_i (wake_info_data), - .start_capture_i (low_power_o), - .record_dis_i (reg2hw.wake_info_capture_dis.q), - .wakeups_i (peri_reqs_masked.wakeups), - .fall_through_i (low_power_fall_through), - .abort_i (low_power_abort), - .info_o (hw2reg.wake_info) - ); - - //////////////////////////// - /// Interrupts - //////////////////////////// - - // This interrupt is asserted whenever the fast FSM transitions - // into active state. However, it does not assert during POR - prim_intr_hw #(.Width(1)) intr_wakeup ( - .clk_i, - .rst_ni, - .event_intr_i (wkup), - .reg2hw_intr_enable_q_i (reg2hw.intr_enable.q), - .reg2hw_intr_test_q_i (reg2hw.intr_test.q), - .reg2hw_intr_test_qe_i (reg2hw.intr_test.qe), - .reg2hw_intr_state_q_i (reg2hw.intr_state.q), - .hw2reg_intr_state_de_o (hw2reg.intr_state.de), - .hw2reg_intr_state_d_o (hw2reg.intr_state.d), - .intr_o (intr_wakeup_o) - ); - - - //////////////////////////// - /// Assertions - //////////////////////////// - - `ASSERT_KNOWN(TlDValidKnownO_A, tl_o.d_valid ) - `ASSERT_KNOWN(TlAReadyKnownO_A, tl_o.a_ready ) - `ASSERT_KNOWN(AlertsKnownO_A, alert_tx_o ) - `ASSERT_KNOWN(AstKnownO_A, pwr_ast_o ) - `ASSERT_KNOWN(RstKnownO_A, pwr_rst_o ) - `ASSERT_KNOWN(ClkKnownO_A, pwr_clk_o ) - `ASSERT_KNOWN(OtpKnownO_A, pwr_otp_o ) - `ASSERT_KNOWN(LcKnownO_A, pwr_lc_o ) - `ASSERT_KNOWN(IntrKnownO_A, intr_wakeup_o ) - - // EscTimeOutCnt also sets the required clock ratios between escalator and local clock - // Ie, clk_lc cannot be so slow that the timeout count is reached - `ifdef INC_ASSERT - //VCS coverage off - // pragma coverage off - logic effective_rst_n; - assign effective_rst_n = clk_lc_i && rst_ni; - - logic [31:0] cnt; - always_ff @(posedge clk_i or negedge effective_rst_n) begin - if (!effective_rst_n) begin - cnt <= '0; - end else begin - cnt <= cnt + 1'b1; - end - end - //VCS coverage on - // pragma coverage on - - `ASSERT(ClkRatio_A, cnt < EscTimeOutCnt) - - `endif - - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ERR(FsmCheck_A, u_fsm.u_state_regs, - pwr_rst_o.rst_lc_req && pwr_rst_o.rst_sys_req) - `ASSERT_PRIM_FSM_ERROR_TRIGGER_ERR(SlowFsmCheck_A, u_slow_fsm.u_state_regs, - pwr_ast_o.pwr_clamp && !pwr_ast_o.main_pd_n, 0, 2, - clk_slow_i, !rst_slow_ni) - - // Alert assertions for reg_we onehot check - `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[0]) -endmodule // pwrmgr diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv b/hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv deleted file mode 100644 index 012727e97ad9e2..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_cdc.sv +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Power Manager CDC handling -// - -`include "prim_assert.sv" - -module pwrmgr_cdc import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*; -( - // Clocks and resets - input clk_slow_i, - input clk_i, - input rst_slow_ni, - input rst_ni, - - // slow domain signals, - input slow_req_pwrup_i, - input slow_ack_pwrdn_i, - input slow_fsm_invalid_i, - input slow_pwrup_cause_toggle_i, - input pwrup_cause_e slow_pwrup_cause_i, - output logic [NumWkups-1:0] slow_wakeup_en_o, - output logic [NumRstReqs-1:0] slow_reset_en_o, - output logic slow_main_pd_no, - output logic slow_io_clk_en_o, - output logic slow_core_clk_en_o, - output logic slow_usb_clk_en_lp_o, - output logic slow_usb_clk_en_active_o, - output logic slow_req_pwrdn_o, - output logic slow_ack_pwrup_o, - output pwr_ast_rsp_t slow_ast_o, - output pwr_peri_t slow_peri_reqs_o, - input pwr_peri_t slow_peri_reqs_masked_i, - output logic slow_clr_req_o, - input slow_usb_ip_clk_en_i, - output slow_usb_ip_clk_status_o, - - // fast domain signals - input req_pwrdn_i, - input ack_pwrup_i, - input cfg_cdc_sync_i, - input [NumWkups-1:0] wakeup_en_i, - input logic [NumRstReqs-1:0] reset_en_i, - input main_pd_ni, - input io_clk_en_i, - input core_clk_en_i, - input usb_clk_en_lp_i, - input usb_clk_en_active_i, - output logic ack_pwrdn_o, - output logic fsm_invalid_o, - output logic req_pwrup_o, - output pwrup_cause_e pwrup_cause_o, - output pwr_peri_t peri_reqs_o, - output logic cdc_sync_done_o, - input clr_slow_req_i, - output logic usb_ip_clk_en_o, - input usb_ip_clk_status_i, - - // peripheral inputs, mixed domains - input pwr_peri_t peri_i, - input pwr_flash_t flash_i, - output pwr_flash_t flash_o, - - // otp interface - input pwr_otp_rsp_t otp_i, - output pwr_otp_rsp_t otp_o, - - // AST inputs, unknown domain - input pwr_ast_rsp_t ast_i, - - // rom_ctrl signals - input prim_mubi_pkg::mubi4_t rom_ctrl_done_i, - output prim_mubi_pkg::mubi4_t rom_ctrl_done_o, - - // core sleeping - input core_sleeping_i, - output logic core_sleeping_o - -); - - //////////////////////////////// - // Sync from clk_i to clk_slow_i - //////////////////////////////// - - logic slow_cdc_sync; - pwr_ast_rsp_t slow_ast_q, slow_ast_q2; - - prim_flop_2sync # ( - .Width(1) - ) u_req_pwrdn_sync ( - .clk_i(clk_slow_i), - .rst_ni(rst_slow_ni), - .d_i(req_pwrdn_i), - .q_o(slow_req_pwrdn_o) - ); - - prim_flop_2sync # ( - .Width(1) - ) u_ack_pwrup_sync ( - .clk_i(clk_slow_i), - .rst_ni(rst_slow_ni), - .d_i(ack_pwrup_i), - .q_o(slow_ack_pwrup_o) - ); - - prim_pulse_sync u_slow_cdc_sync ( - .clk_src_i(clk_i), - .rst_src_ni(rst_ni), - .src_pulse_i(cfg_cdc_sync_i), - .clk_dst_i(clk_slow_i), - .rst_dst_ni(rst_slow_ni), - .dst_pulse_o(slow_cdc_sync) - ); - - // Even though this is multi-bit, the bits are individual request lines. - // So there is no general concern about recombining as there is - // no intent to use them in a related manner. - prim_flop_2sync # ( - .Width($bits(pwr_peri_t)) - ) u_slow_ext_req_sync ( - .clk_i (clk_slow_i), - .rst_ni (rst_slow_ni), - .d_i (peri_i), - .q_o (slow_peri_reqs_o) - ); - - prim_flop_2sync # ( - .Width(1) - ) u_ip_clk_status_sync ( - .clk_i (clk_slow_i), - .rst_ni (rst_slow_ni), - .d_i (usb_ip_clk_status_i), - .q_o (slow_usb_ip_clk_status_o) - ); - - // Some of the AST signals are multi-bits themselves (such as clk_val) - // thus they need to be delayed one more stage to check for stability - prim_flop_2sync # ( - .Width($bits(pwr_ast_rsp_t)), - .ResetValue(PWR_AST_RSP_SYNC_DEFAULT) - ) u_ast_sync ( - .clk_i (clk_slow_i), - .rst_ni (rst_slow_ni), - .d_i (ast_i), - .q_o (slow_ast_q) - ); - - always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin - if (!rst_slow_ni) begin - slow_ast_q2 <= PWR_AST_RSP_SYNC_DEFAULT; - end else begin - slow_ast_q2 <= slow_ast_q; - end - end - - // if possible, we should simulate below with random delays through - // flop_2sync - always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin - if (!rst_slow_ni) begin - slow_ast_o <= PWR_AST_RSP_SYNC_DEFAULT; - end else if (slow_ast_q2 == slow_ast_q) begin - // Output only updates whenever sync and delayed outputs both agree. - // If there are delays in sync, this will result in a 1 cycle difference - // and the output will hold the previous value - slow_ast_o <= slow_ast_q2; - end - end - - // only register configurations can be sync'd using slow_cdc_sync - always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin - if (!rst_slow_ni) begin - slow_wakeup_en_o <= '0; - slow_reset_en_o <= '0; - slow_main_pd_no <= '1; - slow_io_clk_en_o <= '0; - slow_core_clk_en_o <= '0; - slow_usb_clk_en_lp_o <= '0; - slow_usb_clk_en_active_o <= 1'b1; - end else if (slow_cdc_sync) begin - slow_wakeup_en_o <= wakeup_en_i; - slow_reset_en_o <= reset_en_i; - slow_main_pd_no <= main_pd_ni; - slow_io_clk_en_o <= io_clk_en_i; - slow_core_clk_en_o <= core_clk_en_i; - slow_usb_clk_en_lp_o <= usb_clk_en_lp_i; - slow_usb_clk_en_active_o <= usb_clk_en_active_i; - end - end - - //////////////////////////////// - // Sync from clk_slow_i to clk_i - //////////////////////////////// - - logic pwrup_cause_toggle_q, pwrup_cause_toggle_q2; - logic pwrup_cause_chg; - - prim_flop_2sync # ( - .Width(1) - ) u_req_pwrup_sync ( - .clk_i, - .rst_ni, - .d_i(slow_req_pwrup_i), - .q_o(req_pwrup_o) - ); - - prim_flop_2sync # ( - .Width(1) - ) u_ack_pwrdn_sync ( - .clk_i, - .rst_ni, - .d_i(slow_ack_pwrdn_i), - .q_o(ack_pwrdn_o) - ); - - prim_flop_2sync # ( - .Width(1) - ) u_int_fsm_invalid_sync ( - .clk_i, - .rst_ni, - .d_i(slow_fsm_invalid_i), - .q_o(fsm_invalid_o) - ); - - prim_flop_2sync # ( - .Width(1) - ) u_pwrup_chg_sync ( - .clk_i, - .rst_ni, - .d_i(slow_pwrup_cause_toggle_i), - .q_o(pwrup_cause_toggle_q) - ); - - prim_flop_2sync # ( - .Width(1) - ) u_ip_clk_en_sync ( - .clk_i, - .rst_ni, - .d_i(slow_usb_ip_clk_en_i), - .q_o(usb_ip_clk_en_o) - ); - - prim_flop_2sync # ( - .Width(1) - ) u_sleeping_sync ( - .clk_i, - .rst_ni, - .d_i(core_sleeping_i), - .q_o(core_sleeping_o) - ); - - prim_pulse_sync u_scdc_sync ( - .clk_src_i(clk_slow_i), - .rst_src_ni(rst_slow_ni), - .src_pulse_i(slow_cdc_sync), - .clk_dst_i(clk_i), - .rst_dst_ni(rst_ni), - .dst_pulse_o(cdc_sync_done_o) - ); - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - pwrup_cause_toggle_q2 <= 1'b0; - end else begin - pwrup_cause_toggle_q2 <= pwrup_cause_toggle_q; - end - end - - assign pwrup_cause_chg = pwrup_cause_toggle_q2 ^ pwrup_cause_toggle_q; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - pwrup_cause_o <= Por; - end else if (pwrup_cause_chg) begin - pwrup_cause_o <= slow_pwrup_cause_i; - end - end - - prim_flop_2sync #( - .Width($bits(pwr_peri_t)) - ) u_ext_req_sync ( - .clk_i, - .rst_ni, - .d_i(slow_peri_reqs_masked_i), - .q_o(peri_reqs_o) - ); - - prim_flop_2sync #( - .Width(1), - .ResetValue(1'b1) - ) u_sync_flash_idle ( - .clk_i, - .rst_ni, - .d_i(flash_i.flash_idle), - .q_o(flash_o.flash_idle) - ); - - prim_flop_2sync #( - .Width($bits(pwr_otp_rsp_t)), - .ResetValue('0) - ) u_sync_otp ( - .clk_i, - .rst_ni, - .d_i(otp_i), - .q_o(otp_o) - ); - - prim_mubi4_sync #( - .NumCopies(1), - .AsyncOn(1), - .StabilityCheck(1) - ) u_sync_rom_ctrl ( - .clk_i, - .rst_ni, - .mubi_i(rom_ctrl_done_i), - .mubi_o({rom_ctrl_done_o}) - ); - - //////////////////////////////// - // Handshake - //////////////////////////////// - prim_flop_2sync #( - .Width(1), - .ResetValue('0) - ) u_clr_req_sync ( - .clk_i(clk_slow_i), - .rst_ni(rst_slow_ni), - .d_i(clr_slow_req_i), - .q_o(slow_clr_req_o) - ); - -endmodule diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_cdc_pulse.sv b/hw/ip/pwrmgr/rtl/pwrmgr_cdc_pulse.sv deleted file mode 100644 index 07a73106bf30d5..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_cdc_pulse.sv +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Power Manager module to find slow clock edges -// The clock is not used directly to avoid STA issues, instead a toggle -// pulse is used. - -`include "prim_assert.sv" - -module pwrmgr_cdc_pulse ( - input clk_slow_i, - input clk_i, - input rst_ni, - input rst_slow_ni, - input start_i, - input stop_i, - output logic pulse_o -); - - logic slow_toggle_pq, slow_toggle_nq; - logic clk_slow_pq, clk_slow_nq; - logic clk_slow_pq2, clk_slow_nq2; - logic toggle; - logic valid; - - // toggle pulse generated on positive edge - always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin - if (!rst_slow_ni) begin - slow_toggle_pq <= 1'b0; - end else begin - slow_toggle_pq <= ~slow_toggle_pq; - end - end - - // toggle pulse generated on negative edge - always_ff @(negedge clk_slow_i or negedge rst_slow_ni) begin - if (!rst_slow_ni) begin - slow_toggle_nq <= 1'b0; - end else begin - slow_toggle_nq <= ~slow_toggle_nq; - end - end - - - prim_flop_2sync # ( - .Width(1) - ) i_pos_sync ( - .clk_i, - .rst_ni, - .d_i(slow_toggle_pq), - .q_o(clk_slow_pq) - ); - - prim_flop_2sync # ( - .Width(1) - ) i_neg_sync ( - .clk_i, - .rst_ni, - .d_i(slow_toggle_nq), - .q_o(clk_slow_nq) - ); - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - clk_slow_pq2 <= 1'b0; - clk_slow_nq2 <= 1'b0; - end else begin - clk_slow_pq2 <= clk_slow_pq; - clk_slow_nq2 <= clk_slow_nq; - end - end - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - valid <= 1'b0; - end else if (valid && stop_i) begin - valid <= 1'b0; - end else if (!valid && toggle && start_i) begin - valid <= 1'b1; - end - end - - // toggle is found on either positive and negative edges of clk_slow_i - assign toggle = clk_slow_pq2 ^ clk_slow_pq | clk_slow_nq2 ^ clk_slow_nq; - assign pulse_o = valid & toggle; - - - - -endmodule // pwrmgr diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv b/hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv deleted file mode 100644 index 2bbc5bb975eb6f..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv +++ /dev/null @@ -1,542 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Power Manager Fast FSM -// - -`include "prim_assert.sv" - -module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;( - input clk_i, - input rst_ni, - input clk_slow_i, - input rst_slow_ni, - - // interface with slow_fsm - input req_pwrup_i, - input pwrup_cause_e pwrup_cause_i, - output logic ack_pwrup_o, - output logic req_pwrdn_o, - input ack_pwrdn_i, - input low_power_entry_i, - input main_pd_ni, - input [TotalResetWidth-1:0] reset_reqs_i, - input fsm_invalid_i, - output logic clr_slow_req_o, - input usb_ip_clk_en_i, - output logic usb_ip_clk_status_o, - - // consumed in pwrmgr - output logic wkup_o, // generate wake interrupt - output logic fall_through_o, - output logic abort_o, - output logic clr_hint_o, - output logic clr_cfg_lock_o, - - // rstmgr - output pwr_rst_req_t pwr_rst_o, - input pwr_rst_rsp_t pwr_rst_i, - - // clkmgr - output pwr_clk_req_t ips_clk_en_o, - input pwr_clk_rsp_t clk_en_status_i, - - // otp - output logic otp_init_o, - input otp_done_i, - input otp_idle_i, - - // lc - output logic lc_init_o, - input lc_done_i, - input lc_idle_i, - input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, - input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, - - // flash - input flash_idle_i, - - // rom_ctrl - input prim_mubi_pkg::mubi4_t rom_ctrl_done_i, - input prim_mubi_pkg::mubi4_t rom_ctrl_good_i, - - // pinmux - output logic strap_o, - output logic low_power_o, - - // processing elements - output lc_ctrl_pkg::lc_tx_t fetch_en_o -); - - import prim_mubi_pkg::mubi4_t; - import prim_mubi_pkg::mubi4_test_true_strict; - import prim_mubi_pkg::mubi4_or_hi; - import prim_mubi_pkg::mubi4_and_hi; - import lc_ctrl_pkg::lc_tx_and_hi; - import lc_ctrl_pkg::lc_tx_test_true_strict; - - // The code below always assumes the always on domain is index 0 - `ASSERT_INIT(AlwaysOnIndex_A, ALWAYS_ON_DOMAIN == 0) - - // when there are multiple on domains, the latter 1 should become another parameter - localparam int OffDomainSelStart = ALWAYS_ON_DOMAIN + 1; - - // all powered down domains have resets asserted - logic pd_n_rsts_asserted; - - // all domains have resets asserted - logic all_rsts_asserted; - - // resets are valid - logic reset_valid; - - // reset hint to rstmgr - reset_cause_e reset_cause_q, reset_cause_d; - - // reset request - logic reset_req; - logic direct_rst_req; - logic ndmreset_req; - logic hw_rst_req; - logic sw_rst_req; - - // strap sample should only happen on cold boot or when the - // the system goes through a reset cycle - logic strap_sampled; - - // disable processing element fetching - lc_ctrl_pkg::lc_tx_t fetch_en_q, fetch_en_d; - - fast_pwr_state_e state_d, state_q; - logic reset_ongoing_q, reset_ongoing_d; - logic req_pwrdn_q, req_pwrdn_d; - logic ack_pwrup_q, ack_pwrup_d; - logic ip_clk_en_q, ip_clk_en_d; - logic [PowerDomains-1:0] rst_lc_req_q, rst_sys_req_q; - logic [PowerDomains-1:0] rst_lc_req_d, rst_sys_req_d; - logic otp_init; - logic lc_init; - logic low_power_q, low_power_d; - - assign pd_n_rsts_asserted = pwr_rst_i.rst_lc_src_n[PowerDomains-1:OffDomainSelStart] == '0 & - pwr_rst_i.rst_sys_src_n[PowerDomains-1:OffDomainSelStart] == '0; - - logic lc_rsts_valid; - assign lc_rsts_valid = ((rst_lc_req_q & ~pwr_rst_i.rst_lc_src_n) | - (~rst_lc_req_q & pwr_rst_i.rst_lc_src_n)) == {PowerDomains{1'b1}}; - logic sys_rsts_valid; - assign sys_rsts_valid = ((rst_sys_req_q & ~pwr_rst_i.rst_sys_src_n) | - (~rst_sys_req_q & pwr_rst_i.rst_sys_src_n)) == {PowerDomains{1'b1}}; - - assign all_rsts_asserted = lc_rsts_valid & sys_rsts_valid; - - // Any reset request was asserted. - assign reset_req = |reset_reqs_i; - - // Any peripheral triggererd hardware reset request. - assign hw_rst_req = |reset_reqs_i[NumRstReqs-1:0]; - - // Direct reset request that bypass checks. - assign direct_rst_req = reset_reqs_i[ResetEscIdx] | - reset_reqs_i[ResetMainPwrIdx]; - - // Ndm reset request. - assign ndmreset_req = reset_reqs_i[ResetNdmIdx]; - - // Software triggered reset request. - assign sw_rst_req = reset_reqs_i[ResetSwReqIdx]; - - // when in low power path, resets are controlled by domain power down - // when in reset path, all resets must be asserted - // when the reset cause is something else, it is invalid - assign reset_valid = reset_cause_q == LowPwrEntry ? main_pd_ni | pd_n_rsts_asserted : - reset_cause_q == HwReq ? all_rsts_asserted : 1'b0; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - ack_pwrup_q <= 1'b0; - req_pwrdn_q <= 1'b0; - reset_ongoing_q <= 1'b0; - ip_clk_en_q <= 1'b0; - rst_lc_req_q <= {PowerDomains{1'b1}}; - rst_sys_req_q <= {PowerDomains{1'b1}}; - reset_cause_q <= ResetUndefined; - low_power_q <= 1'b1; - end else begin - ack_pwrup_q <= ack_pwrup_d; - req_pwrdn_q <= req_pwrdn_d; - reset_ongoing_q <= reset_ongoing_d; - ip_clk_en_q <= ip_clk_en_d; - rst_lc_req_q <= rst_lc_req_d; - rst_sys_req_q <= rst_sys_req_d; - reset_cause_q <= reset_cause_d; - low_power_q <= low_power_d; - end - end - - // SEC_CM: FSM.SPARSE - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, fast_pwr_state_e, FastPwrStateLowPower) - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - strap_sampled <= 1'b0; - end else if (&rst_sys_req_q) begin - strap_sampled <= 1'b0; - end else if (strap_o) begin - strap_sampled <= 1'b1; - end - end - - prim_lc_sender u_fetch_en ( - .clk_i, - .rst_ni, - .lc_en_i(fetch_en_d), - .lc_en_o(fetch_en_q) - ); - assign fetch_en_o = fetch_en_q; - - // Life cycle broadcast may take time to propagate through the system. - // The sync below simulates that behavior using the slowest clock in the - // system. - logic slow_lc_done; - logic lc_done; - - prim_flop_2sync #( - .Width(1) - ) u_slow_sync_lc_done ( - .clk_i(clk_slow_i), - .rst_ni(rst_slow_ni), - .d_i(lc_done_i), - .q_o(slow_lc_done) - ); - - prim_flop_2sync #( - .Width(1) - ) u_sync_lc_done ( - .clk_i, - .rst_ni, - .d_i(slow_lc_done), - .q_o(lc_done) - ); - - - logic clks_enabled; - logic clks_disabled; - - // clocks all enabled computed as follows: - // if enable is high, meaning clock is requested to turn on, the status must - // also be 1. - // if enable is low, meaning clock is not requested to turn on, the status is - // don't care. - // the bit-wise OR of both conditions must be all true. - assign clks_enabled = ip_clk_en_q && - &((ips_clk_en_o & clk_en_status_i) | ~ips_clk_en_o); - - // clocks all disabled is the opposite: - // if enable is low the status must also be low. - // if enable is high, the status is don't care. - // the bit-wise OR of both conditions must be all true. - assign clks_disabled = ~ip_clk_en_q && - &((~ips_clk_en_o & ~clk_en_status_i) | ips_clk_en_o); - - - // rom integrity checks are disabled during TEST / RMA states - // During TEST / RMA states, both dft_en and hw_debug_en are On. - // During DEV / PROD states, either both signals are Off, or only - // hw_debug_en is On - - mubi4_t rom_intg_chk_dis; - assign rom_intg_chk_dis = lc_tx_test_true_strict(lc_tx_and_hi(lc_dft_en_i, lc_hw_debug_en_i)) ? - prim_mubi_pkg::MuBi4True : - prim_mubi_pkg::MuBi4False; - - mubi4_t rom_intg_chk_done; - mubi4_t rom_intg_chk_good; - assign rom_intg_chk_done = mubi4_or_hi(mubi4_and_hi(rom_intg_chk_dis, rom_ctrl_done_i), - rom_ctrl_done_i); - assign rom_intg_chk_good = mubi4_or_hi(rom_intg_chk_dis, rom_ctrl_good_i); - - always_comb begin - otp_init = 1'b0; - lc_init = 1'b0; - wkup_o = 1'b0; - fall_through_o = 1'b0; - abort_o = 1'b0; - clr_hint_o = 1'b0; - clr_cfg_lock_o = 1'b0; - strap_o = 1'b0; - clr_slow_req_o = 1'b0; - - state_d = state_q; - ack_pwrup_d = ack_pwrup_q; - req_pwrdn_d = req_pwrdn_q; - reset_ongoing_d = reset_ongoing_q; - ip_clk_en_d = ip_clk_en_q; - rst_lc_req_d = rst_lc_req_q; - rst_sys_req_d = rst_sys_req_q; - reset_cause_d = reset_cause_q; - low_power_d = low_power_q; - fetch_en_d = fetch_en_q; - - unique case(state_q) - - FastPwrStateLowPower: begin - if (req_pwrup_i || reset_ongoing_q) begin - state_d = FastPwrStateEnableClocks; - end - end - - FastPwrStateEnableClocks: begin - ip_clk_en_d = 1'b1; - if (clks_enabled) begin - state_d = FastPwrStateReleaseLcRst; - end - end - - FastPwrStateReleaseLcRst: begin - rst_lc_req_d = '0; // release rst_lc_n for all power domains - rst_sys_req_d = '0; // release rst_sys_n for all power domains - // once all resets are released continue to otp initilization - if (&pwr_rst_i.rst_lc_src_n) begin - state_d = FastPwrStateOtpInit; - end - end - - FastPwrStateOtpInit: begin - otp_init = 1'b1; - - if (otp_done_i) begin - state_d = FastPwrStateLcInit; - end - end - - FastPwrStateLcInit: begin - lc_init = 1'b1; - - if (lc_done) begin - state_d = FastPwrStateAckPwrUp; - - end - end - - FastPwrStateAckPwrUp: begin - // only ack the slow_fsm if we actually transitioned through it - ack_pwrup_d = !reset_ongoing_q; - - // wait for request power up to drop relative to ack - if (!req_pwrup_i || reset_ongoing_q) begin - ack_pwrup_d = 1'b0; - clr_cfg_lock_o = 1'b1; - // generate a wakeup interrupt if we intended to go to low power - // and we were woken from low power with a wakeup and not reset - wkup_o = (pwrup_cause_i == Wake) & (reset_cause_q == LowPwrEntry); - // This constitutes the end of a reset cycle - reset_ongoing_d = 1'b0; - state_d = FastPwrStateStrap; - end - end - - FastPwrStateStrap: begin - strap_o = ~strap_sampled; - state_d = FastPwrStateRomCheckDone; - end - - FastPwrStateRomCheckDone: begin - // zero outgoing low power indication - low_power_d = '0; - reset_cause_d = ResetNone; - - // When done is observed, advance to good check - if (mubi4_test_true_strict(rom_intg_chk_done)) begin - state_d = FastPwrStateRomCheckGood; - end - end - - FastPwrStateRomCheckGood: begin - if (mubi4_test_true_strict(rom_intg_chk_good)) begin - state_d = FastPwrStateActive; - end - end - - FastPwrStateActive: begin - // only in active state, allow processor to execute - fetch_en_d = lc_ctrl_pkg::On; - - // when handling reset request or low power entry of any - // kind, stop processor from fetching - if (reset_req || low_power_entry_i) begin - fetch_en_d = lc_ctrl_pkg::Off; - reset_cause_d = ResetUndefined; - state_d = FastPwrStateDisClks; - end - end - - FastPwrStateDisClks: begin - ip_clk_en_d = 1'b0; - - if (clks_disabled) begin - state_d = reset_req ? FastPwrStateNvmShutDown : FastPwrStateFallThrough; - low_power_d = ~reset_req; - end else begin - // escalation was received, skip all handshaking and directly reset - state_d = direct_rst_req ? FastPwrStateNvmShutDown : state_q; - low_power_d = ~reset_req; - end - end - - // Low Power Path - FastPwrStateFallThrough: begin - clr_hint_o = 1'b1; - - // The processor was interrupted after it asserted WFI and is executing again - if (!low_power_entry_i) begin - ip_clk_en_d = 1'b1; - wkup_o = 1'b1; - fall_through_o = 1'b1; - state_d = FastPwrStateRomCheckDone; - end else begin - state_d = FastPwrStateNvmIdleChk; - end - end - - FastPwrStateNvmIdleChk: begin - - if (otp_idle_i && lc_idle_i && flash_idle_i) begin - state_d = FastPwrStateLowPowerPrep; - end else begin - ip_clk_en_d = 1'b1; - wkup_o = 1'b1; - abort_o = 1'b1; - state_d = FastPwrStateRomCheckDone; - end - end - - FastPwrStateLowPowerPrep: begin - // reset cause is set only if main power domain will be turned off - reset_cause_d = LowPwrEntry; - - // reset non-always-on domains if requested - // this includes the clock manager, which implies pwr/rst managers must - // be fed directly from the source - for (int i = OffDomainSelStart; i < PowerDomains; i++) begin - rst_lc_req_d[i] = ~main_pd_ni; - rst_sys_req_d[i] = ~main_pd_ni; - end - - if (reset_valid) begin - state_d = FastPwrStateReqPwrDn; - end - end - - FastPwrStateReqPwrDn: begin - req_pwrdn_d = 1'b1; - - if (ack_pwrdn_i) begin - req_pwrdn_d = 1'b0; - state_d = FastPwrStateLowPower; - end - end - - // Reset Path - FastPwrStateNvmShutDown: begin - clr_hint_o = 1'b1; - reset_ongoing_d = 1'b1; - state_d = FastPwrStateResetPrep; - end - - FastPwrStateResetPrep: begin - reset_cause_d = HwReq; - rst_lc_req_d = {PowerDomains{1'b1}}; - rst_sys_req_d = {PowerDomains{(hw_rst_req | - direct_rst_req | - sw_rst_req) | - (ndmreset_req & - lc_ctrl_pkg::lc_tx_test_false_loose(lc_hw_debug_en_i))}}; - - - state_d = FastPwrStateResetWait; - end - - FastPwrStateResetWait: begin - rst_lc_req_d = {PowerDomains{1'b1}}; - clr_slow_req_o = reset_reqs_i[ResetMainPwrIdx]; - // The main power reset request is checked here specifically because it is - // the only reset request in the system that operates on the POR domain. - // This has to be the case since it would otherwise not be able to monitor - // the non-always-on domains. - // - // As a result of this, the normal reset process does not automatically - // wipe out the reset request, so we specifically clear it and wait for it to be - // cleared before proceeding. This also implies if the system is under a persistent - // glitch, or if someone just turned off the power before pwrmgr turns it off itself, - // we will stay stuck here and perpetually hold the system in reset. - if (reset_valid && !reset_reqs_i[ResetMainPwrIdx]) begin - state_d = FastPwrStateLowPower; - end - end - - - // Terminal state, kill everything - // SEC_CM: FSM.TERMINAL - default: begin - rst_lc_req_d = {PowerDomains{1'b1}}; - rst_sys_req_d = {PowerDomains{1'b1}}; - ip_clk_en_d = 1'b0; - end - endcase // unique case (state_q) - - if (fsm_invalid_i) begin - // the slow fsm is completely out of sync, transition to terminal state - state_d = FastPwrStateInvalid; - end - - - end // always_comb - - assign ack_pwrup_o = ack_pwrup_q; - assign req_pwrdn_o = req_pwrdn_q; - assign low_power_o = low_power_q; - - assign pwr_rst_o.rst_lc_req = rst_lc_req_q; - assign pwr_rst_o.rst_sys_req = rst_sys_req_q; - assign pwr_rst_o.reset_cause = reset_cause_q; - assign pwr_rst_o.rstreqs = reset_reqs_i[HwResetWidth-1:0]; - - // main and io clocks are only turned on/off as part of normal - // power sequence - assign ips_clk_en_o.main_ip_clk_en = ip_clk_en_q; - assign ips_clk_en_o.io_ip_clk_en = ip_clk_en_q; - prim_flop #( - .Width(1), - .ResetValue(1'b0) - ) u_usb_ip_clk_en ( - .clk_i, - .rst_ni, - .d_i(ip_clk_en_d & usb_ip_clk_en_i), - .q_o(ips_clk_en_o.usb_ip_clk_en) - ); - assign usb_ip_clk_status_o = clk_en_status_i.usb_status; - - prim_flop #( - .Width(1), - .ResetValue(1'b0) - ) u_reg_otp_init ( - .clk_i, - .rst_ni, - .d_i(otp_init), - .q_o(otp_init_o) - ); - - prim_flop #( - .Width(1), - .ResetValue(1'b0) - ) u_reg_lc_init ( - .clk_i, - .rst_ni, - .d_i(lc_init), - .q_o(lc_init_o) - ); - - -endmodule diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv b/hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv deleted file mode 100644 index c86e8fb4959da3..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Power Manager Package -// - -package pwrmgr_pkg; - - // global constant - parameter int ALWAYS_ON_DOMAIN = 0; - - // variables referenced by other modules / packages - parameter int PowerDomains = 2; // this needs to be a topgen populated number, or from topcfg? - - // variables referenced only by pwrmgr - localparam int TotalWakeWidth = pwrmgr_reg_pkg::NumWkups + 2; // Abort and fall through are added - - parameter int NumSwRstReq = 1; - - // position of escalation request - parameter int HwResetWidth = pwrmgr_reg_pkg::NumRstReqs + - pwrmgr_reg_pkg::NumIntRstReqs + - pwrmgr_reg_pkg::NumDebugRstReqs; - parameter int TotalResetWidth = HwResetWidth + NumSwRstReq; - parameter int ResetSwReqIdx = TotalResetWidth - 1; - - // pwrmgr to ast - typedef struct packed { - logic main_pd_n; - logic pwr_clamp_env; - logic pwr_clamp; - logic slow_clk_en; - logic core_clk_en; - logic io_clk_en; - logic usb_clk_en; - } pwr_ast_req_t; - - typedef struct packed { - logic slow_clk_val; - logic core_clk_val; - logic io_clk_val; - logic usb_clk_val; - logic main_pok; - } pwr_ast_rsp_t; - - // default value of pwr_ast_rsp (for dangling ports) - parameter pwr_ast_rsp_t PWR_AST_RSP_DEFAULT = '{ - slow_clk_val: 1'b1, - core_clk_val: 1'b1, - io_clk_val: 1'b1, - usb_clk_val: 1'b1, - main_pok: 1'b1 - }; - - parameter pwr_ast_rsp_t PWR_AST_RSP_SYNC_DEFAULT = '{ - slow_clk_val: 1'b0, - core_clk_val: 1'b0, - io_clk_val: 1'b0, - usb_clk_val: 1'b0, - main_pok: 1'b0 - }; - - // reasons for pwrmgr reset - typedef enum logic [1:0] { - ResetNone = 0, // there is no reset - LowPwrEntry = 1, // reset is caused by low power entry - HwReq = 2, // reset is caused by peripheral reset requests - ResetUndefined = 3 // this should never happen outside of POR - } reset_cause_e; - - // pwrmgr to rstmgr - typedef struct packed { - logic [PowerDomains-1:0] rst_lc_req; - logic [PowerDomains-1:0] rst_sys_req; - logic [HwResetWidth-1:0] rstreqs; - reset_cause_e reset_cause; - } pwr_rst_req_t; - - // rstmgr to pwrmgr - typedef struct packed { - logic [PowerDomains-1:0] rst_lc_src_n; - logic [PowerDomains-1:0] rst_sys_src_n; - } pwr_rst_rsp_t; - - // default value (for dangling ports) - parameter pwr_rst_rsp_t PWR_RST_RSP_DEFAULT = '{ - rst_lc_src_n: {PowerDomains{1'b1}}, - rst_sys_src_n: {PowerDomains{1'b1}} - }; - - // pwrmgr to clkmgr - typedef struct packed { - logic main_ip_clk_en; - logic io_ip_clk_en; - logic usb_ip_clk_en; - } pwr_clk_req_t; - - // clkmgr to pwrmgr - typedef struct packed { - logic main_status; - logic io_status; - logic usb_status; - } pwr_clk_rsp_t; - - // pwrmgr to otp - typedef struct packed { - logic otp_init; - } pwr_otp_req_t; - - // otp to pwrmgr - typedef struct packed { - logic otp_done; - logic otp_idle; - } pwr_otp_rsp_t; - - // default value (for dangling ports) - parameter pwr_otp_rsp_t PWR_OTP_RSP_DEFAULT = '{ - otp_done: 1'b1, - otp_idle: 1'b1 - }; - - // pwrmgr to lifecycle - typedef struct packed { - logic lc_init; - } pwr_lc_req_t; - - // lifecycle to pwrmgr - typedef struct packed { - logic lc_done; - logic lc_idle; - } pwr_lc_rsp_t; - - // default value (for dangling ports) - parameter pwr_lc_rsp_t PWR_LC_RSP_DEFAULT = '{ - lc_done: 1'b1, - lc_idle: 1'b1 - }; - - typedef struct packed { - logic flash_idle; - } pwr_flash_t; - - parameter pwr_flash_t PWR_FLASH_DEFAULT = '{ - flash_idle: 1'b1 - }; - - // processor to pwrmgr - typedef struct packed { - logic core_sleeping; - } pwr_cpu_t; - - // cpu reset requests and status - typedef struct packed { - logic ndmreset_req; - } pwrmgr_cpu_t; - - // exported resets - - // default value for pwrmgr_ast_rsp_t (for dangling ports) - parameter pwrmgr_cpu_t PWRMGR_CPU_DEFAULT = '{ - ndmreset_req: '0 - }; - - // default value (for dangling ports) - parameter pwr_cpu_t PWR_CPU_DEFAULT = '{ - core_sleeping: 1'b0 - }; - - // default value (for dangling ports) - parameter int WAKEUPS_DEFAULT = '0; - parameter int RSTREQS_DEFAULT = '0; - - // peripherals to pwrmgr - typedef struct packed { - logic [pwrmgr_reg_pkg::NumWkups-1:0] wakeups; - // reset requests include external requests + escalation reset - logic [TotalResetWidth-1:0] rstreqs; - } pwr_peri_t; - - // power-up causes - typedef enum logic [1:0] { - Por = 2'h0, - Wake = 2'h1, - Reset = 2'h2 - } pwrup_cause_e; - - // low power hints - typedef enum logic { - None = 1'b0, - LowPower = 1'b1 - } low_power_hint_e; - - // fast fsm state enum - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 19 -n 12 \ - // -s 3096160381 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: ||||||||||||||||| (30.99%) - // 6: |||||||||||||||||||| (35.09%) - // 7: ||||||||| (15.79%) - // 8: |||||| (10.53%) - // 9: ||| (5.85%) - // 10: | (1.75%) - // 11: -- - // 12: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 10 - // Minimum Hamming weight: 2 - // Maximum Hamming weight: 10 - // - localparam int FastPwrStateWidth = 12; - typedef enum logic [FastPwrStateWidth-1:0] { - FastPwrStateLowPower = 12'b000000110111, - FastPwrStateEnableClocks = 12'b101011001110, - FastPwrStateReleaseLcRst = 12'b100111000000, - FastPwrStateOtpInit = 12'b111110100010, - FastPwrStateLcInit = 12'b101001010011, - FastPwrStateStrap = 12'b110000111010, - FastPwrStateAckPwrUp = 12'b000010101000, - FastPwrStateRomCheckDone = 12'b010111110011, - FastPwrStateRomCheckGood = 12'b010000000100, - FastPwrStateActive = 12'b001101100100, - FastPwrStateDisClks = 12'b001110010101, - FastPwrStateFallThrough = 12'b011011010000, - FastPwrStateNvmIdleChk = 12'b100101111001, - FastPwrStateLowPowerPrep = 12'b010110001111, - FastPwrStateNvmShutDown = 12'b001100001010, - FastPwrStateResetPrep = 12'b011001101111, - FastPwrStateResetWait = 12'b111111111100, - FastPwrStateReqPwrDn = 12'b111010001001, - FastPwrStateInvalid = 12'b110101010110 - } fast_pwr_state_e; - - // Encoding generated with: - // $ ./util/design/sparse-fsm-encode.py -d 5 -m 12 -n 10 \ - // -s 1726685338 --language=sv - // - // Hamming distance histogram: - // - // 0: -- - // 1: -- - // 2: -- - // 3: -- - // 4: -- - // 5: |||||||||||||||||||| (54.55%) - // 6: |||||||||||||||| (45.45%) - // 7: -- - // 8: -- - // 9: -- - // 10: -- - // - // Minimum Hamming distance: 5 - // Maximum Hamming distance: 6 - // Minimum Hamming weight: 2 - // Maximum Hamming weight: 8 - // - localparam int SlowPwrStateWidth = 10; - typedef enum logic [SlowPwrStateWidth-1:0] { - SlowPwrStateReset = 10'b0000100010, - SlowPwrStateLowPower = 10'b1011000111, - SlowPwrStateMainPowerOn = 10'b0110101111, - SlowPwrStatePwrClampOff = 10'b0110010001, - SlowPwrStateClocksOn = 10'b1010111100, - SlowPwrStateReqPwrUp = 10'b0011011010, - SlowPwrStateIdle = 10'b1111100000, - SlowPwrStateAckPwrDn = 10'b0001110101, - SlowPwrStateClocksOff = 10'b1101111011, - SlowPwrStatePwrClampOn = 10'b0101001100, - SlowPwrStateMainPowerOff = 10'b1000001001, - SlowPwrStateInvalid = 10'b1100010110 - } slow_pwr_state_e; - -endpackage // pwrmgr_pkg diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_reg_pkg.sv b/hw/ip/pwrmgr/rtl/pwrmgr_reg_pkg.sv deleted file mode 100644 index f55eaaf7a32b44..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_reg_pkg.sv +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Package auto-generated by `reggen` containing data structure - -package pwrmgr_reg_pkg; - - // Param list - parameter int NumWkups = 1; - parameter int NumRstReqs = 1; - - // Address widths within the block - parameter int BlockAw = 6; - - //////////////////////////// - // Typedefs for registers // - //////////////////////////// - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_intr_state_reg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_intr_enable_reg_t; - - typedef struct packed { - logic q; - logic qe; - } pwrmgr_reg2hw_intr_test_reg_t; - - typedef struct packed { - struct packed { - logic q; - } low_power_hint; - struct packed { - logic q; - } core_clk_en; - struct packed { - logic q; - } io_clk_en; - struct packed { - logic q; - } usb_clk_en_lp; - struct packed { - logic q; - } usb_clk_en_active; - struct packed { - logic q; - } main_pd_n; - } pwrmgr_reg2hw_control_reg_t; - - typedef struct packed { - logic q; - logic qe; - } pwrmgr_reg2hw_cfg_cdc_sync_reg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_wakeup_en_mreg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_reset_en_mreg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_wake_info_capture_dis_reg_t; - - typedef struct packed { - struct packed { - logic q; - logic qe; - } reasons; - struct packed { - logic q; - logic qe; - } fall_through; - struct packed { - logic q; - logic qe; - } abort; - } pwrmgr_reg2hw_wake_info_reg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_intr_state_reg_t; - - typedef struct packed { - logic d; - } pwrmgr_hw2reg_ctrl_cfg_regwen_reg_t; - - typedef struct packed { - struct packed { - logic d; - logic de; - } low_power_hint; - } pwrmgr_hw2reg_control_reg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_cfg_cdc_sync_reg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_wake_status_mreg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_reset_status_mreg_t; - - typedef struct packed { - struct packed { - logic d; - } reasons; - struct packed { - logic d; - } fall_through; - struct packed { - logic d; - } abort; - } pwrmgr_hw2reg_wake_info_reg_t; - - // Register -> HW type - typedef struct packed { - pwrmgr_reg2hw_intr_state_reg_t intr_state; // [20:20] - pwrmgr_reg2hw_intr_enable_reg_t intr_enable; // [19:19] - pwrmgr_reg2hw_intr_test_reg_t intr_test; // [18:17] - pwrmgr_reg2hw_control_reg_t control; // [16:11] - pwrmgr_reg2hw_cfg_cdc_sync_reg_t cfg_cdc_sync; // [10:9] - pwrmgr_reg2hw_wakeup_en_mreg_t [0:0] wakeup_en; // [8:8] - pwrmgr_reg2hw_reset_en_mreg_t [0:0] reset_en; // [7:7] - pwrmgr_reg2hw_wake_info_capture_dis_reg_t wake_info_capture_dis; // [6:6] - pwrmgr_reg2hw_wake_info_reg_t wake_info; // [5:0] - } pwrmgr_reg2hw_t; - - // HW -> register type - typedef struct packed { - pwrmgr_hw2reg_intr_state_reg_t intr_state; // [13:12] - pwrmgr_hw2reg_ctrl_cfg_regwen_reg_t ctrl_cfg_regwen; // [11:11] - pwrmgr_hw2reg_control_reg_t control; // [10:9] - pwrmgr_hw2reg_cfg_cdc_sync_reg_t cfg_cdc_sync; // [8:7] - pwrmgr_hw2reg_wake_status_mreg_t [0:0] wake_status; // [6:5] - pwrmgr_hw2reg_reset_status_mreg_t [0:0] reset_status; // [4:3] - pwrmgr_hw2reg_wake_info_reg_t wake_info; // [2:0] - } pwrmgr_hw2reg_t; - - // Register offsets - parameter logic [BlockAw-1:0] PWRMGR_INTR_STATE_OFFSET = 6'h 0; - parameter logic [BlockAw-1:0] PWRMGR_INTR_ENABLE_OFFSET = 6'h 4; - parameter logic [BlockAw-1:0] PWRMGR_INTR_TEST_OFFSET = 6'h 8; - parameter logic [BlockAw-1:0] PWRMGR_CTRL_CFG_REGWEN_OFFSET = 6'h c; - parameter logic [BlockAw-1:0] PWRMGR_CONTROL_OFFSET = 6'h 10; - parameter logic [BlockAw-1:0] PWRMGR_CFG_CDC_SYNC_OFFSET = 6'h 14; - parameter logic [BlockAw-1:0] PWRMGR_WAKEUP_EN_REGWEN_OFFSET = 6'h 18; - parameter logic [BlockAw-1:0] PWRMGR_WAKEUP_EN_OFFSET = 6'h 1c; - parameter logic [BlockAw-1:0] PWRMGR_WAKE_STATUS_OFFSET = 6'h 20; - parameter logic [BlockAw-1:0] PWRMGR_RESET_EN_REGWEN_OFFSET = 6'h 24; - parameter logic [BlockAw-1:0] PWRMGR_RESET_EN_OFFSET = 6'h 28; - parameter logic [BlockAw-1:0] PWRMGR_RESET_STATUS_OFFSET = 6'h 2c; - parameter logic [BlockAw-1:0] PWRMGR_WAKE_INFO_CAPTURE_DIS_OFFSET = 6'h 30; - parameter logic [BlockAw-1:0] PWRMGR_WAKE_INFO_OFFSET = 6'h 34; - - // Reset values for hwext registers and their fields - parameter logic [0:0] PWRMGR_INTR_TEST_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_INTR_TEST_WAKEUP_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_CTRL_CFG_REGWEN_RESVAL = 1'h 1; - parameter logic [0:0] PWRMGR_CTRL_CFG_REGWEN_EN_RESVAL = 1'h 1; - parameter logic [2:0] PWRMGR_WAKE_INFO_RESVAL = 3'h 0; - parameter logic [0:0] PWRMGR_WAKE_INFO_REASONS_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_WAKE_INFO_FALL_THROUGH_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_WAKE_INFO_ABORT_RESVAL = 1'h 0; - - // Register index - typedef enum int { - PWRMGR_INTR_STATE, - PWRMGR_INTR_ENABLE, - PWRMGR_INTR_TEST, - PWRMGR_CTRL_CFG_REGWEN, - PWRMGR_CONTROL, - PWRMGR_CFG_CDC_SYNC, - PWRMGR_WAKEUP_EN_REGWEN, - PWRMGR_WAKEUP_EN, - PWRMGR_WAKE_STATUS, - PWRMGR_RESET_EN_REGWEN, - PWRMGR_RESET_EN, - PWRMGR_RESET_STATUS, - PWRMGR_WAKE_INFO_CAPTURE_DIS, - PWRMGR_WAKE_INFO - } pwrmgr_id_e; - - // Register width information to check illegal writes - parameter logic [3:0] PWRMGR_PERMIT [14] = '{ - 4'b 0001, // index[ 0] PWRMGR_INTR_STATE - 4'b 0001, // index[ 1] PWRMGR_INTR_ENABLE - 4'b 0001, // index[ 2] PWRMGR_INTR_TEST - 4'b 0001, // index[ 3] PWRMGR_CTRL_CFG_REGWEN - 4'b 0011, // index[ 4] PWRMGR_CONTROL - 4'b 0001, // index[ 5] PWRMGR_CFG_CDC_SYNC - 4'b 0001, // index[ 6] PWRMGR_WAKEUP_EN_REGWEN - 4'b 0001, // index[ 7] PWRMGR_WAKEUP_EN - 4'b 0001, // index[ 8] PWRMGR_WAKE_STATUS - 4'b 0001, // index[ 9] PWRMGR_RESET_EN_REGWEN - 4'b 0001, // index[10] PWRMGR_RESET_EN - 4'b 0001, // index[11] PWRMGR_RESET_STATUS - 4'b 0001, // index[12] PWRMGR_WAKE_INFO_CAPTURE_DIS - 4'b 0001 // index[13] PWRMGR_WAKE_INFO - }; - -endpackage diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv b/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv deleted file mode 100644 index 8c908e17e066d1..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv +++ /dev/null @@ -1,950 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Top module auto-generated by `reggen` - -`include "prim_assert.sv" - -module pwrmgr_reg_top ( - input clk_i, - input rst_ni, - input tlul_pkg::tl_h2d_t tl_i, - output tlul_pkg::tl_d2h_t tl_o, - // To HW - output pwrmgr_reg_pkg::pwrmgr_reg2hw_t reg2hw, // Write - input pwrmgr_reg_pkg::pwrmgr_hw2reg_t hw2reg, // Read - - // Integrity check errors - output logic intg_err_o, - - // Config - input devmode_i // If 1, explicit error return for unmapped register access -); - - import pwrmgr_reg_pkg::* ; - - localparam int AW = 6; - localparam int DW = 32; - localparam int DBW = DW/8; // Byte Width - - // register signals - logic reg_we; - logic reg_re; - logic [AW-1:0] reg_addr; - logic [DW-1:0] reg_wdata; - logic [DBW-1:0] reg_be; - logic [DW-1:0] reg_rdata; - logic reg_error; - - logic addrmiss, wr_err; - - logic [DW-1:0] reg_rdata_next; - logic reg_busy; - - tlul_pkg::tl_h2d_t tl_reg_h2d; - tlul_pkg::tl_d2h_t tl_reg_d2h; - - - // incoming payload check - logic intg_err; - tlul_cmd_intg_chk u_chk ( - .tl_i(tl_i), - .err_o(intg_err) - ); - - // also check for spurious write enables - logic reg_we_err; - logic [13:0] reg_we_check; - prim_reg_we_check #( - .OneHotWidth(14) - ) u_prim_reg_we_check ( - .clk_i(clk_i), - .rst_ni(rst_ni), - .oh_i (reg_we_check), - .en_i (reg_we && !addrmiss), - .err_o (reg_we_err) - ); - - logic err_q; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - err_q <= '0; - end else if (intg_err || reg_we_err) begin - err_q <= 1'b1; - end - end - - // integrity error output is permanent and should be used for alert generation - // register errors are transactional - assign intg_err_o = err_q | intg_err | reg_we_err; - - // outgoing integrity generation - tlul_pkg::tl_d2h_t tl_o_pre; - tlul_rsp_intg_gen #( - .EnableRspIntgGen(1), - .EnableDataIntgGen(1) - ) u_rsp_intg_gen ( - .tl_i(tl_o_pre), - .tl_o(tl_o) - ); - - assign tl_reg_h2d = tl_i; - assign tl_o_pre = tl_reg_d2h; - - tlul_adapter_reg #( - .RegAw(AW), - .RegDw(DW), - .EnableDataIntgGen(0) - ) u_reg_if ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - .tl_i (tl_reg_h2d), - .tl_o (tl_reg_d2h), - - .en_ifetch_i(prim_mubi_pkg::MuBi4False), - .intg_error_o(), - - .we_o (reg_we), - .re_o (reg_re), - .addr_o (reg_addr), - .wdata_o (reg_wdata), - .be_o (reg_be), - .busy_i (reg_busy), - .rdata_i (reg_rdata), - .error_i (reg_error) - ); - - // cdc oversampling signals - - assign reg_rdata = reg_rdata_next ; - assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err; - - // Define SW related signals - // Format: __{wd|we|qs} - // or _{wd|we|qs} if field == 1 or 0 - logic intr_state_we; - logic intr_state_qs; - logic intr_state_wd; - logic intr_enable_we; - logic intr_enable_qs; - logic intr_enable_wd; - logic intr_test_we; - logic intr_test_wd; - logic ctrl_cfg_regwen_re; - logic ctrl_cfg_regwen_qs; - logic control_we; - logic control_low_power_hint_qs; - logic control_low_power_hint_wd; - logic control_core_clk_en_qs; - logic control_core_clk_en_wd; - logic control_io_clk_en_qs; - logic control_io_clk_en_wd; - logic control_usb_clk_en_lp_qs; - logic control_usb_clk_en_lp_wd; - logic control_usb_clk_en_active_qs; - logic control_usb_clk_en_active_wd; - logic control_main_pd_n_qs; - logic control_main_pd_n_wd; - logic cfg_cdc_sync_we; - logic cfg_cdc_sync_qs; - logic cfg_cdc_sync_wd; - logic wakeup_en_regwen_we; - logic wakeup_en_regwen_qs; - logic wakeup_en_regwen_wd; - logic wakeup_en_we; - logic wakeup_en_qs; - logic wakeup_en_wd; - logic wake_status_qs; - logic reset_en_regwen_we; - logic reset_en_regwen_qs; - logic reset_en_regwen_wd; - logic reset_en_we; - logic reset_en_qs; - logic reset_en_wd; - logic reset_status_qs; - logic wake_info_capture_dis_we; - logic wake_info_capture_dis_qs; - logic wake_info_capture_dis_wd; - logic wake_info_re; - logic wake_info_we; - logic wake_info_reasons_qs; - logic wake_info_reasons_wd; - logic wake_info_fall_through_qs; - logic wake_info_fall_through_wd; - logic wake_info_abort_qs; - logic wake_info_abort_wd; - - // Register instances - // R[intr_state]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_wd), - - // from internal hardware - .de (hw2reg.intr_state.de), - .d (hw2reg.intr_state.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.q), - .ds (), - - // to register interface (read) - .qs (intr_state_qs) - ); - - - // R[intr_enable]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_qs) - ); - - - // R[intr_test]: V(True) - logic intr_test_qe; - logic [0:0] intr_test_flds_we; - assign intr_test_qe = &intr_test_flds_we; - prim_subreg_ext #( - .DW (1) - ) u_intr_test ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[0]), - .q (reg2hw.intr_test.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.qe = intr_test_qe; - - - // R[ctrl_cfg_regwen]: V(True) - prim_subreg_ext #( - .DW (1) - ) u_ctrl_cfg_regwen ( - .re (ctrl_cfg_regwen_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.ctrl_cfg_regwen.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (ctrl_cfg_regwen_qs) - ); - - - // R[control]: V(False) - // Create REGWEN-gated WE signal - logic control_gated_we; - assign control_gated_we = control_we & ctrl_cfg_regwen_qs; - // F[low_power_hint]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_low_power_hint ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_low_power_hint_wd), - - // from internal hardware - .de (hw2reg.control.low_power_hint.de), - .d (hw2reg.control.low_power_hint.d), - - // to internal hardware - .qe (), - .q (reg2hw.control.low_power_hint.q), - .ds (), - - // to register interface (read) - .qs (control_low_power_hint_qs) - ); - - // F[core_clk_en]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_core_clk_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_core_clk_en_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.core_clk_en.q), - .ds (), - - // to register interface (read) - .qs (control_core_clk_en_qs) - ); - - // F[io_clk_en]: 5:5 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_io_clk_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_io_clk_en_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.io_clk_en.q), - .ds (), - - // to register interface (read) - .qs (control_io_clk_en_qs) - ); - - // F[usb_clk_en_lp]: 6:6 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_usb_clk_en_lp ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_usb_clk_en_lp_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.usb_clk_en_lp.q), - .ds (), - - // to register interface (read) - .qs (control_usb_clk_en_lp_qs) - ); - - // F[usb_clk_en_active]: 7:7 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_control_usb_clk_en_active ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_usb_clk_en_active_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.usb_clk_en_active.q), - .ds (), - - // to register interface (read) - .qs (control_usb_clk_en_active_qs) - ); - - // F[main_pd_n]: 8:8 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_control_main_pd_n ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_main_pd_n_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.main_pd_n.q), - .ds (), - - // to register interface (read) - .qs (control_main_pd_n_qs) - ); - - - // R[cfg_cdc_sync]: V(False) - logic cfg_cdc_sync_qe; - logic [0:0] cfg_cdc_sync_flds_we; - prim_flop #( - .Width(1), - .ResetValue(0) - ) u_cfg_cdc_sync0_qe ( - .clk_i(clk_i), - .rst_ni(rst_ni), - .d_i(&cfg_cdc_sync_flds_we), - .q_o(cfg_cdc_sync_qe) - ); - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_cfg_cdc_sync ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_cdc_sync_we), - .wd (cfg_cdc_sync_wd), - - // from internal hardware - .de (hw2reg.cfg_cdc_sync.de), - .d (hw2reg.cfg_cdc_sync.d), - - // to internal hardware - .qe (cfg_cdc_sync_flds_we[0]), - .q (reg2hw.cfg_cdc_sync.q), - .ds (), - - // to register interface (read) - .qs (cfg_cdc_sync_qs) - ); - assign reg2hw.cfg_cdc_sync.qe = cfg_cdc_sync_qe; - - - // R[wakeup_en_regwen]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_wakeup_en_regwen ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_regwen_we), - .wd (wakeup_en_regwen_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wakeup_en_regwen_qs) - ); - - - // Subregister 0 of Multireg wakeup_en - // R[wakeup_en]: V(False) - // Create REGWEN-gated WE signal - logic wakeup_en_gated_we; - assign wakeup_en_gated_we = wakeup_en_we & wakeup_en_regwen_qs; - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wakeup_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_gated_we), - .wd (wakeup_en_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_en[0].q), - .ds (), - - // to register interface (read) - .qs (wakeup_en_qs) - ); - - - // Subregister 0 of Multireg wake_status - // R[wake_status]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_status ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.wake_status[0].de), - .d (hw2reg.wake_status[0].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wake_status_qs) - ); - - - // R[reset_en_regwen]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_reset_en_regwen ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (reset_en_regwen_we), - .wd (reset_en_regwen_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (reset_en_regwen_qs) - ); - - - // Subregister 0 of Multireg reset_en - // R[reset_en]: V(False) - // Create REGWEN-gated WE signal - logic reset_en_gated_we; - assign reset_en_gated_we = reset_en_we & reset_en_regwen_qs; - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_reset_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (reset_en_gated_we), - .wd (reset_en_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.reset_en[0].q), - .ds (), - - // to register interface (read) - .qs (reset_en_qs) - ); - - - // Subregister 0 of Multireg reset_status - // R[reset_status]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_reset_status ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.reset_status[0].de), - .d (hw2reg.reset_status[0].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (reset_status_qs) - ); - - - // R[wake_info_capture_dis]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_info_capture_dis ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wake_info_capture_dis_we), - .wd (wake_info_capture_dis_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wake_info_capture_dis.q), - .ds (), - - // to register interface (read) - .qs (wake_info_capture_dis_qs) - ); - - - // R[wake_info]: V(True) - logic wake_info_qe; - logic [2:0] wake_info_flds_we; - assign wake_info_qe = &wake_info_flds_we; - // F[reasons]: 0:0 - prim_subreg_ext #( - .DW (1) - ) u_wake_info_reasons ( - .re (wake_info_re), - .we (wake_info_we), - .wd (wake_info_reasons_wd), - .d (hw2reg.wake_info.reasons.d), - .qre (), - .qe (wake_info_flds_we[0]), - .q (reg2hw.wake_info.reasons.q), - .ds (), - .qs (wake_info_reasons_qs) - ); - assign reg2hw.wake_info.reasons.qe = wake_info_qe; - - // F[fall_through]: 1:1 - prim_subreg_ext #( - .DW (1) - ) u_wake_info_fall_through ( - .re (wake_info_re), - .we (wake_info_we), - .wd (wake_info_fall_through_wd), - .d (hw2reg.wake_info.fall_through.d), - .qre (), - .qe (wake_info_flds_we[1]), - .q (reg2hw.wake_info.fall_through.q), - .ds (), - .qs (wake_info_fall_through_qs) - ); - assign reg2hw.wake_info.fall_through.qe = wake_info_qe; - - // F[abort]: 2:2 - prim_subreg_ext #( - .DW (1) - ) u_wake_info_abort ( - .re (wake_info_re), - .we (wake_info_we), - .wd (wake_info_abort_wd), - .d (hw2reg.wake_info.abort.d), - .qre (), - .qe (wake_info_flds_we[2]), - .q (reg2hw.wake_info.abort.q), - .ds (), - .qs (wake_info_abort_qs) - ); - assign reg2hw.wake_info.abort.qe = wake_info_qe; - - - - logic [13:0] addr_hit; - always_comb begin - addr_hit = '0; - addr_hit[ 0] = (reg_addr == PWRMGR_INTR_STATE_OFFSET); - addr_hit[ 1] = (reg_addr == PWRMGR_INTR_ENABLE_OFFSET); - addr_hit[ 2] = (reg_addr == PWRMGR_INTR_TEST_OFFSET); - addr_hit[ 3] = (reg_addr == PWRMGR_CTRL_CFG_REGWEN_OFFSET); - addr_hit[ 4] = (reg_addr == PWRMGR_CONTROL_OFFSET); - addr_hit[ 5] = (reg_addr == PWRMGR_CFG_CDC_SYNC_OFFSET); - addr_hit[ 6] = (reg_addr == PWRMGR_WAKEUP_EN_REGWEN_OFFSET); - addr_hit[ 7] = (reg_addr == PWRMGR_WAKEUP_EN_OFFSET); - addr_hit[ 8] = (reg_addr == PWRMGR_WAKE_STATUS_OFFSET); - addr_hit[ 9] = (reg_addr == PWRMGR_RESET_EN_REGWEN_OFFSET); - addr_hit[10] = (reg_addr == PWRMGR_RESET_EN_OFFSET); - addr_hit[11] = (reg_addr == PWRMGR_RESET_STATUS_OFFSET); - addr_hit[12] = (reg_addr == PWRMGR_WAKE_INFO_CAPTURE_DIS_OFFSET); - addr_hit[13] = (reg_addr == PWRMGR_WAKE_INFO_OFFSET); - end - - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; - - // Check sub-word write is permitted - always_comb begin - wr_err = (reg_we & - ((addr_hit[ 0] & (|(PWRMGR_PERMIT[ 0] & ~reg_be))) | - (addr_hit[ 1] & (|(PWRMGR_PERMIT[ 1] & ~reg_be))) | - (addr_hit[ 2] & (|(PWRMGR_PERMIT[ 2] & ~reg_be))) | - (addr_hit[ 3] & (|(PWRMGR_PERMIT[ 3] & ~reg_be))) | - (addr_hit[ 4] & (|(PWRMGR_PERMIT[ 4] & ~reg_be))) | - (addr_hit[ 5] & (|(PWRMGR_PERMIT[ 5] & ~reg_be))) | - (addr_hit[ 6] & (|(PWRMGR_PERMIT[ 6] & ~reg_be))) | - (addr_hit[ 7] & (|(PWRMGR_PERMIT[ 7] & ~reg_be))) | - (addr_hit[ 8] & (|(PWRMGR_PERMIT[ 8] & ~reg_be))) | - (addr_hit[ 9] & (|(PWRMGR_PERMIT[ 9] & ~reg_be))) | - (addr_hit[10] & (|(PWRMGR_PERMIT[10] & ~reg_be))) | - (addr_hit[11] & (|(PWRMGR_PERMIT[11] & ~reg_be))) | - (addr_hit[12] & (|(PWRMGR_PERMIT[12] & ~reg_be))) | - (addr_hit[13] & (|(PWRMGR_PERMIT[13] & ~reg_be))))); - end - - // Generate write-enables - assign intr_state_we = addr_hit[0] & reg_we & !reg_error; - - assign intr_state_wd = reg_wdata[0]; - assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; - - assign intr_enable_wd = reg_wdata[0]; - assign intr_test_we = addr_hit[2] & reg_we & !reg_error; - - assign intr_test_wd = reg_wdata[0]; - assign ctrl_cfg_regwen_re = addr_hit[3] & reg_re & !reg_error; - assign control_we = addr_hit[4] & reg_we & !reg_error; - - assign control_low_power_hint_wd = reg_wdata[0]; - - assign control_core_clk_en_wd = reg_wdata[4]; - - assign control_io_clk_en_wd = reg_wdata[5]; - - assign control_usb_clk_en_lp_wd = reg_wdata[6]; - - assign control_usb_clk_en_active_wd = reg_wdata[7]; - - assign control_main_pd_n_wd = reg_wdata[8]; - assign cfg_cdc_sync_we = addr_hit[5] & reg_we & !reg_error; - - assign cfg_cdc_sync_wd = reg_wdata[0]; - assign wakeup_en_regwen_we = addr_hit[6] & reg_we & !reg_error; - - assign wakeup_en_regwen_wd = reg_wdata[0]; - assign wakeup_en_we = addr_hit[7] & reg_we & !reg_error; - - assign wakeup_en_wd = reg_wdata[0]; - assign reset_en_regwen_we = addr_hit[9] & reg_we & !reg_error; - - assign reset_en_regwen_wd = reg_wdata[0]; - assign reset_en_we = addr_hit[10] & reg_we & !reg_error; - - assign reset_en_wd = reg_wdata[0]; - assign wake_info_capture_dis_we = addr_hit[12] & reg_we & !reg_error; - - assign wake_info_capture_dis_wd = reg_wdata[0]; - assign wake_info_re = addr_hit[13] & reg_re & !reg_error; - assign wake_info_we = addr_hit[13] & reg_we & !reg_error; - - assign wake_info_reasons_wd = reg_wdata[0]; - - assign wake_info_fall_through_wd = reg_wdata[1]; - - assign wake_info_abort_wd = reg_wdata[2]; - - // Assign write-enables to checker logic vector. - always_comb begin - reg_we_check = '0; - reg_we_check[0] = intr_state_we; - reg_we_check[1] = intr_enable_we; - reg_we_check[2] = intr_test_we; - reg_we_check[3] = 1'b0; - reg_we_check[4] = control_gated_we; - reg_we_check[5] = cfg_cdc_sync_we; - reg_we_check[6] = wakeup_en_regwen_we; - reg_we_check[7] = wakeup_en_gated_we; - reg_we_check[8] = 1'b0; - reg_we_check[9] = reset_en_regwen_we; - reg_we_check[10] = reset_en_gated_we; - reg_we_check[11] = 1'b0; - reg_we_check[12] = wake_info_capture_dis_we; - reg_we_check[13] = wake_info_we; - end - - // Read data return - always_comb begin - reg_rdata_next = '0; - unique case (1'b1) - addr_hit[0]: begin - reg_rdata_next[0] = intr_state_qs; - end - - addr_hit[1]: begin - reg_rdata_next[0] = intr_enable_qs; - end - - addr_hit[2]: begin - reg_rdata_next[0] = '0; - end - - addr_hit[3]: begin - reg_rdata_next[0] = ctrl_cfg_regwen_qs; - end - - addr_hit[4]: begin - reg_rdata_next[0] = control_low_power_hint_qs; - reg_rdata_next[4] = control_core_clk_en_qs; - reg_rdata_next[5] = control_io_clk_en_qs; - reg_rdata_next[6] = control_usb_clk_en_lp_qs; - reg_rdata_next[7] = control_usb_clk_en_active_qs; - reg_rdata_next[8] = control_main_pd_n_qs; - end - - addr_hit[5]: begin - reg_rdata_next[0] = cfg_cdc_sync_qs; - end - - addr_hit[6]: begin - reg_rdata_next[0] = wakeup_en_regwen_qs; - end - - addr_hit[7]: begin - reg_rdata_next[0] = wakeup_en_qs; - end - - addr_hit[8]: begin - reg_rdata_next[0] = wake_status_qs; - end - - addr_hit[9]: begin - reg_rdata_next[0] = reset_en_regwen_qs; - end - - addr_hit[10]: begin - reg_rdata_next[0] = reset_en_qs; - end - - addr_hit[11]: begin - reg_rdata_next[0] = reset_status_qs; - end - - addr_hit[12]: begin - reg_rdata_next[0] = wake_info_capture_dis_qs; - end - - addr_hit[13]: begin - reg_rdata_next[0] = wake_info_reasons_qs; - reg_rdata_next[1] = wake_info_fall_through_qs; - reg_rdata_next[2] = wake_info_abort_qs; - end - - default: begin - reg_rdata_next = '1; - end - endcase - end - - // shadow busy - logic shadow_busy; - assign shadow_busy = 1'b0; - - // register busy - assign reg_busy = shadow_busy; - - // Unused signal tieoff - - // wdata / byte enable are not always fully used - // add a blanket unused statement to handle lint waivers - logic unused_wdata; - logic unused_be; - assign unused_wdata = ^reg_wdata; - assign unused_be = ^reg_be; - - // Assertions for Register Interface - `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) - `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) - - `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni) - - `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) - - // this is formulated as an assumption such that the FPV testbenches do disprove this - // property by mistake - //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis) - -endmodule diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_slow_fsm.sv b/hw/ip/pwrmgr/rtl/pwrmgr_slow_fsm.sv deleted file mode 100644 index e5857520f1b7c5..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_slow_fsm.sv +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Power Manager Slow FSM -// - -`include "prim_assert.sv" - -module pwrmgr_slow_fsm import pwrmgr_pkg::*; ( - input clk_i, - input rst_ni, - input rst_main_ni, - - // sync'ed requests from peripherals - input wakeup_i, - input reset_req_i, - - // interface with fast fsm - output logic req_pwrup_o, - output logic pwrup_cause_toggle_o, - output pwrup_cause_e pwrup_cause_o, - input ack_pwrup_i, - input req_pwrdn_i, - output logic ack_pwrdn_o, - output logic rst_req_o, - output logic fsm_invalid_o, - input clr_req_i, - output logic usb_ip_clk_en_o, - input usb_ip_clk_status_i, - - // low power entry configuration - input main_pd_ni, - input io_clk_en_i, - input core_clk_en_i, - input usb_clk_en_lp_i, - input usb_clk_en_active_i, - - // AST interface - input pwr_ast_rsp_t ast_i, - output pwr_ast_req_t ast_o -); - - slow_pwr_state_e state_q, state_d; - - // All signals crossing over to other domain must be flopped - pwrup_cause_e cause_q, cause_d; - logic cause_toggle_q, cause_toggle_d; - logic req_pwrup_q, req_pwrup_d; - logic ack_pwrdn_q, ack_pwrdn_d; - - logic clk_active; - - // All power signals and signals going to analog logic are flopped to avoid transitional glitches - logic pd_nq, pd_nd; - logic pwr_clamp_q, pwr_clamp_d; - logic pwr_clamp_env_q, pwr_clamp_env_d; - logic core_clk_en_q, core_clk_en_d; - logic io_clk_en_q, io_clk_en_d; - logic usb_clk_en_q, usb_clk_en_d; - logic fsm_invalid_q, fsm_invalid_d; - - logic all_clks_valid; - logic all_clks_invalid; - - // when to monitor pok for instability - // These are monitored only in active and low power states - logic mon_main_pok; - logic set_main_pok; - logic async_main_pok_st; - logic main_pok_st; - - // all clocks sources are valid - // if clocks (usb) not configured to be active, then just bypass check - assign all_clks_valid = ast_i.core_clk_val & - ast_i.io_clk_val & - (~usb_clk_en_active_i | ast_i.usb_clk_val); - - // usb clock state during low power is not completely controlled by - // input. - // if main_pd_ni is 0, (ie power will be turned off), then the low power - // state of usb is also off. If main_pd_ni is 1 (power will be kept on), - // then the low power state of usb is directly controlled. - logic usb_clk_en_lp; - assign usb_clk_en_lp = main_pd_ni & usb_clk_en_lp_i; - - // all other clocks are also diasbled when power is turned off. - logic core_clk_en; - logic io_clk_en; - assign core_clk_en = main_pd_ni & core_clk_en_i; - assign io_clk_en = main_pd_ni & io_clk_en_i; - - // if clocks were configured to turn off, make sure val is invalid - // if clocks were not configured to turn off, just bypass the check - assign all_clks_invalid = (core_clk_en | ~ast_i.core_clk_val) & - (io_clk_en | ~ast_i.io_clk_val) & - (usb_clk_en_lp | ~ast_i.usb_clk_val); - - // ensure that clock controls are constantly re-evaluated and not just - // in one specific state - // When fsm is invalid, force the clocks to be on such that the fast fsm - // can forcibly reset the system. - // In the event the clocks cannot be turned on even when forced, the fsm - // invalid signal forces power to turn off. - assign core_clk_en_d = fsm_invalid_q | (clk_active | core_clk_en); - assign io_clk_en_d = fsm_invalid_q | (clk_active | io_clk_en); - assign usb_clk_en_d = fsm_invalid_q | (clk_active ? usb_clk_en_active_i : usb_clk_en_lp); - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - cause_q <= Por; - cause_toggle_q <= 1'b0; - pd_nq <= 1'b1; - pwr_clamp_q <= 1'b1; - pwr_clamp_env_q <= 1'b1; - core_clk_en_q <= 1'b0; - io_clk_en_q <= 1'b0; - usb_clk_en_q <= 1'b0; - req_pwrup_q <= 1'b0; - ack_pwrdn_q <= 1'b0; - fsm_invalid_q <= 1'b0; - end else begin - cause_q <= cause_d; - cause_toggle_q <= cause_toggle_d; - pd_nq <= pd_nd; - pwr_clamp_q <= pwr_clamp_d; - pwr_clamp_env_q <= pwr_clamp_env_d; - core_clk_en_q <= core_clk_en_d; - io_clk_en_q <= io_clk_en_d; - usb_clk_en_q <= usb_clk_en_d; - req_pwrup_q <= req_pwrup_d; - ack_pwrdn_q <= ack_pwrdn_d; - fsm_invalid_q <= fsm_invalid_d; - end - end - - // SEC_CM: FSM.SPARSE - `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, slow_pwr_state_e, SlowPwrStateReset) - - always_comb begin - state_d = state_q; - cause_d = cause_q; - pd_nd = pd_nq; - cause_toggle_d = cause_toggle_q; - pwr_clamp_d = pwr_clamp_q; - pwr_clamp_env_d = pwr_clamp_env_q; - - req_pwrup_d = req_pwrup_q; - ack_pwrdn_d = ack_pwrdn_q; - fsm_invalid_d = fsm_invalid_q; - - set_main_pok = '0; - - clk_active = '0; - - unique case(state_q) - - SlowPwrStateReset: begin - state_d = SlowPwrStateMainPowerOn; - cause_d = Por; - end - - SlowPwrStateLowPower: begin - // reset request behaves identically to a wakeup, other than the power-up cause being - // different - if (wakeup_i || reset_req_i) begin - state_d = SlowPwrStateMainPowerOn; - cause_toggle_d = ~cause_toggle_q; - cause_d = reset_req_i ? Reset : Wake; - end - end - - SlowPwrStateMainPowerOn: begin - pd_nd = 1'b1; - - if (main_pok_st) begin - set_main_pok = 1'b1; - pwr_clamp_env_d = 1'b0; - state_d = SlowPwrStatePwrClampOff; - end - end - - SlowPwrStatePwrClampOff: begin - pwr_clamp_d = 1'b0; - state_d = SlowPwrStateClocksOn; - end - - SlowPwrStateClocksOn: begin - clk_active = 1'b1; - - if (all_clks_valid) begin - state_d = SlowPwrStateReqPwrUp; - end - end - - SlowPwrStateReqPwrUp: begin - clk_active = 1'b1; - req_pwrup_d = 1'b1; - - // req_pwrdn_i should be 0 here to indicate - // the request from the previous round has definitely completed - if (ack_pwrup_i && !req_pwrdn_i) begin - req_pwrup_d = 1'b0; - state_d = SlowPwrStateIdle; - end - end - - SlowPwrStateIdle: begin - // ack_pwrup_i should be 0 here to indicate - // the ack from the previous round has definitively completed - clk_active = 1'b1; - - if (req_pwrdn_i && !ack_pwrup_i) begin - state_d = SlowPwrStateAckPwrDn; - end - end - - SlowPwrStateAckPwrDn: begin - clk_active = 1'b1; - ack_pwrdn_d = 1'b1; - - if (!req_pwrdn_i) begin - ack_pwrdn_d = 1'b0; - state_d = SlowPwrStateClocksOff; - end - end - - SlowPwrStateClocksOff: begin - if (all_clks_invalid) begin - // if main power is turned off, assert early clamp ahead - pwr_clamp_env_d = ~main_pd_ni; - state_d = SlowPwrStatePwrClampOn; - end - end - - SlowPwrStatePwrClampOn: begin - // if main power is turned off, assert clamp ahead - pwr_clamp_d = pwr_clamp_env_q; - state_d = SlowPwrStateMainPowerOff; - end - - SlowPwrStateMainPowerOff: begin - pd_nd = main_pd_ni; - - // Proceed if power is already off, or if there was no intent to - // turn off the power. - if (!main_pok_st | main_pd_ni) begin - state_d = SlowPwrStateLowPower; - end - end - - // Very terminal state, kill everything - // Signal the fast FSM if it somehow is still running. - // Both FSMs are now permanently out of sync and the device - // must be rebooted. - // SEC_CM: FSM.TERMINAL - default: begin - fsm_invalid_d = 1'b1; - pd_nd = 1'b0; - pwr_clamp_d = 1'b1; - end - endcase // unique case (state_q) - end // always_comb - - // If the main_pok ever drops, capture that glitch - // and hold onto it for reset escalation - always_ff @(posedge clk_i or negedge rst_main_ni) begin - if (!rst_main_ni) begin - async_main_pok_st <= '0; - end else begin - async_main_pok_st <= ast_i.main_pok; - end - end - - // We need to synchronize the above because the reset - // may cause the signal to change at any time. - prim_flop_2sync # ( - .Width(1) - ) u_main_pok_sync ( - .clk_i, - .rst_ni, - .d_i(async_main_pok_st), - .q_o(main_pok_st) - ); - - // Determine when pok should be monitored - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - mon_main_pok <= '0; - end else if (!pd_nd && mon_main_pok) begin - mon_main_pok <= 1'b0; - end else if (set_main_pok) begin - mon_main_pok <= 1'b1; - end - end - - // power stability reset request - // If the main power becomes unstable for whatever reason, - // request reset - // SEC_CM: MAIN_PD.RST.LOCAL_ESC - logic pwr_rst_req; - assign pwr_rst_req = mon_main_pok & ~main_pok_st; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - rst_req_o <= '0; - end else if (clr_req_i) begin - rst_req_o <= '0; - end else begin - rst_req_o <= rst_req_o | pwr_rst_req; - end - end - - assign pwrup_cause_o = cause_q; - assign pwrup_cause_toggle_o = cause_toggle_q; - assign req_pwrup_o = req_pwrup_q; - assign ack_pwrdn_o = ack_pwrdn_q; - assign fsm_invalid_o = fsm_invalid_q; - - assign ast_o.core_clk_en = core_clk_en_q; - assign ast_o.io_clk_en = io_clk_en_q; - // usb's enable is handshake with pwr_fsm, as it can be turned on/off - // outside of the normal low power sequence - prim_flop #( - .Width(1), - .ResetValue('0) - ) u_usb_clk_en ( - .clk_i, - .rst_ni, - // immediate enable - // graceful disable when status is 0 - .d_i(usb_clk_en_q | usb_ip_clk_status_i), - .q_o(ast_o.usb_clk_en) - ); - assign usb_ip_clk_en_o = usb_clk_en_q; - - assign ast_o.main_pd_n = pd_nq; - assign ast_o.pwr_clamp_env = pwr_clamp_env_q; - assign ast_o.pwr_clamp = pwr_clamp_q; - // This is hardwired to 1 all the time - assign ast_o.slow_clk_en = 1'b1; - - - //////////////////////////// - /// Unused - //////////////////////////// - - logic unused_slow_clk_val; - assign unused_slow_clk_val = ast_i.slow_clk_val; - - //////////////////////////// - /// Assertion - //////////////////////////// - // Under normal circumstances, this should NEVER fire - // May need to add a signal to disable this check for simulation - `ASSERT(IntRstReq_A, pwr_rst_req == '0) - -endmodule diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_wake_info.sv b/hw/ip/pwrmgr/rtl/pwrmgr_wake_info.sv deleted file mode 100644 index d547d1a36f8494..00000000000000 --- a/hw/ip/pwrmgr/rtl/pwrmgr_wake_info.sv +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Power Manager Wake Information -// - -`include "prim_assert.sv" - -module pwrmgr_wake_info import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*; -( - input clk_i, - input rst_ni, - input wr_i, - input [TotalWakeWidth-1:0] data_i, - input start_capture_i, - input record_dis_i, - input [NumWkups-1:0] wakeups_i, - input fall_through_i, - input abort_i, - output pwrmgr_hw2reg_wake_info_reg_t info_o -); - - logic record_en; - - // detect rising edge of start_capture_i - logic start_capture_q1, start_capture; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - start_capture_q1 <= 1'b1; - end else begin - start_capture_q1 <= start_capture_i; - end - end - - assign start_capture = start_capture_i & ~start_capture_q1; - - // generate the record enbale signal - // HW enables the recording - // Software can suppress the recording or disable it - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - record_en <= 1'b0; - end else if (start_capture && !record_dis_i) begin - // if not disabled by software - // a recording enable puls by HW starts recording - record_en <= 1'b1; - end else if (record_dis_i && record_en) begin - // if recording is already ongoing - // a disable command by software shuts things down - record_en <= 1'b0; - end - end - - logic [TotalWakeWidth-1:0] info; - always_ff @(posedge clk_i or negedge rst_ni) begin - if (!rst_ni) begin - info <= '0; - end else if (wr_i) begin - info <= info & ~data_i; // W1C - end else if (record_en) begin // If set once, hold until clear - info[0 +: NumWkups] <= info[0 +: NumWkups] | wakeups_i; - info[NumWkups +: 2] <= info[NumWkups +: 2] | {abort_i, fall_through_i}; - end - end - - // assign outputs - assign info_o.abort.d = info[NumWkups + 1]; - assign info_o.fall_through.d = info[NumWkups]; - assign info_o.reasons = info[NumWkups-1:0]; - - - -endmodule diff --git a/hw/ip/pwrmgr/util/reg_pwrmgr.py b/hw/ip/pwrmgr/util/reg_pwrmgr.py deleted file mode 100755 index 4c74ce066881a7..00000000000000 --- a/hw/ip/pwrmgr/util/reg_pwrmgr.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python3 -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -r"""Convert mako template to Hjson register description -""" -import argparse -import sys -from io import StringIO - -from mako.template import Template - - -def main(): - parser = argparse.ArgumentParser(prog="reg_pwrmgr") - parser.add_argument('input', - nargs='?', - metavar='file', - type=argparse.FileType('r'), - default=sys.stdin, - help='input template file') - parser.add_argument('--n_wkups', - type=int, - default=16, - help='Number of Wakeup sources') - - args = parser.parse_args() - - # Determine output: if stdin then stdout if not then ?? - out = StringIO() - - reg_tpl = Template(args.input.read()) - out.write( - reg_tpl.render(NumWkups=args.n_wkups)) - - print(out.getvalue()) - - out.close() - - -if __name__ == "__main__": - main() diff --git a/hw/ip_templates/pwrmgr/BUILD b/hw/ip_templates/pwrmgr/BUILD index 8b2c124557d7de..36beb77a655e78 100644 --- a/hw/ip_templates/pwrmgr/BUILD +++ b/hw/ip_templates/pwrmgr/BUILD @@ -6,7 +6,5 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "all_files", - srcs = glob(["**"]) + [ - "//hw/ip/pwrmgr/data:all_files", - ], + srcs = glob(["**"]), ) diff --git a/hw/ip_templates/pwrmgr/data/BUILD b/hw/ip_templates/pwrmgr/data/BUILD index 36beb77a655e78..67a01f21b218c4 100644 --- a/hw/ip_templates/pwrmgr/data/BUILD +++ b/hw/ip_templates/pwrmgr/data/BUILD @@ -4,6 +4,15 @@ package(default_visibility = ["//visibility:public"]) +load("//rules:autogen.bzl", "autogen_hjson_header") + +autogen_hjson_header( + name = "pwrmgr_regs", + srcs = [ + "pwrmgr.hjson", + ], +) + filegroup( name = "all_files", srcs = glob(["**"]), diff --git a/hw/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson b/hw/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson index 4d0ddde515167d..a67cf3d5c1ad2c 100644 --- a/hw/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson +++ b/hw/ip_templates/pwrmgr/data/pwrmgr_testplan.hjson @@ -12,7 +12,7 @@ "hw/dv/tools/dvsim/testplans/sec_cm_fsm_testplan.hjson", // TODO: Top-level specific Hjson imported here. This will likely be resolved // once we move to IPgen flow. - "hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson"] + "pwrmgr_sec_cm_testplan.hjson"] testpoints: [ { name: smoke diff --git a/hw/ip_templates/pwrmgr/dv/env/pwrmgr_env.core b/hw/ip_templates/pwrmgr/dv/env/pwrmgr_env.core index 8d737e00f3aed1..847d4fb73225c4 100644 --- a/hw/ip_templates/pwrmgr/dv/env/pwrmgr_env.core +++ b/hw/ip_templates/pwrmgr/dv/env/pwrmgr_env.core @@ -9,6 +9,7 @@ filesets: depend: - lowrisc:dv:ralgen - lowrisc:dv:cip_lib + - lowrisc:ip:pwrmgr_pkg files: - pwrmgr_env_pkg.sv - pwrmgr_env_cfg.sv: {is_include_file: true} @@ -43,7 +44,7 @@ generate: generator: ralgen parameters: name: pwrmgr - ip_hjson: ../../../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson + ip_hjson: ../../data/pwrmgr.hjson targets: default: diff --git a/hw/ip_templates/pwrmgr/dv/pwrmgr_sim_cfg.hjson b/hw/ip_templates/pwrmgr/dv/pwrmgr_sim_cfg.hjson index baebf306caf276..8aeb06e11336dc 100644 --- a/hw/ip_templates/pwrmgr/dv/pwrmgr_sim_cfg.hjson +++ b/hw/ip_templates/pwrmgr/dv/pwrmgr_sim_cfg.hjson @@ -18,10 +18,7 @@ fusesoc_core: lowrisc:dv:pwrmgr_sim:0.1 // Testplan hjson file. - testplan: "{proj_root}/hw/ip/pwrmgr/data/pwrmgr_testplan.hjson" - - // RAL spec - used to generate the RAL model. - ral_spec: "{proj_root}/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson" + testplan: "{self_dir}/../data/pwrmgr_testplan.hjson" // Import additional common sim cfg files. import_cfgs: [// Project wide common sim cfg file @@ -42,7 +39,7 @@ ] // Exclusion files - vcs_cov_excl_files: ["{proj_root}/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el"] + vcs_cov_excl_files: ["{self_dir}/cov/pwrmgr_cov_manual_excl.el"] // Add additional tops for simulation. sim_tops: ["pwrmgr_bind", diff --git a/hw/ip_templates/pwrmgr/dv/sva/pwrmgr_sva.core b/hw/ip_templates/pwrmgr/dv/sva/pwrmgr_sva.core index a3491ab7871a37..b71c2dede28a47 100644 --- a/hw/ip_templates/pwrmgr/dv/sva/pwrmgr_sva.core +++ b/hw/ip_templates/pwrmgr/dv/sva/pwrmgr_sva.core @@ -9,7 +9,7 @@ filesets: depend: - lowrisc:tlul:headers - lowrisc:fpv:csr_assert_gen - - lowrisc:ip:pwrmgr + - lowrisc:ip:pwrmgr_pkg - lowrisc:dv:clkmgr_pwrmgr_sva_if - lowrisc:dv:pwrmgr_rstmgr_sva_if files: @@ -27,7 +27,7 @@ generate: csr_assert_gen: generator: csr_assert_gen parameters: - spec: ../../../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson + spec: ../../data/pwrmgr.hjson targets: default: &default_target diff --git a/hw/ip_templates/pwrmgr/pwrmgr.core b/hw/ip_templates/pwrmgr/pwrmgr.core index af706a346f7146..c384dae955aaba 100644 --- a/hw/ip_templates/pwrmgr/pwrmgr.core +++ b/hw/ip_templates/pwrmgr/pwrmgr.core @@ -3,7 +3,7 @@ CAPI=2: # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 name: "lowrisc:ip:pwrmgr:0.1" -description: "Power manager component without the generated portions" +description: "Power manager RTL" filesets: files_rtl: @@ -15,18 +15,19 @@ filesets: - lowrisc:prim:all - lowrisc:ip:rom_ctrl_pkg - lowrisc:ip:lc_ctrl_pkg - - lowrisc:ip:pwrmgr_pkg - lowrisc:prim:sparse_fsm - lowrisc:prim:mubi - lowrisc:prim:clock_buf - lowrisc:prim:measure - lowrisc:ip_interfaces:alert_handler_reg + - lowrisc:ip:pwrmgr_pkg + - lowrisc:ip:pwrmgr_reg files: - - rtl/pwrmgr.sv - rtl/pwrmgr_cdc.sv - rtl/pwrmgr_slow_fsm.sv - rtl/pwrmgr_fsm.sv - rtl/pwrmgr_wake_info.sv + - rtl/pwrmgr.sv file_type: systemVerilogSource files_verilator_waiver: diff --git a/hw/ip_templates/pwrmgr/pwrmgr_reg.core b/hw/ip_templates/pwrmgr/pwrmgr_reg.core index 93eaf5bd351846..c20cd917273d83 100644 --- a/hw/ip_templates/pwrmgr/pwrmgr_reg.core +++ b/hw/ip_templates/pwrmgr/pwrmgr_reg.core @@ -9,10 +9,11 @@ filesets: files_rtl: depend: - lowrisc:tlul:headers + - lowrisc:ip:tlul - lowrisc:prim:subreg - - "!fileset_topgen ? (lowrisc:systems:pwrmgr_reg)" - - "fileset_topgen ? (lowrisc:systems:topgen-reg-only)" files: + - rtl/pwrmgr_reg_pkg.sv + - rtl/pwrmgr_reg_top.sv file_type: systemVerilogSource targets: diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson index 674518f352e3c2..1e7c82a49bc9c1 100644 --- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson +++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson @@ -2673,7 +2673,7 @@ Aon "0" ] - attr: templated + attr: ipgen clock_connections: { clk_i: clkmgr_aon_clocks.clk_io_div4_powerup diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson index e07857f3aa8fb6..5f3cb7a26df17c 100644 --- a/hw/top_earlgrey/data/top_earlgrey.hjson +++ b/hw/top_earlgrey/data/top_earlgrey.hjson @@ -384,8 +384,7 @@ }, domain: ["Aon", "0"], base_addr: "0x40400000", - attr: "templated", - + attr: "ipgen", }, { name: "rstmgr_aon", type: "rstmgr", diff --git a/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson b/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson index b805910301931e..69aecd2aa4c283 100644 --- a/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson +++ b/hw/top_earlgrey/dv/top_earlgrey_sim_cfgs.hjson @@ -44,7 +44,6 @@ "{proj_root}/hw/ip/prim/dv/prim_present/prim_present_sim_cfg.hjson", "{proj_root}/hw/ip/prim/dv/prim_prince/prim_prince_sim_cfg.hjson", "{proj_root}/hw/ip/pwm/dv/pwm_sim_cfg.hjson", - "{proj_root}/hw/ip/pwrmgr/dv/pwrmgr_sim_cfg.hjson", "{proj_root}/hw/ip/rom_ctrl/dv/rom_ctrl_sim_cfg.hjson", "{proj_root}/hw/ip/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim_cfg.hjson", "{proj_root}/hw/ip/rstmgr/dv/rstmgr_sim_cfg.hjson", @@ -59,6 +58,7 @@ "{proj_root}/hw/ip/usbdev/dv/usbdev_sim_cfg.hjson", // Top level IPs. "{proj_root}/hw/top_earlgrey/ip_autogen/alert_handler/dv/alert_handler_sim_cfg.hjson", + "{proj_root}/hw/top_earlgrey/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson", "{proj_root}/hw/top_earlgrey/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson", "{proj_root}/hw/top_earlgrey/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson", // Top level. diff --git a/hw/top_earlgrey/ip/BUILD b/hw/top_earlgrey/ip/BUILD index 820afa6d2d4512..7bb5064fb52c10 100644 --- a/hw/top_earlgrey/ip/BUILD +++ b/hw/top_earlgrey/ip/BUILD @@ -11,7 +11,7 @@ filegroup( "//hw/top_earlgrey/ip/clkmgr:all_files", "//hw/top_earlgrey/ip/flash_ctrl:all_files", "//hw/top_earlgrey/ip/pinmux:all_files", - "//hw/top_earlgrey/ip/pwrmgr:all_files", + "//hw/top_earlgrey/ip_autogen/pwrmgr:all_files", "//hw/top_earlgrey/ip/rstmgr:all_files", "//hw/top_earlgrey/ip/sensor_ctrl:all_files", "//hw/top_earlgrey/ip/xbar:all_files", diff --git a/hw/top_earlgrey/ip/pwrmgr/BUILD b/hw/top_earlgrey/ip/pwrmgr/BUILD deleted file mode 100644 index bcf75f93b22894..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/BUILD +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "all_files", - srcs = glob(["**"]) + [ - "//hw/top_earlgrey/ip/pwrmgr/data:all_files", - ], -) diff --git a/hw/top_earlgrey/ip/pwrmgr/data/BUILD b/hw/top_earlgrey/ip/pwrmgr/data/BUILD deleted file mode 100644 index 33e6b89e5d35a8..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/data/BUILD +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "all_files", - srcs = glob(["**"]) + [ - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:all_files", - ], -) diff --git a/hw/top_earlgrey/ip/pwrmgr/data/autogen/BUILD b/hw/top_earlgrey/ip/pwrmgr/data/autogen/BUILD deleted file mode 100644 index 67a01f21b218c4..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/data/autogen/BUILD +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -load("//rules:autogen.bzl", "autogen_hjson_header") - -autogen_hjson_header( - name = "pwrmgr_regs", - srcs = [ - "pwrmgr.hjson", - ], -) - -filegroup( - name = "all_files", - srcs = glob(["**"]), -) diff --git a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson b/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson deleted file mode 100644 index b6fdaaa45c4f77..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson +++ /dev/null @@ -1,875 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// ------------------- W A R N I N G: A U T O - G E N E R A T E D C O D E !! -------------------// -// PLEASE DO NOT HAND-EDIT THIS FILE. IT HAS BEEN AUTO-GENERATED WITH THE FOLLOWING COMMAND: -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -{ - name: "pwrmgr", - human_name: "Power Manager", - one_line_desc: "Sequences on-chip power, clocks, and resets through different reset and power states", - one_paragraph_desc: ''' - Power Manager sequences on-chip power, clocks, and reset signals on power-on reset (aka cold boot), low power entry and exit, and non-power-on resets. - To this end, it can turn power domains on and off, control root resets with Reset Manager, and control root clock enables with AST and Clock Manager. - During power up, Power Manager is responsible for triggering OTP sensing, initiating Life Cycle Controller, coordinating with ROM Controller for the startup ROM check, and eventually releasing software to execute. - It features several countermeasures to deter fault injection (FI) attacks. - ''' - // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. - cip_id: "20", - design_spec: "../doc", - dv_doc: "../doc/dv", - hw_checklist: "../doc/checklist", - sw_checklist: "/sw/device/lib/dif/dif_pwrmgr", - revisions: [ - { - version: "0.1.0", - life_stage: "L1", - design_stage: "D1", - verification_stage: "V0", // this module is not verified at the block level - dif_stage: "S0", - commit_id: "b2abc989498f072d9a5530f8aab9b58c1f92c9fb" - } - { - version: "1.0.0", - life_stage: "L1", - design_stage: "D2S", - verification_stage: "V2S", - dif_stage: "S2", - } - ] - clocking: [ - {clock: "clk_i", reset: "rst_ni", primary: true}, - {reset: "rst_main_ni"}, - {clock: "clk_slow_i", reset: "rst_slow_ni"}, - {clock: "clk_lc_i", reset: "rst_lc_ni"}, - {clock: "clk_esc_i", reset: "rst_esc_ni"} - ] - bus_interfaces: [ - { protocol: "tlul", direction: "device" } - ], - interrupt_list: [ - { name: "wakeup", desc: "Wake from low power state. See wake info for more details" }, - ], - alert_list: [ - { name: "fatal_fault", - desc: ''' - This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. - ''' - } - ], - features: [ - { name: "PWRMGR.STARTUP.LIFE_CYCLE_INITIALIZATION", - desc: "Wait completion of Life Cycle initialization." - } - { name: "PWRMGR.CLOCK_CONTROL.IO_IN_LOW_POWER", - desc: '''Controls whether the IO clock remains active in - low power mode. - ''' - } - { name: "PWRMGR.CLOCK_CONTROL.MAIN_IN_LOW_POWER", - desc: '''Controls whether the MAIN clock remains active in - low power mode. - ''' - } - { name: "PWRMGR.CLOCK_CONTROL.USB_IN_LOW_POWER", - desc: '''Controls whether the USB clock remains active in - low power mode. - ''' - } - { name: "PWRMGR.CLOCK_CONTROL.USB_WHEN_ACTIVE", - desc: "Controls whether the USB clock is enabled in active state." - } - { name: "PWRMGR.LOW_POWER.ENTRY", - desc: '''Controls of low power entry, and cases when low power is - not entered due to interrupts or specific units getting busy. - ''' - } - { name: "PWRMGR.LOW_POWER.DISABLE_POWER" - desc: '''Controls whether power is turned off for non-AON domains when - in low power. - ''' - } - { name: "PWRMGR.LOW_POWER.SYSRST_CTRL_AON_WKUP_REQ_WAKEUP_ENABLE" - desc: "Enable wakeup request wkup_req from sysrst_ctrl_aon." - } - { name: "PWRMGR.LOW_POWER.SYSRST_CTRL_AON_WKUP_REQ_WAKEUP_REQUEST" - desc: "Wakeup request wkup_req from sysrst_ctrl_aon." - } - { name: "PWRMGR.LOW_POWER.ADC_CTRL_AON_WKUP_REQ_WAKEUP_ENABLE" - desc: "Enable wakeup request wkup_req from adc_ctrl_aon." - } - { name: "PWRMGR.LOW_POWER.ADC_CTRL_AON_WKUP_REQ_WAKEUP_REQUEST" - desc: "Wakeup request wkup_req from adc_ctrl_aon." - } - { name: "PWRMGR.LOW_POWER.PINMUX_AON_PIN_WKUP_REQ_WAKEUP_ENABLE" - desc: "Enable wakeup request pin_wkup_req from pinmux_aon." - } - { name: "PWRMGR.LOW_POWER.PINMUX_AON_PIN_WKUP_REQ_WAKEUP_REQUEST" - desc: "Wakeup request pin_wkup_req from pinmux_aon." - } - { name: "PWRMGR.LOW_POWER.PINMUX_AON_USB_WKUP_REQ_WAKEUP_ENABLE" - desc: "Enable wakeup request usb_wkup_req from pinmux_aon." - } - { name: "PWRMGR.LOW_POWER.PINMUX_AON_USB_WKUP_REQ_WAKEUP_REQUEST" - desc: "Wakeup request usb_wkup_req from pinmux_aon." - } - { name: "PWRMGR.LOW_POWER.AON_TIMER_AON_WKUP_REQ_WAKEUP_ENABLE" - desc: "Enable wakeup request wkup_req from aon_timer_aon." - } - { name: "PWRMGR.LOW_POWER.AON_TIMER_AON_WKUP_REQ_WAKEUP_REQUEST" - desc: "Wakeup request wkup_req from aon_timer_aon." - } - { name: "PWRMGR.LOW_POWER.SENSOR_CTRL_AON_WKUP_REQ_WAKEUP_ENABLE" - desc: "Enable wakeup request wkup_req from sensor_ctrl_aon." - } - { name: "PWRMGR.LOW_POWER.SENSOR_CTRL_AON_WKUP_REQ_WAKEUP_REQUEST" - desc: "Wakeup request wkup_req from sensor_ctrl_aon." - } - { name: "PWRMGR.LOW_POWER.WAKE_INFO" - desc: "Record what caused the chip to wakeup from low power." - } - { name: "PWRMGR.RESET.CHECK_ROM_INTEGRITY", - desc: "Wait for successful completion of ROM integrity checks." - } - { name: "PWRMGR.RESET.SYSRST_CTRL_AON_RST_REQ_ENABLE", - desc: "Enable reset request from sysrst_ctrl_aon." - } - { name: "PWRMGR.RESET.SYSRST_CTRL_AON_RST_REQ_REQUEST", - desc: "Reset request from sysrst_ctrl_aon." - } - { name: "PWRMGR.RESET.AON_TIMER_AON_AON_TIMER_RST_REQ_ENABLE", - desc: "Enable reset request from aon_timer_aon." - } - { name: "PWRMGR.RESET.AON_TIMER_AON_AON_TIMER_RST_REQ_REQUEST", - desc: "Reset request from aon_timer_aon." - } - { name: "PWRMGR.RESET.ESCALATION_REQUEST", - desc: "Trigger reset in response to incoming escalation requests." - } - { name: "PWRMGR.RESET.ESCALATION_TIMEOUT", - desc: "Trigger reset in response to non-responsive escalation network." - } - { name: "PWRMGR.RESET.SW_RST_REQUEST", - desc: "Trigger reset in response to rstmgr's sw reset request." - } - { name: "PWRMGR.RESET.MAIN_POWER_GLITCH_RESET", - desc: "Trigger reset in response to glitch in main power." - } - { name: "PWRMGR.RESET.NDM_RESET_REQUEST", - desc: "Trigger reset in response to RV_DM ndm reset." - } - { name: "PWRMGR.RESET.POR_REQUEST", - desc: "Trigger reset in response to POR_N pin." - } - ] - - inter_signal_list: [ - { struct: "pwr_ast", - type: "req_rsp", - name: "pwr_ast", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_rst", - type: "req_rsp", - name: "pwr_rst", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_clk", - type: "req_rsp", - name: "pwr_clk", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_otp", - type: "req_rsp", - name: "pwr_otp", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_lc", - type: "req_rsp", - name: "pwr_lc", - act: "req", - package: "pwrmgr_pkg", - }, - - { struct: "pwr_flash", - type: "uni", - name: "pwr_flash", - act: "rcv", - package: "pwrmgr_pkg", - }, - - { struct: "esc_tx", - type: "uni", - name: "esc_rst_tx", - act: "rcv", - package: "prim_esc_pkg", - }, - - { struct: "esc_rx", - type: "uni", - name: "esc_rst_rx", - act: "req", - package: "prim_esc_pkg", - }, - - { struct: "pwr_cpu", - type: "uni", - name: "pwr_cpu", - act: "rcv", - package: "pwrmgr_pkg", - }, - - { struct: "logic", - width: 6, - type: "uni", - name: "wakeups", - act: "rcv", - package: "", - }, - - { struct: "logic", - width: 2, - type: "uni", - name: "rstreqs", - act: "rcv", - package: "", - }, - - { struct: "logic", - type: "uni", - name: "ndmreset_req", - act: "rcv", - }, - - { struct: "logic", - type: "uni", - name: "strap", - act: "req", - package: "", - }, - - { struct: "logic", - type: "uni", - name: "low_power", - act: "req", - package: "", - }, - - { struct: "pwrmgr_data", - type: "uni", - name: "rom_ctrl", - act: "rcv", - package: "rom_ctrl_pkg", - }, - - { struct: "lc_tx", - type: "uni", - name: "fetch_en", - act: "req", - package: "lc_ctrl_pkg", - }, - - { struct: "lc_tx", - type: "uni", - name: "lc_dft_en", - act: "rcv", - package: "lc_ctrl_pkg", - }, - - { struct: "lc_tx", - type: "uni", - name: "lc_hw_debug_en", - act: "rcv", - package: "lc_ctrl_pkg", - }, - - { struct: "mubi4", - type: "uni", - name: "sw_rst_req", - act: "rcv", - package: "prim_mubi_pkg", - }, - ], - - param_list: [ - { name: "NumWkups", - desc: "Number of wakeups", - type: "int", - default: "6", - local: "true" - }, - - { name: "SYSRST_CTRL_AON_WKUP_REQ_IDX", - desc: "Vector index for sysrst_ctrl_aon wkup_req, applies for WAKEUP_EN, WAKE_STATUS and WAKE_INFO", - type: "int", - default: "0", - local: "true" - }, - - { name: "ADC_CTRL_AON_WKUP_REQ_IDX", - desc: "Vector index for adc_ctrl_aon wkup_req, applies for WAKEUP_EN, WAKE_STATUS and WAKE_INFO", - type: "int", - default: "1", - local: "true" - }, - - { name: "PINMUX_AON_PIN_WKUP_REQ_IDX", - desc: "Vector index for pinmux_aon pin_wkup_req, applies for WAKEUP_EN, WAKE_STATUS and WAKE_INFO", - type: "int", - default: "2", - local: "true" - }, - - { name: "PINMUX_AON_USB_WKUP_REQ_IDX", - desc: "Vector index for pinmux_aon usb_wkup_req, applies for WAKEUP_EN, WAKE_STATUS and WAKE_INFO", - type: "int", - default: "3", - local: "true" - }, - - { name: "AON_TIMER_AON_WKUP_REQ_IDX", - desc: "Vector index for aon_timer_aon wkup_req, applies for WAKEUP_EN, WAKE_STATUS and WAKE_INFO", - type: "int", - default: "4", - local: "true" - }, - - { name: "SENSOR_CTRL_AON_WKUP_REQ_IDX", - desc: "Vector index for sensor_ctrl_aon wkup_req, applies for WAKEUP_EN, WAKE_STATUS and WAKE_INFO", - type: "int", - default: "5", - local: "true" - }, - - - { name: "NumRstReqs", - desc: "Number of peripheral reset requets", - type: "int", - default: "2", - local: "true" - }, - - { name: "NumIntRstReqs", - desc: "Number of pwrmgr internal reset requets", - type: "int", - default: "2", - local: "true" - }, - - { name: "NumDebugRstReqs", - desc: "Number of debug reset requets", - type: "int", - default: "1", - local: "true" - }, - - { name: "ResetMainPwrIdx", - desc: "Reset req idx for MainPwr", - type: "int", - default: "2", - local: "true" - }, - { name: "ResetEscIdx", - desc: "Reset req idx for Esc", - type: "int", - default: "3", - local: "true" - }, - { name: "ResetNdmIdx", - desc: "Reset req idx for Ndm", - type: "int", - default: "4", - local: "true" - }, - - ], - countermeasures: [ - { name: "BUS.INTEGRITY", - desc: "End-to-end bus integrity scheme." - } - { name: "LC_CTRL.INTERSIG.MUBI", - desc: "life cycle control / debug signals are multibit." - } - { name: "ROM_CTRL.INTERSIG.MUBI", - desc: "rom control done/good signals are multibit." - } - { name: "RSTMGR.INTERSIG.MUBI", - desc: "reset manager software request is multibit." - } - { name: "ESC_RX.CLK.BKGN_CHK", - desc: "Escalation receiver has a background timeout check" - } - { name: "ESC_RX.CLK.LOCAL_ESC", - desc: "Escalation receiver clock timeout has a local reset escalation" - } - { name: "FSM.SPARSE", - desc: "Sparse encoding for slow and fast state machines." - } - { name: "FSM.TERMINAL", - desc: ''' - When FSMs reach a bad state, go into a terminate state that does not - recover without user or external host intervention. - ''' - } - { name: "CTRL_FLOW.GLOBAL_ESC", - desc: "When global escalation is received, proceed directly to reset." - } - { name: "MAIN_PD.RST.LOCAL_ESC", - desc: "When main power domain reset glitches, proceed directly to reset." - } - { name: "CTRL.CONFIG.REGWEN", - desc: "Main control protected by regwen." - } - { name: "WAKEUP.CONFIG.REGWEN", - desc: "Wakeup configuration protected by regwen." - } - { name: "RESET.CONFIG.REGWEN", - desc: "Reset configuration protected by regwen." - } - - ] - - regwidth: "32", - registers: [ - - { name: "CTRL_CFG_REGWEN", - swaccess: "ro", - hwaccess: "hwo", - hwext: "true", - desc: ''' - Controls the configurability of the !!CONTROL register. - - This register ensures the contents do not change once a low power hint and - WFI has occurred. - - It unlocks whenever a low power transition has completed (transition back to the - ACTIVE state) for any reason. - ''', - - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Configuration enable. - - This bit defaults to 1 and is set to 0 by hardware when low power entry is initiated. - When the device transitions back from low power state to active state, this bit is set - back to 1 to allow software configuration of !!CONTROL - ''', - resval: "1", - }, - ] - tags: [// This regwen is completely under HW management and thus cannot be manipulated - // by software. - "excl:CsrNonInitTests:CsrExclCheck"] - }, - - - { name: "CONTROL", - desc: "Control register", - swaccess: "rw", - hwaccess: "hro", - regwen: "CTRL_CFG_REGWEN", - tags: [// Turning off USB clock in active state impacts other CSRs - // at the chip level (in other blocks, such as clkmgr), - // so we exclude writing from this register. - "excl:CsrAllTests:CsrExclWrite"] - fields: [ - { bits: "0", - hwaccess: "hrw", - name: "LOW_POWER_HINT", - desc: ''' - The low power hint to power manager. - The hint is an indication for how the manager should treat the next WFI. - Once the power manager begins a low power transition, or if a valid reset request is registered, - this bit is automatically cleared by HW. - ''' - resval: "0" - enum: [ - { value: "0", - name: "None", - desc: ''' - No low power intent - ''' - }, - { value: "1", - name: "Low Power", - desc: ''' - Next WFI should trigger low power entry - ''' - }, - ] - tags: [// The regwen for this reg is RO. CSR seq can't support to check this reg - "excl:CsrAllTests:CsrExclAll"] - }, - - { bits: "4", - name: "CORE_CLK_EN", - desc: "core clock enable during low power state", - resval: "0" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - Core clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - Core clock enabled during low power state - ''' - }, - ] - }, - - { bits: "5", - name: "IO_CLK_EN", - desc: "IO clock enable during low power state", - resval: "0" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - IO clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - IO clock enabled during low power state - ''' - }, - ] - }, - - { bits: "6", - name: "USB_CLK_EN_LP", - desc: "USB clock enable during low power state", - resval: "0", - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - USB clock disabled during low power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - USB clock enabled during low power state. - - However, if !!CONTROL.MAIN_PD_N is 0, USB clock is disabled - during low power state. - ''' - }, - ] - }, - - { bits: "7", - name: "USB_CLK_EN_ACTIVE", - desc: "USB clock enable during active power state", - resval: "1" - enum: [ - { value: "0", - name: "Disabled", - desc: ''' - USB clock disabled during active power state - ''' - }, - { value: "1", - name: "Enabled", - desc: ''' - USB clock enabled during active power state - ''' - }, - ] - }, - - { bits: "8", - name: "MAIN_PD_N", - desc: "Active low, main power domain power down", - resval: "1" - enum: [ - { value: "0", - name: "Power down", - desc: ''' - Main power domain is powered down during low power state. - ''' - }, - { value: "1", - name: "Power up", - desc: ''' - Main power domain is kept powered during low power state - ''' - }, - ] - }, - - - ], - }, - - { name: "CFG_CDC_SYNC", - swaccess: "rw", - hwaccess: "hrw", - hwqe: "true", - desc: ''' - The configuration registers CONTROL, WAKEUP_EN, RESET_EN are all written in the - fast clock domain but used in the slow clock domain. - - The configuration are not propagated across the clock boundary until this - register is triggered and read. See fields below for more details - ''', - - fields: [ - { bits: "0", - name: "SYNC", - desc: ''' - Configuration sync. When this bit is written to 1, a sync pulse is generated. When - the sync completes, this bit then self clears. - - Software should write this bit to 1, wait for it to clear, before assuming the slow clock - domain has accepted the programmed values. - ''', - resval: "0", - }, - ] - tags: [// This bit triggers a payload synchronization and self clears when complete. - // Do not write this bit as there will be side effects and the value will not persist - "excl:CsrNonInitTests:CsrExclWrite"] - }, - - { name: "WAKEUP_EN_REGWEN", - desc: "Configuration enable for wakeup_en register", - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - resval: "1" - name: "EN", - desc: ''' - When 1, WAKEUP_EN register can be configured. - When 0, WAKEUP_EN register cannot be configured. - ''', - }, - ] - }, - - { multireg: - { name: "WAKEUP_EN", - desc: "Bit mask for enabled wakeups", - swaccess: "rw", - hwaccess: "hro", - regwen: "WAKEUP_EN_REGWEN", - resval: "0" - cname: "wakeup_en", - count: "NumWkups" - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Whenever a particular bit is set to 1, that wakeup is also enabled. - Whenever a particular bit is set to 0, that wakeup cannot wake the device from low power. - ''', - }, - ] - }, - }, - - { multireg: - { name: "WAKE_STATUS", - desc: "A read only register of all current wake requests post enable mask", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - cname: "wake_status", - count: "NumWkups", - tags: [// Cannot auto-predict current wake request status - "excl:CsrNonInitTests:CsrExclWriteCheck"], - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - Current value of wake requests - ''', - }, - ] - }, - }, - - { name: "RESET_EN_REGWEN", - desc: "Configuration enable for reset_en register", - swaccess: "rw0c", - hwaccess: "none", - fields: [ - { bits: "0", - resval: "1" - name: "EN", - desc: ''' - When 1, RESET_EN register can be configured. - When 0, RESET_EN register cannot be configured. - ''', - }, - ] - }, - - { multireg: - { name: "RESET_EN", - desc: "Bit mask for enabled reset requests", - swaccess: "rw", - hwaccess: "hro", - regwen: "RESET_EN_REGWEN", - resval: "0" - cname: "rstreq_en", - count: "NumRstReqs" - fields: [ - { bits: "0", - name: "EN", - desc: ''' - Whenever a particular bit is set to 1, that reset request is enabled. - Whenever a particular bit is set to 0, that reset request cannot reset the device. - ''', - }, - ] - tags: [// Self resets should never be triggered by automated tests - "excl:CsrAllTests:CsrExclWrite"] - }, - }, - - { multireg: - { name: "RESET_STATUS", - desc: "A read only register of all current reset requests post enable mask", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - cname: "reset_status", - count: "NumRstReqs", - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - Current value of reset request - ''', - }, - ] - }, - }, - - { name: "ESCALATE_RESET_STATUS", - desc: "A read only register of escalation reset request", - swaccess: "ro", - hwaccess: "hwo", - resval: "0" - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - When 1, an escalation reset has been seen. - When 0, there is no escalation reset. - ''', - }, - ] - }, - - { name: "WAKE_INFO_CAPTURE_DIS", - desc: "Indicates which functions caused the chip to wakeup", - swaccess: "rw", - hwaccess: "hro", - resval: "0" - fields: [ - { bits: "0", - name: "VAL", - desc: ''' - When written to 1, this actively suppresses the wakeup info capture. - When written to 0, wakeup info capture timing is controlled by HW. - ''', - }, - ] - }, - - { name: "WAKE_INFO", - desc: ''' - Indicates which functions caused the chip to wakeup. - The wake info recording begins whenever the device begins a valid low power entry. - - This capture is continued until it is explicitly disabled through WAKE_INFO_CAPTURE_DIS. - This means it is possible to capture multiple wakeup reasons. - ''', - swaccess: "rw1c", - hwaccess: "hrw", - hwext: "true", - hwqe: "true", - resval: "0" - fields: [ - { bits: "5:0", - name: "REASONS", - desc: "Various peripheral wake reasons" - }, - { bits: "6", - name: "FALL_THROUGH", - desc: ''' - The fall through wakeup reason indicates that despite setting a WFI and providing a low power - hint, an interrupt arrived at just the right time to break the executing core out of WFI. - - The power manager detects this condition, halts low power entry and reports as a wakeup reason - ''', - }, - { bits: "7", - name: "ABORT", - desc: ''' - The abort wakeup reason indicates that despite setting a WFI and providing a low power - hint, an active flash / lifecycle / otp transaction was ongoing when the power controller - attempted to initiate low power entry. - - The power manager detects this condition, halts low power entry and reports as a wakeup reason - ''', - }, - ] - tags: [// This regwen is completely under HW management and thus cannot be manipulated - // by software. - "excl:CsrNonInitTests:CsrExclCheck"] - }, - - { name: "FAULT_STATUS", - desc: "A read only register that shows the existing faults", - swaccess: "ro", - hwaccess: "hrw", - sync: "clk_lc_i", - resval: "0" - fields: [ - { bits: "0", - name: "REG_INTG_ERR", - desc: ''' - When 1, an integrity error has occurred. - ''', - }, - - { bits: "1", - name: "ESC_TIMEOUT", - desc: ''' - When 1, an escalation clock / reset timeout has occurred. - ''', - }, - - { bits: "2", - name: "MAIN_PD_GLITCH", - desc: ''' - When 1, unexpected power glitch was observed on main PD. - ''', - }, - ] - }, - ] -} diff --git a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson b/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson deleted file mode 100644 index 87812926e43b0a..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 - -// Security countermeasures testplan extracted from the IP Hjson using reggen. -// -// This testplan is auto-generated only the first time it is created. This is -// because this testplan needs to be hand-editable. It is possible that these -// testpoints can go out of date if the spec is updated with new -// countermeasures. When `reggen` is invoked when this testplan already exists, -// It checks if the list of testpoints is up-to-date and enforces the user to -// make further manual updates. -// -// These countermeasures and their descriptions can be found here: -// .../pwrmgr/data/pwrmgr.hjson -// -// It is possible that the testing of some of these countermeasures may already -// be covered as a testpoint in a different testplan. This duplication is ok - -// the test would have likely already been developed. We simply map those tests -// to the testpoints below using the `tests` key. -// -// Please ensure that this testplan is imported in: -// .../pwrmgr/data/pwrmgr_testplan.hjson -{ - testpoints: [ - { - name: sec_cm_bus_integrity - desc: '''Verify the countermeasure(s) BUS.INTEGRITY. - This entry is covered by tl_access_test - (hw/dv/tools/dvsim/tests/tl_access_tests.hjson) - ''' - stage: V2S - tests: ["pwrmgr_tl_intg_err"] - } - { - name: sec_cm_lc_ctrl_intersig_mubi - desc: '''Verify the countermeasure(s) LC_CTRL.INTERSIG.MUBI. - - **Stimulus**: - - Use comprehensive stimulus - reset and wakeup - - as background traffic to ensure this counter measure - is valid for various states of fast and slow state. - - Drive lc_hw_debug_en_i and lc_dft_en_i with - mixed valid and invalid values. - - **Check**: - - Collect coverage by binding cip_mubi_cov_if to - tb.dut.lc_hw_debug_en_i and tb.dut.lc_dft_en_i - - Add assertion to check whether rom_intg_chk_dis - is set to '1' only when lc_dft_en_i or lc_hw_debug_en_i - is high. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_lc_ctrl_intersig_mubi"] - } - { - name: sec_cm_rom_ctrl_intersig_mubi - desc: '''Verify the countermeasure(s) ROM_CTRL.INTERSIG.MUBI. - - **Stimulus**: - - Use comprehensive stimulus - reset and wakeup - - as background traffic to ensure this counter measure - is valid for various states of fast and slow fsm. - - Drive rom_ctrl_i with mixed valid and invalid values. - - **Check**: - - Collect coverage by binding cip_mubi_cov_if to - tb.dut.rom_ctrl_i - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_rom_ctrl_intersig_mubi"] - } - { - name: sec_cm_rstmgr_intersig_mubi - desc: '''Verify the countermeasure(s) RSTMGR.INTERSIG.MUBI. - - **Stimulus**: - - Drive tb.dut.sw_rst_req_i with mixed valid and invalid values - - **Check**: - - See sw rst only happens when dut gets valid value by - probing fast fsm state. The state has to move low power state. - - Collect coverage by binding cip_mubi_cov_if to - tb.dut.sw_rst_req_i - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_rstmgr_intersig_mubi"] - } - { - name: sec_cm_esc_rx_clk_bkgn_chk - desc: '''Verify the countermeasure(s) ESC_RX.CLK.BKGN_CHK. - - **Stimulus**: - - At FastPwrStateActive state, create escalation clock - or reset failure by stopping clock or asserting reset. - - **Check**: - - Expecting fatal alert event and rstreqs[ResetEscIdx]. - - Add assertion to see if u_esc_timeout happens, then - rstreqs[ResetEscIdx] should be asserted. - - After the alert agent processese the alert - by asserting escalation reset, - see if dut is back to normal operation state. - ''' - stage: V2S - tests: ["pwrmgr_esc_clk_rst_malfunc"] - } - { - name: sec_cm_esc_rx_clk_local_esc - desc: '''Verify the countermeasure(s) ESC_RX.CLK.LOCAL_ESC. - - This is triggered by common cm primitives (SecCmPrimCount). - (https://github.com/lowRISC/opentitan/blob/master - /hw/dv/sv/cip_lib/doc/index.md#security-verification - -for-common-countermeasure-primitives) - - **Check**: - - Detect fast state transition to FastPwrStateResetPrep. - - Add assertion to check if u_sec_timeout happens, then - rstreqs[ResetEscIdx] should be asserted. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm"] - } - { - name: sec_cm_fsm_sparse - desc: '''Verify the countermeasure(s) FSM.SPARSE. - This is triggered by common cm primitives (SecCmPrimSparseFsmFlop). - (https://github.com/lowRISC/opentitan/blob/master - /hw/dv/sv/cip_lib/doc/index.md#security-verification - -for-common-countermeasure-primitives) - ''' - stage: V2S - tests: ["pwrmgr_sec_cm"] - } - { - name: sec_cm_fsm_terminal - desc: '''Verify the countermeasure(s) FSM.TERMINAL. - - This is caused by any invalid (slow|fast) state. - - **Check**: - - If slow state is invalid, fast state becomes FastPwrStateInvalid, - pwr_ast_o.pwr_clamp =1 and pwr_ast_o.main_pd_n = 0. - - If fast state is invalid, pwr_rst_o.rst_lc_req is all one, - pwr_rst_o.rst_sys_req is all one and pwr_clk_o = 0. - Dut should be recovered by asserting rst_n = 0. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm"] - } - { - name: sec_cm_ctrl_flow_global_esc - desc: '''Verify the countermeasure(s) CTRL_FLOW.GLOBAL_ESC. - - **Stimulus**: - - Send escalation request to esc_rst_tx_i - - **Check**: - - Check fast state transition to FastPwrStateResetPrep - - Add assertion to see if we get pwr_rst_o.rstreqs[ResetEscIdx] - set when dut receives esc_rst_tx_i - ''' - stage: V2S - tests: ["pwrmgr_global_esc"] - } - { - name: sec_cm_main_pd_rst_local_esc - desc: '''Verify the countermeasure(s) MAIN_PD.RST.LOCAL_ESC. - - **Stimulus**: - - Create power reset glitch by setting tb.dut.rst_main_ni - and tb.dut.pwr_ast_i.main_pok to 0 - - **Check**: - - Check fast state transition to FastPwrStateResetPrep - - Add assertion to see if we get pwr_rst_o.rstreqs[ResetMainPwrIdx] - ''' - stage: V2S - tests: ["pwrmgr_glitch"] - } - { - name: sec_cm_ctrl_config_regwen - desc: '''Verify the countermeasure(s) CTRL.CONFIG.REGWEN. - - **Stimulus**: - - Initiate low power transition by setting - PWRMGR.CONTROL.LOW_POWER_HINT to 1. Wait for a few cycle - to ensure the csr value propagates to slow clock domain. - Then issue csr write to PWRMGR.CONTROL - - **Check**: - - After the csr update under PWRMGR.CTRL_CFG_REGWEN = 0, - read back and check the value is not updated by - the csr update attempt. - ''' - stage: V2S - tests: ["pwrmgr_sec_cm_ctrl_config_regwen"] - } - { - name: sec_cm_wakeup_config_regwen - desc: '''Verify the countermeasure(s) WAKEUP.CONFIG.REGWEN. - - This is covered by auto csr test. - ''' - stage: V2S - tests: ["pwrmgr_csr_rw"] - } - { - name: sec_cm_reset_config_regwen - desc: '''Verify the countermeasure(s) RESET.CONFIG.REGWEN. - - This is covered by auto csr test. - ''' - stage: V2S - tests: ["pwrmgr_csr_rw"] - } - ] -} diff --git a/hw/top_earlgrey/ip/pwrmgr/pwrmgr_reg.core b/hw/top_earlgrey/ip/pwrmgr/pwrmgr_reg.core deleted file mode 100644 index 1c349cc562d685..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/pwrmgr_reg.core +++ /dev/null @@ -1,20 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors. -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:systems:pwrmgr_reg:0.1" -description: "Auto-generated power manager registers for top_earlgrey" - -filesets: - files_rtl: - depend: - - lowrisc:tlul:headers - files: - - rtl/autogen/pwrmgr_reg_pkg.sv - - rtl/autogen/pwrmgr_reg_top.sv - file_type: systemVerilogSource - -targets: - default: - filesets: - - files_rtl diff --git a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_pkg.sv b/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_pkg.sv deleted file mode 100644 index 81c0da45da9c09..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_pkg.sv +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Package auto-generated by `reggen` containing data structure - -package pwrmgr_reg_pkg; - - // Param list - parameter int NumWkups = 6; - parameter int SYSRST_CTRL_AON_WKUP_REQ_IDX = 0; - parameter int ADC_CTRL_AON_WKUP_REQ_IDX = 1; - parameter int PINMUX_AON_PIN_WKUP_REQ_IDX = 2; - parameter int PINMUX_AON_USB_WKUP_REQ_IDX = 3; - parameter int AON_TIMER_AON_WKUP_REQ_IDX = 4; - parameter int SENSOR_CTRL_AON_WKUP_REQ_IDX = 5; - parameter int NumRstReqs = 2; - parameter int NumIntRstReqs = 2; - parameter int NumDebugRstReqs = 1; - parameter int ResetMainPwrIdx = 2; - parameter int ResetEscIdx = 3; - parameter int ResetNdmIdx = 4; - parameter int NumAlerts = 1; - - // Address widths within the block - parameter int BlockAw = 7; - - //////////////////////////// - // Typedefs for registers // - //////////////////////////// - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_intr_state_reg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_intr_enable_reg_t; - - typedef struct packed { - logic q; - logic qe; - } pwrmgr_reg2hw_intr_test_reg_t; - - typedef struct packed { - logic q; - logic qe; - } pwrmgr_reg2hw_alert_test_reg_t; - - typedef struct packed { - struct packed { - logic q; - } low_power_hint; - struct packed { - logic q; - } core_clk_en; - struct packed { - logic q; - } io_clk_en; - struct packed { - logic q; - } usb_clk_en_lp; - struct packed { - logic q; - } usb_clk_en_active; - struct packed { - logic q; - } main_pd_n; - } pwrmgr_reg2hw_control_reg_t; - - typedef struct packed { - logic q; - logic qe; - } pwrmgr_reg2hw_cfg_cdc_sync_reg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_wakeup_en_mreg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_reset_en_mreg_t; - - typedef struct packed { - logic q; - } pwrmgr_reg2hw_wake_info_capture_dis_reg_t; - - typedef struct packed { - struct packed { - logic [5:0] q; - logic qe; - } reasons; - struct packed { - logic q; - logic qe; - } fall_through; - struct packed { - logic q; - logic qe; - } abort; - } pwrmgr_reg2hw_wake_info_reg_t; - - typedef struct packed { - struct packed { - logic q; - } reg_intg_err; - struct packed { - logic q; - } esc_timeout; - struct packed { - logic q; - } main_pd_glitch; - } pwrmgr_reg2hw_fault_status_reg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_intr_state_reg_t; - - typedef struct packed { - logic d; - } pwrmgr_hw2reg_ctrl_cfg_regwen_reg_t; - - typedef struct packed { - struct packed { - logic d; - logic de; - } low_power_hint; - } pwrmgr_hw2reg_control_reg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_cfg_cdc_sync_reg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_wake_status_mreg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_reset_status_mreg_t; - - typedef struct packed { - logic d; - logic de; - } pwrmgr_hw2reg_escalate_reset_status_reg_t; - - typedef struct packed { - struct packed { - logic [5:0] d; - } reasons; - struct packed { - logic d; - } fall_through; - struct packed { - logic d; - } abort; - } pwrmgr_hw2reg_wake_info_reg_t; - - typedef struct packed { - struct packed { - logic d; - logic de; - } reg_intg_err; - struct packed { - logic d; - logic de; - } esc_timeout; - struct packed { - logic d; - logic de; - } main_pd_glitch; - } pwrmgr_hw2reg_fault_status_reg_t; - - // Register -> HW type - typedef struct packed { - pwrmgr_reg2hw_intr_state_reg_t intr_state; // [36:36] - pwrmgr_reg2hw_intr_enable_reg_t intr_enable; // [35:35] - pwrmgr_reg2hw_intr_test_reg_t intr_test; // [34:33] - pwrmgr_reg2hw_alert_test_reg_t alert_test; // [32:31] - pwrmgr_reg2hw_control_reg_t control; // [30:25] - pwrmgr_reg2hw_cfg_cdc_sync_reg_t cfg_cdc_sync; // [24:23] - pwrmgr_reg2hw_wakeup_en_mreg_t [5:0] wakeup_en; // [22:17] - pwrmgr_reg2hw_reset_en_mreg_t [1:0] reset_en; // [16:15] - pwrmgr_reg2hw_wake_info_capture_dis_reg_t wake_info_capture_dis; // [14:14] - pwrmgr_reg2hw_wake_info_reg_t wake_info; // [13:3] - pwrmgr_reg2hw_fault_status_reg_t fault_status; // [2:0] - } pwrmgr_reg2hw_t; - - // HW -> register type - typedef struct packed { - pwrmgr_hw2reg_intr_state_reg_t intr_state; // [38:37] - pwrmgr_hw2reg_ctrl_cfg_regwen_reg_t ctrl_cfg_regwen; // [36:36] - pwrmgr_hw2reg_control_reg_t control; // [35:34] - pwrmgr_hw2reg_cfg_cdc_sync_reg_t cfg_cdc_sync; // [33:32] - pwrmgr_hw2reg_wake_status_mreg_t [5:0] wake_status; // [31:20] - pwrmgr_hw2reg_reset_status_mreg_t [1:0] reset_status; // [19:16] - pwrmgr_hw2reg_escalate_reset_status_reg_t escalate_reset_status; // [15:14] - pwrmgr_hw2reg_wake_info_reg_t wake_info; // [13:6] - pwrmgr_hw2reg_fault_status_reg_t fault_status; // [5:0] - } pwrmgr_hw2reg_t; - - // Register offsets - parameter logic [BlockAw-1:0] PWRMGR_INTR_STATE_OFFSET = 7'h 0; - parameter logic [BlockAw-1:0] PWRMGR_INTR_ENABLE_OFFSET = 7'h 4; - parameter logic [BlockAw-1:0] PWRMGR_INTR_TEST_OFFSET = 7'h 8; - parameter logic [BlockAw-1:0] PWRMGR_ALERT_TEST_OFFSET = 7'h c; - parameter logic [BlockAw-1:0] PWRMGR_CTRL_CFG_REGWEN_OFFSET = 7'h 10; - parameter logic [BlockAw-1:0] PWRMGR_CONTROL_OFFSET = 7'h 14; - parameter logic [BlockAw-1:0] PWRMGR_CFG_CDC_SYNC_OFFSET = 7'h 18; - parameter logic [BlockAw-1:0] PWRMGR_WAKEUP_EN_REGWEN_OFFSET = 7'h 1c; - parameter logic [BlockAw-1:0] PWRMGR_WAKEUP_EN_OFFSET = 7'h 20; - parameter logic [BlockAw-1:0] PWRMGR_WAKE_STATUS_OFFSET = 7'h 24; - parameter logic [BlockAw-1:0] PWRMGR_RESET_EN_REGWEN_OFFSET = 7'h 28; - parameter logic [BlockAw-1:0] PWRMGR_RESET_EN_OFFSET = 7'h 2c; - parameter logic [BlockAw-1:0] PWRMGR_RESET_STATUS_OFFSET = 7'h 30; - parameter logic [BlockAw-1:0] PWRMGR_ESCALATE_RESET_STATUS_OFFSET = 7'h 34; - parameter logic [BlockAw-1:0] PWRMGR_WAKE_INFO_CAPTURE_DIS_OFFSET = 7'h 38; - parameter logic [BlockAw-1:0] PWRMGR_WAKE_INFO_OFFSET = 7'h 3c; - parameter logic [BlockAw-1:0] PWRMGR_FAULT_STATUS_OFFSET = 7'h 40; - - // Reset values for hwext registers and their fields - parameter logic [0:0] PWRMGR_INTR_TEST_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_INTR_TEST_WAKEUP_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_ALERT_TEST_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_CTRL_CFG_REGWEN_RESVAL = 1'h 1; - parameter logic [0:0] PWRMGR_CTRL_CFG_REGWEN_EN_RESVAL = 1'h 1; - parameter logic [7:0] PWRMGR_WAKE_INFO_RESVAL = 8'h 0; - parameter logic [5:0] PWRMGR_WAKE_INFO_REASONS_RESVAL = 6'h 0; - parameter logic [0:0] PWRMGR_WAKE_INFO_FALL_THROUGH_RESVAL = 1'h 0; - parameter logic [0:0] PWRMGR_WAKE_INFO_ABORT_RESVAL = 1'h 0; - - // Register index - typedef enum int { - PWRMGR_INTR_STATE, - PWRMGR_INTR_ENABLE, - PWRMGR_INTR_TEST, - PWRMGR_ALERT_TEST, - PWRMGR_CTRL_CFG_REGWEN, - PWRMGR_CONTROL, - PWRMGR_CFG_CDC_SYNC, - PWRMGR_WAKEUP_EN_REGWEN, - PWRMGR_WAKEUP_EN, - PWRMGR_WAKE_STATUS, - PWRMGR_RESET_EN_REGWEN, - PWRMGR_RESET_EN, - PWRMGR_RESET_STATUS, - PWRMGR_ESCALATE_RESET_STATUS, - PWRMGR_WAKE_INFO_CAPTURE_DIS, - PWRMGR_WAKE_INFO, - PWRMGR_FAULT_STATUS - } pwrmgr_id_e; - - // Register width information to check illegal writes - parameter logic [3:0] PWRMGR_PERMIT [17] = '{ - 4'b 0001, // index[ 0] PWRMGR_INTR_STATE - 4'b 0001, // index[ 1] PWRMGR_INTR_ENABLE - 4'b 0001, // index[ 2] PWRMGR_INTR_TEST - 4'b 0001, // index[ 3] PWRMGR_ALERT_TEST - 4'b 0001, // index[ 4] PWRMGR_CTRL_CFG_REGWEN - 4'b 0011, // index[ 5] PWRMGR_CONTROL - 4'b 0001, // index[ 6] PWRMGR_CFG_CDC_SYNC - 4'b 0001, // index[ 7] PWRMGR_WAKEUP_EN_REGWEN - 4'b 0001, // index[ 8] PWRMGR_WAKEUP_EN - 4'b 0001, // index[ 9] PWRMGR_WAKE_STATUS - 4'b 0001, // index[10] PWRMGR_RESET_EN_REGWEN - 4'b 0001, // index[11] PWRMGR_RESET_EN - 4'b 0001, // index[12] PWRMGR_RESET_STATUS - 4'b 0001, // index[13] PWRMGR_ESCALATE_RESET_STATUS - 4'b 0001, // index[14] PWRMGR_WAKE_INFO_CAPTURE_DIS - 4'b 0001, // index[15] PWRMGR_WAKE_INFO - 4'b 0001 // index[16] PWRMGR_FAULT_STATUS - }; - -endpackage diff --git a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv b/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv deleted file mode 100644 index fb57456b0c2e1b..00000000000000 --- a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv +++ /dev/null @@ -1,1490 +0,0 @@ -// Copyright lowRISC contributors. -// Licensed under the Apache License, Version 2.0, see LICENSE for details. -// SPDX-License-Identifier: Apache-2.0 -// -// Register Top module auto-generated by `reggen` - -`include "prim_assert.sv" - -module pwrmgr_reg_top ( - input clk_i, - input rst_ni, - input clk_lc_i, - input rst_lc_ni, - input tlul_pkg::tl_h2d_t tl_i, - output tlul_pkg::tl_d2h_t tl_o, - // To HW - output pwrmgr_reg_pkg::pwrmgr_reg2hw_t reg2hw, // Write - input pwrmgr_reg_pkg::pwrmgr_hw2reg_t hw2reg, // Read - - // Integrity check errors - output logic intg_err_o, - - // Config - input devmode_i // If 1, explicit error return for unmapped register access -); - - import pwrmgr_reg_pkg::* ; - - localparam int AW = 7; - localparam int DW = 32; - localparam int DBW = DW/8; // Byte Width - - // register signals - logic reg_we; - logic reg_re; - logic [AW-1:0] reg_addr; - logic [DW-1:0] reg_wdata; - logic [DBW-1:0] reg_be; - logic [DW-1:0] reg_rdata; - logic reg_error; - - logic addrmiss, wr_err; - - logic [DW-1:0] reg_rdata_next; - logic reg_busy; - - tlul_pkg::tl_h2d_t tl_reg_h2d; - tlul_pkg::tl_d2h_t tl_reg_d2h; - - - // incoming payload check - logic intg_err; - tlul_cmd_intg_chk u_chk ( - .tl_i(tl_i), - .err_o(intg_err) - ); - - // also check for spurious write enables - logic reg_we_err; - logic [16:0] reg_we_check; - prim_reg_we_check #( - .OneHotWidth(17) - ) u_prim_reg_we_check ( - .clk_i(clk_i), - .rst_ni(rst_ni), - .oh_i (reg_we_check), - .en_i (reg_we && !addrmiss), - .err_o (reg_we_err) - ); - - logic err_q; - always_ff @(posedge clk_lc_i or negedge rst_lc_ni) begin - if (!rst_lc_ni) begin - err_q <= '0; - end else if (intg_err || reg_we_err) begin - err_q <= 1'b1; - end - end - - // integrity error output is permanent and should be used for alert generation - // register errors are transactional - assign intg_err_o = err_q | intg_err | reg_we_err; - - // outgoing integrity generation - tlul_pkg::tl_d2h_t tl_o_pre; - tlul_rsp_intg_gen #( - .EnableRspIntgGen(1), - .EnableDataIntgGen(1) - ) u_rsp_intg_gen ( - .tl_i(tl_o_pre), - .tl_o(tl_o) - ); - - assign tl_reg_h2d = tl_i; - assign tl_o_pre = tl_reg_d2h; - - tlul_adapter_reg #( - .RegAw(AW), - .RegDw(DW), - .EnableDataIntgGen(0) - ) u_reg_if ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - .tl_i (tl_reg_h2d), - .tl_o (tl_reg_d2h), - - .en_ifetch_i(prim_mubi_pkg::MuBi4False), - .intg_error_o(), - - .we_o (reg_we), - .re_o (reg_re), - .addr_o (reg_addr), - .wdata_o (reg_wdata), - .be_o (reg_be), - .busy_i (reg_busy), - .rdata_i (reg_rdata), - .error_i (reg_error) - ); - - // cdc oversampling signals - - assign reg_rdata = reg_rdata_next ; - assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err; - - // Define SW related signals - // Format: __{wd|we|qs} - // or _{wd|we|qs} if field == 1 or 0 - logic intr_state_we; - logic intr_state_qs; - logic intr_state_wd; - logic intr_enable_we; - logic intr_enable_qs; - logic intr_enable_wd; - logic intr_test_we; - logic intr_test_wd; - logic alert_test_we; - logic alert_test_wd; - logic ctrl_cfg_regwen_re; - logic ctrl_cfg_regwen_qs; - logic control_we; - logic control_low_power_hint_qs; - logic control_low_power_hint_wd; - logic control_core_clk_en_qs; - logic control_core_clk_en_wd; - logic control_io_clk_en_qs; - logic control_io_clk_en_wd; - logic control_usb_clk_en_lp_qs; - logic control_usb_clk_en_lp_wd; - logic control_usb_clk_en_active_qs; - logic control_usb_clk_en_active_wd; - logic control_main_pd_n_qs; - logic control_main_pd_n_wd; - logic cfg_cdc_sync_we; - logic cfg_cdc_sync_qs; - logic cfg_cdc_sync_wd; - logic wakeup_en_regwen_we; - logic wakeup_en_regwen_qs; - logic wakeup_en_regwen_wd; - logic wakeup_en_we; - logic wakeup_en_en_0_qs; - logic wakeup_en_en_0_wd; - logic wakeup_en_en_1_qs; - logic wakeup_en_en_1_wd; - logic wakeup_en_en_2_qs; - logic wakeup_en_en_2_wd; - logic wakeup_en_en_3_qs; - logic wakeup_en_en_3_wd; - logic wakeup_en_en_4_qs; - logic wakeup_en_en_4_wd; - logic wakeup_en_en_5_qs; - logic wakeup_en_en_5_wd; - logic wake_status_val_0_qs; - logic wake_status_val_1_qs; - logic wake_status_val_2_qs; - logic wake_status_val_3_qs; - logic wake_status_val_4_qs; - logic wake_status_val_5_qs; - logic reset_en_regwen_we; - logic reset_en_regwen_qs; - logic reset_en_regwen_wd; - logic reset_en_we; - logic reset_en_en_0_qs; - logic reset_en_en_0_wd; - logic reset_en_en_1_qs; - logic reset_en_en_1_wd; - logic reset_status_val_0_qs; - logic reset_status_val_1_qs; - logic escalate_reset_status_qs; - logic wake_info_capture_dis_we; - logic wake_info_capture_dis_qs; - logic wake_info_capture_dis_wd; - logic wake_info_re; - logic wake_info_we; - logic [5:0] wake_info_reasons_qs; - logic [5:0] wake_info_reasons_wd; - logic wake_info_fall_through_qs; - logic wake_info_fall_through_wd; - logic wake_info_abort_qs; - logic wake_info_abort_wd; - logic fault_status_reg_intg_err_qs; - logic fault_status_esc_timeout_qs; - logic fault_status_main_pd_glitch_qs; - // Define register CDC handling. - // CDC handling is done on a per-reg instead of per-field boundary. - - // Register instances - // R[intr_state]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW1C), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_state ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_state_we), - .wd (intr_state_wd), - - // from internal hardware - .de (hw2reg.intr_state.de), - .d (hw2reg.intr_state.d), - - // to internal hardware - .qe (), - .q (reg2hw.intr_state.q), - .ds (), - - // to register interface (read) - .qs (intr_state_qs) - ); - - - // R[intr_enable]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_intr_enable ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (intr_enable_we), - .wd (intr_enable_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.intr_enable.q), - .ds (), - - // to register interface (read) - .qs (intr_enable_qs) - ); - - - // R[intr_test]: V(True) - logic intr_test_qe; - logic [0:0] intr_test_flds_we; - assign intr_test_qe = &intr_test_flds_we; - prim_subreg_ext #( - .DW (1) - ) u_intr_test ( - .re (1'b0), - .we (intr_test_we), - .wd (intr_test_wd), - .d ('0), - .qre (), - .qe (intr_test_flds_we[0]), - .q (reg2hw.intr_test.q), - .ds (), - .qs () - ); - assign reg2hw.intr_test.qe = intr_test_qe; - - - // R[alert_test]: V(True) - logic alert_test_qe; - logic [0:0] alert_test_flds_we; - assign alert_test_qe = &alert_test_flds_we; - prim_subreg_ext #( - .DW (1) - ) u_alert_test ( - .re (1'b0), - .we (alert_test_we), - .wd (alert_test_wd), - .d ('0), - .qre (), - .qe (alert_test_flds_we[0]), - .q (reg2hw.alert_test.q), - .ds (), - .qs () - ); - assign reg2hw.alert_test.qe = alert_test_qe; - - - // R[ctrl_cfg_regwen]: V(True) - prim_subreg_ext #( - .DW (1) - ) u_ctrl_cfg_regwen ( - .re (ctrl_cfg_regwen_re), - .we (1'b0), - .wd ('0), - .d (hw2reg.ctrl_cfg_regwen.d), - .qre (), - .qe (), - .q (), - .ds (), - .qs (ctrl_cfg_regwen_qs) - ); - - - // R[control]: V(False) - // Create REGWEN-gated WE signal - logic control_gated_we; - assign control_gated_we = control_we & ctrl_cfg_regwen_qs; - // F[low_power_hint]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_low_power_hint ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_low_power_hint_wd), - - // from internal hardware - .de (hw2reg.control.low_power_hint.de), - .d (hw2reg.control.low_power_hint.d), - - // to internal hardware - .qe (), - .q (reg2hw.control.low_power_hint.q), - .ds (), - - // to register interface (read) - .qs (control_low_power_hint_qs) - ); - - // F[core_clk_en]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_core_clk_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_core_clk_en_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.core_clk_en.q), - .ds (), - - // to register interface (read) - .qs (control_core_clk_en_qs) - ); - - // F[io_clk_en]: 5:5 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_io_clk_en ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_io_clk_en_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.io_clk_en.q), - .ds (), - - // to register interface (read) - .qs (control_io_clk_en_qs) - ); - - // F[usb_clk_en_lp]: 6:6 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_control_usb_clk_en_lp ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_usb_clk_en_lp_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.usb_clk_en_lp.q), - .ds (), - - // to register interface (read) - .qs (control_usb_clk_en_lp_qs) - ); - - // F[usb_clk_en_active]: 7:7 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_control_usb_clk_en_active ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_usb_clk_en_active_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.usb_clk_en_active.q), - .ds (), - - // to register interface (read) - .qs (control_usb_clk_en_active_qs) - ); - - // F[main_pd_n]: 8:8 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_control_main_pd_n ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (control_gated_we), - .wd (control_main_pd_n_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.control.main_pd_n.q), - .ds (), - - // to register interface (read) - .qs (control_main_pd_n_qs) - ); - - - // R[cfg_cdc_sync]: V(False) - logic cfg_cdc_sync_qe; - logic [0:0] cfg_cdc_sync_flds_we; - prim_flop #( - .Width(1), - .ResetValue(0) - ) u_cfg_cdc_sync0_qe ( - .clk_i(clk_i), - .rst_ni(rst_ni), - .d_i(&cfg_cdc_sync_flds_we), - .q_o(cfg_cdc_sync_qe) - ); - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_cfg_cdc_sync ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (cfg_cdc_sync_we), - .wd (cfg_cdc_sync_wd), - - // from internal hardware - .de (hw2reg.cfg_cdc_sync.de), - .d (hw2reg.cfg_cdc_sync.d), - - // to internal hardware - .qe (cfg_cdc_sync_flds_we[0]), - .q (reg2hw.cfg_cdc_sync.q), - .ds (), - - // to register interface (read) - .qs (cfg_cdc_sync_qs) - ); - assign reg2hw.cfg_cdc_sync.qe = cfg_cdc_sync_qe; - - - // R[wakeup_en_regwen]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_wakeup_en_regwen ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_regwen_we), - .wd (wakeup_en_regwen_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wakeup_en_regwen_qs) - ); - - - // Subregister 0 of Multireg wakeup_en - // R[wakeup_en]: V(False) - // Create REGWEN-gated WE signal - logic wakeup_en_gated_we; - assign wakeup_en_gated_we = wakeup_en_we & wakeup_en_regwen_qs; - // F[en_0]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wakeup_en_en_0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_gated_we), - .wd (wakeup_en_en_0_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_en[0].q), - .ds (), - - // to register interface (read) - .qs (wakeup_en_en_0_qs) - ); - - // F[en_1]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wakeup_en_en_1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_gated_we), - .wd (wakeup_en_en_1_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_en[1].q), - .ds (), - - // to register interface (read) - .qs (wakeup_en_en_1_qs) - ); - - // F[en_2]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wakeup_en_en_2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_gated_we), - .wd (wakeup_en_en_2_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_en[2].q), - .ds (), - - // to register interface (read) - .qs (wakeup_en_en_2_qs) - ); - - // F[en_3]: 3:3 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wakeup_en_en_3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_gated_we), - .wd (wakeup_en_en_3_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_en[3].q), - .ds (), - - // to register interface (read) - .qs (wakeup_en_en_3_qs) - ); - - // F[en_4]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wakeup_en_en_4 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_gated_we), - .wd (wakeup_en_en_4_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_en[4].q), - .ds (), - - // to register interface (read) - .qs (wakeup_en_en_4_qs) - ); - - // F[en_5]: 5:5 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wakeup_en_en_5 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wakeup_en_gated_we), - .wd (wakeup_en_en_5_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wakeup_en[5].q), - .ds (), - - // to register interface (read) - .qs (wakeup_en_en_5_qs) - ); - - - // Subregister 0 of Multireg wake_status - // R[wake_status]: V(False) - // F[val_0]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_status_val_0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.wake_status[0].de), - .d (hw2reg.wake_status[0].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wake_status_val_0_qs) - ); - - // F[val_1]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_status_val_1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.wake_status[1].de), - .d (hw2reg.wake_status[1].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wake_status_val_1_qs) - ); - - // F[val_2]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_status_val_2 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.wake_status[2].de), - .d (hw2reg.wake_status[2].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wake_status_val_2_qs) - ); - - // F[val_3]: 3:3 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_status_val_3 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.wake_status[3].de), - .d (hw2reg.wake_status[3].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wake_status_val_3_qs) - ); - - // F[val_4]: 4:4 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_status_val_4 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.wake_status[4].de), - .d (hw2reg.wake_status[4].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wake_status_val_4_qs) - ); - - // F[val_5]: 5:5 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_status_val_5 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.wake_status[5].de), - .d (hw2reg.wake_status[5].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (wake_status_val_5_qs) - ); - - - // R[reset_en_regwen]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessW0C), - .RESVAL (1'h1), - .Mubi (1'b0) - ) u_reset_en_regwen ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (reset_en_regwen_we), - .wd (reset_en_regwen_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (reset_en_regwen_qs) - ); - - - // Subregister 0 of Multireg reset_en - // R[reset_en]: V(False) - // Create REGWEN-gated WE signal - logic reset_en_gated_we; - assign reset_en_gated_we = reset_en_we & reset_en_regwen_qs; - // F[en_0]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_reset_en_en_0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (reset_en_gated_we), - .wd (reset_en_en_0_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.reset_en[0].q), - .ds (), - - // to register interface (read) - .qs (reset_en_en_0_qs) - ); - - // F[en_1]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_reset_en_en_1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (reset_en_gated_we), - .wd (reset_en_en_1_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.reset_en[1].q), - .ds (), - - // to register interface (read) - .qs (reset_en_en_1_qs) - ); - - - // Subregister 0 of Multireg reset_status - // R[reset_status]: V(False) - // F[val_0]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_reset_status_val_0 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.reset_status[0].de), - .d (hw2reg.reset_status[0].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (reset_status_val_0_qs) - ); - - // F[val_1]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_reset_status_val_1 ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.reset_status[1].de), - .d (hw2reg.reset_status[1].d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (reset_status_val_1_qs) - ); - - - // R[escalate_reset_status]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_escalate_reset_status ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.escalate_reset_status.de), - .d (hw2reg.escalate_reset_status.d), - - // to internal hardware - .qe (), - .q (), - .ds (), - - // to register interface (read) - .qs (escalate_reset_status_qs) - ); - - - // R[wake_info_capture_dis]: V(False) - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRW), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_wake_info_capture_dis ( - .clk_i (clk_i), - .rst_ni (rst_ni), - - // from register interface - .we (wake_info_capture_dis_we), - .wd (wake_info_capture_dis_wd), - - // from internal hardware - .de (1'b0), - .d ('0), - - // to internal hardware - .qe (), - .q (reg2hw.wake_info_capture_dis.q), - .ds (), - - // to register interface (read) - .qs (wake_info_capture_dis_qs) - ); - - - // R[wake_info]: V(True) - logic wake_info_qe; - logic [2:0] wake_info_flds_we; - assign wake_info_qe = &wake_info_flds_we; - // F[reasons]: 5:0 - prim_subreg_ext #( - .DW (6) - ) u_wake_info_reasons ( - .re (wake_info_re), - .we (wake_info_we), - .wd (wake_info_reasons_wd), - .d (hw2reg.wake_info.reasons.d), - .qre (), - .qe (wake_info_flds_we[0]), - .q (reg2hw.wake_info.reasons.q), - .ds (), - .qs (wake_info_reasons_qs) - ); - assign reg2hw.wake_info.reasons.qe = wake_info_qe; - - // F[fall_through]: 6:6 - prim_subreg_ext #( - .DW (1) - ) u_wake_info_fall_through ( - .re (wake_info_re), - .we (wake_info_we), - .wd (wake_info_fall_through_wd), - .d (hw2reg.wake_info.fall_through.d), - .qre (), - .qe (wake_info_flds_we[1]), - .q (reg2hw.wake_info.fall_through.q), - .ds (), - .qs (wake_info_fall_through_qs) - ); - assign reg2hw.wake_info.fall_through.qe = wake_info_qe; - - // F[abort]: 7:7 - prim_subreg_ext #( - .DW (1) - ) u_wake_info_abort ( - .re (wake_info_re), - .we (wake_info_we), - .wd (wake_info_abort_wd), - .d (hw2reg.wake_info.abort.d), - .qre (), - .qe (wake_info_flds_we[2]), - .q (reg2hw.wake_info.abort.q), - .ds (), - .qs (wake_info_abort_qs) - ); - assign reg2hw.wake_info.abort.qe = wake_info_qe; - - - // R[fault_status]: V(False) - // F[reg_intg_err]: 0:0 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_fault_status_reg_intg_err ( - // sync clock and reset required for this register - .clk_i (clk_lc_i), - .rst_ni (rst_lc_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.fault_status.reg_intg_err.de), - .d (hw2reg.fault_status.reg_intg_err.d), - - // to internal hardware - .qe (), - .q (reg2hw.fault_status.reg_intg_err.q), - .ds (), - - // to register interface (read) - .qs (fault_status_reg_intg_err_qs) - ); - - // F[esc_timeout]: 1:1 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_fault_status_esc_timeout ( - // sync clock and reset required for this register - .clk_i (clk_lc_i), - .rst_ni (rst_lc_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.fault_status.esc_timeout.de), - .d (hw2reg.fault_status.esc_timeout.d), - - // to internal hardware - .qe (), - .q (reg2hw.fault_status.esc_timeout.q), - .ds (), - - // to register interface (read) - .qs (fault_status_esc_timeout_qs) - ); - - // F[main_pd_glitch]: 2:2 - prim_subreg #( - .DW (1), - .SwAccess(prim_subreg_pkg::SwAccessRO), - .RESVAL (1'h0), - .Mubi (1'b0) - ) u_fault_status_main_pd_glitch ( - // sync clock and reset required for this register - .clk_i (clk_lc_i), - .rst_ni (rst_lc_ni), - - // from register interface - .we (1'b0), - .wd ('0), - - // from internal hardware - .de (hw2reg.fault_status.main_pd_glitch.de), - .d (hw2reg.fault_status.main_pd_glitch.d), - - // to internal hardware - .qe (), - .q (reg2hw.fault_status.main_pd_glitch.q), - .ds (), - - // to register interface (read) - .qs (fault_status_main_pd_glitch_qs) - ); - - - - logic [16:0] addr_hit; - always_comb begin - addr_hit = '0; - addr_hit[ 0] = (reg_addr == PWRMGR_INTR_STATE_OFFSET); - addr_hit[ 1] = (reg_addr == PWRMGR_INTR_ENABLE_OFFSET); - addr_hit[ 2] = (reg_addr == PWRMGR_INTR_TEST_OFFSET); - addr_hit[ 3] = (reg_addr == PWRMGR_ALERT_TEST_OFFSET); - addr_hit[ 4] = (reg_addr == PWRMGR_CTRL_CFG_REGWEN_OFFSET); - addr_hit[ 5] = (reg_addr == PWRMGR_CONTROL_OFFSET); - addr_hit[ 6] = (reg_addr == PWRMGR_CFG_CDC_SYNC_OFFSET); - addr_hit[ 7] = (reg_addr == PWRMGR_WAKEUP_EN_REGWEN_OFFSET); - addr_hit[ 8] = (reg_addr == PWRMGR_WAKEUP_EN_OFFSET); - addr_hit[ 9] = (reg_addr == PWRMGR_WAKE_STATUS_OFFSET); - addr_hit[10] = (reg_addr == PWRMGR_RESET_EN_REGWEN_OFFSET); - addr_hit[11] = (reg_addr == PWRMGR_RESET_EN_OFFSET); - addr_hit[12] = (reg_addr == PWRMGR_RESET_STATUS_OFFSET); - addr_hit[13] = (reg_addr == PWRMGR_ESCALATE_RESET_STATUS_OFFSET); - addr_hit[14] = (reg_addr == PWRMGR_WAKE_INFO_CAPTURE_DIS_OFFSET); - addr_hit[15] = (reg_addr == PWRMGR_WAKE_INFO_OFFSET); - addr_hit[16] = (reg_addr == PWRMGR_FAULT_STATUS_OFFSET); - end - - assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; - - // Check sub-word write is permitted - always_comb begin - wr_err = (reg_we & - ((addr_hit[ 0] & (|(PWRMGR_PERMIT[ 0] & ~reg_be))) | - (addr_hit[ 1] & (|(PWRMGR_PERMIT[ 1] & ~reg_be))) | - (addr_hit[ 2] & (|(PWRMGR_PERMIT[ 2] & ~reg_be))) | - (addr_hit[ 3] & (|(PWRMGR_PERMIT[ 3] & ~reg_be))) | - (addr_hit[ 4] & (|(PWRMGR_PERMIT[ 4] & ~reg_be))) | - (addr_hit[ 5] & (|(PWRMGR_PERMIT[ 5] & ~reg_be))) | - (addr_hit[ 6] & (|(PWRMGR_PERMIT[ 6] & ~reg_be))) | - (addr_hit[ 7] & (|(PWRMGR_PERMIT[ 7] & ~reg_be))) | - (addr_hit[ 8] & (|(PWRMGR_PERMIT[ 8] & ~reg_be))) | - (addr_hit[ 9] & (|(PWRMGR_PERMIT[ 9] & ~reg_be))) | - (addr_hit[10] & (|(PWRMGR_PERMIT[10] & ~reg_be))) | - (addr_hit[11] & (|(PWRMGR_PERMIT[11] & ~reg_be))) | - (addr_hit[12] & (|(PWRMGR_PERMIT[12] & ~reg_be))) | - (addr_hit[13] & (|(PWRMGR_PERMIT[13] & ~reg_be))) | - (addr_hit[14] & (|(PWRMGR_PERMIT[14] & ~reg_be))) | - (addr_hit[15] & (|(PWRMGR_PERMIT[15] & ~reg_be))) | - (addr_hit[16] & (|(PWRMGR_PERMIT[16] & ~reg_be))))); - end - - // Generate write-enables - assign intr_state_we = addr_hit[0] & reg_we & !reg_error; - - assign intr_state_wd = reg_wdata[0]; - assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; - - assign intr_enable_wd = reg_wdata[0]; - assign intr_test_we = addr_hit[2] & reg_we & !reg_error; - - assign intr_test_wd = reg_wdata[0]; - assign alert_test_we = addr_hit[3] & reg_we & !reg_error; - - assign alert_test_wd = reg_wdata[0]; - assign ctrl_cfg_regwen_re = addr_hit[4] & reg_re & !reg_error; - assign control_we = addr_hit[5] & reg_we & !reg_error; - - assign control_low_power_hint_wd = reg_wdata[0]; - - assign control_core_clk_en_wd = reg_wdata[4]; - - assign control_io_clk_en_wd = reg_wdata[5]; - - assign control_usb_clk_en_lp_wd = reg_wdata[6]; - - assign control_usb_clk_en_active_wd = reg_wdata[7]; - - assign control_main_pd_n_wd = reg_wdata[8]; - assign cfg_cdc_sync_we = addr_hit[6] & reg_we & !reg_error; - - assign cfg_cdc_sync_wd = reg_wdata[0]; - assign wakeup_en_regwen_we = addr_hit[7] & reg_we & !reg_error; - - assign wakeup_en_regwen_wd = reg_wdata[0]; - assign wakeup_en_we = addr_hit[8] & reg_we & !reg_error; - - assign wakeup_en_en_0_wd = reg_wdata[0]; - - assign wakeup_en_en_1_wd = reg_wdata[1]; - - assign wakeup_en_en_2_wd = reg_wdata[2]; - - assign wakeup_en_en_3_wd = reg_wdata[3]; - - assign wakeup_en_en_4_wd = reg_wdata[4]; - - assign wakeup_en_en_5_wd = reg_wdata[5]; - assign reset_en_regwen_we = addr_hit[10] & reg_we & !reg_error; - - assign reset_en_regwen_wd = reg_wdata[0]; - assign reset_en_we = addr_hit[11] & reg_we & !reg_error; - - assign reset_en_en_0_wd = reg_wdata[0]; - - assign reset_en_en_1_wd = reg_wdata[1]; - assign wake_info_capture_dis_we = addr_hit[14] & reg_we & !reg_error; - - assign wake_info_capture_dis_wd = reg_wdata[0]; - assign wake_info_re = addr_hit[15] & reg_re & !reg_error; - assign wake_info_we = addr_hit[15] & reg_we & !reg_error; - - assign wake_info_reasons_wd = reg_wdata[5:0]; - - assign wake_info_fall_through_wd = reg_wdata[6]; - - assign wake_info_abort_wd = reg_wdata[7]; - - // Assign write-enables to checker logic vector. - always_comb begin - reg_we_check = '0; - reg_we_check[0] = intr_state_we; - reg_we_check[1] = intr_enable_we; - reg_we_check[2] = intr_test_we; - reg_we_check[3] = alert_test_we; - reg_we_check[4] = 1'b0; - reg_we_check[5] = control_gated_we; - reg_we_check[6] = cfg_cdc_sync_we; - reg_we_check[7] = wakeup_en_regwen_we; - reg_we_check[8] = wakeup_en_gated_we; - reg_we_check[9] = 1'b0; - reg_we_check[10] = reset_en_regwen_we; - reg_we_check[11] = reset_en_gated_we; - reg_we_check[12] = 1'b0; - reg_we_check[13] = 1'b0; - reg_we_check[14] = wake_info_capture_dis_we; - reg_we_check[15] = wake_info_we; - reg_we_check[16] = 1'b0; - end - - // Read data return - always_comb begin - reg_rdata_next = '0; - unique case (1'b1) - addr_hit[0]: begin - reg_rdata_next[0] = intr_state_qs; - end - - addr_hit[1]: begin - reg_rdata_next[0] = intr_enable_qs; - end - - addr_hit[2]: begin - reg_rdata_next[0] = '0; - end - - addr_hit[3]: begin - reg_rdata_next[0] = '0; - end - - addr_hit[4]: begin - reg_rdata_next[0] = ctrl_cfg_regwen_qs; - end - - addr_hit[5]: begin - reg_rdata_next[0] = control_low_power_hint_qs; - reg_rdata_next[4] = control_core_clk_en_qs; - reg_rdata_next[5] = control_io_clk_en_qs; - reg_rdata_next[6] = control_usb_clk_en_lp_qs; - reg_rdata_next[7] = control_usb_clk_en_active_qs; - reg_rdata_next[8] = control_main_pd_n_qs; - end - - addr_hit[6]: begin - reg_rdata_next[0] = cfg_cdc_sync_qs; - end - - addr_hit[7]: begin - reg_rdata_next[0] = wakeup_en_regwen_qs; - end - - addr_hit[8]: begin - reg_rdata_next[0] = wakeup_en_en_0_qs; - reg_rdata_next[1] = wakeup_en_en_1_qs; - reg_rdata_next[2] = wakeup_en_en_2_qs; - reg_rdata_next[3] = wakeup_en_en_3_qs; - reg_rdata_next[4] = wakeup_en_en_4_qs; - reg_rdata_next[5] = wakeup_en_en_5_qs; - end - - addr_hit[9]: begin - reg_rdata_next[0] = wake_status_val_0_qs; - reg_rdata_next[1] = wake_status_val_1_qs; - reg_rdata_next[2] = wake_status_val_2_qs; - reg_rdata_next[3] = wake_status_val_3_qs; - reg_rdata_next[4] = wake_status_val_4_qs; - reg_rdata_next[5] = wake_status_val_5_qs; - end - - addr_hit[10]: begin - reg_rdata_next[0] = reset_en_regwen_qs; - end - - addr_hit[11]: begin - reg_rdata_next[0] = reset_en_en_0_qs; - reg_rdata_next[1] = reset_en_en_1_qs; - end - - addr_hit[12]: begin - reg_rdata_next[0] = reset_status_val_0_qs; - reg_rdata_next[1] = reset_status_val_1_qs; - end - - addr_hit[13]: begin - reg_rdata_next[0] = escalate_reset_status_qs; - end - - addr_hit[14]: begin - reg_rdata_next[0] = wake_info_capture_dis_qs; - end - - addr_hit[15]: begin - reg_rdata_next[5:0] = wake_info_reasons_qs; - reg_rdata_next[6] = wake_info_fall_through_qs; - reg_rdata_next[7] = wake_info_abort_qs; - end - - addr_hit[16]: begin - reg_rdata_next[0] = fault_status_reg_intg_err_qs; - reg_rdata_next[1] = fault_status_esc_timeout_qs; - reg_rdata_next[2] = fault_status_main_pd_glitch_qs; - end - - default: begin - reg_rdata_next = '1; - end - endcase - end - - // shadow busy - logic shadow_busy; - assign shadow_busy = 1'b0; - - // register busy - assign reg_busy = shadow_busy; - - // Unused signal tieoff - - // wdata / byte enable are not always fully used - // add a blanket unused statement to handle lint waivers - logic unused_wdata; - logic unused_be; - assign unused_wdata = ^reg_wdata; - assign unused_be = ^reg_be; - - // Assertions for Register Interface - `ASSERT_PULSE(wePulse, reg_we, clk_i, !rst_ni) - `ASSERT_PULSE(rePulse, reg_re, clk_i, !rst_ni) - - `ASSERT(reAfterRv, $rose(reg_re || reg_we) |=> tl_o_pre.d_valid, clk_i, !rst_ni) - - `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit), clk_i, !rst_ni) - - // this is formulated as an assumption such that the FPV testbenches do disprove this - // property by mistake - //`ASSUME(reqParity, tl_reg_h2d.a_valid |-> tl_reg_h2d.a_user.chk_en == tlul_pkg::CheckDis) - -endmodule diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/BUILD b/hw/top_earlgrey/ip_autogen/pwrmgr/BUILD index 8b2c124557d7de..36beb77a655e78 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/BUILD +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/BUILD @@ -6,7 +6,5 @@ package(default_visibility = ["//visibility:public"]) filegroup( name = "all_files", - srcs = glob(["**"]) + [ - "//hw/ip/pwrmgr/data:all_files", - ], + srcs = glob(["**"]), ) diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/data/BUILD b/hw/top_earlgrey/ip_autogen/pwrmgr/data/BUILD index 36beb77a655e78..67a01f21b218c4 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/data/BUILD +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/data/BUILD @@ -4,6 +4,15 @@ package(default_visibility = ["//visibility:public"]) +load("//rules:autogen.bzl", "autogen_hjson_header") + +autogen_hjson_header( + name = "pwrmgr_regs", + srcs = [ + "pwrmgr.hjson", + ], +) + filegroup( name = "all_files", srcs = glob(["**"]), diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson b/hw/top_earlgrey/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson index 4d0ddde515167d..a67cf3d5c1ad2c 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson @@ -12,7 +12,7 @@ "hw/dv/tools/dvsim/testplans/sec_cm_fsm_testplan.hjson", // TODO: Top-level specific Hjson imported here. This will likely be resolved // once we move to IPgen flow. - "hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr_sec_cm_testplan.hjson"] + "pwrmgr_sec_cm_testplan.hjson"] testpoints: [ { name: smoke diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core index 8d737e00f3aed1..847d4fb73225c4 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core @@ -9,6 +9,7 @@ filesets: depend: - lowrisc:dv:ralgen - lowrisc:dv:cip_lib + - lowrisc:ip:pwrmgr_pkg files: - pwrmgr_env_pkg.sv - pwrmgr_env_cfg.sv: {is_include_file: true} @@ -43,7 +44,7 @@ generate: generator: ralgen parameters: name: pwrmgr - ip_hjson: ../../../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson + ip_hjson: ../../data/pwrmgr.hjson targets: default: diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson index baebf306caf276..8aeb06e11336dc 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson @@ -18,10 +18,7 @@ fusesoc_core: lowrisc:dv:pwrmgr_sim:0.1 // Testplan hjson file. - testplan: "{proj_root}/hw/ip/pwrmgr/data/pwrmgr_testplan.hjson" - - // RAL spec - used to generate the RAL model. - ral_spec: "{proj_root}/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson" + testplan: "{self_dir}/../data/pwrmgr_testplan.hjson" // Import additional common sim cfg files. import_cfgs: [// Project wide common sim cfg file @@ -42,7 +39,7 @@ ] // Exclusion files - vcs_cov_excl_files: ["{proj_root}/hw/ip/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el"] + vcs_cov_excl_files: ["{self_dir}/cov/pwrmgr_cov_manual_excl.el"] // Add additional tops for simulation. sim_tops: ["pwrmgr_bind", diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core index a3491ab7871a37..b71c2dede28a47 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core @@ -9,7 +9,7 @@ filesets: depend: - lowrisc:tlul:headers - lowrisc:fpv:csr_assert_gen - - lowrisc:ip:pwrmgr + - lowrisc:ip:pwrmgr_pkg - lowrisc:dv:clkmgr_pwrmgr_sva_if - lowrisc:dv:pwrmgr_rstmgr_sva_if files: @@ -27,7 +27,7 @@ generate: csr_assert_gen: generator: csr_assert_gen parameters: - spec: ../../../../top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson + spec: ../../data/pwrmgr.hjson targets: default: &default_target diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr.core b/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr.core index af706a346f7146..c384dae955aaba 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr.core +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr.core @@ -3,7 +3,7 @@ CAPI=2: # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 name: "lowrisc:ip:pwrmgr:0.1" -description: "Power manager component without the generated portions" +description: "Power manager RTL" filesets: files_rtl: @@ -15,18 +15,19 @@ filesets: - lowrisc:prim:all - lowrisc:ip:rom_ctrl_pkg - lowrisc:ip:lc_ctrl_pkg - - lowrisc:ip:pwrmgr_pkg - lowrisc:prim:sparse_fsm - lowrisc:prim:mubi - lowrisc:prim:clock_buf - lowrisc:prim:measure - lowrisc:ip_interfaces:alert_handler_reg + - lowrisc:ip:pwrmgr_pkg + - lowrisc:ip:pwrmgr_reg files: - - rtl/pwrmgr.sv - rtl/pwrmgr_cdc.sv - rtl/pwrmgr_slow_fsm.sv - rtl/pwrmgr_fsm.sv - rtl/pwrmgr_wake_info.sv + - rtl/pwrmgr.sv file_type: systemVerilogSource files_verilator_waiver: diff --git a/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr_reg.core b/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr_reg.core index 93eaf5bd351846..c20cd917273d83 100644 --- a/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr_reg.core +++ b/hw/top_earlgrey/ip_autogen/pwrmgr/pwrmgr_reg.core @@ -9,10 +9,11 @@ filesets: files_rtl: depend: - lowrisc:tlul:headers + - lowrisc:ip:tlul - lowrisc:prim:subreg - - "!fileset_topgen ? (lowrisc:systems:pwrmgr_reg)" - - "fileset_topgen ? (lowrisc:systems:topgen-reg-only)" files: + - rtl/pwrmgr_reg_pkg.sv + - rtl/pwrmgr_reg_top.sv file_type: systemVerilogSource targets: diff --git a/sw/device/lib/dif/BUILD b/sw/device/lib/dif/BUILD index fa5b9a3ead0fc8..caddd5069c49a5 100644 --- a/sw/device/lib/dif/BUILD +++ b/sw/device/lib/dif/BUILD @@ -736,7 +736,7 @@ cc_library( ], deps = [ ":base", - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//sw/device/lib/base:bitfield", "//sw/device/lib/base:macros", "//sw/device/lib/base:memory", diff --git a/sw/device/lib/dif/dif_pwrmgr.md b/sw/device/lib/dif/dif_pwrmgr.md index 1828c864f21475..a91839aaacd0d8 100644 --- a/sw/device/lib/dif/dif_pwrmgr.md +++ b/sw/device/lib/dif/dif_pwrmgr.md @@ -1,6 +1,6 @@ # Power Manager DIF Checklist -This checklist is for [Development Stage](../../../../doc/project_governance/development_stages.md) transitions for the [Power Manager DIF](../../../../hw/ip/pwrmgr/README.md). +This checklist is for [Development Stage](../../../../doc/project_governance/development_stages.md) transitions for the [Power Manager DIF](../../../../hw/ip_autogen/pwrmgr/README.md). All checklist items refer to the content in the [Checklist](../../../../doc/project_governance/checklist/README.md).

DIF Checklist

diff --git a/sw/device/silicon_creator/lib/BUILD b/sw/device/silicon_creator/lib/BUILD index f1a013a38d4b40..b5429fd5d39189 100644 --- a/sw/device/silicon_creator/lib/BUILD +++ b/sw/device/silicon_creator/lib/BUILD @@ -176,7 +176,7 @@ cc_library( deps = [ "//hw/ip/aon_timer/data:aon_timer_regs", "//hw/top_earlgrey/ip/flash_ctrl/data/autogen:flash_ctrl_regs", - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/ip/rstmgr/data/autogen:rstmgr_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/base:multibits", diff --git a/sw/device/silicon_creator/lib/drivers/BUILD b/sw/device/silicon_creator/lib/drivers/BUILD index 583f91c19b2c7f..c64e16489b8d8e 100644 --- a/sw/device/silicon_creator/lib/drivers/BUILD +++ b/sw/device/silicon_creator/lib/drivers/BUILD @@ -684,7 +684,7 @@ cc_library( deps = [ "//hw/ip/aon_timer/data:aon_timer_regs", "//hw/ip/otp_ctrl/data:otp_ctrl_regs", - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/base:abs_mmio", "//sw/device/silicon_creator/lib/base:sec_mmio", @@ -779,7 +779,7 @@ cc_library( srcs = ["pwrmgr.c"], hdrs = ["pwrmgr.h"], deps = [ - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/base:abs_mmio", "//sw/device/silicon_creator/lib/base:sec_mmio", diff --git a/sw/device/silicon_creator/rom/BUILD b/sw/device/silicon_creator/rom/BUILD index b018f38abfa8b0..3462455bd8e5fb 100644 --- a/sw/device/silicon_creator/rom/BUILD +++ b/sw/device/silicon_creator/rom/BUILD @@ -96,7 +96,7 @@ cc_library( "//hw/top_earlgrey/ip/ast/data:ast_regs", "//hw/top_earlgrey/ip/clkmgr/data/autogen:clkmgr_regs", "//hw/top_earlgrey/ip/pinmux/data/autogen:pinmux_regs", - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/ip/rstmgr/data/autogen:rstmgr_regs", "//hw/top_earlgrey/ip/sensor_ctrl/data:sensor_ctrl_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", diff --git a/sw/device/silicon_creator/rom/e2e/BUILD b/sw/device/silicon_creator/rom/e2e/BUILD index e64d4c47f636cc..f2ab65c7c81bfb 100644 --- a/sw/device/silicon_creator/rom/e2e/BUILD +++ b/sw/device/silicon_creator/rom/e2e/BUILD @@ -3691,7 +3691,7 @@ opentitan_functest( "cw310_rom_with_fake_keys", ], deps = [ - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//sw/device/lib/base:memory", "//sw/device/lib/dif:aon_timer", "//sw/device/lib/dif:pwrmgr", diff --git a/sw/device/tests/sim_dv/BUILD b/sw/device/tests/sim_dv/BUILD index d82d349cc82ae6..66bbd4bc9b2b80 100644 --- a/sw/device/tests/sim_dv/BUILD +++ b/sw/device/tests/sim_dv/BUILD @@ -954,7 +954,7 @@ cc_library( hdrs = ["pwrmgr_sleep_all_wake_ups_impl.h"], target_compatible_with = [OPENTITAN_CPU], deps = [ - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/base:mmio", "//sw/device/lib/dif:adc_ctrl", @@ -979,7 +979,7 @@ opentitan_functest( srcs = ["pwrmgr_normal_sleep_all_wake_ups.c"], targets = ["dv"], deps = [ - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/dif:pwrmgr", "//sw/device/lib/dif:rv_plic", @@ -998,7 +998,7 @@ opentitan_functest( srcs = ["pwrmgr_deep_sleep_all_wake_ups.c"], targets = ["dv"], deps = [ - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/dif:pwrmgr", "//sw/device/lib/dif:rv_plic", @@ -1020,7 +1020,7 @@ opentitan_functest( srcs = ["pwrmgr_random_sleep_all_wake_ups.c"], targets = ["dv"], deps = [ - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/sw/autogen:top_earlgrey", "//sw/device/lib/dif:pwrmgr", "//sw/device/lib/dif:rv_plic", diff --git a/sw/device/tock/BUILD b/sw/device/tock/BUILD index 2b6765caa90b1b..19d277e11cca05 100644 --- a/sw/device/tock/BUILD +++ b/sw/device/tock/BUILD @@ -50,7 +50,7 @@ filegroup( "//hw/top_earlgrey/ip/clkmgr/data/autogen:clkmgr_regs", "//hw/top_earlgrey/ip/flash_ctrl/data/autogen:flash_ctrl_regs", "//hw/top_earlgrey/ip/pinmux/data/autogen:pinmux_regs", - "//hw/top_earlgrey/ip/pwrmgr/data/autogen:pwrmgr_regs", + "//hw/top_earlgrey/ip_autogen/pwrmgr/data:pwrmgr_regs", "//hw/top_earlgrey/ip/rstmgr/data/autogen:rstmgr_regs", "//hw/top_earlgrey/ip/sensor_ctrl/data:sensor_ctrl_regs", ], diff --git a/util/ipgen/README.md b/util/ipgen/README.md index 69e35a0c0f1145..32d4540a976219 100644 --- a/util/ipgen/README.md +++ b/util/ipgen/README.md @@ -2,8 +2,8 @@ Ipgen is a tool to produce IP blocks from IP templates. -IP templates are highly customizable IP blocks which need to be pre-processed before they can be used in a hardware design. -In the pre-processing ("rendering"), which is performed by the ipgen tool, templates of source files, written in the Mako templating language, are converted into "real" source files. +IP templates are highly customizable IP blocks which are pre-processed to render blocks that can be used in a hardware design. +The templates of the source files are written in the Mako templating language, and are rendered by the ipgen tool to become the actual source files. The templates can be customized through template parameters, which are available within the templates. Ipgen is a command-line tool and a library. @@ -20,7 +20,7 @@ An IP template directory has a well-defined structure: * The IP template name (``) equals the directory name. * The directory contains a file `data/.tpldesc.hjson` containing all configuration information related to the template. * The directory also contains zero or more files ending in `.tpl`. - These files are Mako templates and rendered into an file in the same location without the `.tpl` file extension. + These files are Mako templates and rendered into a file in the same relative location without the `.tpl` file extension. ### The template description file @@ -37,7 +37,7 @@ Keys within `template_param_list`: * `name` (string): Name of the template parameter. * `desc` (string): Human-readable description of the template parameter. * `type` (string): Data type of the parameter. Valid values: `int`, `str` -* `default` (string|int): The default value of the parameter. The data type should match the `type` argument. As convenience, strings are converted into integers on demand (if possible). +* `default` (string|int|object): The default value of the parameter. The data type should match the `type` argument. As convenience, strings are converted into integers on demand (if possible). #### Example template description file @@ -46,20 +46,20 @@ An exemplary template description file with two parameters, `src` and `target` i ```hjson // data/.tpldesc.hjson { - "template_param_list": [ + template_param_list: [ { - "name": "src", - "desc": "Number of Interrupt Source", - "type": "int", - "default": "32" - }, + name: "src" + desc: "Number of Interrupt Source" + type: "int" + default: "32" + } { - "name": "target", - "desc": "Number of Interrupt Targets", - "type": "int", - "default": "32" - }, - ], + name: "target" + desc: "Number of Interrupt Targets" + type: "int" + default: "32" + } + ] } ``` @@ -67,7 +67,7 @@ An exemplary template description file with two parameters, `src` and `target` i Templates are written in the [Mako templating language](https://www.makotemplates.org/). All template parameters are available in the rendering context. -For example, a template parameter `src` can be used in the template as `{{ src }}`. +For example, a template parameter `src` can be used in the template as `${src}`. Furthermore, the following functions are available: @@ -100,7 +100,7 @@ The following rules should be applied when creating IP templates: FuseSoC core files should be written in a way that upholds the principle "same name, same public interface", i.e. if a FuseSoC core has the same name as another one, it must also provide the same public interface. -Since SystemVerilog does not provide no strong control over which symbols become part of the public API developers must be carefully evaluate their source code. +Since SystemVerilog does not provide strong control over which symbols become part of the public API, developers must carefully evaluate their source code. At least, the public interface is comprised of - module header(s), e.g. parameter names, ports (names, data types), - package names, and all identifiers within it, including enum values (but not the values assigned to them),