From 851c45979b1484e7d8c7d42d8056215ef7598759 Mon Sep 17 00:00:00 2001 From: Alexander Williams Date: Mon, 23 Dec 2024 21:18:17 -0800 Subject: [PATCH 1/2] [topgen] Generate top-specific tests in their outdirs Darjeeling's software tests only avoided overwriting the earlgrey tests by nature of sorting earlier alphabetically. Move autogenerated tests to the top-specific output directories. Fix up paths to match. Signed-off-by: Alexander Williams --- .../sw/autogen/tests/alert_test.c | 928 +++++++ .../sw/autogen/tests/plic_all_irqs_test.c | 2200 +++++++++++++++++ .../data/ip/chip_alert_handler_testplan.hjson | 8 +- .../data/ip/chip_rv_plic_testplan.hjson | 6 +- hw/top_earlgrey/dv/chip_sim_cfg.hjson | 8 +- .../top_earlgrey/sw/autogen/tests}/BUILD | 0 .../sw/autogen/tests}/alert_test.c | 0 .../sw/autogen/tests}/plic_all_irqs_test.c | 0 sw/device/tests/sival/BUILD | 10 +- util/topgen.py | 37 +- util/topgen/templates/toplevel.c.tpl | 2 +- 11 files changed, 3165 insertions(+), 34 deletions(-) create mode 100644 hw/top_darjeeling/sw/autogen/tests/alert_test.c create mode 100644 hw/top_darjeeling/sw/autogen/tests/plic_all_irqs_test.c rename {sw/device/tests/autogen => hw/top_earlgrey/sw/autogen/tests}/BUILD (100%) rename {sw/device/tests/autogen => hw/top_earlgrey/sw/autogen/tests}/alert_test.c (100%) rename {sw/device/tests/autogen => hw/top_earlgrey/sw/autogen/tests}/plic_all_irqs_test.c (100%) diff --git a/hw/top_darjeeling/sw/autogen/tests/alert_test.c b/hw/top_darjeeling/sw/autogen/tests/alert_test.c new file mode 100644 index 0000000000000..d859b2be780ff --- /dev/null +++ b/hw/top_darjeeling/sw/autogen/tests/alert_test.c @@ -0,0 +1,928 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// clang-format off + +// +// ------------------- 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: +// util/topgen.py -t hw/top_darjeeling/data/top_darjeeling.hjson +// -o hw/top_darjeeling +#include "sw/device/lib/arch/boot_stage.h" +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/dif/dif_aes.h" +#include "sw/device/lib/dif/dif_alert_handler.h" +#include "sw/device/lib/dif/dif_aon_timer.h" +#include "sw/device/lib/dif/dif_clkmgr.h" +#include "sw/device/lib/dif/dif_csrng.h" +#include "sw/device/lib/dif/dif_dma.h" +#include "sw/device/lib/dif/dif_edn.h" +#include "sw/device/lib/dif/dif_gpio.h" +#include "sw/device/lib/dif/dif_hmac.h" +#include "sw/device/lib/dif/dif_i2c.h" +#include "sw/device/lib/dif/dif_keymgr_dpe.h" +#include "sw/device/lib/dif/dif_kmac.h" +#include "sw/device/lib/dif/dif_lc_ctrl.h" +#include "sw/device/lib/dif/dif_mbx.h" +#include "sw/device/lib/dif/dif_otbn.h" +#include "sw/device/lib/dif/dif_otp_ctrl.h" +#include "sw/device/lib/dif/dif_pinmux.h" +#include "sw/device/lib/dif/dif_pwrmgr.h" +#include "sw/device/lib/dif/dif_rom_ctrl.h" +#include "sw/device/lib/dif/dif_rstmgr.h" +#include "sw/device/lib/dif/dif_rv_core_ibex.h" +#include "sw/device/lib/dif/dif_rv_plic.h" +#include "sw/device/lib/dif/dif_rv_timer.h" +#include "sw/device/lib/dif/dif_sensor_ctrl.h" +#include "sw/device/lib/dif/dif_soc_dbg_ctrl.h" +#include "sw/device/lib/dif/dif_soc_proxy.h" +#include "sw/device/lib/dif/dif_spi_device.h" +#include "sw/device/lib/dif/dif_spi_host.h" +#include "sw/device/lib/dif/dif_sram_ctrl.h" +#include "sw/device/lib/dif/dif_uart.h" +#include "sw/device/lib/testing/alert_handler_testutils.h" +#include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h" +#include "sw/device/lib/testing/test_framework/check.h" +#include "sw/device/lib/testing/test_framework/ottf_test_config.h" + +#include "alert_handler_regs.h" // Generated. +#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" + +OTTF_DEFINE_TEST_CONFIG(); + +static dif_alert_handler_t alert_handler; +static dif_aes_t aes; +static dif_aon_timer_t aon_timer_aon; +static dif_clkmgr_t clkmgr_aon; +static dif_csrng_t csrng; +static dif_dma_t dma; +static dif_edn_t edn0; +static dif_edn_t edn1; +static dif_gpio_t gpio; +static dif_hmac_t hmac; +static dif_i2c_t i2c0; +static dif_keymgr_dpe_t keymgr_dpe; +static dif_kmac_t kmac; +static dif_lc_ctrl_t lc_ctrl; +static dif_mbx_t mbx0; +static dif_mbx_t mbx1; +static dif_mbx_t mbx2; +static dif_mbx_t mbx3; +static dif_mbx_t mbx4; +static dif_mbx_t mbx5; +static dif_mbx_t mbx6; +static dif_mbx_t mbx_jtag; +static dif_mbx_t mbx_pcie0; +static dif_mbx_t mbx_pcie1; +static dif_otbn_t otbn; +static dif_otp_ctrl_t otp_ctrl; +static dif_pinmux_t pinmux_aon; +static dif_pwrmgr_t pwrmgr_aon; +static dif_rom_ctrl_t rom_ctrl0; +static dif_rom_ctrl_t rom_ctrl1; +static dif_rstmgr_t rstmgr_aon; +static dif_rv_core_ibex_t rv_core_ibex; +static dif_rv_plic_t rv_plic; +static dif_rv_timer_t rv_timer; +static dif_sensor_ctrl_t sensor_ctrl; +static dif_soc_dbg_ctrl_t soc_dbg_ctrl; +static dif_soc_proxy_t soc_proxy; +static dif_spi_device_t spi_device; +static dif_spi_host_t spi_host0; +static dif_sram_ctrl_t sram_ctrl_main; +static dif_sram_ctrl_t sram_ctrl_mbox; +static dif_sram_ctrl_t sram_ctrl_ret_aon; +static dif_uart_t uart0; + +/** + * Initialize the peripherals used in this test. + */ +static void init_peripherals(void) { + mmio_region_t base_addr; + base_addr = mmio_region_from_addr(TOP_EARLGREY_ALERT_HANDLER_BASE_ADDR); + CHECK_DIF_OK(dif_alert_handler_init(base_addr, &alert_handler)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_AES_BASE_ADDR); + CHECK_DIF_OK(dif_aes_init(base_addr, &aes)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_AON_TIMER_AON_BASE_ADDR); + CHECK_DIF_OK(dif_aon_timer_init(base_addr, &aon_timer_aon)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_CLKMGR_AON_BASE_ADDR); + CHECK_DIF_OK(dif_clkmgr_init(base_addr, &clkmgr_aon)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_CSRNG_BASE_ADDR); + CHECK_DIF_OK(dif_csrng_init(base_addr, &csrng)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_DMA_BASE_ADDR); + CHECK_DIF_OK(dif_dma_init(base_addr, &dma)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_EDN0_BASE_ADDR); + CHECK_DIF_OK(dif_edn_init(base_addr, &edn0)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_EDN1_BASE_ADDR); + CHECK_DIF_OK(dif_edn_init(base_addr, &edn1)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_GPIO_BASE_ADDR); + CHECK_DIF_OK(dif_gpio_init(base_addr, &gpio)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_HMAC_BASE_ADDR); + CHECK_DIF_OK(dif_hmac_init(base_addr, &hmac)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_I2C0_BASE_ADDR); + CHECK_DIF_OK(dif_i2c_init(base_addr, &i2c0)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_KEYMGR_DPE_BASE_ADDR); + CHECK_DIF_OK(dif_keymgr_dpe_init(base_addr, &keymgr_dpe)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_KMAC_BASE_ADDR); + CHECK_DIF_OK(dif_kmac_init(base_addr, &kmac)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_LC_CTRL_REGS_BASE_ADDR); + CHECK_DIF_OK(dif_lc_ctrl_init(base_addr, &lc_ctrl)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX0_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx0)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX1_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx1)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX2_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx2)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX3_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx3)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX4_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx4)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX5_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx5)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX6_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx6)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX_JTAG_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx_jtag)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX_PCIE0_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx_pcie0)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX_PCIE1_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx_pcie1)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_OTBN_BASE_ADDR); + CHECK_DIF_OK(dif_otbn_init(base_addr, &otbn)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_OTP_CTRL_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_otp_ctrl_init(base_addr, &otp_ctrl)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_PINMUX_AON_BASE_ADDR); + CHECK_DIF_OK(dif_pinmux_init(base_addr, &pinmux_aon)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_PWRMGR_AON_BASE_ADDR); + CHECK_DIF_OK(dif_pwrmgr_init(base_addr, &pwrmgr_aon)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_ROM_CTRL0_REGS_BASE_ADDR); + CHECK_DIF_OK(dif_rom_ctrl_init(base_addr, &rom_ctrl0)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_ROM_CTRL1_REGS_BASE_ADDR); + CHECK_DIF_OK(dif_rom_ctrl_init(base_addr, &rom_ctrl1)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_RSTMGR_AON_BASE_ADDR); + CHECK_DIF_OK(dif_rstmgr_init(base_addr, &rstmgr_aon)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_RV_CORE_IBEX_CFG_BASE_ADDR); + CHECK_DIF_OK(dif_rv_core_ibex_init(base_addr, &rv_core_ibex)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_RV_PLIC_BASE_ADDR); + CHECK_DIF_OK(dif_rv_plic_init(base_addr, &rv_plic)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_RV_TIMER_BASE_ADDR); + CHECK_DIF_OK(dif_rv_timer_init(base_addr, &rv_timer)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SENSOR_CTRL_BASE_ADDR); + CHECK_DIF_OK(dif_sensor_ctrl_init(base_addr, &sensor_ctrl)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SOC_DBG_CTRL_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_soc_dbg_ctrl_init(base_addr, &soc_dbg_ctrl)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SOC_PROXY_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_soc_proxy_init(base_addr, &soc_proxy)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SPI_DEVICE_BASE_ADDR); + CHECK_DIF_OK(dif_spi_device_init(base_addr, &spi_device)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SPI_HOST0_BASE_ADDR); + CHECK_DIF_OK(dif_spi_host_init(base_addr, &spi_host0)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SRAM_CTRL_MAIN_REGS_BASE_ADDR); + CHECK_DIF_OK(dif_sram_ctrl_init(base_addr, &sram_ctrl_main)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SRAM_CTRL_MBOX_REGS_BASE_ADDR); + CHECK_DIF_OK(dif_sram_ctrl_init(base_addr, &sram_ctrl_mbox)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_SRAM_CTRL_RET_AON_REGS_BASE_ADDR); + CHECK_DIF_OK(dif_sram_ctrl_init(base_addr, &sram_ctrl_ret_aon)); + + base_addr = mmio_region_from_addr(TOP_DARJEELING_UART0_BASE_ADDR); + CHECK_DIF_OK(dif_uart_init(base_addr, &uart0)); + +} + +/** + * Configure the alert handler to escalate on alerts upto phase 1 (i.e. wipe + * secret) but not trigger reset. Then CPU can check if alert_handler triggers the correct + * alert_cause register. + */ +static void alert_handler_config(void) { + dif_alert_handler_alert_t alerts[ALERT_HANDLER_PARAM_N_ALERTS]; + dif_alert_handler_class_t alert_classes[ALERT_HANDLER_PARAM_N_ALERTS]; + + // Enable all incoming alerts and configure them to classa. + // This alert should never fire because we do not expect any incoming alerts. + for (dif_alert_handler_alert_t i = 0; i < ALERT_HANDLER_PARAM_N_ALERTS; ++i) { + alerts[i] = i; + alert_classes[i] = kDifAlertHandlerClassA; + } + + dif_alert_handler_escalation_phase_t esc_phases[] = { + {.phase = kDifAlertHandlerClassStatePhase0, + .signal = 0, + .duration_cycles = 2000}}; + + dif_alert_handler_class_config_t class_config = { + .auto_lock_accumulation_counter = kDifToggleDisabled, + .accumulator_threshold = 0, + .irq_deadline_cycles = 10000, + .escalation_phases = esc_phases, + .escalation_phases_len = ARRAYSIZE(esc_phases), + .crashdump_escalation_phase = kDifAlertHandlerClassStatePhase1, + }; + + dif_alert_handler_class_config_t class_configs[] = {class_config, + class_config}; + + dif_alert_handler_class_t classes[] = {kDifAlertHandlerClassA, + kDifAlertHandlerClassB}; + dif_alert_handler_config_t config = { + .alerts = alerts, + .alert_classes = alert_classes, + .alerts_len = ARRAYSIZE(alerts), + .classes = classes, + .class_configs = class_configs, + .classes_len = ARRAYSIZE(class_configs), + .ping_timeout = 1000, + }; + + CHECK_STATUS_OK(alert_handler_testutils_configure_all(&alert_handler, config, + kDifToggleEnabled)); +} + +// Trigger alert for each module by writing one to `alert_test` register. +// Then check alert_handler's alert_cause register to make sure the correct alert reaches +// alert_handler. +static void trigger_alert_test(void) { + bool is_cause; + dif_alert_handler_alert_t exp_alert; + + // Write aes's alert_test reg and check alert_cause. + for (dif_aes_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_aes_alert_force(&aes, kDifAesAlertRecovCtrlUpdateErr + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdAesRecovCtrlUpdateErr + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write aon_timer's alert_test reg and check alert_cause. + for (dif_aon_timer_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_aon_timer_alert_force(&aon_timer_aon, kDifAonTimerAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdAonTimerAonFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write clkmgr's alert_test reg and check alert_cause. + for (dif_clkmgr_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_clkmgr_alert_force(&clkmgr_aon, kDifClkmgrAlertRecovFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdClkmgrAonRecovFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write csrng's alert_test reg and check alert_cause. + for (dif_csrng_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_csrng_alert_force(&csrng, kDifCsrngAlertRecovAlert + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdCsrngRecovAlert + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write dma's alert_test reg and check alert_cause. + for (dif_dma_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_dma_alert_force(&dma, kDifDmaAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdDmaFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write edn's alert_test reg and check alert_cause. + for (dif_edn_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_edn_alert_force(&edn0, kDifEdnAlertRecovAlert + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdEdn0RecovAlert + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write edn's alert_test reg and check alert_cause. + for (dif_edn_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_edn_alert_force(&edn1, kDifEdnAlertRecovAlert + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdEdn1RecovAlert + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write gpio's alert_test reg and check alert_cause. + for (dif_gpio_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_gpio_alert_force(&gpio, kDifGpioAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdGpioFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write hmac's alert_test reg and check alert_cause. + for (dif_hmac_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_hmac_alert_force(&hmac, kDifHmacAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdHmacFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write i2c's alert_test reg and check alert_cause. + for (dif_i2c_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_i2c_alert_force(&i2c0, kDifI2cAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdI2c0FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write keymgr_dpe's alert_test reg and check alert_cause. + for (dif_keymgr_dpe_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_keymgr_dpe_alert_force(&keymgr_dpe, kDifKeymgrDpeAlertRecovOperationErr + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdKeymgrDpeRecovOperationErr + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write kmac's alert_test reg and check alert_cause. + for (dif_kmac_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_kmac_alert_force(&kmac, kDifKmacAlertRecovOperationErr + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdKmacRecovOperationErr + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write lc_ctrl's alert_test reg and check alert_cause. + for (dif_lc_ctrl_alert_t i = 0; i < 3; ++i) { + CHECK_DIF_OK(dif_lc_ctrl_alert_force(&lc_ctrl, kDifLcCtrlAlertFatalProgError + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdLcCtrlFatalProgError + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx0, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbx0FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx1, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbx1FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx2, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbx2FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx3, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbx3FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx4, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbx4FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx5, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbx5FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx6, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbx6FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx_jtag, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbxJtagFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx_pcie0, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbxPcie0FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write mbx's alert_test reg and check alert_cause. + for (dif_mbx_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_mbx_alert_force(&mbx_pcie1, kDifMbxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdMbxPcie1FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write otbn's alert_test reg and check alert_cause. + for (dif_otbn_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_otbn_alert_force(&otbn, kDifOtbnAlertFatal + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdOtbnFatal + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // TODO(lowrisc/opentitan#20348): Enable otp_ctrl when this is fixed. + if (kBootStage != kBootStageOwner) { + // Write otp_ctrl's alert_test reg and check alert_cause. + for (dif_otp_ctrl_alert_t i = 0; i < 5; ++i) { + CHECK_DIF_OK(dif_otp_ctrl_alert_force(&otp_ctrl, kDifOtpCtrlAlertFatalMacroError + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdOtpCtrlFatalMacroError + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + } + + // Write pinmux's alert_test reg and check alert_cause. + for (dif_pinmux_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_pinmux_alert_force(&pinmux_aon, kDifPinmuxAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdPinmuxAonFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write pwrmgr's alert_test reg and check alert_cause. + for (dif_pwrmgr_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_pwrmgr_alert_force(&pwrmgr_aon, kDifPwrmgrAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdPwrmgrAonFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write rom_ctrl's alert_test reg and check alert_cause. + for (dif_rom_ctrl_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_rom_ctrl_alert_force(&rom_ctrl0, kDifRomCtrlAlertFatal + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdRomCtrl0Fatal + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write rom_ctrl's alert_test reg and check alert_cause. + for (dif_rom_ctrl_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_rom_ctrl_alert_force(&rom_ctrl1, kDifRomCtrlAlertFatal + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdRomCtrl1Fatal + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write rstmgr's alert_test reg and check alert_cause. + for (dif_rstmgr_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_rstmgr_alert_force(&rstmgr_aon, kDifRstmgrAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdRstmgrAonFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write rv_core_ibex's alert_test reg and check alert_cause. + for (dif_rv_core_ibex_alert_t i = 0; i < 4; ++i) { + CHECK_DIF_OK(dif_rv_core_ibex_alert_force(&rv_core_ibex, kDifRvCoreIbexAlertFatalSwErr + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdRvCoreIbexFatalSwErr + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write rv_plic's alert_test reg and check alert_cause. + for (dif_rv_plic_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_rv_plic_alert_force(&rv_plic, kDifRvPlicAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdRvPlicFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write rv_timer's alert_test reg and check alert_cause. + for (dif_rv_timer_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_rv_timer_alert_force(&rv_timer, kDifRvTimerAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdRvTimerFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write sensor_ctrl's alert_test reg and check alert_cause. + for (dif_sensor_ctrl_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_sensor_ctrl_alert_force(&sensor_ctrl, kDifSensorCtrlAlertRecovAlert + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSensorCtrlRecovAlert + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write soc_dbg_ctrl's alert_test reg and check alert_cause. + for (dif_soc_dbg_ctrl_alert_t i = 0; i < 2; ++i) { + CHECK_DIF_OK(dif_soc_dbg_ctrl_alert_force(&soc_dbg_ctrl, kDifSocDbgCtrlAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSocDbgCtrlFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write soc_proxy's alert_test reg and check alert_cause. + for (dif_soc_proxy_alert_t i = 0; i < 29; ++i) { + CHECK_DIF_OK(dif_soc_proxy_alert_force(&soc_proxy, kDifSocProxyAlertFatalAlertIntg + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSocProxyFatalAlertIntg + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write spi_device's alert_test reg and check alert_cause. + for (dif_spi_device_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_spi_device_alert_force(&spi_device, kDifSpiDeviceAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSpiDeviceFatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write spi_host's alert_test reg and check alert_cause. + for (dif_spi_host_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_spi_host_alert_force(&spi_host0, kDifSpiHostAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSpiHost0FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write sram_ctrl's alert_test reg and check alert_cause. + for (dif_sram_ctrl_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_sram_ctrl_alert_force(&sram_ctrl_main, kDifSramCtrlAlertFatalError + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSramCtrlMainFatalError + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write sram_ctrl's alert_test reg and check alert_cause. + for (dif_sram_ctrl_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_sram_ctrl_alert_force(&sram_ctrl_mbox, kDifSramCtrlAlertFatalError + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSramCtrlMboxFatalError + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write sram_ctrl's alert_test reg and check alert_cause. + for (dif_sram_ctrl_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_sram_ctrl_alert_force(&sram_ctrl_ret_aon, kDifSramCtrlAlertFatalError + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdSramCtrlRetAonFatalError + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } + + // Write uart's alert_test reg and check alert_cause. + for (dif_uart_alert_t i = 0; i < 1; ++i) { + CHECK_DIF_OK(dif_uart_alert_force(&uart0, kDifUartAlertFatalFault + i)); + + // Verify that alert handler received it. + exp_alert = kTopDarjeelingAlertIdUart0FatalFault + i; + CHECK_DIF_OK(dif_alert_handler_alert_is_cause( + &alert_handler, exp_alert, &is_cause)); + CHECK(is_cause, "Expect alert %d!", exp_alert); + + // Clear alert cause register + CHECK_DIF_OK(dif_alert_handler_alert_acknowledge( + &alert_handler, exp_alert)); + } +} + +bool test_main(void) { + init_peripherals(); + alert_handler_config(); + trigger_alert_test(); + return true; +} diff --git a/hw/top_darjeeling/sw/autogen/tests/plic_all_irqs_test.c b/hw/top_darjeeling/sw/autogen/tests/plic_all_irqs_test.c new file mode 100644 index 0000000000000..deea6e57c0688 --- /dev/null +++ b/hw/top_darjeeling/sw/autogen/tests/plic_all_irqs_test.c @@ -0,0 +1,2200 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// clang-format off +// +// ------------------- 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: +// util/topgen.py -t hw/top_darjeeling/data/top_darjeeling.hjson +// -o hw/top_darjeeling +#include + +// This test should avoid otp_ctrl interrupts in rom_ext, since the rom +// extension configures CSR accesses to OTP and AST to become illegal. +// +// This test is getting too big so we need to split it up. To do so, +// each peripheral is given an ID (according to their alphabetical order) +// and we define TEST_MIN_IRQ_PERIPHERAL and TEST_MAX_IRQ_PERIPHERAL to +// choose which ones are being tested. + +#ifndef TEST_MIN_IRQ_PERIPHERAL +#define TEST_MIN_IRQ_PERIPHERAL 0 +#endif + +#ifndef TEST_MAX_IRQ_PERIPHERAL +#define TEST_MAX_IRQ_PERIPHERAL 20 +#endif + +#include "sw/device/lib/arch/boot_stage.h" +#include "sw/device/lib/base/csr.h" +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/dif/dif_alert_handler.h" +#include "sw/device/lib/dif/dif_aon_timer.h" +#include "sw/device/lib/dif/dif_csrng.h" +#include "sw/device/lib/dif/dif_dma.h" +#include "sw/device/lib/dif/dif_edn.h" +#include "sw/device/lib/dif/dif_gpio.h" +#include "sw/device/lib/dif/dif_hmac.h" +#include "sw/device/lib/dif/dif_i2c.h" +#include "sw/device/lib/dif/dif_keymgr_dpe.h" +#include "sw/device/lib/dif/dif_kmac.h" +#include "sw/device/lib/dif/dif_mbx.h" +#include "sw/device/lib/dif/dif_otbn.h" +#include "sw/device/lib/dif/dif_otp_ctrl.h" +#include "sw/device/lib/dif/dif_pwrmgr.h" +#include "sw/device/lib/dif/dif_rv_plic.h" +#include "sw/device/lib/dif/dif_rv_timer.h" +#include "sw/device/lib/dif/dif_sensor_ctrl.h" +#include "sw/device/lib/dif/dif_soc_proxy.h" +#include "sw/device/lib/dif/dif_spi_device.h" +#include "sw/device/lib/dif/dif_spi_host.h" +#include "sw/device/lib/dif/dif_uart.h" +#include "sw/device/lib/runtime/ibex.h" +#include "sw/device/lib/runtime/irq.h" +#include "sw/device/lib/runtime/log.h" +#include "sw/device/lib/testing/rv_plic_testutils.h" +#include "sw/device/lib/testing/test_framework/check.h" +#include "sw/device/lib/testing/test_framework/ottf_main.h" +#include "sw/device/lib/testing/test_framework/status.h" + +#include "hw/top_darjeeling/sw/autogen/top_darjeeling.h" + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL +static dif_alert_handler_t alert_handler; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL +static dif_aon_timer_t aon_timer_aon; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL +static dif_csrng_t csrng; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL +static dif_dma_t dma; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL +static dif_edn_t edn0; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL +static dif_edn_t edn1; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL +static dif_gpio_t gpio; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL +static dif_hmac_t hmac; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL +static dif_i2c_t i2c0; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL +static dif_keymgr_dpe_t keymgr_dpe; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL +static dif_kmac_t kmac; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx0; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx1; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx2; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx3; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx4; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx5; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx6; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx_jtag; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx_pcie0; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static dif_mbx_t mbx_pcie1; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL +static dif_otbn_t otbn; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL +static dif_otp_ctrl_t otp_ctrl; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL +static dif_pwrmgr_t pwrmgr_aon; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL +static dif_rv_timer_t rv_timer; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL +static dif_sensor_ctrl_t sensor_ctrl; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL +static dif_soc_proxy_t soc_proxy; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL +static dif_spi_device_t spi_device; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL +static dif_spi_host_t spi_host0; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL +static dif_uart_t uart0; +#endif + +static dif_rv_plic_t plic; +static const top_darjeeling_plic_target_t kHart = kTopDarjeelingPlicTargetIbex0; + +/** + * Flag indicating which peripheral is under test. + * + * Declared volatile because it is referenced in the main program flow as well + * as the ISR. + */ +static volatile top_darjeeling_plic_peripheral_t peripheral_expected; + +/** + * Flags indicating the IRQ expected to have triggered and serviced within the + * peripheral. + * + * Declared volatile because it is referenced in the main program flow as well + * as the ISR. + */ + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_alert_handler_irq_t alert_handler_irq_expected; +static volatile dif_alert_handler_irq_t alert_handler_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_aon_timer_irq_t aon_timer_irq_expected; +static volatile dif_aon_timer_irq_t aon_timer_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_csrng_irq_t csrng_irq_expected; +static volatile dif_csrng_irq_t csrng_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_dma_irq_t dma_irq_expected; +static volatile dif_dma_irq_t dma_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_edn_irq_t edn_irq_expected; +static volatile dif_edn_irq_t edn_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_gpio_irq_t gpio_irq_expected; +static volatile dif_gpio_irq_t gpio_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_hmac_irq_t hmac_irq_expected; +static volatile dif_hmac_irq_t hmac_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_i2c_irq_t i2c_irq_expected; +static volatile dif_i2c_irq_t i2c_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_keymgr_dpe_irq_t keymgr_dpe_irq_expected; +static volatile dif_keymgr_dpe_irq_t keymgr_dpe_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_kmac_irq_t kmac_irq_expected; +static volatile dif_kmac_irq_t kmac_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_mbx_irq_t mbx_irq_expected; +static volatile dif_mbx_irq_t mbx_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_otbn_irq_t otbn_irq_expected; +static volatile dif_otbn_irq_t otbn_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_otp_ctrl_irq_t otp_ctrl_irq_expected; +static volatile dif_otp_ctrl_irq_t otp_ctrl_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_pwrmgr_irq_t pwrmgr_irq_expected; +static volatile dif_pwrmgr_irq_t pwrmgr_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_rv_timer_irq_t rv_timer_irq_expected; +static volatile dif_rv_timer_irq_t rv_timer_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_sensor_ctrl_irq_t sensor_ctrl_irq_expected; +static volatile dif_sensor_ctrl_irq_t sensor_ctrl_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_soc_proxy_irq_t soc_proxy_irq_expected; +static volatile dif_soc_proxy_irq_t soc_proxy_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_spi_device_irq_t spi_device_irq_expected; +static volatile dif_spi_device_irq_t spi_device_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_spi_host_irq_t spi_host_irq_expected; +static volatile dif_spi_host_irq_t spi_host_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_uart_irq_t uart_irq_expected; +static volatile dif_uart_irq_t uart_irq_serviced; +#endif + +/** + * Provides external IRQ handling for this test. + * + * This function overrides the default OTTF external ISR. + * + * For each IRQ, it performs the following: + * 1. Claims the IRQ fired (finds PLIC IRQ index). + * 2. Checks that the index belongs to the expected peripheral. + * 3. Checks that the correct and the only IRQ from the expected peripheral + * triggered. + * 4. Clears the IRQ at the peripheral. + * 5. Completes the IRQ service at PLIC. + */ +void ottf_external_isr(uint32_t *exc_info) { + dif_rv_plic_irq_id_t plic_irq_id; + CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic, kHart, &plic_irq_id)); + + top_darjeeling_plic_peripheral_t peripheral = (top_darjeeling_plic_peripheral_t) + top_darjeeling_plic_interrupt_for_peripheral[plic_irq_id]; + CHECK(peripheral == peripheral_expected, + "Interrupt from incorrect peripheral: exp = %d, obs = %d", + peripheral_expected, peripheral); + + switch (peripheral) { +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralAlertHandler: { + dif_alert_handler_irq_t irq = + (dif_alert_handler_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdAlertHandlerClassa); + CHECK(irq == alert_handler_irq_expected, + "Incorrect alert_handler IRQ triggered: exp = %d, obs = %d", + alert_handler_irq_expected, irq); + alert_handler_irq_serviced = irq; + + dif_alert_handler_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_alert_handler_irq_get_state(&alert_handler, &snapshot)); + CHECK(snapshot == (dif_alert_handler_irq_state_snapshot_t)(1 << irq), + "Only alert_handler IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_alert_handler_irq_acknowledge(&alert_handler, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralAonTimerAon: { + dif_aon_timer_irq_t irq = + (dif_aon_timer_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdAonTimerAonWkupTimerExpired); + CHECK(irq == aon_timer_irq_expected, + "Incorrect aon_timer_aon IRQ triggered: exp = %d, obs = %d", + aon_timer_irq_expected, irq); + aon_timer_irq_serviced = irq; + + dif_aon_timer_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_aon_timer_irq_get_state(&aon_timer_aon, &snapshot)); + CHECK(snapshot == (dif_aon_timer_irq_state_snapshot_t)(1 << irq), + "Only aon_timer_aon IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(&aon_timer_aon, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralCsrng: { + dif_csrng_irq_t irq = + (dif_csrng_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdCsrngCsCmdReqDone); + CHECK(irq == csrng_irq_expected, + "Incorrect csrng IRQ triggered: exp = %d, obs = %d", + csrng_irq_expected, irq); + csrng_irq_serviced = irq; + + dif_csrng_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_csrng_irq_get_state(&csrng, &snapshot)); + CHECK(snapshot == (dif_csrng_irq_state_snapshot_t)(1 << irq), + "Only csrng IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_csrng_irq_acknowledge(&csrng, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralDma: { + dif_dma_irq_t irq = + (dif_dma_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdDmaDmaDone); + CHECK(irq == dma_irq_expected, + "Incorrect dma IRQ triggered: exp = %d, obs = %d", + dma_irq_expected, irq); + dma_irq_serviced = irq; + + dif_dma_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_dma_irq_get_state(&dma, &snapshot)); + CHECK(snapshot == (dif_dma_irq_state_snapshot_t)(1 << irq), + "Only dma IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x7 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_dma_irq_force(&dma, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_dma_irq_set_enabled(&dma, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_dma_irq_acknowledge(&dma, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralEdn0: { + dif_edn_irq_t irq = + (dif_edn_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdEdn0EdnCmdReqDone); + CHECK(irq == edn_irq_expected, + "Incorrect edn0 IRQ triggered: exp = %d, obs = %d", + edn_irq_expected, irq); + edn_irq_serviced = irq; + + dif_edn_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_edn_irq_get_state(&edn0, &snapshot)); + CHECK(snapshot == (dif_edn_irq_state_snapshot_t)(1 << irq), + "Only edn0 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_edn_irq_acknowledge(&edn0, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralEdn1: { + dif_edn_irq_t irq = + (dif_edn_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdEdn1EdnCmdReqDone); + CHECK(irq == edn_irq_expected, + "Incorrect edn1 IRQ triggered: exp = %d, obs = %d", + edn_irq_expected, irq); + edn_irq_serviced = irq; + + dif_edn_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_edn_irq_get_state(&edn1, &snapshot)); + CHECK(snapshot == (dif_edn_irq_state_snapshot_t)(1 << irq), + "Only edn1 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_edn_irq_acknowledge(&edn1, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralGpio: { + dif_gpio_irq_t irq = + (dif_gpio_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdGpioGpio0); + CHECK(irq == gpio_irq_expected, + "Incorrect gpio IRQ triggered: exp = %d, obs = %d", + gpio_irq_expected, irq); + gpio_irq_serviced = irq; + + dif_gpio_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_gpio_irq_get_state(&gpio, &snapshot)); + CHECK(snapshot == (dif_gpio_irq_state_snapshot_t)(1 << irq), + "Only gpio IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_gpio_irq_acknowledge(&gpio, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralHmac: { + dif_hmac_irq_t irq = + (dif_hmac_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdHmacHmacDone); + CHECK(irq == hmac_irq_expected, + "Incorrect hmac IRQ triggered: exp = %d, obs = %d", + hmac_irq_expected, irq); + hmac_irq_serviced = irq; + + dif_hmac_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_hmac_irq_get_state(&hmac, &snapshot)); + CHECK(snapshot == (dif_hmac_irq_state_snapshot_t)(1 << irq), + "Only hmac IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x2 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_hmac_irq_force(&hmac, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_hmac_irq_set_enabled(&hmac, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_hmac_irq_acknowledge(&hmac, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralI2c0: { + dif_i2c_irq_t irq = + (dif_i2c_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdI2c0FmtThreshold); + CHECK(irq == i2c_irq_expected, + "Incorrect i2c0 IRQ triggered: exp = %d, obs = %d", + i2c_irq_expected, irq); + i2c_irq_serviced = irq; + + dif_i2c_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_i2c_irq_get_state(&i2c0, &snapshot)); + CHECK(snapshot == (dif_i2c_irq_state_snapshot_t)(1 << irq), + "Only i2c0 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x1c17 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_i2c_irq_force(&i2c0, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_i2c_irq_set_enabled(&i2c0, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_i2c_irq_acknowledge(&i2c0, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralKeymgrDpe: { + dif_keymgr_dpe_irq_t irq = + (dif_keymgr_dpe_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdKeymgrDpeOpDone); + CHECK(irq == keymgr_dpe_irq_expected, + "Incorrect keymgr_dpe IRQ triggered: exp = %d, obs = %d", + keymgr_dpe_irq_expected, irq); + keymgr_dpe_irq_serviced = irq; + + dif_keymgr_dpe_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_keymgr_dpe_irq_get_state(&keymgr_dpe, &snapshot)); + CHECK(snapshot == (dif_keymgr_dpe_irq_state_snapshot_t)(1 << irq), + "Only keymgr_dpe IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_keymgr_dpe_irq_acknowledge(&keymgr_dpe, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralKmac: { + dif_kmac_irq_t irq = + (dif_kmac_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdKmacKmacDone); + CHECK(irq == kmac_irq_expected, + "Incorrect kmac IRQ triggered: exp = %d, obs = %d", + kmac_irq_expected, irq); + kmac_irq_serviced = irq; + + dif_kmac_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_kmac_irq_get_state(&kmac, &snapshot)); + CHECK(snapshot == (dif_kmac_irq_state_snapshot_t)(1 << irq), + "Only kmac IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x2 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_kmac_irq_force(&kmac, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_kmac_irq_set_enabled(&kmac, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_kmac_irq_acknowledge(&kmac, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbx0: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbx0MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx0 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx0, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx0 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx0, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbx1: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbx1MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx1 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx1, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx1 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx1, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbx2: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbx2MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx2 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx2, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx2 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx2, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbx3: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbx3MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx3 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx3, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx3 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx3, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbx4: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbx4MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx4 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx4, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx4 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx4, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbx5: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbx5MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx5 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx5, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx5 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx5, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbx6: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbx6MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx6 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx6, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx6 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx6, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbxJtag: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbxJtagMbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx_jtag IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx_jtag, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx_jtag IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx_jtag, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbxPcie0: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbxPcie0MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx_pcie0 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx_pcie0, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx_pcie0 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx_pcie0, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralMbxPcie1: { + dif_mbx_irq_t irq = + (dif_mbx_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdMbxPcie1MbxReady); + CHECK(irq == mbx_irq_expected, + "Incorrect mbx_pcie1 IRQ triggered: exp = %d, obs = %d", + mbx_irq_expected, irq); + mbx_irq_serviced = irq; + + dif_mbx_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_mbx_irq_get_state(&mbx_pcie1, &snapshot)); + CHECK(snapshot == (dif_mbx_irq_state_snapshot_t)(1 << irq), + "Only mbx_pcie1 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_mbx_irq_acknowledge(&mbx_pcie1, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralOtbn: { + dif_otbn_irq_t irq = + (dif_otbn_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdOtbnDone); + CHECK(irq == otbn_irq_expected, + "Incorrect otbn IRQ triggered: exp = %d, obs = %d", + otbn_irq_expected, irq); + otbn_irq_serviced = irq; + + dif_otbn_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_otbn_irq_get_state(&otbn, &snapshot)); + CHECK(snapshot == (dif_otbn_irq_state_snapshot_t)(1 << irq), + "Only otbn IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_otbn_irq_acknowledge(&otbn, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralOtpCtrl: { + dif_otp_ctrl_irq_t irq = + (dif_otp_ctrl_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdOtpCtrlOtpOperationDone); + CHECK(irq == otp_ctrl_irq_expected, + "Incorrect otp_ctrl IRQ triggered: exp = %d, obs = %d", + otp_ctrl_irq_expected, irq); + otp_ctrl_irq_serviced = irq; + + dif_otp_ctrl_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_otp_ctrl_irq_get_state(&otp_ctrl, &snapshot)); + CHECK(snapshot == (dif_otp_ctrl_irq_state_snapshot_t)(1 << irq), + "Only otp_ctrl IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_otp_ctrl_irq_acknowledge(&otp_ctrl, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralPwrmgrAon: { + dif_pwrmgr_irq_t irq = + (dif_pwrmgr_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdPwrmgrAonWakeup); + CHECK(irq == pwrmgr_irq_expected, + "Incorrect pwrmgr_aon IRQ triggered: exp = %d, obs = %d", + pwrmgr_irq_expected, irq); + pwrmgr_irq_serviced = irq; + + dif_pwrmgr_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_pwrmgr_irq_get_state(&pwrmgr_aon, &snapshot)); + CHECK(snapshot == (dif_pwrmgr_irq_state_snapshot_t)(1 << irq), + "Only pwrmgr_aon IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge(&pwrmgr_aon, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralRvTimer: { + dif_rv_timer_irq_t irq = + (dif_rv_timer_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdRvTimerTimerExpiredHart0Timer0); + CHECK(irq == rv_timer_irq_expected, + "Incorrect rv_timer IRQ triggered: exp = %d, obs = %d", + rv_timer_irq_expected, irq); + rv_timer_irq_serviced = irq; + + dif_rv_timer_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_rv_timer_irq_get_state(&rv_timer, kHart, &snapshot)); + CHECK(snapshot == (dif_rv_timer_irq_state_snapshot_t)(1 << irq), + "Only rv_timer IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_rv_timer_irq_acknowledge(&rv_timer, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralSensorCtrl: { + dif_sensor_ctrl_irq_t irq = + (dif_sensor_ctrl_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdSensorCtrlIoStatusChange); + CHECK(irq == sensor_ctrl_irq_expected, + "Incorrect sensor_ctrl IRQ triggered: exp = %d, obs = %d", + sensor_ctrl_irq_expected, irq); + sensor_ctrl_irq_serviced = irq; + + dif_sensor_ctrl_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_sensor_ctrl_irq_get_state(&sensor_ctrl, &snapshot)); + CHECK(snapshot == (dif_sensor_ctrl_irq_state_snapshot_t)(1 << irq), + "Only sensor_ctrl IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_sensor_ctrl_irq_acknowledge(&sensor_ctrl, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralSocProxy: { + dif_soc_proxy_irq_t irq = + (dif_soc_proxy_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdSocProxyExternal0); + CHECK(irq == soc_proxy_irq_expected, + "Incorrect soc_proxy IRQ triggered: exp = %d, obs = %d", + soc_proxy_irq_expected, irq); + soc_proxy_irq_serviced = irq; + + dif_soc_proxy_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_soc_proxy_irq_get_state(&soc_proxy, &snapshot)); + CHECK(snapshot == (dif_soc_proxy_irq_state_snapshot_t)(1 << irq), + "Only soc_proxy IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_soc_proxy_irq_acknowledge(&soc_proxy, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralSpiDevice: { + dif_spi_device_irq_t irq = + (dif_spi_device_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty); + CHECK(irq == spi_device_irq_expected, + "Incorrect spi_device IRQ triggered: exp = %d, obs = %d", + spi_device_irq_expected, irq); + spi_device_irq_serviced = irq; + + dif_spi_device_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_spi_device_irq_get_state(&spi_device, &snapshot)); + CHECK(snapshot == (dif_spi_device_irq_state_snapshot_t)(1 << irq), + "Only spi_device IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x20 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_spi_device_irq_force(&spi_device, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_spi_device_irq_set_enabled(&spi_device, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_spi_device_irq_acknowledge(&spi_device, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralSpiHost0: { + dif_spi_host_irq_t irq = + (dif_spi_host_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdSpiHost0Error); + CHECK(irq == spi_host_irq_expected, + "Incorrect spi_host0 IRQ triggered: exp = %d, obs = %d", + spi_host_irq_expected, irq); + spi_host_irq_serviced = irq; + + dif_spi_host_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_spi_host_irq_get_state(&spi_host0, &snapshot)); + CHECK(snapshot == (dif_spi_host_irq_state_snapshot_t)(1 << irq), + "Only spi_host0 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x2 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_spi_host_irq_force(&spi_host0, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_spi_host_irq_set_enabled(&spi_host0, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_spi_host_irq_acknowledge(&spi_host0, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL + case kTopDarjeelingPlicPeripheralUart0: { + dif_uart_irq_t irq = + (dif_uart_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopDarjeelingPlicIrqIdUart0TxWatermark); + CHECK(irq == uart_irq_expected, + "Incorrect uart0 IRQ triggered: exp = %d, obs = %d", + uart_irq_expected, irq); + uart_irq_serviced = irq; + + dif_uart_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_uart_irq_get_state(&uart0, &snapshot)); + CHECK(snapshot == (dif_uart_irq_state_snapshot_t)((1 << irq) | 0x101), + "Expected uart0 interrupt status %x. Actual interrupt " + "status = %x", + (1 << irq) | 0x101, snapshot); + + if (0x103 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_uart_irq_force(&uart0, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x101 & (1 << irq))) { + CHECK_DIF_OK(dif_uart_irq_set_enabled(&uart0, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_uart_irq_acknowledge(&uart0, irq)); + } + break; + } +#endif + + default: + LOG_FATAL("ISR is not implemented!"); + test_status_set(kTestStatusFailed); + } + // Complete the IRQ at PLIC. + CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic, kHart, plic_irq_id)); +} + +/** + * Initializes the handles to all peripherals. + */ +static void peripherals_init(void) { + mmio_region_t base_addr; + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_ALERT_HANDLER_BASE_ADDR); + CHECK_DIF_OK(dif_alert_handler_init(base_addr, &alert_handler)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_AON_TIMER_AON_BASE_ADDR); + CHECK_DIF_OK(dif_aon_timer_init(base_addr, &aon_timer_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_CSRNG_BASE_ADDR); + CHECK_DIF_OK(dif_csrng_init(base_addr, &csrng)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_DMA_BASE_ADDR); + CHECK_DIF_OK(dif_dma_init(base_addr, &dma)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_EDN0_BASE_ADDR); + CHECK_DIF_OK(dif_edn_init(base_addr, &edn0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_EDN1_BASE_ADDR); + CHECK_DIF_OK(dif_edn_init(base_addr, &edn1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_GPIO_BASE_ADDR); + CHECK_DIF_OK(dif_gpio_init(base_addr, &gpio)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_HMAC_BASE_ADDR); + CHECK_DIF_OK(dif_hmac_init(base_addr, &hmac)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_I2C0_BASE_ADDR); + CHECK_DIF_OK(dif_i2c_init(base_addr, &i2c0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_KEYMGR_DPE_BASE_ADDR); + CHECK_DIF_OK(dif_keymgr_dpe_init(base_addr, &keymgr_dpe)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_KMAC_BASE_ADDR); + CHECK_DIF_OK(dif_kmac_init(base_addr, &kmac)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX0_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX1_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX2_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx2)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX3_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx3)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX4_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx4)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX5_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx5)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX6_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx6)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX_JTAG_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx_jtag)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX_PCIE0_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx_pcie0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_MBX_PCIE1_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_mbx_init(base_addr, &mbx_pcie1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_OTBN_BASE_ADDR); + CHECK_DIF_OK(dif_otbn_init(base_addr, &otbn)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_OTP_CTRL_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_otp_ctrl_init(base_addr, &otp_ctrl)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_PWRMGR_AON_BASE_ADDR); + CHECK_DIF_OK(dif_pwrmgr_init(base_addr, &pwrmgr_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_RV_TIMER_BASE_ADDR); + CHECK_DIF_OK(dif_rv_timer_init(base_addr, &rv_timer)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_SENSOR_CTRL_BASE_ADDR); + CHECK_DIF_OK(dif_sensor_ctrl_init(base_addr, &sensor_ctrl)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_SOC_PROXY_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_soc_proxy_init(base_addr, &soc_proxy)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_SPI_DEVICE_BASE_ADDR); + CHECK_DIF_OK(dif_spi_device_init(base_addr, &spi_device)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_SPI_HOST0_BASE_ADDR); + CHECK_DIF_OK(dif_spi_host_init(base_addr, &spi_host0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_DARJEELING_UART0_BASE_ADDR); + CHECK_DIF_OK(dif_uart_init(base_addr, &uart0)); +#endif + + base_addr = mmio_region_from_addr(TOP_DARJEELING_RV_PLIC_BASE_ADDR); + CHECK_DIF_OK(dif_rv_plic_init(base_addr, &plic)); +} + +/** + * Clears pending IRQs in all peripherals. + */ +static void peripheral_irqs_clear(void) { +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_alert_handler_irq_acknowledge_all(&alert_handler)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_aon_timer_irq_acknowledge_all(&aon_timer_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_csrng_irq_acknowledge_all(&csrng)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_dma_irq_acknowledge_all(&dma)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_edn_irq_acknowledge_all(&edn0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_edn_irq_acknowledge_all(&edn1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_gpio_irq_acknowledge_all(&gpio)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_hmac_irq_acknowledge_all(&hmac)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_i2c_irq_acknowledge_all(&i2c0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_keymgr_dpe_irq_acknowledge_all(&keymgr_dpe)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_kmac_irq_acknowledge_all(&kmac)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx2)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx3)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx4)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx5)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx6)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx_jtag)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx_pcie0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_acknowledge_all(&mbx_pcie1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_otbn_irq_acknowledge_all(&otbn)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL + if (kBootStage != kBootStageOwner) { + CHECK_DIF_OK(dif_otp_ctrl_irq_acknowledge_all(&otp_ctrl)); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge_all(&pwrmgr_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_rv_timer_irq_acknowledge_all(&rv_timer, kHart)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_sensor_ctrl_irq_acknowledge_all(&sensor_ctrl)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_soc_proxy_irq_acknowledge_all(&soc_proxy)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_device_irq_acknowledge_all(&spi_device)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_host_irq_acknowledge_all(&spi_host0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_uart_irq_acknowledge_all(&uart0)); +#endif +} + +/** + * Enables all IRQs in all peripherals. + */ +static void peripheral_irqs_enable(void) { +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + dif_alert_handler_irq_state_snapshot_t alert_handler_irqs = + (dif_alert_handler_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + dif_csrng_irq_state_snapshot_t csrng_irqs = + (dif_csrng_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + dif_dma_irq_state_snapshot_t dma_irqs = + (dif_dma_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + dif_edn_irq_state_snapshot_t edn_irqs = + (dif_edn_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + dif_gpio_irq_state_snapshot_t gpio_irqs = + (dif_gpio_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + dif_hmac_irq_state_snapshot_t hmac_irqs = + (dif_hmac_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + dif_i2c_irq_state_snapshot_t i2c_irqs = + (dif_i2c_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL + dif_keymgr_dpe_irq_state_snapshot_t keymgr_dpe_irqs = + (dif_keymgr_dpe_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL + dif_kmac_irq_state_snapshot_t kmac_irqs = + (dif_kmac_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + dif_mbx_irq_state_snapshot_t mbx_irqs = + (dif_mbx_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL + dif_otbn_irq_state_snapshot_t otbn_irqs = + (dif_otbn_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL + dif_otp_ctrl_irq_state_snapshot_t otp_ctrl_irqs = + (dif_otp_ctrl_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL + dif_pwrmgr_irq_state_snapshot_t pwrmgr_irqs = + (dif_pwrmgr_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL + dif_rv_timer_irq_state_snapshot_t rv_timer_irqs = + (dif_rv_timer_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL + dif_sensor_ctrl_irq_state_snapshot_t sensor_ctrl_irqs = + (dif_sensor_ctrl_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL + dif_soc_proxy_irq_state_snapshot_t soc_proxy_irqs = + (dif_soc_proxy_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL + dif_spi_device_irq_state_snapshot_t spi_device_irqs = + (dif_spi_device_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL + dif_spi_host_irq_state_snapshot_t spi_host_irqs = + (dif_spi_host_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL + // Note: this peripheral contains status interrupts that are asserted by + // default. Therefore, not all interrupts are enabled here, since that + // would interfere with this test. Instead, these interrupts are enabled on + // demand once they are being tested. + dif_uart_irq_state_snapshot_t uart_irqs = + (dif_uart_irq_state_snapshot_t)0xfffffefe; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_alert_handler_irq_restore_all(&alert_handler, &alert_handler_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_csrng_irq_restore_all(&csrng, &csrng_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_dma_irq_restore_all(&dma, &dma_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_edn_irq_restore_all(&edn0, &edn_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_edn_irq_restore_all(&edn1, &edn_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_gpio_irq_restore_all(&gpio, &gpio_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_hmac_irq_restore_all(&hmac, &hmac_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_i2c_irq_restore_all(&i2c0, &i2c_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_keymgr_dpe_irq_restore_all(&keymgr_dpe, &keymgr_dpe_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_kmac_irq_restore_all(&kmac, &kmac_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx0, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx1, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx2, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx3, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx4, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx5, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx6, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx_jtag, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx_pcie0, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_mbx_irq_restore_all(&mbx_pcie1, &mbx_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_otbn_irq_restore_all(&otbn, &otbn_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL + if (kBootStage != kBootStageOwner) { + CHECK_DIF_OK(dif_otp_ctrl_irq_restore_all(&otp_ctrl, &otp_ctrl_irqs)); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_pwrmgr_irq_restore_all(&pwrmgr_aon, &pwrmgr_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_rv_timer_irq_restore_all(&rv_timer, kHart, &rv_timer_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_sensor_ctrl_irq_restore_all(&sensor_ctrl, &sensor_ctrl_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_soc_proxy_irq_restore_all(&soc_proxy, &soc_proxy_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_device_irq_restore_all(&spi_device, &spi_device_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_host_irq_restore_all(&spi_host0, &spi_host_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL + // lowrisc/opentitan#8656: Skip UART0 in non-DV setups due to interference + // from the logging facility. + if (kDeviceType == kDeviceSimDV) { + CHECK_DIF_OK(dif_uart_irq_restore_all(&uart0, &uart_irqs)); + } +#endif +} + +/** + * Triggers all IRQs in all peripherals one by one. + * + * Walks through all instances of all peripherals and triggers an interrupt one + * by one, by forcing with the `intr_test` CSR. On trigger, the CPU instantly + * jumps into the ISR. The main flow of execution thus proceeds to check that + * the correct IRQ was serviced immediately. The ISR, in turn checks if the + * expected IRQ from the expected peripheral triggered. + */ +static void peripheral_irqs_trigger(void) { + unsigned int status_default_mask; + // Depending on the build configuration, this variable may show up as unused + // in the clang linter. This statement waives that error. + (void)status_default_mask; + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralAlertHandler; + for (dif_alert_handler_irq_t irq = kDifAlertHandlerIrqClassa; irq <= kDifAlertHandlerIrqClassd; + ++irq) { + alert_handler_irq_expected = irq; + LOG_INFO("Triggering alert_handler IRQ %d.", irq); + CHECK_DIF_OK(dif_alert_handler_irq_force(&alert_handler, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(alert_handler_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from alert_handler is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + // lowrisc/opentitan#8656: Skip UART0 in non-DV setups due to interference + // from the logging facility. + // aon_timer may generate a NMI instead of a PLIC IRQ depending on the ROM. + // Since there are other tests covering this already, we just skip this for + // non-DV setups. + if (kDeviceType == kDeviceSimDV) { + peripheral_expected = kTopDarjeelingPlicPeripheralAonTimerAon; + for (dif_aon_timer_irq_t irq = kDifAonTimerIrqWkupTimerExpired; irq <= kDifAonTimerIrqWdogTimerBark; + ++irq) { + aon_timer_irq_expected = irq; + LOG_INFO("Triggering aon_timer_aon IRQ %d.", irq); + CHECK_DIF_OK(dif_aon_timer_irq_force(&aon_timer_aon, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(aon_timer_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from aon_timer_aon is serviced.", irq); + } + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralCsrng; + for (dif_csrng_irq_t irq = kDifCsrngIrqCsCmdReqDone; irq <= kDifCsrngIrqCsFatalErr; + ++irq) { + csrng_irq_expected = irq; + LOG_INFO("Triggering csrng IRQ %d.", irq); + CHECK_DIF_OK(dif_csrng_irq_force(&csrng, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(csrng_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from csrng is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralDma; + status_default_mask = 0x0; + for (dif_dma_irq_t irq = kDifDmaIrqDmaDone; irq <= kDifDmaIrqDmaError; + ++irq) { + dma_irq_expected = irq; + LOG_INFO("Triggering dma IRQ %d.", irq); + CHECK_DIF_OK(dif_dma_irq_force(&dma, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_dma_irq_set_enabled(&dma, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(dma_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from dma is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralEdn0; + for (dif_edn_irq_t irq = kDifEdnIrqEdnCmdReqDone; irq <= kDifEdnIrqEdnFatalErr; + ++irq) { + edn_irq_expected = irq; + LOG_INFO("Triggering edn0 IRQ %d.", irq); + CHECK_DIF_OK(dif_edn_irq_force(&edn0, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(edn_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from edn0 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralEdn1; + for (dif_edn_irq_t irq = kDifEdnIrqEdnCmdReqDone; irq <= kDifEdnIrqEdnFatalErr; + ++irq) { + edn_irq_expected = irq; + LOG_INFO("Triggering edn1 IRQ %d.", irq); + CHECK_DIF_OK(dif_edn_irq_force(&edn1, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(edn_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from edn1 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralGpio; + for (dif_gpio_irq_t irq = kDifGpioIrqGpio0; irq <= kDifGpioIrqGpio31; + ++irq) { + gpio_irq_expected = irq; + LOG_INFO("Triggering gpio IRQ %d.", irq); + CHECK_DIF_OK(dif_gpio_irq_force(&gpio, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(gpio_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from gpio is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralHmac; + status_default_mask = 0x0; + for (dif_hmac_irq_t irq = kDifHmacIrqHmacDone; irq <= kDifHmacIrqHmacErr; + ++irq) { + hmac_irq_expected = irq; + LOG_INFO("Triggering hmac IRQ %d.", irq); + CHECK_DIF_OK(dif_hmac_irq_force(&hmac, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_hmac_irq_set_enabled(&hmac, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(hmac_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from hmac is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralI2c0; + status_default_mask = 0x0; + for (dif_i2c_irq_t irq = kDifI2cIrqFmtThreshold; irq <= kDifI2cIrqHostTimeout; + ++irq) { + i2c_irq_expected = irq; + LOG_INFO("Triggering i2c0 IRQ %d.", irq); + CHECK_DIF_OK(dif_i2c_irq_force(&i2c0, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_i2c_irq_set_enabled(&i2c0, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(i2c_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from i2c0 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 8 && 8 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralKeymgrDpe; + for (dif_keymgr_dpe_irq_t irq = kDifKeymgrDpeIrqOpDone; irq <= kDifKeymgrDpeIrqOpDone; + ++irq) { + keymgr_dpe_irq_expected = irq; + LOG_INFO("Triggering keymgr_dpe IRQ %d.", irq); + CHECK_DIF_OK(dif_keymgr_dpe_irq_force(&keymgr_dpe, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(keymgr_dpe_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from keymgr_dpe is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 9 && 9 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralKmac; + status_default_mask = 0x0; + for (dif_kmac_irq_t irq = kDifKmacIrqKmacDone; irq <= kDifKmacIrqKmacErr; + ++irq) { + kmac_irq_expected = irq; + LOG_INFO("Triggering kmac IRQ %d.", irq); + CHECK_DIF_OK(dif_kmac_irq_force(&kmac, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_kmac_irq_set_enabled(&kmac, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(kmac_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from kmac is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbx0; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx0 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx0, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx0 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbx1; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx1 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx1, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx1 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbx2; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx2 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx2, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx2 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbx3; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx3 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx3, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx3 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbx4; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx4 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx4, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx4 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbx5; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx5 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx5, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx5 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbx6; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx6 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx6, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx6 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbxJtag; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx_jtag IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx_jtag, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx_jtag is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbxPcie0; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx_pcie0 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx_pcie0, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx_pcie0 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 10 && 10 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralMbxPcie1; + for (dif_mbx_irq_t irq = kDifMbxIrqMbxReady; irq <= kDifMbxIrqMbxError; + ++irq) { + mbx_irq_expected = irq; + LOG_INFO("Triggering mbx_pcie1 IRQ %d.", irq); + CHECK_DIF_OK(dif_mbx_irq_force(&mbx_pcie1, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(mbx_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from mbx_pcie1 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 11 && 11 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralOtbn; + for (dif_otbn_irq_t irq = kDifOtbnIrqDone; irq <= kDifOtbnIrqDone; + ++irq) { + otbn_irq_expected = irq; + LOG_INFO("Triggering otbn IRQ %d.", irq); + CHECK_DIF_OK(dif_otbn_irq_force(&otbn, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(otbn_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from otbn is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 12 && 12 < TEST_MAX_IRQ_PERIPHERAL + // Skip OTP_CTRL in boot stage owner since ROM_EXT configures all accesses + // to OTP_CTRL and AST to be illegal. + if (kBootStage != kBootStageOwner) { + peripheral_expected = kTopDarjeelingPlicPeripheralOtpCtrl; + for (dif_otp_ctrl_irq_t irq = kDifOtpCtrlIrqOtpOperationDone; irq <= kDifOtpCtrlIrqOtpError; + ++irq) { + otp_ctrl_irq_expected = irq; + LOG_INFO("Triggering otp_ctrl IRQ %d.", irq); + CHECK_DIF_OK(dif_otp_ctrl_irq_force(&otp_ctrl, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(otp_ctrl_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from otp_ctrl is serviced.", irq); + } + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 13 && 13 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralPwrmgrAon; + for (dif_pwrmgr_irq_t irq = kDifPwrmgrIrqWakeup; irq <= kDifPwrmgrIrqWakeup; + ++irq) { + pwrmgr_irq_expected = irq; + LOG_INFO("Triggering pwrmgr_aon IRQ %d.", irq); + CHECK_DIF_OK(dif_pwrmgr_irq_force(&pwrmgr_aon, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(pwrmgr_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from pwrmgr_aon is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 14 && 14 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralRvTimer; + for (dif_rv_timer_irq_t irq = kDifRvTimerIrqTimerExpiredHart0Timer0; irq <= kDifRvTimerIrqTimerExpiredHart0Timer0; + ++irq) { + rv_timer_irq_expected = irq; + LOG_INFO("Triggering rv_timer IRQ %d.", irq); + CHECK_DIF_OK(dif_rv_timer_irq_force(&rv_timer, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(rv_timer_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from rv_timer is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 15 && 15 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralSensorCtrl; + for (dif_sensor_ctrl_irq_t irq = kDifSensorCtrlIrqIoStatusChange; irq <= kDifSensorCtrlIrqInitStatusChange; + ++irq) { + sensor_ctrl_irq_expected = irq; + LOG_INFO("Triggering sensor_ctrl IRQ %d.", irq); + CHECK_DIF_OK(dif_sensor_ctrl_irq_force(&sensor_ctrl, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(sensor_ctrl_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from sensor_ctrl is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 16 && 16 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralSocProxy; + for (dif_soc_proxy_irq_t irq = kDifSocProxyIrqExternal0; irq <= kDifSocProxyIrqExternal31; + ++irq) { + soc_proxy_irq_expected = irq; + LOG_INFO("Triggering soc_proxy IRQ %d.", irq); + CHECK_DIF_OK(dif_soc_proxy_irq_force(&soc_proxy, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(soc_proxy_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from soc_proxy is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 17 && 17 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralSpiDevice; + status_default_mask = 0x0; + for (dif_spi_device_irq_t irq = kDifSpiDeviceIrqUploadCmdfifoNotEmpty; irq <= kDifSpiDeviceIrqTpmRdfifoDrop; + ++irq) { + spi_device_irq_expected = irq; + LOG_INFO("Triggering spi_device IRQ %d.", irq); + CHECK_DIF_OK(dif_spi_device_irq_force(&spi_device, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_spi_device_irq_set_enabled(&spi_device, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(spi_device_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from spi_device is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 18 && 18 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopDarjeelingPlicPeripheralSpiHost0; + status_default_mask = 0x0; + for (dif_spi_host_irq_t irq = kDifSpiHostIrqError; irq <= kDifSpiHostIrqSpiEvent; + ++irq) { + spi_host_irq_expected = irq; + LOG_INFO("Triggering spi_host0 IRQ %d.", irq); + CHECK_DIF_OK(dif_spi_host_irq_force(&spi_host0, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_spi_host_irq_set_enabled(&spi_host0, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(spi_host_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from spi_host0 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 19 && 19 < TEST_MAX_IRQ_PERIPHERAL + // lowrisc/opentitan#8656: Skip UART0 in non-DV setups due to interference + // from the logging facility. + // aon_timer may generate a NMI instead of a PLIC IRQ depending on the ROM. + // Since there are other tests covering this already, we just skip this for + // non-DV setups. + if (kDeviceType == kDeviceSimDV) { + peripheral_expected = kTopDarjeelingPlicPeripheralUart0; + status_default_mask = 0x101; + for (dif_uart_irq_t irq = kDifUartIrqTxWatermark; irq <= kDifUartIrqTxEmpty; + ++irq) { + uart_irq_expected = irq; + LOG_INFO("Triggering uart0 IRQ %d.", irq); + CHECK_DIF_OK(dif_uart_irq_force(&uart0, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_uart_irq_set_enabled(&uart0, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(uart_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from uart0 is serviced.", irq); + } + } +#endif +} + +/** + * Checks that the target ID corresponds to the ID of the hart on which + * this test is executed on. This check is meant to be used in a + * single-hart system only. + */ +static void check_hart_id(uint32_t exp_hart_id) { + uint32_t act_hart_id; + CSR_READ(CSR_REG_MHARTID, &act_hart_id); + CHECK(act_hart_id == exp_hart_id, "Processor has unexpected HART ID."); +} + +OTTF_DEFINE_TEST_CONFIG(); + +bool test_main(void) { + irq_global_ctrl(true); + irq_external_ctrl(true); + peripherals_init(); + check_hart_id((uint32_t)kHart); + rv_plic_testutils_irq_range_enable( + &plic, kHart, kTopDarjeelingPlicIrqIdNone + 1, kTopDarjeelingPlicIrqIdLast); + peripheral_irqs_clear(); + peripheral_irqs_enable(); + peripheral_irqs_trigger(); + return true; +} + +// clang-format on diff --git a/hw/top_earlgrey/data/ip/chip_alert_handler_testplan.hjson b/hw/top_earlgrey/data/ip/chip_alert_handler_testplan.hjson index 8e8b34f77bccf..45d501bfdab5a 100644 --- a/hw/top_earlgrey/data/ip/chip_alert_handler_testplan.hjson +++ b/hw/top_earlgrey/data/ip/chip_alert_handler_testplan.hjson @@ -23,7 +23,7 @@ si_stage: SV3 lc_states: ["PROD"] tests: ["chip_sw_alert_test"] - bazel: ["//sw/device/tests/autogen:alert_test"] + bazel: ["//hw/top_earlgrey/sw/autogen/tests:alert_test"] } { name: chip_sw_alert_handler_escalations @@ -125,9 +125,9 @@ lc_states: ["PROD"] tests: ["chip_plic_all_irqs_0", "chip_plic_all_irqs_10", "chip_plic_all_irqs_20"] bazel: [ - "//sw/device/tests/autogen:plic_all_irqs_test_0", - "//sw/device/tests/autogen:plic_all_irqs_test_10", - "//sw/device/tests/autogen:plic_all_irqs_test_20", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_0", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_10", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_20", ] } { diff --git a/hw/top_earlgrey/data/ip/chip_rv_plic_testplan.hjson b/hw/top_earlgrey/data/ip/chip_rv_plic_testplan.hjson index ad55686fcbe20..f89a523402c60 100644 --- a/hw/top_earlgrey/data/ip/chip_rv_plic_testplan.hjson +++ b/hw/top_earlgrey/data/ip/chip_rv_plic_testplan.hjson @@ -26,9 +26,9 @@ "chip_plic_all_irqs_20", ] bazel: [ - "//sw/device/tests/autogen:plic_all_irqs_test_0", - "//sw/device/tests/autogen:plic_all_irqs_test_10", - "//sw/device/tests/autogen:plic_all_irqs_test_20", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_0", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_10", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_20", ] } { diff --git a/hw/top_earlgrey/dv/chip_sim_cfg.hjson b/hw/top_earlgrey/dv/chip_sim_cfg.hjson index ecee7eaa3a8b4..252903b80b3aa 100644 --- a/hw/top_earlgrey/dv/chip_sim_cfg.hjson +++ b/hw/top_earlgrey/dv/chip_sim_cfg.hjson @@ -1302,7 +1302,7 @@ { name: chip_sw_alert_test uvm_test_seq: chip_sw_base_vseq - sw_images: ["//sw/device/tests/autogen:alert_test:1:new_rules"] + sw_images: ["//hw/top_earlgrey/sw/autogen/tests:alert_test:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] } { @@ -1718,19 +1718,19 @@ { name: chip_plic_all_irqs_0 uvm_test_seq: chip_sw_base_vseq - sw_images: ["//sw/device/tests/autogen:plic_all_irqs_test_0:1:new_rules"] + sw_images: ["//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_0:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] } { name: chip_plic_all_irqs_10 uvm_test_seq: chip_sw_base_vseq - sw_images: ["//sw/device/tests/autogen:plic_all_irqs_test_10:1:new_rules"] + sw_images: ["//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_10:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] } { name: chip_plic_all_irqs_20 uvm_test_seq: chip_sw_base_vseq - sw_images: ["//sw/device/tests/autogen:plic_all_irqs_test_20:1:new_rules"] + sw_images: ["//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_20:1:new_rules"] en_run_modes: ["sw_test_mode_test_rom"] } { diff --git a/sw/device/tests/autogen/BUILD b/hw/top_earlgrey/sw/autogen/tests/BUILD similarity index 100% rename from sw/device/tests/autogen/BUILD rename to hw/top_earlgrey/sw/autogen/tests/BUILD diff --git a/sw/device/tests/autogen/alert_test.c b/hw/top_earlgrey/sw/autogen/tests/alert_test.c similarity index 100% rename from sw/device/tests/autogen/alert_test.c rename to hw/top_earlgrey/sw/autogen/tests/alert_test.c diff --git a/sw/device/tests/autogen/plic_all_irqs_test.c b/hw/top_earlgrey/sw/autogen/tests/plic_all_irqs_test.c similarity index 100% rename from sw/device/tests/autogen/plic_all_irqs_test.c rename to hw/top_earlgrey/sw/autogen/tests/plic_all_irqs_test.c diff --git a/sw/device/tests/sival/BUILD b/sw/device/tests/sival/BUILD index 9ff56268ef160..46707b3dc0108 100644 --- a/sw/device/tests/sival/BUILD +++ b/sw/device/tests/sival/BUILD @@ -19,6 +19,9 @@ test_suite( test_suite( name = "sv2_tests", tests = [ + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_0", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_10", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_20", "//sw/device/silicon_creator/lib:otbn_boot_services_functest", "//sw/device/tests:aes_smoketest", "//sw/device/tests:aon_timer_irq_test", @@ -63,9 +66,6 @@ test_suite( "//sw/device/tests:sram_ctrl_smoketest", "//sw/device/tests:uart_smoketest", "//sw/device/tests:uart_tx_rx_test", - "//sw/device/tests/autogen:plic_all_irqs_test_0", - "//sw/device/tests/autogen:plic_all_irqs_test_10", - "//sw/device/tests/autogen:plic_all_irqs_test_20", "//sw/device/tests/crypto:aes_kwp_functest", "//sw/device/tests/crypto:aes_kwp_kat_functest", "//sw/device/tests/crypto:ecdh_p256_sideload_functest", @@ -78,6 +78,8 @@ test_suite( test_suite( name = "sv3_tests", tests = [ + "//hw/top_earlgrey/sw/autogen/tests:alert_test", + "//hw/top_earlgrey/sw/autogen/tests:plic_all_irqs_test_0", "//sw/device/silicon_creator/rom/e2e:rom_e2e_smoke", "//sw/device/tests:aes_entropy_test", "//sw/device/tests:aes_idle_test", @@ -208,8 +210,6 @@ test_suite( "//sw/device/tests:usbdev_stream_test", "//sw/device/tests:usbdev_test", "//sw/device/tests:usbdev_vbus_test", - "//sw/device/tests/autogen:alert_test", - "//sw/device/tests/autogen:plic_all_irqs_test_0", "//sw/device/tests/crypto:aes_functest", "//sw/device/tests/crypto:aes_kwp_sideload_functest", "//sw/device/tests/crypto:aes_sideload_functest", diff --git a/util/topgen.py b/util/topgen.py index abbb59bd394f7..77e831b64d499 100755 --- a/util/topgen.py +++ b/util/topgen.py @@ -1397,6 +1397,26 @@ def render_template(template_path: str, rendered_path: Path, path / "data" / "autogen" / "defs.bzl", gencmd=gencmd_bzl) + # Auto-generate tests in "sw/device/tests/autogen" area. + for fname in ["plic_all_irqs_test.c", "BUILD"]: + # TODO(#25752): Delay generating tests until multi-top SW generation + # is designed and implemented. + if fname == "BUILD" and topname != "earlgrey": + continue + outfile = cformat_dir / "tests" / fname + render_template(TOPGEN_TEMPLATE_PATH / f"{fname}.tpl", + outfile, + helper=c_helper, + gencmd=gencmd_c) + + # Render alert tests only if there is really an alert handler + if lib.find_module(completecfg['module'], 'alert_handler'): + outfile = cformat_dir / "tests" / "alert_test.c" + render_template(TOPGEN_TEMPLATE_PATH / "alert_test.c.tpl", + outfile, + helper=c_helper, + gencmd=gencmd_c) + # generate chip level xbar and alert_handler TB tb_files = [ "xbar_env_pkg__params.sv", "tb__xbar_connect.sv", @@ -1434,23 +1454,6 @@ def render_template(template_path: str, rendered_path: Path, # generate documentation for toplevel gen_top_docs(completecfg, c_helper, out_path) - # Auto-generate tests in "sw/device/tests/autogen" area. - gencmd = warnhdr + GENCMD.format(top_name=top_name) - for fname in ["plic_all_irqs_test.c", "BUILD"]: - outfile = SRCTREE_TOP / "sw/device/tests/autogen" / fname - render_template(TOPGEN_TEMPLATE_PATH / f"{fname}.tpl", - outfile, - helper=c_helper, - gencmd=gencmd) - - # Render alert tests only if there is really an alert handler - if lib.find_module(completecfg['module'], 'alert_handler'): - outfile = SRCTREE_TOP / "sw/device/tests/autogen" / "alert_test.c" - render_template(TOPGEN_TEMPLATE_PATH / "alert_test.c.tpl", - outfile, - helper=c_helper, - gencmd=gencmd) - if __name__ == "__main__": main() diff --git a/util/topgen/templates/toplevel.c.tpl b/util/topgen/templates/toplevel.c.tpl index b254b33eb5f1e..6a568da29f288 100644 --- a/util/topgen/templates/toplevel.c.tpl +++ b/util/topgen/templates/toplevel.c.tpl @@ -26,4 +26,4 @@ ${helper.alert_mapping.render_definition()} * This array is a mapping from `${helper.plic_interrupts.name.as_c_type()}` to * `${helper.plic_sources.name.as_c_type()}`. */ -${helper.plic_mapping.render_definition()} \ No newline at end of file +${helper.plic_mapping.render_definition()}\ From 0c08d49a885eebfbffa274c1b4c87a768087abde Mon Sep 17 00:00:00 2001 From: Alexander Williams Date: Mon, 23 Dec 2024 15:58:33 -0800 Subject: [PATCH 2/2] [englishbreakfast] Convert to ordinary topgen flow Convert englishbreakfast to use the ordinary topgen flow. Commit the generated code like other tops. Remove the fileset_top and fileset_topgen flags, in addition to the topgen-fusesoc.py script. The fileset_top and fileset_topgen flags are now completely unused, since all the IPs that once depended on them have been reimplemented as ipgen cores. Remove the cruft. Signed-off-by: Alexander Williams --- .gitignore | 7 - BUILD.bazel | 2 - ci/scripts/build-bitstream-vivado.sh | 11 +- ci/scripts/build-chip-verilator.sh | 5 +- doc/getting_started/setup_fpga.md | 2 +- hw/Makefile | 2 +- hw/top_englishbreakfast/README.md | 3 + .../chip_englishbreakfast_cw305.core | 7 +- .../chip_englishbreakfast_verilator.core | 1 - hw/top_englishbreakfast/data/autogen/BUILD | 10 + hw/top_englishbreakfast/data/autogen/defs.bzl | 55 + .../autogen/top_englishbreakfast.gen.hjson | 12779 ++++++ .../dv/autogen/rstmgr_tgl_excl.cfg | 31 + .../dv/autogen/tb__alert_handler_connect.sv | 34 + .../dv/autogen/tb__xbar_connect.sv | 136 + .../dv/autogen/xbar_env_pkg__params.sv | 108 + .../dv/autogen/xbar_tgl_excl.cfg | 98 + .../dv/env/autogen/chip_env_pkg__params.sv | 38 + hw/top_englishbreakfast/ip/ast/README.md | 1 + hw/top_englishbreakfast/ip/ast/ast_regs.html | 1 + hw/top_englishbreakfast/ip/ast/data | 1 + hw/top_englishbreakfast/ip/ast/data/ast.hjson | 1 - hw/top_englishbreakfast/ip/ast/doc | 1 + .../ip/ast/rtl/ast_reg_pkg.sv | 380 + .../ip/ast/rtl/ast_reg_top.sv | 1969 + .../ip/sensor_ctrl/README.md | 1 + hw/top_englishbreakfast/ip/sensor_ctrl/data | 1 + .../ip/sensor_ctrl/data/sensor_ctrl.hjson | 1 - hw/top_englishbreakfast/ip/sensor_ctrl/doc | 1 + .../data/autogen/xbar_main.gen.hjson | 333 + .../ip/xbar_main/data/autogen/xbar_main.hjson | 95 + .../xbar_main/dv/autogen/tb__xbar_connect.sv | 34 + .../ip/xbar_main/dv/autogen/xbar_cov_excl.el | 23 + .../ip/xbar_main/dv/autogen/xbar_cover.cfg | 63 + .../dv/autogen/xbar_env_pkg__params.sv | 63 + .../xbar_main/dv/autogen/xbar_main_bind.core | 19 + .../ip/xbar_main/dv/autogen/xbar_main_bind.sv | 90 + .../xbar_main/dv/autogen/xbar_main_sim.core | 30 + .../dv/autogen/xbar_main_sim_cfg.hjson | 31 + .../ip/xbar_main/rtl/autogen/tl_main_pkg.sv | 59 + .../ip/xbar_main/rtl/autogen/xbar_main.sv | 344 + .../ip/xbar_main/xbar_main.core | 25 + .../data/autogen/xbar_peri.gen.hjson | 339 + .../ip/xbar_peri/data/autogen/xbar_peri.hjson | 95 + .../xbar_peri/dv/autogen/tb__xbar_connect.sv | 37 + .../ip/xbar_peri/dv/autogen/xbar_cov_excl.el | 14 + .../ip/xbar_peri/dv/autogen/xbar_cover.cfg | 70 + .../dv/autogen/xbar_env_pkg__params.sv | 62 + .../xbar_peri/dv/autogen/xbar_peri_bind.core | 19 + .../ip/xbar_peri/dv/autogen/xbar_peri_bind.sv | 90 + .../xbar_peri/dv/autogen/xbar_peri_sim.core | 30 + .../dv/autogen/xbar_peri_sim_cfg.hjson | 31 + .../ip/xbar_peri/rtl/autogen/tl_peri_pkg.sv | 57 + .../ip/xbar_peri/rtl/autogen/xbar_peri.sv | 239 + .../ip/xbar_peri/xbar_peri.core | 25 + .../ip_autogen/clkmgr/BUILD | 10 + .../ip_autogen/clkmgr/README.md | 18 + .../ip_autogen/clkmgr/clkmgr.core | 71 + .../ip_autogen/clkmgr/clkmgr_pkg.core | 21 + .../ip_autogen/clkmgr/clkmgr_reg.core | 23 + .../ip_autogen/clkmgr/data/clkmgr.hjson | 884 + .../clkmgr/data/clkmgr_sec_cm_testplan.hjson | 190 + .../clkmgr/data/clkmgr_testplan.hjson | 334 + ...top_englishbreakfast_clkmgr.ipconfig.hjson | 243 + .../ip_autogen/clkmgr/defs.bzl | 9 + .../ip_autogen/clkmgr/doc/checklist.md | 271 + .../clkmgr/doc/clkmgr_block_diagram.svg | 1 + .../clkmgr/doc/clkmgr_rst_domain.svg | 1 + .../clkmgr/doc/example_chip_partition.svg | 1 + .../ip_autogen/clkmgr/doc/interfaces.md | 59 + .../clkmgr/doc/programmers_guide.md | 17 + .../ip_autogen/clkmgr/doc/registers.md | 460 + .../clkmgr/doc/theory_of_operation.md | 293 + .../ip_autogen/clkmgr/dv/README.md | 187 + .../ip_autogen/clkmgr/dv/clkmgr_sim.core | 30 + .../ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson | 136 + .../clkmgr/dv/cov/clkmgr_cov_bind.sv | 38 + .../clkmgr/dv/cov/clkmgr_cov_manual_excl.el | 49 + .../clkmgr/dv/cov/clkmgr_cov_unr_excl.el | 200 + .../clkmgr/dv/cov/clkmgr_tgl_excl.cfg | 17 + .../ip_autogen/clkmgr/dv/doc/tb.svg | 1 + .../clkmgr/dv/env/clkmgr_csrs_if.sv | 23 + .../ip_autogen/clkmgr/dv/env/clkmgr_env.core | 50 + .../ip_autogen/clkmgr/dv/env/clkmgr_env.sv | 67 + .../clkmgr/dv/env/clkmgr_env_cfg.sv | 45 + .../clkmgr/dv/env/clkmgr_env_cov.sv | 190 + .../clkmgr/dv/env/clkmgr_env_pkg.sv | 151 + .../ip_autogen/clkmgr/dv/env/clkmgr_if.sv | 362 + .../clkmgr/dv/env/clkmgr_scoreboard.sv | 398 + .../clkmgr/dv/env/clkmgr_virtual_sequencer.sv | 14 + .../clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv | 456 + .../dv/env/seq_lib/clkmgr_clk_status_vseq.sv | 35 + .../dv/env/seq_lib/clkmgr_common_vseq.sv | 70 + .../dv/env/seq_lib/clkmgr_extclk_vseq.sv | 241 + .../seq_lib/clkmgr_frequency_timeout_vseq.sv | 142 + .../dv/env/seq_lib/clkmgr_frequency_vseq.sv | 236 + .../clkmgr/dv/env/seq_lib/clkmgr_peri_vseq.sv | 51 + .../dv/env/seq_lib/clkmgr_regwen_vseq.sv | 82 + .../dv/env/seq_lib/clkmgr_smoke_vseq.sv | 108 + .../dv/env/seq_lib/clkmgr_stress_all_vseq.sv | 44 + .../dv/env/seq_lib/clkmgr_trans_vseq.sv | 96 + .../clkmgr/dv/env/seq_lib/clkmgr_vseq_list.sv | 15 + .../clkmgr/dv/sva/clkmgr_aon_cg_en_sva_if.sv | 10 + .../ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv | 323 + .../clkmgr/dv/sva/clkmgr_cg_en_sva_if.sv | 30 + .../clkmgr/dv/sva/clkmgr_div_sva_if.sv | 68 + .../clkmgr/dv/sva/clkmgr_extclk_sva_if.sv | 81 + .../dv/sva/clkmgr_gated_clock_sva_if.sv | 26 + .../sva/clkmgr_lost_calib_ctrl_en_sva_if.sv | 22 + .../dv/sva/clkmgr_lost_calib_regwen_sva_if.sv | 17 + .../dv/sva/clkmgr_sec_cm_checker_assert.sv | 59 + .../ip_autogen/clkmgr/dv/sva/clkmgr_sva.core | 40 + .../clkmgr/dv/sva/clkmgr_sva_ifs.core | 28 + .../clkmgr/dv/sva/clkmgr_trans_sva_if.sv | 35 + .../ip_autogen/clkmgr/dv/tb.sv | 211 + .../clkmgr/dv/tests/clkmgr_base_test.sv | 20 + .../clkmgr/dv/tests/clkmgr_test.core | 19 + .../clkmgr/dv/tests/clkmgr_test_pkg.sv | 22 + .../ip_autogen/clkmgr/lint/clkmgr.vlt | 5 + .../ip_autogen/clkmgr/lint/clkmgr.waiver | 21 + .../ip_autogen/clkmgr/rtl/clkmgr.sv | 983 + .../ip_autogen/clkmgr/rtl/clkmgr_byp.sv | 163 + .../clkmgr/rtl/clkmgr_clk_status.sv | 58 + .../ip_autogen/clkmgr/rtl/clkmgr_meas_chk.sv | 127 + .../ip_autogen/clkmgr/rtl/clkmgr_pkg.sv | 74 + .../ip_autogen/clkmgr/rtl/clkmgr_reg_pkg.sv | 330 + .../ip_autogen/clkmgr/rtl/clkmgr_reg_top.sv | 2291 + .../ip_autogen/clkmgr/rtl/clkmgr_root_ctrl.sv | 41 + .../ip_autogen/clkmgr/rtl/clkmgr_trans.sv | 175 + .../ip_autogen/flash_ctrl/BUILD | 10 + .../ip_autogen/flash_ctrl/README.md | 195 + .../flash_ctrl/data/flash_ctrl.hjson | 3223 ++ .../data/flash_ctrl_sec_cm_testplan.hjson | 319 + .../flash_ctrl/data/flash_ctrl_testplan.hjson | 499 + ...englishbreakfast_flash_ctrl.ipconfig.hjson | 30 + .../ip_autogen/flash_ctrl/defs.bzl | 9 + .../ip_autogen/flash_ctrl/doc/checklist.md | 267 + .../flash_ctrl/doc/flash_abstraction.svg | 1 + .../flash_ctrl/doc/flash_block_diagram.svg | 1 + .../flash_ctrl/doc/flash_boundaries.svg | 1 + .../flash_ctrl/doc/flash_integrity.svg | 1 + .../flash_ctrl/doc/flash_partitions.svg | 1 + .../doc/flash_protocol_controller.svg | 1 + .../flash_ctrl/doc/flash_read_pipeline.svg | 1 + .../ip_autogen/flash_ctrl/doc/interfaces.md | 141 + .../flash_ctrl/doc/programmers_guide.md | 75 + .../ip_autogen/flash_ctrl/doc/registers.md | 2122 + .../flash_ctrl/doc/theory_of_operation.md | 528 + .../ip_autogen/flash_ctrl/dv/README.md | 209 + .../flash_ctrl/dv/cov/flash_ctrl_cov.core | 21 + .../flash_ctrl/dv/cov/flash_ctrl_cov.vRefine | 45 + .../flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv | 35 + .../dv/cov/flash_ctrl_phy_cov_if.sv | 95 + .../ip_autogen/flash_ctrl/dv/doc/tb.svg | 1 + .../flash_ctrl/dv/env/flash_ctrl_dv_if.sv | 19 + .../dv/env/flash_ctrl_eflash_ral_pkg.sv | 61 + .../flash_ctrl/dv/env/flash_ctrl_env.core | 113 + .../flash_ctrl/dv/env/flash_ctrl_env.sv | 102 + .../flash_ctrl/dv/env/flash_ctrl_env_cfg.sv | 1297 + .../flash_ctrl/dv/env/flash_ctrl_env_cov.sv | 132 + .../flash_ctrl/dv/env/flash_ctrl_env_pkg.sv | 570 + .../flash_ctrl/dv/env/flash_ctrl_if.sv | 79 + .../flash_ctrl/dv/env/flash_ctrl_mem_if.sv | 18 + .../dv/env/flash_ctrl_otf_scoreboard.sv | 576 + .../dv/env/flash_ctrl_scoreboard.sv | 947 + .../flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv | 289 + .../dv/env/flash_ctrl_virtual_sequencer.sv | 22 + .../flash_ctrl/dv/env/flash_mem_addr_attrs.sv | 53 + .../flash_ctrl/dv/env/flash_mem_bkdr_util.sv | 38 + .../flash_ctrl/dv/env/flash_otf_item.sv | 270 + .../flash_ctrl/dv/env/flash_otf_mem_entry.sv | 15 + .../flash_ctrl/dv/env/flash_otf_read_entry.sv | 134 + .../flash_ctrl_access_after_disable_vseq.sv | 63 + .../dv/env/seq_lib/flash_ctrl_base_vseq.sv | 1690 + .../env/seq_lib/flash_ctrl_callback_vseq.sv | 17 + .../dv/env/seq_lib/flash_ctrl_common_vseq.sv | 257 + .../seq_lib/flash_ctrl_config_regwen_vseq.sv | 88 + .../dv/env/seq_lib/flash_ctrl_connect_vseq.sv | 86 + .../seq_lib/flash_ctrl_derr_detect_vseq.sv | 70 + .../dv/env/seq_lib/flash_ctrl_disable_vseq.sv | 55 + .../seq_lib/flash_ctrl_erase_suspend_vseq.sv | 300 + .../env/seq_lib/flash_ctrl_err_base_vseq.sv | 56 + .../env/seq_lib/flash_ctrl_error_mp_vseq.sv | 510 + .../flash_ctrl_error_prog_type_vseq.sv | 279 + .../seq_lib/flash_ctrl_error_prog_win_vseq.sv | 159 + .../env/seq_lib/flash_ctrl_fetch_code_vseq.sv | 345 + .../flash_ctrl_filesystem_support_vseq.sv | 277 + .../flash_ctrl_full_mem_access_vseq.sv | 199 + .../flash_ctrl_host_addr_infection_vseq.sv | 79 + .../seq_lib/flash_ctrl_host_ctrl_arb_vseq.sv | 250 + .../seq_lib/flash_ctrl_host_dir_rd_vseq.sv | 208 + .../flash_ctrl_hw_prog_rma_wipe_err_vseq.sv | 95 + .../flash_ctrl_hw_read_seed_err_vseq.sv | 80 + .../env/seq_lib/flash_ctrl_hw_rma_err_vseq.sv | 140 + .../seq_lib/flash_ctrl_hw_rma_reset_vseq.sv | 130 + .../dv/env/seq_lib/flash_ctrl_hw_rma_vseq.sv | 338 + .../env/seq_lib/flash_ctrl_hw_sec_otp_vseq.sv | 307 + .../flash_ctrl_info_part_access_vseq.sv | 189 + .../env/seq_lib/flash_ctrl_integrity_vseq.sv | 66 + .../dv/env/seq_lib/flash_ctrl_intr_rd_vseq.sv | 48 + .../dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv | 29 + .../env/seq_lib/flash_ctrl_invalid_op_vseq.sv | 236 + .../env/seq_lib/flash_ctrl_lcmgr_intg_vseq.sv | 43 + .../seq_lib/flash_ctrl_legacy_base_vseq.sv | 70 + .../env/seq_lib/flash_ctrl_mid_op_rst_vseq.sv | 304 + .../env/seq_lib/flash_ctrl_mp_regions_vseq.sv | 415 + .../env/seq_lib/flash_ctrl_otf_base_vseq.sv | 1555 + .../env/seq_lib/flash_ctrl_otp_reset_vseq.sv | 184 + .../seq_lib/flash_ctrl_oversize_error_vseq.sv | 82 + .../flash_ctrl_phy_ack_consistency_vseq.sv | 73 + .../seq_lib/flash_ctrl_phy_arb_redun_vseq.sv | 172 + .../dv/env/seq_lib/flash_ctrl_phy_arb_vseq.sv | 299 + .../flash_ctrl_phy_host_grant_err_vseq.sv | 90 + .../env/seq_lib/flash_ctrl_prog_reset_vseq.sv | 113 + .../seq_lib/flash_ctrl_rand_ops_base_vseq.sv | 409 + .../env/seq_lib/flash_ctrl_rand_ops_vseq.sv | 47 + .../seq_lib/flash_ctrl_rd_buff_evict_vseq.sv | 477 + .../dv/env/seq_lib/flash_ctrl_rd_ooo_vseq.sv | 91 + .../seq_lib/flash_ctrl_rd_path_intg_vseq.sv | 89 + .../env/seq_lib/flash_ctrl_re_evict_vseq.sv | 13 + .../seq_lib/flash_ctrl_read_rnd_wd_vseq.sv | 27 + .../flash_ctrl_read_word_sweep_vseq.sv | 69 + .../dv/env/seq_lib/flash_ctrl_ro_vseq.sv | 48 + .../env/seq_lib/flash_ctrl_rw_evict_vseq.sv | 130 + .../env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv | 59 + .../dv/env/seq_lib/flash_ctrl_rw_vseq.sv | 56 + .../seq_lib/flash_ctrl_serr_address_vseq.sv | 32 + .../seq_lib/flash_ctrl_serr_counter_vseq.sv | 18 + .../env/seq_lib/flash_ctrl_smoke_hw_vseq.sv | 104 + .../dv/env/seq_lib/flash_ctrl_smoke_vseq.sv | 46 + .../env/seq_lib/flash_ctrl_stress_all_vseq.sv | 36 + .../dv/env/seq_lib/flash_ctrl_sw_op_vseq.sv | 166 + .../dv/env/seq_lib/flash_ctrl_vseq_list.sv | 67 + .../dv/env/seq_lib/flash_ctrl_wo_vseq.sv | 25 + .../seq_lib/flash_ctrl_wr_path_intg_vseq.sv | 127 + .../seq_lib/flash_ctrl_write_rnd_wd_vseq.sv | 30 + .../flash_ctrl_write_word_sweep_vseq.sv | 34 + .../dv/flash_ctrl_base_sim_cfg.hjson | 503 + .../flash_ctrl/dv/flash_ctrl_sim.core | 38 + .../flash_ctrl/dv/flash_ctrl_sim_cfg.hjson | 18 + .../flash_ctrl/dv/sva/flash_ctrl_bind.sv | 23 + .../flash_ctrl/dv/sva/flash_ctrl_sva.core | 40 + .../ip_autogen/flash_ctrl/dv/tb/tb.sv | 350 + .../dv/tests/flash_ctrl_base_test.sv | 103 + .../flash_ctrl/dv/tests/flash_ctrl_test.core | 19 + .../dv/tests/flash_ctrl_test_pkg.sv | 22 + .../flash_ctrl/dv/tools/xcelium/xfile | 1 + .../ip_autogen/flash_ctrl/flash_ctrl.core | 96 + .../ip_autogen/flash_ctrl/flash_ctrl_pkg.core | 59 + .../flash_ctrl/flash_ctrl_prim_reg_top.core | 29 + .../ip_autogen/flash_ctrl/flash_ctrl_reg.core | 20 + .../ip_autogen/flash_ctrl/lint/flash_ctrl.vlt | 27 + .../flash_ctrl/lint/flash_ctrl.waiver | 24 + .../flash_ctrl/lint/flash_ctrl_pkg.vlt | 5 + .../flash_ctrl/lint/flash_ctrl_pkg.waiver | 8 + .../ip_autogen/flash_ctrl/rtl/flash_ctrl.sv | 1501 + .../flash_ctrl/rtl/flash_ctrl_arb.sv | 280 + .../flash_ctrl/rtl/flash_ctrl_core_reg_top.sv | 13753 ++++++ .../flash_ctrl/rtl/flash_ctrl_erase.sv | 69 + .../flash_ctrl/rtl/flash_ctrl_info_cfg.sv | 133 + .../flash_ctrl/rtl/flash_ctrl_lcmgr.sv | 947 + .../flash_ctrl/rtl/flash_ctrl_mem_reg_top.sv | 42 + .../flash_ctrl/rtl/flash_ctrl_pkg.sv | 628 + .../flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv | 2389 + .../flash_ctrl/rtl/flash_ctrl_prog.sv | 195 + .../flash_ctrl/rtl/flash_ctrl_rd.sv | 185 + .../flash_ctrl/rtl/flash_ctrl_reg_pkg.sv | 1540 + .../flash_ctrl/rtl/flash_ctrl_region_cfg.sv | 171 + .../ip_autogen/flash_ctrl/rtl/flash_mp.sv | 377 + .../rtl/flash_mp_data_region_sel.sv | 58 + .../ip_autogen/flash_ctrl/rtl/flash_phy.sv | 401 + .../flash_ctrl/rtl/flash_phy_core.sv | 604 + .../flash_ctrl/rtl/flash_phy_erase.sv | 87 + .../flash_ctrl/rtl/flash_phy_pkg.sv | 156 + .../flash_ctrl/rtl/flash_phy_prog.sv | 390 + .../ip_autogen/flash_ctrl/rtl/flash_phy_rd.sv | 851 + .../flash_ctrl/rtl/flash_phy_rd_buf_dep.sv | 128 + .../flash_ctrl/rtl/flash_phy_rd_buffers.sv | 70 + .../flash_ctrl/rtl/flash_phy_scramble.sv | 239 + .../ip_autogen/pinmux/BUILD | 10 + .../ip_autogen/pinmux/README.md | 29 + .../ip_autogen/pinmux/data/pinmux.hjson | 1153 + .../pinmux/data/pinmux_fpv_testplan.hjson | 883 + .../pinmux/data/pinmux_sec_cm_testplan.hjson | 69 + ...top_englishbreakfast_pinmux.ipconfig.hjson | 22 + .../ip_autogen/pinmux/defs.bzl | 9 + .../ip_autogen/pinmux/doc/checklist.md | 267 + .../ip_autogen/pinmux/doc/dv/README.md | 35 + .../ip_autogen/pinmux/doc/dv/fpv.svg | 1 + .../pinmux/doc/generic_pad_wrapper.svg | 1 + .../ip_autogen/pinmux/doc/interfaces.md | 97 + .../pinmux/doc/pinmux_muxing_matrix.svg | 1 + .../doc/pinmux_overview_block_diagram.svg | 1 + .../ip_autogen/pinmux/doc/pinout_cw305.md | 107 + .../pinmux/doc/programmers_guide.md | 115 + .../ip_autogen/pinmux/doc/registers.md | 1813 + .../ip_autogen/pinmux/doc/targets.md | 9 + .../pinmux/doc/theory_of_operation.md | 215 + .../fpv/pinmux_chip_expected_failure.hjson | 12 + .../pinmux/fpv/pinmux_chip_fpv.core | 44 + .../pinmux/fpv/pinmux_common_fpv.core | 28 + .../pinmux/fpv/pinmux_expected_failure.hjson | 12 + .../ip_autogen/pinmux/fpv/pinmux_fpv.core | 38 + .../pinmux/fpv/tb/pinmux_bind_fpv.sv | 86 + .../pinmux/fpv/tb/pinmux_chip_tb.sv | 242 + .../ip_autogen/pinmux/fpv/tb/pinmux_tb.sv | 108 + .../pinmux/fpv/vip/pinmux_assert_fpv.sv | 730 + .../ip_autogen/pinmux/lint/pinmux.vlt | 5 + .../ip_autogen/pinmux/lint/pinmux.waiver | 41 + .../ip_autogen/pinmux/pinmux.core | 94 + .../ip_autogen/pinmux/pinmux_pkg.core | 23 + .../ip_autogen/pinmux/pinmux_reg.core | 21 + .../ip_autogen/pinmux/rtl/pinmux.sv | 692 + .../pinmux/rtl/pinmux_jtag_breakout.sv | 24 + .../ip_autogen/pinmux/rtl/pinmux_jtag_buf.sv | 37 + .../ip_autogen/pinmux/rtl/pinmux_pkg.sv | 78 + .../ip_autogen/pinmux/rtl/pinmux_reg_pkg.sv | 2531 ++ .../ip_autogen/pinmux/rtl/pinmux_reg_top.sv | 37746 ++++++++++++++++ .../pinmux/rtl/pinmux_strap_sampling.sv | 454 + .../ip_autogen/pinmux/rtl/pinmux_wkup.sv | 91 + .../ip_autogen/pinmux/syn/constraints.sdc | 58 + .../pinmux/syn/pinmux_syn_cfg.hjson | 19 + .../ip_autogen/pwrmgr/BUILD | 10 + .../ip_autogen/pwrmgr/README.md | 36 + .../ip_autogen/pwrmgr/data/pwrmgr.hjson | 847 + .../pwrmgr/data/pwrmgr_sec_cm_testplan.hjson | 219 + .../pwrmgr/data/pwrmgr_testplan.hjson | 369 + ...top_englishbreakfast_pwrmgr.ipconfig.hjson | 66 + .../ip_autogen/pwrmgr/defs.bzl | 9 + .../ip_autogen/pwrmgr/doc/checklist.md | 266 + .../ip_autogen/pwrmgr/doc/interfaces.md | 67 + .../pwrmgr/doc/programmers_guide.md | 81 + .../pwrmgr/doc/pwrmgr_connectivity.svg | 1 + .../ip_autogen/pwrmgr/doc/pwrmgr_fsms.svg | 1 + .../ip_autogen/pwrmgr/doc/registers.md | 427 + .../pwrmgr/doc/theory_of_operation.md | 304 + .../ip_autogen/pwrmgr/dv/README.md | 255 + .../pwrmgr/dv/cov/pwrmgr_cov_bind.sv | 33 + .../pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el | 34 + .../pwrmgr/dv/cov/pwrmgr_tgl_excl.cfg | 9 + .../ip_autogen/pwrmgr/dv/doc/tb.svg | 1 + .../ip_autogen/pwrmgr/dv/env/pwrmgr_env.core | 57 + .../ip_autogen/pwrmgr/dv/env/pwrmgr_env.sv | 57 + .../pwrmgr/dv/env/pwrmgr_env_cfg.sv | 52 + .../pwrmgr/dv/env/pwrmgr_env_cov.sv | 193 + .../pwrmgr/dv/env/pwrmgr_env_pkg.sv | 89 + .../ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv | 219 + .../pwrmgr/dv/env/pwrmgr_scoreboard.sv | 367 + .../pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv | 14 + .../seq_lib/pwrmgr_aborted_low_power_vseq.sv | 126 + .../pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv | 843 + .../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 + .../seq_lib/pwrmgr_escalation_timeout_vseq.sv | 88 + .../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 | 138 + .../pwrmgr_repeat_wakeup_reset_vseq.sv | 79 + .../env/seq_lib/pwrmgr_reset_invalid_vseq.sv | 129 + .../dv/env/seq_lib/pwrmgr_reset_vseq.sv | 79 + .../pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv | 48 + .../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 | 23 + .../env/seq_lib/pwrmgr_wakeup_reset_vseq.sv | 168 + .../dv/env/seq_lib/pwrmgr_wakeup_vseq.sv | 130 + .../ip_autogen/pwrmgr/dv/pwrmgr_sim.core | 30 + .../ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson | 161 + .../pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv | 145 + .../ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv | 86 + .../dv/sva/pwrmgr_clock_enables_sva_if.sv | 59 + .../pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv | 102 + .../dv/sva/pwrmgr_sec_cm_checker_assert.sv | 165 + .../ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core | 43 + .../pwrmgr/dv/sva/pwrmgr_unit_only_bind.sv | 23 + .../pwrmgr/dv/sva/pwrmgr_unit_only_sva.core | 36 + .../ip_autogen/pwrmgr/dv/tb.sv | 140 + .../pwrmgr/dv/tests/pwrmgr_base_test.sv | 20 + .../pwrmgr/dv/tests/pwrmgr_test.core | 19 + .../pwrmgr/dv/tests/pwrmgr_test_pkg.sv | 22 + .../ip_autogen/pwrmgr/lint/pwrmgr.vlt | 5 + .../ip_autogen/pwrmgr/lint/pwrmgr.waiver | 5 + .../ip_autogen/pwrmgr/lint/pwrmgr_pkg.vlt | 12 + .../ip_autogen/pwrmgr/pwrmgr.core | 81 + .../ip_autogen/pwrmgr/pwrmgr_pkg.core | 32 + .../ip_autogen/pwrmgr/pwrmgr_reg.core | 21 + .../ip_autogen/pwrmgr/rtl/pwrmgr.sv | 760 + .../ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv | 335 + .../ip_autogen/pwrmgr/rtl/pwrmgr_cdc_pulse.sv | 91 + .../ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv | 542 + .../ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv | 272 + .../ip_autogen/pwrmgr/rtl/pwrmgr_reg_pkg.sv | 277 + .../ip_autogen/pwrmgr/rtl/pwrmgr_reg_top.sv | 1241 + .../ip_autogen/pwrmgr/rtl/pwrmgr_slow_fsm.sv | 358 + .../ip_autogen/pwrmgr/rtl/pwrmgr_wake_info.sv | 74 + .../ip_autogen/pwrmgr/util/reg_pwrmgr.py | 42 + .../ip_autogen/rstmgr/BUILD | 10 + .../ip_autogen/rstmgr/README.md | 29 + .../rstmgr/data/rstmgr.cfg.example.hjson | 48 + .../ip_autogen/rstmgr/data/rstmgr.hjson | 605 + .../rstmgr/data/rstmgr_sec_cm_testplan.hjson | 108 + .../rstmgr/data/rstmgr_testplan.hjson | 247 + ...top_englishbreakfast_rstmgr.ipconfig.hjson | 459 + .../ip_autogen/rstmgr/defs.bzl | 9 + .../ip_autogen/rstmgr/doc/checklist.md | 266 + .../ip_autogen/rstmgr/doc/interfaces.md | 55 + .../rstmgr/doc/programmers_guide.md | 5 + .../ip_autogen/rstmgr/doc/registers.md | 316 + .../ip_autogen/rstmgr/doc/reset_topology.svg | 1 + .../rstmgr/doc/theory_of_operation.md | 305 + .../ip_autogen/rstmgr/dv/README.md | 121 + .../rstmgr/dv/cov/rstmgr_cov_bind.sv | 13 + .../ip_autogen/rstmgr/dv/cov/rstmgr_cover.cfg | 9 + .../rstmgr/dv/cov/rstmgr_tgl_excl.cfg | 34 + .../rstmgr/dv/cov/rstmgr_unr_excl.el | 88 + .../ip_autogen/rstmgr/dv/doc/tb.svg | 1 + .../ip_autogen/rstmgr/dv/env/rstmgr_env.core | 54 + .../ip_autogen/rstmgr/dv/env/rstmgr_env.sv | 67 + .../rstmgr/dv/env/rstmgr_env_cfg.sv | 37 + .../rstmgr/dv/env/rstmgr_env_cov.sv | 104 + .../rstmgr/dv/env/rstmgr_env_pkg.sv | 110 + .../ip_autogen/rstmgr/dv/env/rstmgr_if.sv | 69 + .../rstmgr/dv/env/rstmgr_scoreboard.sv | 312 + .../rstmgr/dv/env/rstmgr_virtual_sequencer.sv | 14 + .../rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv | 556 + .../dv/env/seq_lib/rstmgr_common_vseq.sv | 15 + .../env/seq_lib/rstmgr_leaf_rst_cnsty_vseq.sv | 228 + .../rstmgr_leaf_rst_shadow_attack_vseq.sv | 84 + .../env/seq_lib/rstmgr_por_stretcher_vseq.sv | 43 + .../dv/env/seq_lib/rstmgr_reset_vseq.sv | 189 + .../rstmgr_sec_cm_scan_intersig_mubi_vseq.sv | 52 + .../dv/env/seq_lib/rstmgr_smoke_vseq.sv | 116 + .../dv/env/seq_lib/rstmgr_stress_all_vseq.sv | 37 + .../seq_lib/rstmgr_sw_rst_reset_race_vseq.sv | 59 + .../dv/env/seq_lib/rstmgr_sw_rst_vseq.sv | 49 + .../rstmgr/dv/env/seq_lib/rstmgr_vseq_list.sv | 15 + .../dv/rstmgr_cnsty_chk/cov_manual_excl.el | 15 + .../dv/rstmgr_cnsty_chk/cov_unr_excl.el | 17 + .../data/rstmgr_cnsty_chk_testplan.hjson | 43 + .../rstmgr_cnsty_chk_sim.core | 32 + .../rstmgr_cnsty_chk_sim_cfg.hjson | 57 + .../rstmgr/dv/rstmgr_cnsty_chk/tb.sv | 471 + .../ip_autogen/rstmgr/dv/rstmgr_sim.core | 30 + .../ip_autogen/rstmgr/dv/rstmgr_sim_cfg.hjson | 113 + .../rstmgr/dv/sva/rstmgr_attrs_sva_if.sv | 19 + .../ip_autogen/rstmgr/dv/sva/rstmgr_bind.sv | 106 + .../rstmgr/dv/sva/rstmgr_cascading_sva_if.sv | 188 + .../dv/sva/rstmgr_rst_en_track_sva_if.sv | 243 + .../ip_autogen/rstmgr/dv/sva/rstmgr_sva.core | 35 + .../rstmgr/dv/sva/rstmgr_sva_ifs.core | 25 + .../rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv | 44 + .../ip_autogen/rstmgr/dv/tb.sv | 145 + .../rstmgr/dv/tests/rstmgr_base_test.sv | 20 + .../rstmgr/dv/tests/rstmgr_test.core | 19 + .../rstmgr/dv/tests/rstmgr_test_pkg.sv | 22 + .../ip_autogen/rstmgr/lint/rstmgr.vlt | 5 + .../ip_autogen/rstmgr/lint/rstmgr.waiver | 37 + .../ip_autogen/rstmgr/rstmgr.core | 69 + .../ip_autogen/rstmgr/rstmgr_cnsty_chk.core | 40 + .../ip_autogen/rstmgr/rstmgr_pkg.core | 22 + .../ip_autogen/rstmgr/rstmgr_reg.core | 21 + .../ip_autogen/rstmgr/rtl/rstmgr.sv | 969 + .../ip_autogen/rstmgr/rtl/rstmgr_cnsty_chk.sv | 273 + .../rstmgr/rtl/rstmgr_crash_info.sv | 60 + .../ip_autogen/rstmgr/rtl/rstmgr_ctrl.sv | 77 + .../ip_autogen/rstmgr/rtl/rstmgr_leaf_rst.sv | 134 + .../ip_autogen/rstmgr/rtl/rstmgr_pkg.sv | 99 + .../ip_autogen/rstmgr/rtl/rstmgr_por.sv | 106 + .../ip_autogen/rstmgr/rtl/rstmgr_reg_pkg.sv | 248 + .../ip_autogen/rstmgr/rtl/rstmgr_reg_top.sv | 1124 + .../ip_autogen/rv_plic/BUILD | 10 + .../ip_autogen/rv_plic/README.md | 26 + .../ip_autogen/rv_plic/data/rv_plic.hjson | 901 + .../rv_plic/data/rv_plic_fpv_testplan.hjson | 73 + .../data/rv_plic_sec_cm_testplan.hjson | 33 + ...op_englishbreakfast_rv_plic.ipconfig.hjson | 13 + .../ip_autogen/rv_plic/defs.bzl | 9 + .../ip_autogen/rv_plic/doc/block_diagram.svg | 1 + .../ip_autogen/rv_plic/doc/checklist.md | 264 + .../ip_autogen/rv_plic/doc/dv/README.md | 48 + .../ip_autogen/rv_plic/doc/dv/fpv.svg | 1 + .../rv_plic/doc/programmers_guide.md | 100 + .../rv_plic/doc/theory_of_operation.md | 118 + .../fpv/rv_plic_expected_failure.hjson | 12 + .../ip_autogen/rv_plic/fpv/rv_plic_fpv.core | 44 + .../rv_plic/fpv/tb/rv_plic_bind_fpv.sv | 47 + .../ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv | 40 + .../rv_plic/fpv/vip/rv_plic_assert_fpv.sv | 107 + .../ip_autogen/rv_plic/lint/rv_plic.vlt | 7 + .../ip_autogen/rv_plic/lint/rv_plic.waiver | 22 + .../ip_autogen/rv_plic/rtl/rv_plic.sv | 362 + .../ip_autogen/rv_plic/rtl/rv_plic_gateway.sv | 62 + .../ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv | 817 + .../ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv | 9369 ++++ .../ip_autogen/rv_plic/rtl/rv_plic_target.sv | 74 + .../ip_autogen/rv_plic/rv_plic.core | 40 + .../ip_autogen/rv_plic/rv_plic_component.core | 51 + .../lint/top_englishbreakfast_lint_cfgs.hjson | 25 +- hw/top_englishbreakfast/padring.core | 1 - hw/top_englishbreakfast/physical_pads.core | 1 - .../autogen/chip_englishbreakfast_cw305.sv | 1110 + .../rtl/autogen/top_englishbreakfast.sv | 1674 + .../rtl/autogen/top_englishbreakfast_pkg.sv | 562 + .../top_englishbreakfast_rnd_cnst_pkg.sv | 139 + .../rtl/autogen/top_racl_pkg.sv | 69 + hw/top_englishbreakfast/rtl/padring.sv | 1 - hw/top_englishbreakfast/rtl/physical_pads.sv | 1 - hw/top_englishbreakfast/rtl/top_pkg.sv | 1 - .../sw/autogen/.clang-format | 4 + hw/top_englishbreakfast/sw/autogen/BUILD | 28 + .../sw/autogen/chip/mod.rs | 5 + .../sw/autogen/chip/top_englishbreakfast.rs | 1682 + .../sw/autogen/tests/plic_all_irqs_test.c | 887 + .../sw/autogen/top_englishbreakfast.c | 108 + .../sw/autogen/top_englishbreakfast.h | 967 + .../sw/autogen/top_englishbreakfast_memory.h | 465 + .../sw/autogen/top_englishbreakfast_memory.ld | 59 + .../top_englishbreakfast.core | 12 +- .../top_englishbreakfast_padring.core | 12 +- .../top_englishbreakfast_physical_pads.core | 20 + .../top_englishbreakfast_pkg.core | 16 + hw/top_englishbreakfast/top_pkg.core | 3 - hw/top_englishbreakfast/util/prepare_sw.py | 1 - rules/fusesoc.bzl | 7 +- .../src/chip/autogen/englishbreakfast.rs | 282 + topgen.core | 17 - util/topgen-fusesoc.py | 164 - util/topgen.py | 3 +- util/topgen/c_test.py | 3 +- util/topgen/lib.py | 3 +- util/topgen/templates/toplevel.c.tpl | 2 +- util/topgen/templates/toplevel.h.tpl | 2 +- util/topgen/templates/toplevel.rs.tpl | 2 +- 536 files changed, 171614 insertions(+), 256 deletions(-) create mode 100644 hw/top_englishbreakfast/README.md create mode 100644 hw/top_englishbreakfast/data/autogen/BUILD create mode 100644 hw/top_englishbreakfast/data/autogen/defs.bzl create mode 100644 hw/top_englishbreakfast/data/autogen/top_englishbreakfast.gen.hjson create mode 100644 hw/top_englishbreakfast/dv/autogen/rstmgr_tgl_excl.cfg create mode 100644 hw/top_englishbreakfast/dv/autogen/tb__alert_handler_connect.sv create mode 100644 hw/top_englishbreakfast/dv/autogen/tb__xbar_connect.sv create mode 100644 hw/top_englishbreakfast/dv/autogen/xbar_env_pkg__params.sv create mode 100644 hw/top_englishbreakfast/dv/autogen/xbar_tgl_excl.cfg create mode 100644 hw/top_englishbreakfast/dv/env/autogen/chip_env_pkg__params.sv create mode 120000 hw/top_englishbreakfast/ip/ast/README.md create mode 120000 hw/top_englishbreakfast/ip/ast/ast_regs.html create mode 120000 hw/top_englishbreakfast/ip/ast/data delete mode 120000 hw/top_englishbreakfast/ip/ast/data/ast.hjson create mode 120000 hw/top_englishbreakfast/ip/ast/doc create mode 100644 hw/top_englishbreakfast/ip/ast/rtl/ast_reg_pkg.sv create mode 100644 hw/top_englishbreakfast/ip/ast/rtl/ast_reg_top.sv create mode 120000 hw/top_englishbreakfast/ip/sensor_ctrl/README.md create mode 120000 hw/top_englishbreakfast/ip/sensor_ctrl/data delete mode 120000 hw/top_englishbreakfast/ip/sensor_ctrl/data/sensor_ctrl.hjson create mode 120000 hw/top_englishbreakfast/ip/sensor_ctrl/doc create mode 100644 hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.gen.hjson create mode 100644 hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.hjson create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/tb__xbar_connect.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cov_excl.el create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cover.cfg create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.core create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim.core create mode 100644 hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/tl_main_pkg.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/xbar_main.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_main/xbar_main.core create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.gen.hjson create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.hjson create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/tb__xbar_connect.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cov_excl.el create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cover.cfg create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_env_pkg__params.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.core create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim.core create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/tl_peri_pkg.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/xbar_peri.sv create mode 100644 hw/top_englishbreakfast/ip/xbar_peri/xbar_peri.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/BUILD create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_pkg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_reg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/data/top_englishbreakfast_clkmgr.ipconfig.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/defs.bzl create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/checklist.md create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_block_diagram.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_rst_domain.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/example_chip_partition.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/interfaces.md create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/programmers_guide.md create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/registers.md create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/doc/theory_of_operation.md create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_manual_excl.el create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_unr_excl.el create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_tgl_excl.cfg create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/doc/tb.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_csrs_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cfg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cov.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_scoreboard.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_virtual_sequencer.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_clk_status_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_common_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_timeout_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_peri_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_vseq_list.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_aon_cg_en_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_cg_en_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_div_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_extclk_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_gated_clock_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_ctrl_en_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_regwen_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sec_cm_checker_assert.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva_ifs.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_trans_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_base_test.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test.core create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.waiver create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_byp.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_clk_status.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_meas_chk.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_root_ctrl.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_trans.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/BUILD create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_sec_cm_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/top_englishbreakfast_flash_ctrl.ipconfig.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/defs.bzl create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/checklist.md create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_abstraction.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_block_diagram.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_boundaries.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_integrity.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_partitions.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_protocol_controller.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_read_pipeline.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/interfaces.md create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/programmers_guide.md create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/registers.md create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/theory_of_operation.md create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.vRefine create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_phy_cov_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/doc/tb.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_dv_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_eflash_ral_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cov.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_mem_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_virtual_sequencer.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_addr_attrs.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_bkdr_util.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_item.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_mem_entry.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_read_entry.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_access_after_disable_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_callback_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_common_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_config_regwen_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_connect_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_disable_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_err_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_mp_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_type_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_win_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_full_mem_access_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_addr_infection_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_ctrl_arb_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_dir_rd_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_prog_rma_wipe_err_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_read_seed_err_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_err_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_sec_otp_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_info_part_access_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_integrity_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_rd_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_invalid_op_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_lcmgr_intg_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_legacy_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mid_op_rst_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mp_regions_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_ack_consistency_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_redun_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_host_grant_err_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_buff_evict_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_ooo_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_path_intg_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_re_evict_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_rnd_wd_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_word_sweep_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_ro_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_address_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_counter_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_hw_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_stress_all_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_sw_op_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_sva.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tb/tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_base_test.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tools/xcelium/xfile create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_pkg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_prim_reg_top.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_reg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.waiver create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.waiver create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_arb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_core_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_erase.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_info_cfg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_lcmgr.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_mem_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prog.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_rd.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_reg_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_region_cfg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp_data_region_sel.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_core.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_erase.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_prog.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buf_dep.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buffers.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_scramble.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/BUILD create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_fpv_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_sec_cm_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/data/top_englishbreakfast_pinmux.ipconfig.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/defs.bzl create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/checklist.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/fpv.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/generic_pad_wrapper.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/interfaces.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_muxing_matrix.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_overview_block_diagram.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinout_cw305.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/programmers_guide.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/registers.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/targets.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/doc/theory_of_operation.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_expected_failure.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_fpv.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_common_fpv.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_expected_failure.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_fpv.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_bind_fpv.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_chip_tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/fpv/vip/pinmux_assert_fpv.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.waiver create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/pinmux.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_pkg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_reg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_breakout.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_buf.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_strap_sampling.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_wkup.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/syn/constraints.sdc create mode 100644 hw/top_englishbreakfast/ip_autogen/pinmux/syn/pinmux_syn_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/BUILD create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/data/top_englishbreakfast_pwrmgr.ipconfig.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/defs.bzl create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/checklist.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/interfaces.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/programmers_guide.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_connectivity.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_fsms.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/registers.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/theory_of_operation.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_tgl_excl.cfg create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/doc/tb.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cfg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cov.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_scoreboard.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_sva.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_base_test.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.waiver create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr_pkg.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_pkg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_reg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc_pulse.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_slow_fsm.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_wake_info.sv create mode 100755 hw/top_englishbreakfast/ip_autogen/pwrmgr/util/reg_pwrmgr.py create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/BUILD create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.cfg.example.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_sec_cm_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/data/top_englishbreakfast_rstmgr.ipconfig.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/defs.bzl create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/doc/checklist.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/doc/interfaces.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/doc/programmers_guide.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/doc/registers.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/doc/reset_topology.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/doc/theory_of_operation.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cov_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cover.cfg create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_tgl_excl.cfg create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_unr_excl.el create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/doc/tb.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cfg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cov.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_scoreboard.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_virtual_sequencer.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_common_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_cnsty_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_shadow_attack_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_por_stretcher_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_reset_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sec_cm_scan_intersig_mubi_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_smoke_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_stress_all_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_reset_race_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_vseq.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_vseq_list.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_manual_excl.el create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_unr_excl.el create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/data/rstmgr_cnsty_chk_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim_cfg.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_attrs_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_bind.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_rst_en_track_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva_ifs.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_base_test.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.waiver create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_cnsty_chk.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_pkg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_reg.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_cnsty_chk.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_crash_info.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_ctrl.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_leaf_rst.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_por.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/BUILD create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_fpv_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_sec_cm_testplan.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/data/top_englishbreakfast_rv_plic.ipconfig.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/defs.bzl create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/doc/block_diagram.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/doc/checklist.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/README.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/fpv.svg create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/doc/programmers_guide.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/doc/theory_of_operation.md create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_expected_failure.hjson create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_fpv.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_bind_fpv.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/vip/rv_plic_assert_fpv.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.vlt create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.waiver create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_gateway.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_target.sv create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic.core create mode 100644 hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic_component.core delete mode 120000 hw/top_englishbreakfast/padring.core delete mode 120000 hw/top_englishbreakfast/physical_pads.core create mode 100644 hw/top_englishbreakfast/rtl/autogen/chip_englishbreakfast_cw305.sv create mode 100644 hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast.sv create mode 100644 hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_pkg.sv create mode 100644 hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_rnd_cnst_pkg.sv create mode 100644 hw/top_englishbreakfast/rtl/autogen/top_racl_pkg.sv delete mode 120000 hw/top_englishbreakfast/rtl/padring.sv delete mode 120000 hw/top_englishbreakfast/rtl/physical_pads.sv delete mode 120000 hw/top_englishbreakfast/rtl/top_pkg.sv create mode 100644 hw/top_englishbreakfast/sw/autogen/.clang-format create mode 100644 hw/top_englishbreakfast/sw/autogen/BUILD create mode 100644 hw/top_englishbreakfast/sw/autogen/chip/mod.rs create mode 100644 hw/top_englishbreakfast/sw/autogen/chip/top_englishbreakfast.rs create mode 100644 hw/top_englishbreakfast/sw/autogen/tests/plic_all_irqs_test.c create mode 100644 hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.c create mode 100644 hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.h create mode 100644 hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.h create mode 100644 hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.ld rename topgen-reg-only.core => hw/top_englishbreakfast/top_englishbreakfast_padring.core (52%) create mode 100644 hw/top_englishbreakfast/top_englishbreakfast_physical_pads.core create mode 100644 hw/top_englishbreakfast/top_englishbreakfast_pkg.core create mode 100644 sw/host/opentitanlib/src/chip/autogen/englishbreakfast.rs delete mode 100644 topgen.core delete mode 100755 util/topgen-fusesoc.py diff --git a/.gitignore b/.gitignore index 19e35c2f7a72c..1fbeb77c235f0 100644 --- a/.gitignore +++ b/.gitignore @@ -64,13 +64,6 @@ hw/foundry/ # ROM_EXT signer vendored in dependencies sw/host/rom_ext_image_signer/vendored_dependencies -# Autogen files for non-Earlgrey tops -hw/top_englishbreakfast/**/autogen/ -hw/top_englishbreakfast/ip/alert_handler/dv/alert_handler_env_pkg__params.sv -hw/top_englishbreakfast/ip/sensor_ctrl/rtl/* -hw/top_englishbreakfast/ip/xbar_main/xbar_main.core -hw/top_englishbreakfast/ip/xbar_peri/xbar_peri.core - # Rust Cargo build system files. sw/host/**/target rust-project.json diff --git a/BUILD.bazel b/BUILD.bazel index 36c85f77b16c1..33a74a8f6f28e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -14,8 +14,6 @@ filegroup( name = "cores", srcs = [ "check_tool_requirements.core", - "topgen.core", - "topgen-reg-only.core", ], ) diff --git a/ci/scripts/build-bitstream-vivado.sh b/ci/scripts/build-bitstream-vivado.sh index 29e039b712eb3..408639bdc167d 100755 --- a/ci/scripts/build-bitstream-vivado.sh +++ b/ci/scripts/build-bitstream-vivado.sh @@ -26,12 +26,10 @@ case x"$TOPLEVEL" in xtop_earlgrey) HAS_SCRAMBLED_ROM=1 HAS_OTP=1 - RUN_TOPGEN_FUSESOC=0 ;; xtop_englishbreakfast) HAS_SCRAMBLED_ROM=0 HAS_OTP=0 - RUN_TOPGEN_FUSESOC=1 ;; *) usage "Unknown toplevel: $TOPLEVEL" @@ -86,17 +84,10 @@ else OTP_ARG="" fi -if [ $RUN_TOPGEN_FUSESOC == 1 ]; then - util/topgen-fusesoc.py --files-root=. --topname="$TOPLEVEL" - FILESET=topgen -else - FILESET=top -fi - CORE_NAME="lowrisc:systems:chip_${FLAVOUR}_${TARGET}" fusesoc --verbose --cores-root=. \ - run --flag=fileset_$FILESET --target=synth --setup --build \ + run --target=synth --setup --build \ --build-root="$OBJ_DIR/hw" \ "$CORE_NAME" \ --BootRomInitFile="$BOOTROM_VMEM" \ diff --git a/ci/scripts/build-chip-verilator.sh b/ci/scripts/build-chip-verilator.sh index 80e17abdcde6b..52ec80fe0de43 100755 --- a/ci/scripts/build-chip-verilator.sh +++ b/ci/scripts/build-chip-verilator.sh @@ -18,20 +18,17 @@ tl="$1" case "$tl" in earlgrey) - fileset=fileset_top fusesoc_core=lowrisc:dv:chip_verilator_sim vname=Vchip_sim_tb verilator_options="--threads 4" make_options="-j 4" ;; englishbreakfast) - fileset=fileset_topgen fusesoc_core=lowrisc:systems:chip_englishbreakfast_verilator vname=Vchip_englishbreakfast_verilator # Englishbreakfast on CI runs on a 2-core CPU verilator_options="--threads 2" make_options="-j 2" - util/topgen-fusesoc.py --files-root=. --topname=top_englishbreakfast ;; *) echo >&2 "Unknown toplevel: $tl" @@ -49,7 +46,7 @@ mkdir -p "$OBJ_DIR/hw" mkdir -p "$BIN_DIR/hw/top_${tl}" fusesoc --cores-root=. \ - run --flag=$fileset --target=sim --setup --build \ + run --target=sim --setup --build \ --build-root="$OBJ_DIR/hw" \ $fusesoc_core \ --verilator_options="${verilator_options}" \ diff --git a/doc/getting_started/setup_fpga.md b/doc/getting_started/setup_fpga.md index 98e0136652b18..43937762fe969 100644 --- a/doc/getting_started/setup_fpga.md +++ b/doc/getting_started/setup_fpga.md @@ -132,7 +132,7 @@ The `--no-export` option of FuseSoC disables copying the source files into the s **Only create Vivado project directory by using FuseSoC directly (skipping Bazel invocation).** ```sh cd $REPO_TOP -fusesoc --cores-root . run --flag=fileset_top --target=synth --no-export --setup lowrisc:systems:chip_earlgrey_${BOARD} +fusesoc --cores-root . run --target=synth --no-export --setup lowrisc:systems:chip_earlgrey_${BOARD} ``` You can then navigate to the created project directory, and open Vivado diff --git a/hw/Makefile b/hw/Makefile index 9cbdf7547556f..9ac6eded01c00 100644 --- a/hw/Makefile +++ b/hw/Makefile @@ -46,7 +46,7 @@ IPS ?= aes \ uart \ usbdev -TOPS ?= top_darjeeling top_earlgrey +TOPS ?= top_darjeeling top_earlgrey top_englishbreakfast USE_BUFFER ?= 0 diff --git a/hw/top_englishbreakfast/README.md b/hw/top_englishbreakfast/README.md new file mode 100644 index 0000000000000..57be68e407599 --- /dev/null +++ b/hw/top_englishbreakfast/README.md @@ -0,0 +1,3 @@ +# Top Englishbreakfast + +This is an experimental top intended for SCA/FI activities. diff --git a/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core b/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core index fd7f9c0c1e2d3..48b1dc7dd9220 100644 --- a/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core +++ b/hw/top_englishbreakfast/chip_englishbreakfast_cw305.core @@ -10,9 +10,14 @@ filesets: depend: - lowrisc:prim_xilinx:prim_xilinx_default_pkg - lowrisc:systems:top_englishbreakfast:0.1 + - lowrisc:systems:top_englishbreakfast_pkg - lowrisc:systems:top_earlgrey_ast - - lowrisc:systems:topgen - lowrisc:systems:top_earlgrey_padring + - lowrisc:systems:top_earlgrey_scan_role_pkg + files: + - rtl/clkgen_xil7series.sv + - rtl/usr_access_xil7series.sv + - rtl/autogen/chip_englishbreakfast_cw305.sv file_type: systemVerilogSource files_constraints: diff --git a/hw/top_englishbreakfast/chip_englishbreakfast_verilator.core b/hw/top_englishbreakfast/chip_englishbreakfast_verilator.core index a3002ac3a9e03..aab80a9cb1f2f 100644 --- a/hw/top_englishbreakfast/chip_englishbreakfast_verilator.core +++ b/hw/top_englishbreakfast/chip_englishbreakfast_verilator.core @@ -8,7 +8,6 @@ filesets: files_sim_verilator: depend: - lowrisc:systems:top_englishbreakfast:0.1 - - lowrisc:systems:topgen - lowrisc:dv_dpi_c:uartdpi - lowrisc:dv_dpi_sv:uartdpi - lowrisc:dv_dpi_c:gpiodpi diff --git a/hw/top_englishbreakfast/data/autogen/BUILD b/hw/top_englishbreakfast/data/autogen/BUILD new file mode 100644 index 0000000000000..c55f14ceea595 --- /dev/null +++ b/hw/top_englishbreakfast/data/autogen/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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: +# util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson +# -o hw/top_englishbreakfast + +exports_files(["top_englishbreakfast.gen.hjson"]) diff --git a/hw/top_englishbreakfast/data/autogen/defs.bzl b/hw/top_englishbreakfast/data/autogen/defs.bzl new file mode 100644 index 0000000000000..a5bbef5ad6a1c --- /dev/null +++ b/hw/top_englishbreakfast/data/autogen/defs.bzl @@ -0,0 +1,55 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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: +# util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson +# -o hw/top_englishbreakfast + +load("//rules/opentitan:hw.bzl", "opentitan_top") +load("//hw/ip/aes:defs.bzl", "AES") +load("//hw/ip/aon_timer:defs.bzl", "AON_TIMER") +load("//hw/top_englishbreakfast/ip/ast:defs.bzl", "AST") +load("//hw/top_englishbreakfast/ip_autogen/clkmgr:defs.bzl", "CLKMGR") +load("//hw/top_englishbreakfast/ip_autogen/flash_ctrl:defs.bzl", "FLASH_CTRL") +load("//hw/ip/gpio:defs.bzl", "GPIO") +load("//hw/top_englishbreakfast/ip_autogen/pinmux:defs.bzl", "PINMUX") +load("//hw/top_englishbreakfast/ip_autogen/pwrmgr:defs.bzl", "PWRMGR") +load("//hw/ip/rom_ctrl:defs.bzl", "ROM_CTRL") +load("//hw/top_englishbreakfast/ip_autogen/rstmgr:defs.bzl", "RSTMGR") +load("//hw/ip/rv_core_ibex:defs.bzl", "RV_CORE_IBEX") +load("//hw/top_englishbreakfast/ip_autogen/rv_plic:defs.bzl", "RV_PLIC") +load("//hw/ip/rv_timer:defs.bzl", "RV_TIMER") +load("//hw/ip/spi_device:defs.bzl", "SPI_DEVICE") +load("//hw/ip/spi_host:defs.bzl", "SPI_HOST") +load("//hw/ip/sram_ctrl:defs.bzl", "SRAM_CTRL") +load("//hw/ip/uart:defs.bzl", "UART") +load("//hw/ip/usbdev:defs.bzl", "USBDEV") + +ENGLISHBREAKFAST = opentitan_top( + name = "englishbreakfast", + hjson = "//hw/top_englishbreakfast/data/autogen:top_englishbreakfast.gen.hjson", + top_lib = "//hw/top_englishbreakfast/sw/autogen:top_englishbreakfast", + top_ld = "//hw/top_englishbreakfast/sw/autogen:top_englishbreakfast_memory", + ips = [ + AES, + AON_TIMER, + AST, + CLKMGR, + FLASH_CTRL, + GPIO, + PINMUX, + PWRMGR, + ROM_CTRL, + RSTMGR, + RV_CORE_IBEX, + RV_PLIC, + RV_TIMER, + SPI_DEVICE, + SPI_HOST, + SRAM_CTRL, + UART, + USBDEV, + ], +) diff --git a/hw/top_englishbreakfast/data/autogen/top_englishbreakfast.gen.hjson b/hw/top_englishbreakfast/data/autogen/top_englishbreakfast.gen.hjson new file mode 100644 index 0000000000000..4b6312b514cc3 --- /dev/null +++ b/hw/top_englishbreakfast/data/autogen/top_englishbreakfast.gen.hjson @@ -0,0 +1,12779 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson \ +// -o hw/top_englishbreakfast/ \ +// --rnd_cnst_seed 4881560218908238235 +{ + name: englishbreakfast + type: top + rnd_cnst_seed: 4881560218908238235 + datawidth: "32" + power: + { + domains: + [ + Aon + "0" + ] + default: "0" + wait_for_external_reset: false + } + unmanaged_clocks: {} + clocks: + { + hier_paths: + { + top: clkmgr_aon_clocks. + ext: "" + lpg: clkmgr_aon_cg_en. + } + srcs: + [ + { + name: main + aon: no + freq: "100000000" + ref: false + } + { + name: io + aon: no + freq: "96000000" + ref: false + } + { + name: usb + aon: no + freq: "48000000" + ref: false + } + { + name: aon + aon: yes + freq: "200000" + ref: false + } + ] + derived_srcs: + [ + { + name: io_div2 + aon: no + freq: "48000000" + ref: false + div: "2" + src: io + } + { + name: io_div4 + aon: no + freq: "24000000" + ref: false + div: "4" + src: io + } + ] + groups: + [ + { + name: ast + src: ext + sw_cg: no + unique: no + clocks: + { + clk_main_i: main + clk_io_i: io + clk_usb_i: usb + clk_aon_i: aon + } + } + { + name: powerup + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_powerup: io_div4 + clk_aon_powerup: aon + clk_main_powerup: main + clk_io_powerup: io + clk_usb_powerup: usb + clk_io_div2_powerup: io_div2 + } + } + { + name: trans + src: top + sw_cg: hint + unique: yes + clocks: + { + clk_main_aes: main + } + } + { + name: infra + src: top + sw_cg: no + unique: no + clocks: + { + clk_main_infra: main + clk_io_div4_infra: io_div4 + clk_io_infra: io + clk_usb_infra: usb + } + } + { + name: secure + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_secure: io_div4 + clk_aon_secure: aon + clk_main_secure: main + } + } + { + name: peri + src: top + sw_cg: yes + unique: no + clocks: + { + clk_io_div4_peri: io_div4 + clk_io_div2_peri: io_div2 + clk_io_peri: io + clk_usb_peri: usb + clk_aon_peri: aon + } + } + { + name: timers + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_timers: io_div4 + clk_aon_timers: aon + } + } + { + name: proc + src: no + sw_cg: no + unique: no + clocks: {} + } + ] + } + unmanaged_resets: {} + resets: + { + hier_paths: + { + top: rstmgr_aon_resets. + ext: "" + lpg: rstmgr_aon_rst_en. + } + nodes: + [ + { + name: por_aon + gen: false + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_aon_n + clock: aon + } + { + name: lc_src + gen: false + type: int + domains: [] + shadowed: false + sw: false + path: "" + clock: io_div4 + } + { + name: sys_src + gen: false + type: int + domains: [] + shadowed: false + sw: false + path: "" + clock: io_div4 + } + { + name: por + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_n + parent: por_aon + clock: main + } + { + name: por_io + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_io_n + parent: por_aon + clock: io + } + { + name: por_io_div2 + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_io_div2_n + parent: por_aon + clock: io_div2 + } + { + name: por_io_div4 + gen: true + type: top + domains: + [ + Aon + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_por_io_div4_n + parent: por_aon + clock: io_div4 + } + { + name: por_usb + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_usb_n + parent: por_aon + clock: usb + } + { + name: lc + gen: true + type: top + domains: + [ + "0" + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_lc_n + parent: lc_src + clock: main + } + { + name: lc_io_div4 + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_lc_io_div4_n + parent: lc_src + clock: io_div4 + } + { + name: sys + gen: true + type: top + domains: + [ + "0" + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_sys_n + parent: sys_src + clock: main + } + { + name: sys_io_div4 + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_sys_io_div4_n + parent: sys_src + clock: io_div4 + } + { + name: sys_aon + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_sys_aon_n + parent: sys_src + clock: aon + } + { + name: spi_device + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_spi_device_n + parent: sys_src + clock: io_div2 + } + { + name: spi_host0 + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_spi_host0_n + parent: sys_src + clock: io + } + { + name: usb + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_usb_n + parent: sys_src + clock: usb + } + ] + } + num_cores: "1" + addr_spaces: + [ + { + name: hart + desc: The main address space, shared between the CPU and DM + subspaces: + [ + { + name: mmio + desc: + ''' + MMIO region excludes any memory that is separate from the module configuration + space, i.e. ROM, main SRAM, and flash are excluded but retention SRAM, spi_device + memory, or usbdev memory are included. + ''' + nodes: + [ + uart0 + uart1 + gpio + spi_device + rv_timer + spi_host0 + usbdev + pwrmgr_aon + rstmgr_aon + clkmgr_aon + pinmux_aon + aon_timer_aon + ast + flash_ctrl.core + flash_ctrl.prim + rv_plic + aes + sram_ctrl_main.regs + rom_ctrl.regs + rv_core_ibex + ] + } + ] + } + ] + module: + [ + { + name: uart0 + type: uart + clock_srcs: + { + clk_i: io_div4 + } + clock_group: peri + reset_connections: + { + rst_ni: + { + name: lc_io_div4 + domain: "0" + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_peri + } + domain: + [ + "0" + ] + param_decl: {} + param_list: [] + inter_signal_list: + [ + { + name: lsio_trigger + desc: + ''' + Self-clearing status trigger for the DMA. + Set when RX or TX FIFOs are past their configured watermarks matching watermark interrupt behaviour. + ''' + struct: logic + type: uni + act: req + width: 1 + inst_name: uart0 + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: uart0 + default: "" + end_idx: -1 + top_signame: uart0_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40000000 + } + } + generate_dif: true + } + { + name: uart1 + type: uart + clock_srcs: + { + clk_i: io_div4 + } + clock_group: peri + reset_connections: + { + rst_ni: + { + name: lc_io_div4 + domain: "0" + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_peri + } + domain: + [ + "0" + ] + param_decl: {} + param_list: [] + inter_signal_list: + [ + { + name: lsio_trigger + desc: + ''' + Self-clearing status trigger for the DMA. + Set when RX or TX FIFOs are past their configured watermarks matching watermark interrupt behaviour. + ''' + struct: logic + type: uni + act: req + width: 1 + inst_name: uart1 + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: uart1 + default: "" + end_idx: -1 + top_signame: uart1_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40010000 + } + } + generate_dif: true + } + { + name: gpio + type: gpio + clock_srcs: + { + clk_i: io_div4 + } + clock_group: peri + reset_connections: + { + rst_ni: + { + name: sys_io_div4 + domain: "0" + } + } + param_decl: + { + GpioAsyncOn: "1" + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_peri + } + domain: + [ + "0" + ] + memory: {} + param_list: + [ + { + name: GpioAsyncOn + desc: Instantiates 2-flop synchronizers on all GPIO inputs if set to 1. + type: bit + default: "1" + local: "false" + expose: "true" + name_top: GpioGpioAsyncOn + } + { + name: GpioAsHwStrapsEn + desc: Enable HW straps sampling logic for GPIO inputs at initial cold boot + type: bit + default: 1'b1 + local: "false" + expose: "true" + name_top: GpioGpioAsHwStrapsEn + } + ] + inter_signal_list: + [ + { + name: strap_en + desc: This signal is pulsed high by the power manager after reset in order to sample the HW straps. + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: gpio + index: -1 + } + { + name: sampled_straps + desc: This vector contains the sampled strap values. + struct: gpio_straps + package: gpio_pkg + type: uni + act: req + width: 1 + default: "'0" + inst_name: gpio + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: gpio + default: "" + end_idx: -1 + top_signame: gpio_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40040000 + } + } + generate_dif: true + } + { + name: spi_device + type: spi_device + clock_srcs: + { + clk_i: io_div4 + scan_clk_i: io_div2 + } + clock_group: peri + reset_connections: + { + rst_ni: + { + name: spi_device + domain: "0" + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_peri + scan_clk_i: clkmgr_aon_clocks.clk_io_div2_peri + } + domain: + [ + "0" + ] + param_decl: {} + memory: {} + param_list: + [ + { + name: SramType + desc: Sram Entries. Word size is 32bit width. + type: spi_device_pkg::sram_type_e + default: spi_device_pkg::DefaultSramType + local: "false" + expose: "true" + name_top: SpiDeviceSramType + } + ] + inter_signal_list: + [ + { + name: ram_cfg_sys2spi + struct: ram_2p_cfg + package: prim_ram_2p_pkg + type: uni + act: rcv + width: 1 + inst_name: spi_device + index: -1 + } + { + name: ram_cfg_rsp_sys2spi + struct: ram_2p_cfg_rsp + package: prim_ram_2p_pkg + type: uni + act: req + width: 1 + inst_name: spi_device + index: -1 + } + { + name: ram_cfg_spi2sys + struct: ram_2p_cfg + package: prim_ram_2p_pkg + type: uni + act: rcv + width: 1 + inst_name: spi_device + index: -1 + } + { + name: ram_cfg_rsp_spi2sys + struct: ram_2p_cfg_rsp + package: prim_ram_2p_pkg + type: uni + act: req + width: 1 + inst_name: spi_device + index: -1 + } + { + name: passthrough + struct: passthrough + package: spi_device_pkg + type: req_rsp + act: req + width: 1 + inst_name: spi_device + default: "" + end_idx: -1 + top_signame: spi_device_passthrough + index: -1 + } + { + name: mbist_en + struct: logic + type: uni + act: rcv + width: 1 + inst_name: spi_device + index: -1 + } + { + name: sck_monitor + struct: logic + type: uni + act: req + width: 1 + inst_name: spi_device + default: "" + package: "" + external: true + top_signame: sck_monitor + conn_type: false + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: spi_device + default: "" + end_idx: -1 + top_signame: spi_device_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40050000 + } + } + generate_dif: true + } + { + name: spi_host0 + type: spi_host + clock_srcs: + { + clk_i: io + } + clock_group: peri + reset_connections: + { + rst_ni: + { + name: spi_host0 + domain: "0" + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_peri + } + domain: + [ + "0" + ] + param_decl: {} + memory: {} + param_list: + [ + { + name: NumCS + desc: The number of active-low chip select (cs_n) lines to create. + type: int + default: "1" + local: "true" + expose: "true" + name_top: SpiHost0NumCS + } + ] + inter_signal_list: + [ + { + name: passthrough + struct: passthrough + package: spi_device_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: spi_host0 + default: "" + top_signame: spi_device_passthrough + index: -1 + } + { + name: lsio_trigger + desc: + ''' + Self-clearing status trigger for the DMA. + Set when RX or TX FIFOs are past their configured watermarks matching watermark interrupt behaviour. + ''' + struct: logic + type: uni + act: req + width: 1 + inst_name: spi_host0 + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: spi_host0 + default: "" + end_idx: -1 + top_signame: spi_host0_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40060000 + } + } + generate_dif: true + } + { + name: rv_timer + type: rv_timer + clock_srcs: + { + clk_i: io_div4 + } + clock_group: timers + reset_connections: + { + rst_ni: + { + name: sys_io_div4 + domain: "0" + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_timers + } + domain: + [ + "0" + ] + param_decl: {} + param_list: [] + inter_signal_list: + [ + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rv_timer + default: "" + end_idx: -1 + top_signame: rv_timer_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40100000 + } + } + generate_dif: true + } + { + name: usbdev + type: usbdev + clock_srcs: + { + clk_i: usb + clk_aon_i: aon + } + clock_group: peri + reset_connections: + { + rst_ni: + { + name: usb + domain: "0" + } + rst_aon_ni: + { + name: sys_aon + domain: "0" + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_usb_peri + clk_aon_i: clkmgr_aon_clocks.clk_aon_peri + } + domain: + [ + "0" + ] + param_decl: {} + memory: {} + param_list: + [ + { + name: Stub + desc: Stub out the core of entropy_src logic + type: bit + default: "0" + local: "false" + expose: "true" + name_top: UsbdevStub + } + { + name: RcvrWakeTimeUs + desc: Maximum number of microseconds for the differential receiver to become operational + type: int + default: "1" + local: "false" + expose: "true" + name_top: UsbdevRcvrWakeTimeUs + } + ] + inter_signal_list: + [ + { + name: usb_rx_d + desc: USB RX data from an external differential receiver, if available + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_rx_d + conn_type: false + index: -1 + } + { + name: usb_tx_d + desc: USB transmit data value (not used if usb_tx_se0 is set) + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_tx_d + conn_type: false + index: -1 + } + { + name: usb_tx_se0 + desc: Force transmission of a USB single-ended zero (i.e. both D+ and D- are low) regardless of usb_tx_d + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_tx_se0 + conn_type: false + index: -1 + } + { + name: usb_tx_use_d_se0 + desc: Use the usb_tx_d and usb_tx_se0 TX interface, instead of usb_dp_o and usb_dn_o + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_tx_use_d_se0 + conn_type: false + index: -1 + } + { + name: usb_dp_pullup + desc: USB D+ pullup control + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_dp_pullup + index: -1 + } + { + name: usb_dn_pullup + desc: USB D- pullup control + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_dn_pullup + index: -1 + } + { + name: usb_rx_enable + desc: USB differential receiver enable + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_rx_enable + conn_type: false + index: -1 + } + { + name: usb_ref_val + desc: This indicates that USB timing reference signal 'usb_ref_pulse' is valid + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_ref_val + conn_type: false + index: -1 + } + { + name: usb_ref_pulse + desc: USB timing reference signal. This signal pulses for a single 48MHz clock every 1ms USB frame + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_ref_pulse + conn_type: false + index: -1 + } + { + name: usb_aon_suspend_req + desc: Request to activate the AON/Wake module and take control of the USB pullups + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_suspend_req + index: -1 + } + { + name: usb_aon_wake_ack + desc: Acknowledge a wake signal from the AON/Wake and relinquish control of the USB pullups + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_wake_ack + index: -1 + } + { + name: usb_aon_bus_reset + desc: Indicates that the reason for waking was that a USB Bus Reset occurred + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_bus_reset + index: -1 + } + { + name: usb_aon_sense_lost + desc: Indicates that the reason for waking was that the VBUS/SENSE signal became deasserted + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_sense_lost + index: -1 + } + { + name: usb_aon_bus_not_idle + desc: Indicates that the reason for waking was that the USB is in a non-idle state + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + index: -1 + } + { + name: usb_aon_wake_detect_active + desc: Indicates that the external AON/Wake module is active and controlling the USB pullups + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + top_signame: pinmux_aon_usbdev_wake_detect_active + index: -1 + } + { + name: ram_cfg + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: 1 + inst_name: usbdev + index: -1 + } + { + name: ram_cfg_rsp + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: 1 + inst_name: usbdev + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: usbdev + default: "" + end_idx: -1 + top_signame: usbdev_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40320000 + } + } + generate_dif: true + } + { + name: pwrmgr_aon + type: pwrmgr + clock_srcs: + { + clk_i: io_div4 + clk_slow_i: aon + clk_lc_i: io_div4 + clk_esc_i: io_div4 + } + clock_group: powerup + reset_connections: + { + rst_ni: + { + name: por_io_div4 + domain: Aon + } + rst_lc_ni: + { + name: lc_io_div4 + domain: Aon + } + rst_esc_ni: + { + name: lc_io_div4 + domain: Aon + } + rst_main_ni: + { + name: por_aon + domain: Aon + } + rst_slow_ni: + { + name: por_aon + domain: Aon + } + } + domain: + [ + Aon + ] + attr: ipgen + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_powerup + clk_slow_i: clkmgr_aon_clocks.clk_aon_powerup + clk_lc_i: clkmgr_aon_clocks.clk_io_div4_powerup + clk_esc_i: clkmgr_aon_clocks.clk_io_div4_powerup + } + param_decl: {} + memory: {} + param_list: + [ + { + name: EscNumSeverities + desc: Number of escalation severities + type: int + default: "4" + local: "false" + expose: "false" + name_top: PwrmgrAonEscNumSeverities + } + { + name: EscPingCountWidth + desc: Width of ping count for the escalation receiver + type: int + default: "16" + local: "false" + expose: "false" + name_top: PwrmgrAonEscPingCountWidth + } + ] + inter_signal_list: + [ + { + name: pwr_ast + struct: pwr_ast + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + external: true + top_signame: pwrmgr_ast + conn_type: false + index: -1 + } + { + name: pwr_rst + struct: pwr_rst + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_signame: pwrmgr_aon_pwr_rst + index: -1 + } + { + name: pwr_clk + struct: pwr_clk + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_signame: pwrmgr_aon_pwr_clk + index: -1 + } + { + name: pwr_otp + struct: pwr_otp + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: pwr_lc + struct: pwr_lc + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: pwr_flash + struct: pwr_flash + package: pwrmgr_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_pwr_flash + index: -1 + } + { + name: esc_rst_tx + struct: esc_tx + package: prim_esc_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: esc_rst_rx + struct: esc_rx + package: prim_esc_pkg + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: pwr_cpu + struct: cpu_pwrmgr + package: rv_core_ibex_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + top_signame: rv_core_ibex_pwrmgr + index: -1 + } + { + name: wakeups + struct: logic + type: uni + act: rcv + width: 3 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: one-to-N + top_signame: pwrmgr_aon_wakeups + index: -1 + } + { + name: rstreqs + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_rstreqs + index: -1 + } + { + name: ndmreset_req + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: strap + struct: logic + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_strap + index: -1 + } + { + name: low_power + struct: logic + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_low_power + index: -1 + } + { + name: rom_ctrl + struct: pwrmgr_data + package: rom_ctrl_pkg + type: uni + act: rcv + width: 1 + default: rom_ctrl_pkg::PWRMGR_DATA_DEFAULT + inst_name: pwrmgr_aon + index: -1 + } + { + name: fetch_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_fetch_en + index: -1 + } + { + name: lc_dft_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: lc_hw_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: sw_rst_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + top_signame: rstmgr_aon_sw_rst_req + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_signame: pwrmgr_aon_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40400000 + } + } + generate_dif: true + } + { + name: rstmgr_aon + type: rstmgr + clock_srcs: + { + clk_i: io_div4 + clk_por_i: io_div4 + clk_aon_i: aon + clk_main_i: main + clk_io_i: io + clk_usb_i: usb + clk_io_div2_i: io_div2 + clk_io_div4_i: io_div4 + } + clock_group: powerup + reset_connections: + { + rst_ni: + { + name: lc_io_div4 + domain: Aon + } + rst_por_ni: + { + name: por_io_div4 + domain: Aon + } + } + domain: + [ + Aon + ] + param_decl: + { + SecCheck: "0" + } + attr: ipgen + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_powerup + clk_por_i: clkmgr_aon_clocks.clk_io_div4_powerup + clk_aon_i: clkmgr_aon_clocks.clk_aon_powerup + clk_main_i: clkmgr_aon_clocks.clk_main_powerup + clk_io_i: clkmgr_aon_clocks.clk_io_powerup + clk_usb_i: clkmgr_aon_clocks.clk_usb_powerup + clk_io_div2_i: clkmgr_aon_clocks.clk_io_div2_powerup + clk_io_div4_i: clkmgr_aon_clocks.clk_io_div4_powerup + } + memory: {} + param_list: + [ + { + name: SecCheck + desc: + ''' + When 1, enable rstmgr reset consistency checks. + When 0, there are no consistency checks. + ''' + type: bit + default: "0" + local: "false" + expose: "true" + name_top: SecRstmgrAonCheck + } + { + name: SecMaxSyncDelay + desc: The maximum synchronization delay for parent / child reset checks. + type: int + default: "2" + local: "false" + expose: "true" + name_top: SecRstmgrAonMaxSyncDelay + } + ] + inter_signal_list: + [ + { + name: por_n + desc: + ''' + Root power on reset signals from ast. + There is one root reset signal for each core power domain. + ''' + struct: logic + type: uni + act: rcv + width: 2 + inst_name: rstmgr_aon + default: "" + package: "" + external: true + top_signame: por_n + conn_type: false + index: -1 + } + { + name: pwr + desc: + ''' + Reset request signals from power manager. + Power manager can request for specific domains of the lc/sys reset tree to assert. + ''' + struct: pwr_rst + type: req_rsp + act: rsp + width: 1 + inst_name: rstmgr_aon + default: "" + package: pwrmgr_pkg + top_signame: pwrmgr_aon_pwr_rst + index: -1 + } + { + name: resets + desc: Leaf resets fed to the system. + struct: rstmgr_out + package: rstmgr_pkg + type: uni + act: req + width: 1 + inst_name: rstmgr_aon + default: "" + top_signame: rstmgr_aon_resets + index: -1 + } + { + name: rst_en + desc: Low-power-group outputs used by alert handler. + struct: rstmgr_rst_en + package: rstmgr_pkg + type: uni + act: req + width: 1 + inst_name: rstmgr_aon + default: "" + top_signame: rstmgr_aon_rst_en + index: -1 + } + { + name: alert_dump + desc: Alert handler crash dump information. + struct: alert_crashdump + package: alert_pkg + type: uni + act: rcv + width: 1 + inst_name: rstmgr_aon + index: -1 + } + { + name: cpu_dump + desc: Main processing element crash dump information. + struct: cpu_crash_dump + package: rv_core_ibex_pkg + type: uni + act: rcv + width: 1 + inst_name: rstmgr_aon + default: "" + top_signame: rv_core_ibex_crash_dump + index: -1 + } + { + name: sw_rst_req + desc: Software requested system reset to pwrmgr. + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: rstmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: rstmgr_aon_sw_rst_req + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rstmgr_aon + default: "" + end_idx: -1 + top_signame: rstmgr_aon_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40410000 + } + } + generate_dif: true + } + { + name: clkmgr_aon + type: clkmgr + clock_srcs: + { + clk_i: io_div4 + clk_main_i: + { + group: ast + clock: main + } + clk_io_i: + { + group: ast + clock: io + } + clk_usb_i: + { + group: ast + clock: usb + } + clk_aon_i: + { + group: ast + clock: aon + } + } + clock_group: powerup + reset_connections: + { + rst_ni: + { + name: por_io_div4 + domain: Aon + } + rst_aon_ni: + { + name: por_aon + domain: Aon + } + rst_io_ni: + { + name: por_io + domain: Aon + } + rst_io_div2_ni: + { + name: por_io_div2 + domain: Aon + } + rst_io_div4_ni: + { + name: por_io_div4 + domain: Aon + } + rst_main_ni: + { + name: por + domain: Aon + } + rst_usb_ni: + { + name: por_usb + domain: Aon + } + rst_root_ni: + { + name: por_io_div4 + domain: Aon + } + rst_root_io_ni: + { + name: por_io + domain: Aon + } + rst_root_io_div2_ni: + { + name: por_io_div2 + domain: Aon + } + rst_root_io_div4_ni: + { + name: por_io_div4 + domain: Aon + } + rst_root_main_ni: + { + name: por + domain: Aon + } + rst_root_usb_ni: + { + name: por_usb + domain: Aon + } + } + domain: + [ + Aon + ] + attr: ipgen + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_powerup + clk_main_i: clk_main_i + clk_io_i: clk_io_i + clk_usb_i: clk_usb_i + clk_aon_i: clk_aon_i + } + param_decl: {} + param_list: [] + inter_signal_list: + [ + { + name: clocks + struct: clkmgr_out + package: clkmgr_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + top_signame: clkmgr_aon_clocks + index: -1 + } + { + name: cg_en + struct: clkmgr_cg_en + package: clkmgr_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + top_signame: clkmgr_aon_cg_en + index: -1 + } + { + name: lc_hw_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + index: -1 + } + { + name: io_clk_byp_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: io_clk_byp_req + conn_type: false + index: -1 + } + { + name: io_clk_byp_ack + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: io_clk_byp_ack + conn_type: false + index: -1 + } + { + name: all_clk_byp_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: all_clk_byp_req + conn_type: false + index: -1 + } + { + name: all_clk_byp_ack + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: all_clk_byp_ack + conn_type: false + index: -1 + } + { + name: hi_speed_sel + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: hi_speed_sel + conn_type: false + index: -1 + } + { + name: div_step_down_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: div_step_down_req + conn_type: false + index: -1 + } + { + name: lc_clk_byp_req + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + index: -1 + } + { + name: lc_clk_byp_ack + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + index: -1 + } + { + name: jitter_en + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: clk_main_jitter_en + conn_type: false + index: -1 + } + { + name: pwr + struct: pwr_clk + type: req_rsp + act: rsp + width: 1 + inst_name: clkmgr_aon + default: "" + package: pwrmgr_pkg + top_signame: pwrmgr_aon_pwr_clk + index: -1 + } + { + name: idle + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: clkmgr_aon_idle + index: -1 + } + { + name: calib_rdy + desc: Indicates clocks are calibrated and frequencies accurate + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + default: prim_mubi_pkg::MuBi4True + inst_name: clkmgr_aon + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: clkmgr_aon + default: "" + end_idx: -1 + top_signame: clkmgr_aon_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40420000 + } + } + generate_dif: true + } + { + name: pinmux_aon + type: pinmux + clock_srcs: + { + clk_i: io_div4 + clk_aon_i: aon + } + clock_group: powerup + reset_connections: + { + rst_ni: + { + name: lc_io_div4 + domain: Aon + } + rst_aon_ni: + { + name: sys_aon + domain: Aon + } + rst_sys_ni: + { + name: sys_io_div4 + domain: Aon + } + } + domain: + [ + Aon + ] + attr: ipgen + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_powerup + clk_aon_i: clkmgr_aon_clocks.clk_aon_powerup + } + param_decl: {} + memory: {} + param_list: + [ + { + name: SecVolatileRawUnlockEn + desc: + ''' + Disable (0) or enable (1) volatile RAW UNLOCK capability. + If enabled, the strap_en_override_i input can be used to re-sample the straps at runtime. + + IMPORTANT NOTE: This should only be used in test chips. The parameter must be set + to 0 in production tapeouts since this weakens the security posture of the RAW + UNLOCK mechanism. + ''' + type: bit + default: 1'b0 + local: "false" + expose: "true" + name_top: SecPinmuxAonVolatileRawUnlockEn + } + { + name: TargetCfg + desc: Target specific pinmux configuration. + type: pinmux_pkg::target_cfg_t + default: pinmux_pkg::DefaultTargetCfg + local: "false" + expose: "true" + name_top: PinmuxAonTargetCfg + } + ] + inter_signal_list: + [ + { + name: lc_hw_debug_en + desc: Debug enable qualifier coming from life cycle controller, used for HW strap qualification. + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_dft_en + desc: Test enable qualifier coming from life cycle controller, used for HW strap qualification. + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_escalate_en + desc: + ''' + Escalation enable signal coming from life cycle controller, used for invalidating + the latched lc_hw_debug_en state inside the strap sampling logic. + ''' + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_check_byp_en + desc: + ''' + Check bypass enable signal coming from life cycle controller, used for invalidating + the latched lc_hw_debug_en state inside the strap sampling logic. This signal is asserted + whenever the life cycle controller performs a life cycle transition. Its main use is + to skip any background checks inside the life cycle partition of the OTP controller while + a life cycle transition is in progress. + ''' + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: pinmux_hw_debug_en + desc: + ''' + This is the latched version of lc_hw_debug_en_i. We use it exclusively to gate the JTAG + signals and TAP side of the RV_DM so that RV_DM can remain live during an NDM reset cycle. + ''' + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_jtag + desc: Qualified JTAG signals for life cycle controller TAP. + struct: jtag + package: jtag_pkg + type: req_rsp + act: req + width: 1 + inst_name: pinmux_aon + index: -1 + } + { + name: rv_jtag + desc: Qualified JTAG signals for RISC-V processor TAP. + struct: jtag + package: jtag_pkg + type: req_rsp + act: req + width: 1 + inst_name: pinmux_aon + index: -1 + } + { + name: dft_jtag + desc: Qualified JTAG signals for DFT TAP. + struct: jtag + package: jtag_pkg + type: req_rsp + act: req + width: 1 + inst_name: pinmux_aon + default: "" + top_signame: pinmux_aon_dft_jtag + index: -1 + } + { + name: dft_strap_test + desc: Sampled DFT strap values, going to the DFT TAP. + struct: dft_strap_test_req + package: pinmux_pkg + type: uni + act: req + width: 1 + default: "'0" + inst_name: pinmux_aon + external: true + top_signame: dft_strap_test + conn_type: false + index: -1 + } + { + name: dft_hold_tap_sel + desc: TAP selection hold indication, asserted by the DFT TAP during boundary scan. + struct: logic + type: uni + act: rcv + width: 1 + default: "'0" + inst_name: pinmux_aon + package: "" + external: true + top_signame: dft_hold_tap_sel + conn_type: false + index: -1 + } + { + name: sleep_en + desc: Level signal that is asserted when the power manager enters sleep. + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_low_power + index: -1 + } + { + name: strap_en + desc: This signal is pulsed high by the power manager after reset in order to sample the HW straps. + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_strap + index: -1 + } + { + name: strap_en_override + desc: + ''' + This signal transitions from 0 -> 1 by the lc_ctrl manager after volatile RAW_UNLOCK in order to re-sample the HW straps. + The signal must stay at 1 until reset. + Note that this is only used in test chips when SecVolatileRawUnlockEn = 1. + Otherwise this signal is unused. + ''' + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: pinmux_aon + index: -1 + } + { + name: pin_wkup_req + desc: Wakeup request from wakeup detectors, to the power manager, running on the AON clock. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_wakeups + index: 0 + } + { + name: usbdev_dppullup_en + desc: Pullup enable signal coming from the USB IP. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_dp_pullup + index: -1 + } + { + name: usbdev_dnpullup_en + desc: Pullup enable signal coming from the USB IP. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_dn_pullup + index: -1 + } + { + name: usb_dppullup_en + desc: " Pullup enable signal going to USB PHY, needs to be maintained in low-power mode." + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + external: true + top_signame: usb_dp_pullup_en + conn_type: false + index: -1 + } + { + name: usb_dnpullup_en + desc: Pullup enable signal going to USB PHY, needs to be maintained in low-power mode. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + external: true + top_signame: usb_dn_pullup_en + conn_type: false + index: -1 + } + { + name: usb_wkup_req + desc: Wakeup request from USB wakeup detector, going to the power manager, running on the AON clock. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_wakeups + index: 1 + } + { + name: usbdev_suspend_req + desc: Indicates whether USB is in suspended state, coming from the USB device. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_aon_suspend_req + index: -1 + } + { + name: usbdev_wake_ack + desc: Acknowledges the USB wakeup request, coming from the USB device. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_aon_wake_ack + index: -1 + } + { + name: usbdev_bus_not_idle + desc: Event signal that indicates that the USB was not idle while monitoring. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + index: -1 + } + { + name: usbdev_bus_reset + desc: Event signal that indicates that the USB issued a Bus Reset while monitoring. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: usbdev_usb_aon_bus_reset + index: -1 + } + { + name: usbdev_sense_lost + desc: Event signal that indicates that USB SENSE signal was lost while monitoring. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: usbdev_usb_aon_sense_lost + index: -1 + } + { + name: usbdev_wake_detect_active + desc: State debug information. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pinmux_aon_usbdev_wake_detect_active + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: pinmux_aon + default: "" + end_idx: -1 + top_signame: pinmux_aon_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40460000 + } + } + generate_dif: true + } + { + name: aon_timer_aon + type: aon_timer + clock_srcs: + { + clk_i: io_div4 + clk_aon_i: aon + } + clock_group: timers + reset_connections: + { + rst_ni: + { + name: sys_io_div4 + domain: Aon + } + rst_aon_ni: + { + name: sys_aon + domain: Aon + } + } + domain: + [ + Aon + ] + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_io_div4_timers + clk_aon_i: clkmgr_aon_clocks.clk_aon_timers + } + param_decl: {} + param_list: [] + inter_signal_list: + [ + { + name: nmi_wdog_timer_bark + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: aon_timer_aon + index: -1 + } + { + name: wkup_req + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: aon_timer_aon + package: "" + top_signame: pwrmgr_aon_wakeups + index: 2 + } + { + name: aon_timer_rst_req + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: aon_timer_aon + package: "" + top_signame: pwrmgr_aon_rstreqs + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: aon_timer_aon + index: -1 + } + { + name: sleep_mode + struct: logic + type: uni + act: rcv + width: 1 + inst_name: aon_timer_aon + default: "" + package: "" + top_signame: pwrmgr_aon_low_power + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: aon_timer_aon + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40470000 + } + } + generate_dif: true + } + { + name: ast + type: ast + clock_srcs: + { + clk_ast_tlul_i: io_div4 + clk_ast_adc_i: aon + clk_ast_alert_i: io_div4 + clk_ast_es_i: main + clk_ast_rng_i: main + clk_ast_usb_i: + { + clock: usb + group: peri + } + } + clock_group: secure + reset_connections: + { + rst_ast_tlul_ni: + { + name: lc_io_div4 + domain: "0" + } + rst_ast_adc_ni: + { + name: sys_aon + domain: "0" + } + rst_ast_alert_ni: + { + name: lc_io_div4 + domain: "0" + } + rst_ast_es_ni: + { + name: sys + domain: "0" + } + rst_ast_rng_ni: + { + name: sys + domain: "0" + } + rst_ast_usb_ni: + { + name: usb + domain: "0" + } + } + attr: reggen_only + clock_connections: + { + clk_ast_tlul_i: clkmgr_aon_clocks.clk_io_div4_secure + clk_ast_adc_i: clkmgr_aon_clocks.clk_aon_secure + clk_ast_alert_i: clkmgr_aon_clocks.clk_io_div4_secure + clk_ast_es_i: clkmgr_aon_clocks.clk_main_secure + clk_ast_rng_i: clkmgr_aon_clocks.clk_main_secure + clk_ast_usb_i: clkmgr_aon_clocks.clk_usb_peri + } + domain: + [ + "0" + ] + param_decl: {} + param_list: [] + inter_signal_list: + [ + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: ast + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x40480000 + } + } + generate_dif: true + } + { + name: flash_ctrl + type: flash_ctrl + clock_srcs: + { + clk_i: main + clk_otp_i: io_div4 + } + clock_group: infra + reset_connections: + { + rst_ni: + { + name: lc + domain: "0" + } + rst_otp_ni: + { + name: lc_io_div4 + domain: "0" + } + } + base_addrs: + { + core: + { + hart: 0x41000000 + } + prim: + { + hart: 0x41008000 + } + mem: + { + hart: 0x20000000 + } + } + param_decl: + { + SecScrambleEn: "0" + } + memory: + { + mem: + { + label: eflash + swaccess: ro + exec: True + byte_write: False + config: + { + banks: 2 + pages_per_bank: 16 + program_resolution: 8 + pgm_resolution_bytes: 64 + bytes_per_page: 2048 + bytes_per_bank: 32768 + size: 0x10000 + } + size: 0x10000 + } + } + attr: ipgen + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_main_infra + clk_otp_i: clkmgr_aon_clocks.clk_io_div4_infra + } + domain: + [ + "0" + ] + param_list: + [ + { + name: RndCnstAddrKey + desc: Compile-time random bits for default address key + type: flash_ctrl_pkg::flash_key_t + randcount: 128 + randtype: data + name_top: RndCnstFlashCtrlAddrKey + default: 0x9e90f8e65f8cdc028e681edcb14cb2e8 + randwidth: 128 + } + { + name: RndCnstDataKey + desc: Compile-time random bits for default data key + type: flash_ctrl_pkg::flash_key_t + randcount: 128 + randtype: data + name_top: RndCnstFlashCtrlDataKey + default: 0x1c9634b9fa84fec1ccc9e2525b4acfbe + randwidth: 128 + } + { + name: RndCnstAllSeeds + desc: Compile-time random bits for default seeds + type: flash_ctrl_pkg::all_seeds_t + randcount: 512 + randtype: data + name_top: RndCnstFlashCtrlAllSeeds + default: 0xf1354b0969540f0f285312fd274e1f6136763b10aef74fea8020040b2a0b515ed5e666d771ef5001237710feb20a90edffd46b00ce07c1b5411e793482c8143e + randwidth: 512 + } + { + name: RndCnstLfsrSeed + desc: Compile-time random bits for initial LFSR seed + type: flash_ctrl_pkg::lfsr_seed_t + randcount: 32 + randtype: data + name_top: RndCnstFlashCtrlLfsrSeed + default: 0x6ae2b721 + randwidth: 32 + } + { + name: RndCnstLfsrPerm + desc: Compile-time random permutation for LFSR output + type: flash_ctrl_pkg::lfsr_perm_t + randcount: 32 + randtype: perm + name_top: RndCnstFlashCtrlLfsrPerm + default: 0x757edcd0d2e4d0b4eae27d831600b8e906756e1e + randwidth: 160 + } + { + name: SecScrambleEn + desc: Compile-time option to enable flash scrambling + type: bit + default: "0" + local: "false" + expose: "true" + name_top: SecFlashCtrlScrambleEn + } + { + name: ProgFifoDepth + desc: Depth of program fifo + type: int + default: "16" + local: "false" + expose: "true" + name_top: FlashCtrlProgFifoDepth + } + { + name: RdFifoDepth + desc: Depth of read fifo + type: int + default: "16" + local: "false" + expose: "true" + name_top: FlashCtrlRdFifoDepth + } + ] + inter_signal_list: + [ + { + name: otp + struct: flash_otp_key + package: otp_ctrl_pkg + type: req_rsp + act: req + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_nvm_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: flash_bist_enable + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + external: true + top_signame: flash_bist_enable + conn_type: false + index: -1 + } + { + name: flash_power_down_h + struct: logic + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + package: "" + external: true + top_signame: flash_power_down_h + conn_type: false + index: -1 + } + { + name: flash_power_ready_h + struct: logic + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + package: "" + external: true + top_signame: flash_power_ready_h + conn_type: false + index: -1 + } + { + name: flash_test_mode_a + struct: "" + type: io + act: none + width: 2 + inst_name: flash_ctrl + index: -1 + } + { + name: flash_test_voltage_h + struct: "" + type: io + act: none + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_creator_seed_sw_rw_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_owner_seed_sw_rw_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_iso_part_sw_rd_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_iso_part_sw_wr_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_seed_hw_rd_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: rma_req + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: rma_ack + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: rma_seed + struct: lc_flash_rma_seed + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: pwrmgr + struct: pwr_flash + package: pwrmgr_pkg + type: uni + act: req + width: 1 + inst_name: flash_ctrl + default: "" + top_signame: pwrmgr_aon_pwr_flash + index: -1 + } + { + name: keymgr + struct: keymgr_flash + package: flash_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: obs_ctrl + struct: ast_obs_ctrl + package: ast_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + external: true + top_signame: obs_ctrl + conn_type: false + index: -1 + } + { + name: fla_obs + struct: logic + type: uni + act: req + width: 8 + inst_name: flash_ctrl + default: "" + package: "" + external: true + top_signame: flash_obs + conn_type: false + index: -1 + } + { + name: core_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: flash_ctrl + default: "" + end_idx: -1 + top_signame: flash_ctrl_core_tl + index: -1 + } + { + name: prim_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: flash_ctrl + default: "" + end_idx: -1 + top_signame: flash_ctrl_prim_tl + index: -1 + } + { + name: mem_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: flash_ctrl + default: "" + end_idx: -1 + top_signame: flash_ctrl_mem_tl + index: -1 + } + ] + generate_dif: true + } + { + name: rv_plic + type: rv_plic + clock_srcs: + { + clk_i: main + } + clock_group: secure + reset_connections: + { + rst_ni: + { + name: sys + domain: "0" + } + } + attr: ipgen + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_main_secure + } + domain: + [ + "0" + ] + param_decl: {} + param_list: [] + inter_signal_list: + [ + { + name: irq + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_plic + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_plic_irq + index: -1 + } + { + name: irq_id + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_plic + index: -1 + } + { + name: msip + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_plic + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_plic_msip + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rv_plic + default: "" + end_idx: -1 + top_signame: rv_plic_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x48000000 + } + } + generate_dif: true + } + { + name: aes + type: aes + clock_srcs: + { + clk_i: main + clk_edn_i: main + } + clock_group: trans + reset_connections: + { + rst_ni: + { + name: sys + domain: "0" + } + rst_edn_ni: + { + name: sys + domain: "0" + } + } + param_decl: + { + SecMasking: "1" + SecSBoxImpl: aes_pkg::SBoxImplDom + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_main_aes + clk_edn_i: clkmgr_aon_clocks.clk_main_aes + } + domain: + [ + "0" + ] + memory: {} + param_list: + [ + { + name: AES192Enable + desc: Disable (0) or enable (1) support for 192-bit key lengths (AES-192). + type: bit + default: 1'b1 + local: "false" + expose: "false" + name_top: AesAES192Enable + } + { + name: SecMasking + desc: + ''' + Disable (0) or enable (1) first-order masking of the AES cipher core. + Masking requires the use of a masked S-Box, see SecSBoxImpl parameter. + ''' + type: bit + default: "1" + local: "false" + expose: "true" + name_top: SecAesMasking + } + { + name: SecSBoxImpl + desc: Selection of the S-Box implementation. See aes_pkg.sv. + type: aes_pkg::sbox_impl_e + default: aes_pkg::SBoxImplDom + local: "false" + expose: "true" + name_top: SecAesSBoxImpl + } + { + name: SecStartTriggerDelay + desc: + ''' + Manual start trigger delay, useful for SCA measurements. + A value of e.g. 40 allows the processor to go into sleep before AES starts operation. + ''' + type: int unsigned + default: "0" + local: "false" + expose: "true" + name_top: SecAesStartTriggerDelay + } + { + name: SecAllowForcingMasks + desc: + ''' + Forbid (0) or allow (1) forcing the masking PRNG output to a constant value via FORCE_MASKS bit in the Auxiliary Control Register. + Useful for SCA measurements. + Meaningful only if masking is enabled. + ''' + type: bit + default: 1'b0 + local: "false" + expose: "true" + name_top: SecAesAllowForcingMasks + } + { + name: SecSkipPRNGReseeding + desc: + ''' + Perform (0) or skip (1) PRNG reseeding requests, useful for SCA measurements only. + The current SCA setup doesn't provide sufficient resources to implement the infrastructure required for PRNG reseeding (CSRNG, EDN). + To enable SCA resistance evaluations, we need to skip reseeding requests on the SCA platform. + ''' + type: bit + default: 1'b0 + local: "false" + expose: "true" + name_top: SecAesSkipPRNGReseeding + } + { + name: RndCnstClearingLfsrSeed + desc: Default seed of the PRNG used for register clearing. + type: aes_pkg::clearing_lfsr_seed_t + randcount: 64 + randtype: data + name_top: RndCnstAesClearingLfsrSeed + default: 0xc5a44f9dc00a807e + randwidth: 64 + } + { + name: RndCnstClearingLfsrPerm + desc: Permutation applied to the LFSR of the PRNG used for clearing. + type: aes_pkg::clearing_lfsr_perm_t + randcount: 64 + randtype: perm + name_top: RndCnstAesClearingLfsrPerm + default: 0x80e79cf48b437e73292eb407c40d04ff2c3b476cf9368e136d55d650f912f1a882f89d5d877baf1bab18a819a58d9285 + randwidth: 384 + } + { + name: RndCnstClearingSharePerm + desc: Permutation applied to the clearing PRNG output for clearing the second share of registers. + type: aes_pkg::clearing_lfsr_perm_t + randcount: 64 + randtype: perm + name_top: RndCnstAesClearingSharePerm + default: 0x80d40cbf860e22779193a5f54b4d997d60d3f2b9a3c4af4754497f09bca214ba3bc1d6aa073e5c86ef8f254dedb29180 + randwidth: 384 + } + { + name: RndCnstMaskingLfsrSeed + desc: Default seed of the PRNG used for masking. + type: aes_pkg::masking_lfsr_seed_t + randcount: 288 + randtype: data + name_top: RndCnstAesMaskingLfsrSeed + default: 0xff657fc29427d0f48aad106e3859890c0902355895a38418fa02e1245e46fac24fa1fc04 + randwidth: 288 + } + { + name: RndCnstMaskingLfsrPerm + desc: Permutation applied to the output of the PRNG used for masking. + type: aes_pkg::masking_lfsr_perm_t + randcount: 160 + randtype: perm + name_top: RndCnstAesMaskingLfsrPerm + default: 0x9d12152e8b3c0f99008d951071673b882f61057f1e7b16685439498c5f34735a4f59705b7437751a369c0c64291b4b2c879a657a9b254a2076401d246d06698f5277010357433197483242189019932b7c9f274d08603a358545621f2a81500e923d51786c2d46021c6e445e589e72803f66418e6b6f6a170d565d8a82237d79949809330b4c530a9186846389133830048326963e4e1147555c07221421287e + randwidth: 1280 + } + ] + inter_signal_list: + [ + { + name: idle + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: aes + default: "" + top_signame: clkmgr_aon_idle + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: aes + index: -1 + } + { + name: edn + struct: edn + package: edn_pkg + type: req_rsp + act: req + width: 1 + inst_name: aes + index: -1 + } + { + name: keymgr_key + struct: hw_key_req + package: keymgr_pkg + type: uni + act: rcv + width: 1 + inst_name: aes + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: aes + default: "" + end_idx: -1 + top_signame: aes_tl + index: -1 + } + ] + base_addrs: + { + null: + { + hart: 0x41100000 + } + } + generate_dif: true + } + { + name: sram_ctrl_main + type: sram_ctrl + clock_srcs: + { + clk_i: main + clk_otp_i: io_div4 + } + clock_group: secure + reset_connections: + { + rst_ni: + { + name: sys + domain: "0" + } + rst_otp_ni: + { + name: lc_io_div4 + domain: "0" + } + } + param_decl: + { + InstrExec: "1" + } + base_addrs: + { + regs: + { + hart: 0x411C0000 + } + ram: + { + hart: 0x10000000 + } + } + memory: + { + ram: + { + label: ram_main + swaccess: rw + exec: True + byte_write: True + size: 0x20000 + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_main_secure + clk_otp_i: clkmgr_aon_clocks.clk_io_div4_secure + } + domain: + [ + "0" + ] + param_list: + [ + { + name: RndCnstSramKey + desc: Compile-time random reset value for SRAM scrambling key. + type: otp_ctrl_pkg::sram_key_t + randcount: 128 + randtype: data + name_top: RndCnstSramCtrlMainSramKey + default: 0xa84afd110e65e2c09d4012491ac45c2d + randwidth: 128 + } + { + name: RndCnstSramNonce + desc: Compile-time random reset value for SRAM scrambling nonce. + type: otp_ctrl_pkg::sram_nonce_t + randcount: 128 + randtype: data + name_top: RndCnstSramCtrlMainSramNonce + default: 0x7799e699c02a50aee3b25af703b953b + randwidth: 128 + } + { + name: RndCnstLfsrSeed + desc: Compile-time random bits for initial LFSR seed + type: sram_ctrl_pkg::lfsr_seed_t + randcount: 32 + randtype: data + name_top: RndCnstSramCtrlMainLfsrSeed + default: 0x72c25acd + randwidth: 32 + } + { + name: RndCnstLfsrPerm + desc: Compile-time random permutation for LFSR output + type: sram_ctrl_pkg::lfsr_perm_t + randcount: 32 + randtype: perm + name_top: RndCnstSramCtrlMainLfsrPerm + default: 0x70f1c20229aef41baec26351432b3283cb33fbbf + randwidth: 160 + } + { + name: MemSizeRam + desc: Memory size of the RAM (in bytes). + type: int + name_top: MemSizeSramCtrlMainRam + default: 131072 + } + { + name: InstSize + desc: Memory size of a single RAM tile (in bytes). + type: int + default: "4096" + local: "false" + expose: "true" + name_top: SramCtrlMainInstSize + } + { + name: NumRamInst + desc: Number of internal RAM instances. Must be the same as ceil(MemSizeRam / InstSize) . + type: int + default: 1 + local: "false" + expose: "true" + name_top: SramCtrlMainNumRamInst + } + { + name: InstrExec + desc: Support execution from SRAM + type: bit + default: "1" + local: "false" + expose: "true" + name_top: SramCtrlMainInstrExec + } + { + name: NumPrinceRoundsHalf + desc: Number of PRINCE half rounds for the SRAM scrambling feature + type: int + default: "3" + local: "false" + expose: "true" + name_top: SramCtrlMainNumPrinceRoundsHalf + } + ] + inter_signal_list: + [ + { + name: sram_otp_key + struct: sram_otp_key + package: otp_ctrl_pkg + type: req_rsp + act: req + width: 1 + inst_name: sram_ctrl_main + index: -1 + } + { + name: cfg + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: + { + name: NumRamInst + desc: Number of internal RAM instances. Must be the same as ceil(MemSizeRam / InstSize) . + param_type: int + unpacked_dimensions: null + default: 1 + local: false + expose: true + name_top: SramCtrlMainNumRamInst + } + default: "'0" + inst_name: sram_ctrl_main + index: -1 + } + { + name: cfg_rsp + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: + { + name: NumRamInst + desc: Number of internal RAM instances. Must be the same as ceil(MemSizeRam / InstSize) . + param_type: int + unpacked_dimensions: null + default: 1 + local: false + expose: true + name_top: SramCtrlMainNumRamInst + } + default: "'0" + inst_name: sram_ctrl_main + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: sram_ctrl_main + index: -1 + } + { + name: lc_hw_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: sram_ctrl_main + index: -1 + } + { + name: otp_en_sram_ifetch + struct: mubi8 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + default: prim_mubi_pkg::MuBi8False + inst_name: sram_ctrl_main + top_signame: sram_ctrl_main_otp_en_sram_ifetch + index: -1 + } + { + name: regs_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: sram_ctrl_main + default: "" + end_idx: -1 + top_signame: sram_ctrl_main_regs_tl + index: -1 + } + { + name: ram_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: sram_ctrl_main + default: "" + end_idx: -1 + top_signame: sram_ctrl_main_ram_tl + index: -1 + } + ] + generate_dif: true + } + { + name: rom_ctrl + type: rom_ctrl + clock_srcs: + { + clk_i: main + } + clock_group: infra + reset_connections: + { + rst_ni: + { + name: sys + domain: "0" + } + } + base_addrs: + { + rom: + { + hart: 0x00008000 + } + regs: + { + hart: 0x411e0000 + } + } + memory: + { + rom: + { + label: rom + swaccess: ro + exec: True + byte_write: False + size: 0x8000 + } + } + param_decl: + { + SecDisableScrambling: 1'b1 + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_main_infra + } + domain: + [ + "0" + ] + param_list: + [ + { + name: BootRomInitFile + desc: Contents of ROM + type: "" + default: '''""''' + local: "false" + expose: "true" + name_top: RomCtrlBootRomInitFile + } + { + name: RndCnstScrNonce + desc: Fixed nonce used for address / data scrambling + type: bit [63:0] + randcount: 64 + randtype: data + name_top: RndCnstRomCtrlScrNonce + default: 0xa055cd153e14afcf + randwidth: 64 + } + { + name: RndCnstScrKey + desc: Randomised constant used as a scrambling key for ROM data + type: bit [127:0] + randcount: 128 + randtype: data + name_top: RndCnstRomCtrlScrKey + default: 0xaf2b8b9ba0eeeeeab949b4462a2e7e3b + randwidth: 128 + } + { + name: SecDisableScrambling + desc: + ''' + Disable scrambling and checking in rom_ctrl, turning the block into a + simple ROM wrapper. This isn't intended for real chips, but is useful + for small FPGA targets where there's not space for the PRINCE + primitives. + ''' + type: bit + default: 1'b1 + local: "false" + expose: "true" + name_top: SecRomCtrlDisableScrambling + } + { + name: MemSizeRom + desc: Memory size of the ROM (in bytes). + type: int + name_top: MemSizeRomCtrlRom + default: 32768 + } + ] + inter_signal_list: + [ + { + name: rom_cfg + struct: rom_cfg + package: prim_rom_pkg + type: uni + act: rcv + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: pwrmgr_data + struct: pwrmgr_data + package: rom_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: keymgr_data + struct: keymgr_data + package: rom_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: kmac_data + struct: app + package: kmac_pkg + type: req_rsp + act: req + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: regs_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rom_ctrl + default: "" + end_idx: -1 + top_signame: rom_ctrl_regs_tl + index: -1 + } + { + name: rom_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rom_ctrl + default: "" + end_idx: -1 + top_signame: rom_ctrl_rom_tl + index: -1 + } + ] + generate_dif: true + } + { + name: rv_core_ibex + type: rv_core_ibex + param_decl: + { + PMPEnable: "0" + PMPGranularity: "0" + PMPNumRegions: "16" + MHPMCounterNum: "0" + MHPMCounterWidth: "32" + RV32E: "0" + RV32M: ibex_pkg::RV32MSingleCycle + RV32B: ibex_pkg::RV32BNone + RegFile: ibex_pkg::RegFileFF + BranchTargetALU: "1" + WritebackStage: "1" + ICache: "0" + ICacheECC: "0" + BranchPredictor: "0" + DbgTriggerEn: "1" + SecureIbex: "0" + DmHaltAddr: "0" + DmExceptionAddr: "0" + PipeLine: "0" + } + clock_srcs: + { + clk_i: main + clk_edn_i: main + clk_esc_i: io_div4 + clk_otp_i: io_div4 + } + clock_group: infra + reset_connections: + { + rst_ni: + { + name: sys + domain: "0" + } + rst_edn_ni: + { + name: sys + domain: "0" + } + rst_esc_ni: + { + name: lc_io_div4 + domain: "0" + } + rst_otp_ni: + { + name: lc_io_div4 + domain: "0" + } + } + clock_connections: + { + clk_i: clkmgr_aon_clocks.clk_main_infra + clk_edn_i: clkmgr_aon_clocks.clk_main_infra + clk_esc_i: clkmgr_aon_clocks.clk_io_div4_infra + clk_otp_i: clkmgr_aon_clocks.clk_io_div4_infra + } + domain: + [ + "0" + ] + memory: {} + param_list: + [ + { + name: RndCnstLfsrSeed + desc: Default seed of the PRNG used for random instructions. + type: ibex_pkg::lfsr_seed_t + randcount: 32 + randtype: data + name_top: RndCnstRvCoreIbexLfsrSeed + default: 0x88f2805b + randwidth: 32 + } + { + name: RndCnstLfsrPerm + desc: Permutation applied to the LFSR of the PRNG used for random instructions. + type: ibex_pkg::lfsr_perm_t + randcount: 32 + randtype: perm + name_top: RndCnstRvCoreIbexLfsrPerm + default: 0xc19b5091071af9efd36fc952e8a99300af097756 + randwidth: 160 + } + { + name: RndCnstIbexKeyDefault + desc: Default icache scrambling key + type: logic [ibex_pkg::SCRAMBLE_KEY_W-1:0] + randcount: 128 + randtype: data + name_top: RndCnstRvCoreIbexIbexKeyDefault + default: 0x6aeabf2275afc88a1d1273b99c6d2d23 + randwidth: 128 + } + { + name: RndCnstIbexNonceDefault + desc: Default icache scrambling nonce + type: logic [ibex_pkg::SCRAMBLE_NONCE_W-1:0] + randcount: 64 + randtype: data + name_top: RndCnstRvCoreIbexIbexNonceDefault + default: 0x9f28888f3ef00fc7 + randwidth: 64 + } + { + name: NEscalationSeverities + desc: Number of escalation severities + type: int unsigned + default: "4" + local: "true" + expose: "true" + name_top: RvCoreIbexNEscalationSeverities + } + { + name: WidthPingCounter + desc: Width of the ping counter + type: int unsigned + default: "16" + local: "true" + expose: "true" + name_top: RvCoreIbexWidthPingCounter + } + { + name: PMPEnable + desc: Enable PMP + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexPMPEnable + } + { + name: PMPGranularity + desc: PMP Granularity + type: int unsigned + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexPMPGranularity + } + { + name: PMPNumRegions + desc: PMP number of regions + type: int unsigned + default: "16" + local: "false" + expose: "true" + name_top: RvCoreIbexPMPNumRegions + } + { + name: MHPMCounterNum + desc: "Number of the MHPM counter " + type: int unsigned + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexMHPMCounterNum + } + { + name: MHPMCounterWidth + desc: "Width of the MHPM Counter " + type: int unsigned + default: "32" + local: "false" + expose: "true" + name_top: RvCoreIbexMHPMCounterWidth + } + { + name: PMPRstCfg + desc: Reset value of PMP config CSRs + type: ibex_pkg::pmp_cfg_t + unpacked_dimensions: "[16]" + default: ibex_pkg::PmpCfgRst + local: "false" + expose: "true" + name_top: RvCoreIbexPMPRstCfg + } + { + name: PMPRstAddr + desc: Reset value of PMP address CSRs + type: logic [33:0] + unpacked_dimensions: "[16]" + default: ibex_pkg::PmpAddrRst + local: "false" + expose: "true" + name_top: RvCoreIbexPMPRstAddr + } + { + name: PMPRstMsecCfg + desc: Reset value of MSECCFG CSR + type: ibex_pkg::pmp_mseccfg_t + default: ibex_pkg::PmpMseccfgRst + local: "false" + expose: "true" + name_top: RvCoreIbexPMPRstMsecCfg + } + { + name: RV32E + desc: RV32E + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexRV32E + } + { + name: RV32M + desc: RV32M + type: ibex_pkg::rv32m_e + default: ibex_pkg::RV32MSingleCycle + local: "false" + expose: "true" + name_top: RvCoreIbexRV32M + } + { + name: RV32B + desc: RV32B + type: ibex_pkg::rv32b_e + default: ibex_pkg::RV32BNone + local: "false" + expose: "true" + name_top: RvCoreIbexRV32B + } + { + name: RegFile + desc: Reg file + type: ibex_pkg::regfile_e + default: ibex_pkg::RegFileFF + local: "false" + expose: "true" + name_top: RvCoreIbexRegFile + } + { + name: BranchTargetALU + desc: Branch target ALU + type: bit + default: "1" + local: "false" + expose: "true" + name_top: RvCoreIbexBranchTargetALU + } + { + name: WritebackStage + desc: Write back stage + type: bit + default: "1" + local: "false" + expose: "true" + name_top: RvCoreIbexWritebackStage + } + { + name: ICache + desc: Instruction cache + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexICache + } + { + name: ICacheECC + desc: Instruction cache ECC + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexICacheECC + } + { + name: ICacheScramble + desc: Scramble instruction cach + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexICacheScramble + } + { + name: ICacheNWays + desc: Number of instruction cache ways + type: int unsigned + default: 2 + local: "false" + expose: "true" + name_top: RvCoreIbexICacheNWays + } + { + name: BranchPredictor + desc: Branch predictor + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexBranchPredictor + } + { + name: DbgTriggerEn + desc: Enable degug trigger + type: bit + default: "1" + local: "false" + expose: "true" + name_top: RvCoreIbexDbgTriggerEn + } + { + name: DbgHwBreakNum + desc: Number of debug hardware break + type: int + default: "1" + local: "false" + expose: "true" + name_top: RvCoreIbexDbgHwBreakNum + } + { + name: SecureIbex + desc: "Width of the MHPM Counter " + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexSecureIbex + } + { + name: DmBaseAddr + desc: Base address of Debug Module + type: int unsigned + default: "437321728" + local: "false" + expose: "true" + name_top: RvCoreIbexDmBaseAddr + } + { + name: DmAddrMask + desc: Adress mask of Debug Module + type: int unsigned + default: "4095" + local: "false" + expose: "true" + name_top: RvCoreIbexDmAddrMask + } + { + name: DmHaltAddr + desc: Halt address + type: int unsigned + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexDmHaltAddr + } + { + name: DmExceptionAddr + desc: Exception address + type: int unsigned + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexDmExceptionAddr + } + { + name: PipeLine + desc: Pipe line + type: bit + default: "0" + local: "false" + expose: "true" + name_top: RvCoreIbexPipeLine + } + ] + inter_signal_list: + [ + { + name: rst_cpu_n + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_icache_tag + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_rsp_icache_tag + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: + { + name: ICacheNWays + desc: Number of instruction cache ways + param_type: int unsigned + unpacked_dimensions: null + default: 2 + local: false + expose: true + name_top: RvCoreIbexICacheNWays + } + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_icache_data + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_rsp_icache_data + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: + { + name: ICacheNWays + desc: Number of instruction cache ways + param_type: int unsigned + unpacked_dimensions: null + default: 2 + local: false + expose: true + name_top: RvCoreIbexICacheNWays + } + inst_name: rv_core_ibex + index: -1 + } + { + name: hart_id + struct: logic + type: uni + act: rcv + width: 32 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_core_ibex_hart_id + index: -1 + } + { + name: boot_addr + struct: logic + type: uni + act: rcv + width: 32 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_core_ibex_boot_addr + index: -1 + } + { + name: irq_software + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_plic_msip + index: -1 + } + { + name: irq_timer + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_core_ibex_irq_timer + index: -1 + } + { + name: irq_external + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_plic_irq + index: -1 + } + { + name: esc_tx + struct: esc_tx + package: prim_esc_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: esc_rx + struct: esc_rx + package: prim_esc_pkg + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: debug_req + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: crash_dump + struct: cpu_crash_dump + package: rv_core_ibex_pkg + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_core_ibex_crash_dump + index: -1 + } + { + name: lc_cpu_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: rv_core_ibex_lc_cpu_en + index: -1 + } + { + name: pwrmgr_cpu_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: pwrmgr_aon_fetch_en + index: -1 + } + { + name: pwrmgr + struct: cpu_pwrmgr + package: rv_core_ibex_pkg + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_core_ibex_pwrmgr + index: -1 + } + { + name: nmi_wdog + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: edn + struct: edn + package: edn_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: icache_otp_key + struct: sram_otp_key + package: otp_ctrl_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: fpga_info + struct: logic + type: uni + act: rcv + width: 32 + inst_name: rv_core_ibex + default: "" + package: "" + external: true + top_signame: fpga_info + conn_type: false + index: -1 + } + { + name: corei_tl_h + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: main_tl_rv_core_ibex__corei + index: -1 + } + { + name: cored_tl_h + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: main_tl_rv_core_ibex__cored + index: -1 + } + { + name: cfg_tl_d + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rv_core_ibex + default: "" + end_idx: -1 + top_signame: rv_core_ibex_cfg_tl_d + index: -1 + } + ] + base_addrs: + { + cfg: + { + hart: 0x411F0000 + } + } + generate_dif: true + } + ] + memory: [] + port: + [ + { + name: ast + inter_signal_list: + [ + { + struct: edn + type: req_rsp + name: edn + act: rsp + package: edn_pkg + inst_name: ast + width: 1 + default: "" + external: true + top_signame: ast_edn + conn_type: false + index: -1 + } + { + struct: lc_tx + type: uni + name: lc_dft_en + act: req + package: lc_ctrl_pkg + inst_name: ast + width: 1 + default: "" + external: true + top_signame: ast_lc_dft_en + conn_type: false + index: -1 + } + { + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + name: ram_1p_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: ram_1p_cfg + conn_type: false + index: -1 + } + { + struct: ram_2p_cfg + package: prim_ram_2p_pkg + type: uni + name: spi_ram_2p_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: spi_ram_2p_cfg + conn_type: false + index: -1 + } + { + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + name: usb_ram_1p_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: usb_ram_1p_cfg + conn_type: false + index: -1 + } + { + struct: rom_cfg + package: prim_rom_pkg + type: uni + name: rom_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: rom_cfg + conn_type: false + index: -1 + } + ] + } + ] + inter_module: + { + connect: + { + pwrmgr_aon.pwr_flash: + [ + flash_ctrl.pwrmgr + ] + pwrmgr_aon.pwr_rst: + [ + rstmgr_aon.pwr + ] + pwrmgr_aon.pwr_clk: + [ + clkmgr_aon.pwr + ] + pwrmgr_aon.strap: + [ + pinmux_aon.strap_en + ] + pwrmgr_aon.low_power: + [ + pinmux_aon.sleep_en + aon_timer_aon.sleep_mode + ] + pwrmgr_aon.fetch_en: + [ + rv_core_ibex.pwrmgr_cpu_en + ] + usbdev.usb_dp_pullup: + [ + pinmux_aon.usbdev_dppullup_en + ] + usbdev.usb_dn_pullup: + [ + pinmux_aon.usbdev_dnpullup_en + ] + usbdev.usb_aon_suspend_req: + [ + pinmux_aon.usbdev_suspend_req + ] + usbdev.usb_aon_wake_ack: + [ + pinmux_aon.usbdev_wake_ack + ] + usbdev.usb_aon_bus_reset: + [ + pinmux_aon.usbdev_bus_reset + ] + usbdev.usb_aon_sense_lost: + [ + pinmux_aon.usbdev_sense_lost + ] + pinmux_aon.usbdev_wake_detect_active: + [ + usbdev.usb_aon_wake_detect_active + ] + clkmgr_aon.idle: + [ + aes.idle + ] + rv_plic.msip: + [ + rv_core_ibex.irq_software + ] + rv_plic.irq: + [ + rv_core_ibex.irq_external + ] + rv_core_ibex.crash_dump: + [ + rstmgr_aon.cpu_dump + ] + rv_core_ibex.pwrmgr: + [ + pwrmgr_aon.pwr_cpu + ] + spi_device.passthrough: + [ + spi_host0.passthrough + ] + rstmgr_aon.sw_rst_req: + [ + pwrmgr_aon.sw_rst_req + ] + pwrmgr_aon.wakeups: + [ + pinmux_aon.pin_wkup_req + pinmux_aon.usb_wkup_req + aon_timer_aon.wkup_req + ] + pwrmgr_aon.rstreqs: + [ + aon_timer_aon.aon_timer_rst_req + ] + main.tl_rv_core_ibex__corei: + [ + rv_core_ibex.corei_tl_h + ] + main.tl_rv_core_ibex__cored: + [ + rv_core_ibex.cored_tl_h + ] + rom_ctrl.rom_tl: + [ + main.tl_rom_ctrl__rom + ] + rom_ctrl.regs_tl: + [ + main.tl_rom_ctrl__regs + ] + main.tl_peri: + [ + peri.tl_main + ] + flash_ctrl.core_tl: + [ + main.tl_flash_ctrl__core + ] + flash_ctrl.prim_tl: + [ + main.tl_flash_ctrl__prim + ] + flash_ctrl.mem_tl: + [ + main.tl_flash_ctrl__mem + ] + aes.tl: + [ + main.tl_aes + ] + rv_plic.tl: + [ + main.tl_rv_plic + ] + rv_core_ibex.cfg_tl_d: + [ + main.tl_rv_core_ibex__cfg + ] + sram_ctrl_main.regs_tl: + [ + main.tl_sram_ctrl_main__regs + ] + sram_ctrl_main.ram_tl: + [ + main.tl_sram_ctrl_main__ram + ] + uart0.tl: + [ + peri.tl_uart0 + ] + uart1.tl: + [ + peri.tl_uart1 + ] + gpio.tl: + [ + peri.tl_gpio + ] + spi_device.tl: + [ + peri.tl_spi_device + ] + spi_host0.tl: + [ + peri.tl_spi_host0 + ] + rv_timer.tl: + [ + peri.tl_rv_timer + ] + usbdev.tl: + [ + peri.tl_usbdev + ] + pwrmgr_aon.tl: + [ + peri.tl_pwrmgr_aon + ] + rstmgr_aon.tl: + [ + peri.tl_rstmgr_aon + ] + clkmgr_aon.tl: + [ + peri.tl_clkmgr_aon + ] + pinmux_aon.tl: + [ + peri.tl_pinmux_aon + ] + } + top: + [ + clkmgr_aon.clocks + clkmgr_aon.cg_en + rstmgr_aon.resets + rstmgr_aon.rst_en + rv_core_ibex.irq_timer + rv_core_ibex.hart_id + rv_core_ibex.boot_addr + rv_core_ibex.lc_cpu_en + pinmux_aon.dft_jtag + sram_ctrl_main.otp_en_sram_ifetch + ] + external: + { + ast.edn: "" + ast.lc_dft_en: "" + ast.ram_1p_cfg: ram_1p_cfg + ast.spi_ram_2p_cfg: spi_ram_2p_cfg + ast.usb_ram_1p_cfg: usb_ram_1p_cfg + ast.rom_cfg: rom_cfg + clkmgr_aon.jitter_en: clk_main_jitter_en + clkmgr_aon.hi_speed_sel: hi_speed_sel + clkmgr_aon.div_step_down_req: div_step_down_req + clkmgr_aon.all_clk_byp_req: all_clk_byp_req + clkmgr_aon.all_clk_byp_ack: all_clk_byp_ack + clkmgr_aon.io_clk_byp_req: io_clk_byp_req + clkmgr_aon.io_clk_byp_ack: io_clk_byp_ack + flash_ctrl.flash_bist_enable: flash_bist_enable + flash_ctrl.flash_power_down_h: flash_power_down_h + flash_ctrl.flash_power_ready_h: flash_power_ready_h + flash_ctrl.obs_ctrl: obs_ctrl + flash_ctrl.fla_obs: flash_obs + peri.tl_ast: ast_tl + pinmux_aon.dft_strap_test: dft_strap_test + pinmux_aon.dft_hold_tap_sel: dft_hold_tap_sel + pinmux_aon.usb_dppullup_en: usb_dp_pullup_en + pinmux_aon.usb_dnpullup_en: usb_dn_pullup_en + pwrmgr_aon.pwr_ast: pwrmgr_ast + rstmgr_aon.por_n: por_n + rv_core_ibex.fpga_info: fpga_info + usbdev.usb_rx_d: "" + usbdev.usb_tx_d: "" + usbdev.usb_tx_se0: "" + usbdev.usb_tx_use_d_se0: "" + usbdev.usb_rx_enable: "" + usbdev.usb_ref_val: "" + usbdev.usb_ref_pulse: "" + spi_device.sck_monitor: sck_monitor + } + } + xbar: + [ + { + name: main + clock_srcs: + { + clk_main_i: main + clk_fixed_i: io_div4 + } + clock_group: infra + reset: rst_main_ni + reset_connections: + { + rst_main_ni: + { + name: sys + domain: "0" + } + rst_fixed_ni: + { + name: sys_io_div4 + domain: "0" + } + } + clock_connections: + { + clk_main_i: clkmgr_aon_clocks.clk_main_infra + clk_fixed_i: clkmgr_aon_clocks.clk_io_div4_infra + } + domain: + [ + "0" + ] + connections: + { + rv_core_ibex.corei: + [ + rom_ctrl.rom + sram_ctrl_main.ram + flash_ctrl.mem + ] + rv_core_ibex.cored: + [ + rom_ctrl.rom + rom_ctrl.regs + sram_ctrl_main.ram + flash_ctrl.mem + peri + flash_ctrl.core + flash_ctrl.prim + aes + rv_plic + sram_ctrl_main.ram + sram_ctrl_main.regs + rv_core_ibex.cfg + ] + } + nodes: + [ + { + name: rv_core_ibex.corei + type: host + addr_space: hart + clock: clk_main_i + reset: rst_main_ni + pipeline: false + xbar: false + stub: false + inst_type: "" + req_fifo_pass: true + rsp_fifo_pass: true + } + { + name: rv_core_ibex.cored + type: host + addr_space: hart + clock: clk_main_i + reset: rst_main_ni + pipeline: false + xbar: false + stub: false + inst_type: "" + req_fifo_pass: true + rsp_fifo_pass: true + } + { + name: rom_ctrl.rom + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: rom_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x8000 + } + size_byte: 0x8000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rom_ctrl.regs + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: rom_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x411e0000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: peri + type: device + clock: clk_fixed_i + reset: rst_fixed_ni + pipeline: false + xbar: true + stub: false + req_fifo_pass: true + addr_space: hart + addr_range: + [ + { + base_addrs: + { + hart: 0x40000000 + } + size_byte: 0x800000 + } + ] + } + { + name: flash_ctrl.core + type: device + clock: clk_main_i + reset: rst_main_ni + req_fifo_pass: true + rsp_fifo_pass: false + inst_type: flash_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x41000000 + } + size_byte: 0x200 + } + ] + xbar: false + stub: false + pipeline: true + } + { + name: flash_ctrl.prim + type: device + clock: clk_main_i + reset: rst_main_ni + req_fifo_pass: true + rsp_fifo_pass: false + inst_type: flash_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x41008000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + pipeline: true + } + { + name: flash_ctrl.mem + type: device + clock: clk_main_i + reset: rst_main_ni + req_fifo_pass: true + rsp_fifo_pass: false + inst_type: flash_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x20000000 + } + size_byte: 0x10000 + } + ] + xbar: false + stub: false + pipeline: true + } + { + name: aes + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: aes + addr_range: + [ + { + base_addrs: + { + hart: 0x41100000 + } + size_byte: 0x100 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rv_plic + type: device + clock: clk_main_i + reset: rst_main_ni + inst_type: rv_plic + pipeline: false + addr_range: + [ + { + base_addrs: + { + hart: 0x48000000 + } + size_byte: 0x8000000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rv_core_ibex.cfg + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: rv_core_ibex + addr_range: + [ + { + base_addrs: + { + hart: 0x411f0000 + } + size_byte: 0x100 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: sram_ctrl_main.regs + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: sram_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x411c0000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: sram_ctrl_main.ram + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: sram_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x10000000 + } + size_byte: 0x20000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + ] + addr_spaces: + [ + hart + ] + clock: clk_main_i + type: xbar + inter_signal_list: + [ + { + name: tl_rv_core_ibex__corei + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: main + default: "" + end_idx: -1 + top_signame: main_tl_rv_core_ibex__corei + index: -1 + } + { + name: tl_rv_core_ibex__cored + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: main + default: "" + end_idx: -1 + top_signame: main_tl_rv_core_ibex__cored + index: -1 + } + { + name: tl_rom_ctrl__rom + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rom_ctrl_rom_tl + index: -1 + } + { + name: tl_rom_ctrl__regs + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rom_ctrl_regs_tl + index: -1 + } + { + name: tl_peri + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + end_idx: -1 + top_signame: main_tl_peri + index: -1 + } + { + name: tl_flash_ctrl__core + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: flash_ctrl_core_tl + index: -1 + } + { + name: tl_flash_ctrl__prim + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: flash_ctrl_prim_tl + index: -1 + } + { + name: tl_flash_ctrl__mem + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: flash_ctrl_mem_tl + index: -1 + } + { + name: tl_aes + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: aes_tl + index: -1 + } + { + name: tl_rv_plic + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rv_plic_tl + index: -1 + } + { + name: tl_rv_core_ibex__cfg + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rv_core_ibex_cfg_tl_d + index: -1 + } + { + name: tl_sram_ctrl_main__regs + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: sram_ctrl_main_regs_tl + index: -1 + } + { + name: tl_sram_ctrl_main__ram + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: sram_ctrl_main_ram_tl + index: -1 + } + ] + } + { + name: peri + clock_srcs: + { + clk_peri_i: io_div4 + clk_spi_host0_i: io + clk_usb_i: usb + } + clock_group: infra + reset: rst_peri_ni + reset_connections: + { + rst_peri_ni: + { + name: sys_io_div4 + domain: "0" + } + rst_spi_host0_ni: + { + name: spi_host0 + domain: "0" + } + rst_usb_ni: + { + name: usb + domain: "0" + } + } + clock_connections: + { + clk_peri_i: clkmgr_aon_clocks.clk_io_div4_infra + clk_spi_host0_i: clkmgr_aon_clocks.clk_io_infra + clk_usb_i: clkmgr_aon_clocks.clk_usb_infra + } + domain: + [ + "0" + ] + connections: + { + main: + [ + uart0 + uart1 + gpio + spi_device + spi_host0 + rv_timer + usbdev + pwrmgr_aon + rstmgr_aon + clkmgr_aon + pinmux_aon + ast + ] + } + nodes: + [ + { + name: main + type: host + addr_space: hart + clock: clk_peri_i + reset: rst_peri_ni + xbar: true + pipeline: false + stub: false + inst_type: "" + req_fifo_pass: true + rsp_fifo_pass: true + } + { + name: uart0 + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: uart + addr_range: + [ + { + base_addrs: + { + hart: 0x40000000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: uart1 + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: uart + addr_range: + [ + { + base_addrs: + { + hart: 0x40010000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: gpio + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: gpio + addr_range: + [ + { + base_addrs: + { + hart: 0x40040000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: spi_device + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: spi_device + addr_range: + [ + { + base_addrs: + { + hart: 0x40050000 + } + size_byte: 0x2000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: spi_host0 + type: device + clock: clk_spi_host0_i + reset: rst_spi_host0_ni + pipeline: false + inst_type: spi_host + addr_range: + [ + { + base_addrs: + { + hart: 0x40060000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rv_timer + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: rv_timer + addr_range: + [ + { + base_addrs: + { + hart: 0x40100000 + } + size_byte: 0x200 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: usbdev + type: device + clock: clk_usb_i + reset: rst_usb_ni + pipeline: false + inst_type: usbdev + addr_range: + [ + { + base_addrs: + { + hart: 0x40320000 + } + size_byte: 0x1000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: pwrmgr_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: pwrmgr + addr_range: + [ + { + base_addrs: + { + hart: 0x40400000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rstmgr_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: rstmgr + addr_range: + [ + { + base_addrs: + { + hart: 0x40410000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: clkmgr_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: clkmgr + addr_range: + [ + { + base_addrs: + { + hart: 0x40420000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: pinmux_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: pinmux + addr_range: + [ + { + base_addrs: + { + hart: 0x40460000 + } + size_byte: 0x1000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: ast + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: ast + addr_range: + [ + { + base_addrs: + { + hart: 0x40480000 + } + size_byte: 0x400 + } + ] + xbar: false + stub: true + req_fifo_pass: true + } + ] + addr_spaces: + [ + hart + ] + clock: clk_peri_i + type: xbar + inter_signal_list: + [ + { + name: tl_main + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: peri + default: "" + top_signame: main_tl_peri + index: -1 + } + { + name: tl_uart0 + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: uart0_tl + index: -1 + } + { + name: tl_uart1 + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: uart1_tl + index: -1 + } + { + name: tl_gpio + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: gpio_tl + index: -1 + } + { + name: tl_spi_device + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: spi_device_tl + index: -1 + } + { + name: tl_spi_host0 + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: spi_host0_tl + index: -1 + } + { + name: tl_rv_timer + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: rv_timer_tl + index: -1 + } + { + name: tl_usbdev + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: usbdev_tl + index: -1 + } + { + name: tl_pwrmgr_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: pwrmgr_aon_tl + index: -1 + } + { + name: tl_rstmgr_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: rstmgr_aon_tl + index: -1 + } + { + name: tl_clkmgr_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: clkmgr_aon_tl + index: -1 + } + { + name: tl_pinmux_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: pinmux_aon_tl + index: -1 + } + { + name: tl_ast + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + external: true + top_signame: ast_tl + conn_type: false + index: -1 + } + ] + } + ] + interrupt_module: + [ + uart0 + uart1 + gpio + spi_device + spi_host0 + usbdev + pwrmgr_aon + aon_timer_aon + flash_ctrl + ] + pinout: + { + banks: + [ + VCC + AVCC + VIOA + VIOB + ] + pads: + [ + { + name: POR_N + type: InputStd + bank: VCC + connection: manual + desc: System reset + port_type: inout + idx: 0 + } + { + name: USB_P + type: BidirTol + bank: VCC + connection: manual + desc: USB P signal + port_type: inout + idx: 1 + } + { + name: USB_N + type: BidirTol + bank: VCC + connection: manual + desc: USB N signal + port_type: inout + idx: 2 + } + { + name: CC1 + type: InputStd + bank: AVCC + connection: manual + desc: ADC input 1 + port_type: inout + idx: 3 + } + { + name: CC2 + type: InputStd + bank: AVCC + connection: manual + desc: ADC input 2 + port_type: inout + idx: 4 + } + { + name: FLASH_TEST_VOLT + type: AnalogIn0 + bank: VCC + connection: manual + desc: Flash test voltage input + port_type: inout + idx: 5 + } + { + name: FLASH_TEST_MODE0 + type: InputStd + bank: VCC + connection: manual + desc: Flash test mode signal + port_type: inout + idx: 6 + } + { + name: FLASH_TEST_MODE1 + type: InputStd + bank: VCC + connection: manual + desc: Flash test mode signal + port_type: inout + idx: 7 + } + { + name: SPI_HOST_D0 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI host data + port_type: inout + idx: 8 + } + { + name: SPI_HOST_D1 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI host data + port_type: inout + idx: 9 + } + { + name: SPI_HOST_D2 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI host data + port_type: inout + idx: 10 + } + { + name: SPI_HOST_D3 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI host data + port_type: inout + idx: 11 + } + { + name: SPI_HOST_CLK + type: BidirStd + bank: VIOA + connection: direct + desc: SPI host clock + port_type: inout + idx: 12 + } + { + name: SPI_HOST_CS_L + type: BidirStd + bank: VIOA + connection: direct + desc: SPI host chip select + port_type: inout + idx: 13 + } + { + name: SPI_DEV_D0 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI device data + port_type: inout + idx: 14 + } + { + name: SPI_DEV_D1 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI device data + port_type: inout + idx: 15 + } + { + name: SPI_DEV_D2 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI device data + port_type: inout + idx: 16 + } + { + name: SPI_DEV_D3 + type: BidirStd + bank: VIOA + connection: direct + desc: SPI device data + port_type: inout + idx: 17 + } + { + name: SPI_DEV_CLK + type: InputStd + bank: VIOA + connection: direct + desc: SPI device clock + port_type: inout + idx: 18 + } + { + name: SPI_DEV_CS_L + type: InputStd + bank: VIOA + connection: direct + desc: SPI device chip select + port_type: inout + idx: 19 + } + { + name: IOA0 + type: BidirStd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 0 + } + { + name: IOA1 + type: BidirStd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 1 + } + { + name: IOA2 + type: BidirStd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 2 + } + { + name: IOA3 + type: BidirStd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 3 + } + { + name: IOA4 + type: BidirStd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 4 + } + { + name: IOA5 + type: BidirStd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 5 + } + { + name: IOA6 + type: BidirOd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 6 + } + { + name: IOA7 + type: BidirOd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 7 + } + { + name: IOA8 + type: BidirOd + bank: VIOA + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 8 + } + { + name: IOB0 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 9 + } + { + name: IOB1 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 10 + } + { + name: IOB2 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 11 + } + { + name: IOB3 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 12 + } + { + name: IOB4 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 13 + } + { + name: IOB5 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 14 + } + { + name: IOB6 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 15 + } + { + name: IOB7 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 16 + } + { + name: IOB8 + type: BidirStd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 17 + } + { + name: IOB9 + type: BidirOd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 18 + } + { + name: IOB10 + type: BidirOd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 19 + } + { + name: IOB11 + type: BidirOd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 20 + } + { + name: IOB12 + type: BidirOd + bank: VIOB + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 21 + } + { + name: IOC0 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 22 + } + { + name: IOC1 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 23 + } + { + name: IOC2 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 24 + } + { + name: IOC3 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 25 + } + { + name: IOC4 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 26 + } + { + name: IOC5 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 27 + } + { + name: IOC6 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 28 + } + { + name: IOC7 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 29 + } + { + name: IOC8 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 30 + } + { + name: IOC9 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 31 + } + { + name: IOC10 + type: BidirOd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 32 + } + { + name: IOC11 + type: BidirOd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 33 + } + { + name: IOC12 + type: BidirOd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 34 + } + { + name: IOR0 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 35 + } + { + name: IOR1 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 36 + } + { + name: IOR2 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 37 + } + { + name: IOR3 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 38 + } + { + name: IOR4 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 39 + } + { + name: IOR5 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 40 + } + { + name: IOR6 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 41 + } + { + name: IOR7 + type: BidirStd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 42 + } + { + name: IOR10 + type: BidirOd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 43 + } + { + name: IOR11 + type: BidirOd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 44 + } + { + name: IOR12 + type: BidirOd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 45 + } + { + name: IOR13 + type: BidirOd + bank: VCC + connection: muxed + desc: Muxed IO pad + port_type: inout + idx: 46 + } + ] + } + pinmux: + { + signals: + [ + { + instance: spi_host0 + port: sck + connection: direct + pad: SPI_HOST_CLK + desc: "" + attr: BidirStd + } + { + instance: spi_host0 + port: csb + connection: direct + pad: SPI_HOST_CS_L + desc: "" + attr: BidirStd + } + { + instance: spi_host0 + port: sd[0] + connection: direct + pad: SPI_HOST_D0 + desc: "" + attr: BidirStd + } + { + instance: spi_host0 + port: sd[1] + connection: direct + pad: SPI_HOST_D1 + desc: "" + attr: BidirStd + } + { + instance: spi_host0 + port: sd[2] + connection: direct + pad: SPI_HOST_D2 + desc: "" + attr: BidirStd + } + { + instance: spi_host0 + port: sd[3] + connection: direct + pad: SPI_HOST_D3 + desc: "" + attr: BidirStd + } + { + instance: spi_device + port: sck + connection: direct + pad: SPI_DEV_CLK + desc: "" + attr: InputStd + } + { + instance: spi_device + port: csb + connection: direct + pad: SPI_DEV_CS_L + desc: "" + attr: InputStd + } + { + instance: spi_device + port: sd[0] + connection: direct + pad: SPI_DEV_D0 + desc: "" + attr: BidirStd + } + { + instance: spi_device + port: sd[1] + connection: direct + pad: SPI_DEV_D1 + desc: "" + attr: BidirStd + } + { + instance: spi_device + port: sd[2] + connection: direct + pad: SPI_DEV_D2 + desc: "" + attr: BidirStd + } + { + instance: spi_device + port: sd[3] + connection: direct + pad: SPI_DEV_D3 + desc: "" + attr: BidirStd + } + { + instance: usbdev + port: usb_dp + connection: manual + pad: "" + desc: "" + attr: BidirStd + } + { + instance: usbdev + port: usb_dn + connection: manual + pad: "" + desc: "" + attr: BidirStd + } + { + instance: gpio + port: "" + connection: muxed + pad: "" + desc: "" + attr: "" + } + { + instance: uart0 + port: "" + connection: muxed + pad: "" + desc: "" + attr: "" + } + { + instance: uart1 + port: "" + connection: muxed + pad: "" + desc: "" + attr: "" + } + { + instance: flash_ctrl + port: "" + connection: muxed + pad: "" + desc: "" + attr: "" + } + { + instance: usbdev + port: sense + connection: muxed + pad: "" + desc: "" + attr: "" + } + ] + num_wkup_detect: 8 + wkup_cnt_width: 8 + enable_usb_wakeup: true + enable_strap_sampling: true + ios: + [ + { + name: spi_host0_sd + width: 4 + type: inout + idx: 0 + pad: SPI_HOST_D0 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 0 + } + { + name: spi_host0_sd + width: 4 + type: inout + idx: 1 + pad: SPI_HOST_D1 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 1 + } + { + name: spi_host0_sd + width: 4 + type: inout + idx: 2 + pad: SPI_HOST_D2 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 2 + } + { + name: spi_host0_sd + width: 4 + type: inout + idx: 3 + pad: SPI_HOST_D3 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 3 + } + { + name: spi_device_sd + width: 4 + type: inout + idx: 0 + pad: SPI_DEV_D0 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 4 + } + { + name: spi_device_sd + width: 4 + type: inout + idx: 1 + pad: SPI_DEV_D1 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 5 + } + { + name: spi_device_sd + width: 4 + type: inout + idx: 2 + pad: SPI_DEV_D2 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 6 + } + { + name: spi_device_sd + width: 4 + type: inout + idx: 3 + pad: SPI_DEV_D3 + attr: BidirStd + connection: direct + desc: "" + glob_idx: 7 + } + { + name: usbdev_usb_dp + width: 1 + type: inout + idx: -1 + pad: "" + attr: BidirStd + connection: manual + desc: "" + glob_idx: 8 + } + { + name: usbdev_usb_dn + width: 1 + type: inout + idx: -1 + pad: "" + attr: BidirStd + connection: manual + desc: "" + glob_idx: 9 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 0 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 0 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 1 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 2 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 2 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 3 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 3 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 4 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 4 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 5 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 5 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 6 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 6 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 7 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 7 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 8 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 8 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 9 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 9 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 10 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 10 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 11 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 11 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 12 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 12 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 13 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 13 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 14 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 14 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 15 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 15 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 16 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 16 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 17 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 17 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 18 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 18 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 19 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 19 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 20 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 20 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 21 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 21 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 22 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 22 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 23 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 23 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 24 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 24 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 25 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 25 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 26 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 26 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 27 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 27 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 28 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 28 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 29 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 29 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 30 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 30 + } + { + name: gpio_gpio + width: 32 + type: inout + idx: 31 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 31 + } + { + name: spi_device_sck + width: 1 + type: input + idx: -1 + pad: SPI_DEV_CLK + attr: InputStd + connection: direct + desc: "" + glob_idx: 10 + } + { + name: spi_device_csb + width: 1 + type: input + idx: -1 + pad: SPI_DEV_CS_L + attr: InputStd + connection: direct + desc: "" + glob_idx: 11 + } + { + name: uart0_rx + width: 1 + type: input + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 32 + } + { + name: uart1_rx + width: 1 + type: input + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 33 + } + { + name: flash_ctrl_tck + width: 1 + type: input + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 34 + } + { + name: flash_ctrl_tms + width: 1 + type: input + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 35 + } + { + name: flash_ctrl_tdi + width: 1 + type: input + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 36 + } + { + name: usbdev_sense + width: 1 + type: input + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 37 + } + { + name: spi_host0_sck + width: 1 + type: output + idx: -1 + pad: SPI_HOST_CLK + attr: BidirStd + connection: direct + desc: "" + glob_idx: 12 + } + { + name: spi_host0_csb + width: 1 + type: output + idx: -1 + pad: SPI_HOST_CS_L + attr: BidirStd + connection: direct + desc: "" + glob_idx: 13 + } + { + name: uart0_tx + width: 1 + type: output + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 32 + } + { + name: uart1_tx + width: 1 + type: output + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 33 + } + { + name: flash_ctrl_tdo + width: 1 + type: output + idx: -1 + pad: "" + attr: "" + connection: muxed + desc: "" + glob_idx: 34 + } + ] + io_counts: + { + dedicated: + { + inouts: 10 + inputs: 2 + outputs: 2 + pads: 20 + } + muxed: + { + inouts: 32 + inputs: 6 + outputs: 3 + pads: 47 + } + } + } + targets: + [ + { + name: cw305 + pinout: + { + remove_ports: [] + remove_pads: + [ + CC1 + CC2 + SPI_DEV_D2 + SPI_DEV_D3 + SPI_HOST_CLK + SPI_HOST_CS_L + SPI_HOST_D0 + SPI_HOST_D1 + SPI_HOST_D2 + SPI_HOST_D3 + FLASH_TEST_VOLT + FLASH_TEST_MODE0 + FLASH_TEST_MODE1 + IOB7 + IOB8 + IOB9 + IOB10 + IOB11 + IOB12 + IOC6 + IOC7 + IOC9 + IOC10 + IOC11 + IOC12 + IOR0 + IOR1 + IOR2 + IOR3 + IOR5 + IOR6 + IOR7 + IOR10 + IOR11 + IOR12 + IOR13 + ] + add_pads: + [ + { + name: IO_CLK + type: InputStd + bank: VCC + connection: manual + desc: Extra clock input for FPGA target + port_type: inout + } + { + name: POR_BUTTON_N + type: InputStd + bank: VCC + connection: manual + desc: POR from the push-button + port_type: inout + } + { + name: IO_USB_SENSE0 + type: BidirStd + bank: VCC + connection: manual + desc: Manual USB signal for FPGA target + port_type: inout + } + { + name: IO_USB_DNPULLUP0 + type: BidirStd + bank: VCC + connection: manual + desc: Manual USB signal for FPGA target + port_type: inout + } + { + name: IO_USB_DPPULLUP0 + type: BidirStd + bank: VCC + connection: manual + desc: Manual USB signal for FPGA target + port_type: inout + } + { + name: IO_CLKOUT + type: BidirStd + bank: VCC + connection: manual + desc: Manual clock output for SCA setup + port_type: inout + } + { + name: IO_TRIGGER + type: BidirStd + bank: VCC + connection: manual + desc: Manual trigger output for SCA setup + port_type: inout + } + ] + } + pinmux: + { + special_signals: + [ + { + name: tap0 + pad: IOC8 + desc: TAP strap signal. + idx: 30 + } + { + name: tap1 + pad: IOC5 + desc: TAP strap signal. + idx: 27 + } + { + name: dft0 + pad: IOR5 + desc: DFT strap signal. + idx: 40 + } + { + name: dft1 + pad: IOR7 + desc: DFT strap signal. + idx: 42 + } + { + name: tck + pad: SPI_DEV_CLK + desc: JTAG tck signal, overlaid on SPI_DEV. + idx: 57 + } + { + name: tms + pad: SPI_DEV_CS_L + desc: JTAG tms signal, overlaid on SPI_DEV. + idx: 58 + } + { + name: trst_n + pad: IOR4 + desc: JTAG trst_n signal. + idx: 39 + } + { + name: tdi + pad: SPI_DEV_D0 + desc: JTAG tdi signal, overlaid on SPI_DEV. + idx: 51 + } + { + name: tdo + pad: SPI_DEV_D1 + desc: JTAG tdo signal, overlaid on SPI_DEV. + idx: 52 + } + ] + } + } + ] + incoming_alert: {} + incoming_interrupt: {} + exported_clks: {} + wakeups: + [ + { + name: pin_wkup_req + width: "1" + module: pinmux_aon + } + { + name: usb_wkup_req + width: "1" + module: pinmux_aon + } + { + name: wkup_req + width: "1" + module: aon_timer_aon + } + ] + reset_requests: + { + peripheral: + [ + { + name: aon_timer_rst_req + width: "1" + module: aon_timer_aon + desc: watchdog reset requestt + } + ] + int: + [ + { + name: MainPwr + desc: main power glitch reset request + module: pwrmgr_aon + } + { + name: Esc + desc: escalation reset request + module: alert_handler + } + ] + debug: + [ + { + name: Ndm + desc: non-debug-module reset request + module: rv_dm + } + ] + } + interrupt: + [ + { + name: uart0_tx_watermark + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Status + default_val: true + incoming: false + } + { + name: uart0_rx_watermark + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: uart0_tx_done + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart0_rx_overflow + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart0_rx_frame_err + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart0_rx_break_err + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart0_rx_timeout + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart0_rx_parity_err + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart0_tx_empty + width: 1 + type: interrupt + module_name: uart0 + intr_type: IntrType.Status + default_val: true + incoming: false + } + { + name: uart1_tx_watermark + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Status + default_val: true + incoming: false + } + { + name: uart1_rx_watermark + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: uart1_tx_done + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart1_rx_overflow + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart1_rx_frame_err + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart1_rx_break_err + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart1_rx_timeout + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart1_rx_parity_err + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: uart1_tx_empty + width: 1 + type: interrupt + module_name: uart1 + intr_type: IntrType.Status + default_val: true + incoming: false + } + { + name: gpio_gpio + width: 32 + type: interrupt + module_name: gpio + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_device_upload_cmdfifo_not_empty + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_device_upload_payload_not_empty + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_device_upload_payload_overflow + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_device_readbuf_watermark + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_device_readbuf_flip + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_device_tpm_header_not_empty + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: spi_device_tpm_rdfifo_cmd_end + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_device_tpm_rdfifo_drop + width: 1 + type: interrupt + module_name: spi_device + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_host0_error + width: 1 + type: interrupt + module_name: spi_host0 + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: spi_host0_spi_event + width: 1 + type: interrupt + module_name: spi_host0 + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: usbdev_pkt_received + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: usbdev_pkt_sent + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: usbdev_disconnected + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_host_lost + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_link_reset + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_link_suspend + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_link_resume + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_av_out_empty + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: usbdev_rx_full + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: usbdev_av_overflow + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_link_in_err + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_rx_crc_err + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_rx_pid_err + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_rx_bitstuff_err + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_frame + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_powered + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_link_out_err + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: usbdev_av_setup_empty + width: 1 + type: interrupt + module_name: usbdev + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: pwrmgr_aon_wakeup + width: 1 + type: interrupt + module_name: pwrmgr_aon + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: aon_timer_aon_wkup_timer_expired + width: 1 + type: interrupt + module_name: aon_timer_aon + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: aon_timer_aon_wdog_timer_bark + width: 1 + type: interrupt + module_name: aon_timer_aon + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: flash_ctrl_prog_empty + width: 1 + type: interrupt + module_name: flash_ctrl + intr_type: IntrType.Status + default_val: true + incoming: false + } + { + name: flash_ctrl_prog_lvl + width: 1 + type: interrupt + module_name: flash_ctrl + intr_type: IntrType.Status + default_val: true + incoming: false + } + { + name: flash_ctrl_rd_full + width: 1 + type: interrupt + module_name: flash_ctrl + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: flash_ctrl_rd_lvl + width: 1 + type: interrupt + module_name: flash_ctrl + intr_type: IntrType.Status + default_val: false + incoming: false + } + { + name: flash_ctrl_op_done + width: 1 + type: interrupt + module_name: flash_ctrl + intr_type: IntrType.Event + default_val: false + incoming: false + } + { + name: flash_ctrl_corr_err + width: 1 + type: interrupt + module_name: flash_ctrl + intr_type: IntrType.Event + default_val: false + incoming: false + } + ] + alert_module: + [ + uart0 + uart1 + gpio + spi_device + spi_host0 + rv_timer + usbdev + pwrmgr_aon + rstmgr_aon + clkmgr_aon + pinmux_aon + aon_timer_aon + flash_ctrl + rv_plic + aes + sram_ctrl_main + rom_ctrl + rv_core_ibex + ] + outgoing_alert_module: {} + alert: + [ + { + name: uart0_fatal_fault + width: 1 + type: alert + async: "1" + module_name: uart0 + lpg_name: peri_lc_io_div4_0 + lpg_idx: 0 + } + { + name: uart1_fatal_fault + width: 1 + type: alert + async: "1" + module_name: uart1 + lpg_name: peri_lc_io_div4_0 + lpg_idx: 0 + } + { + name: gpio_fatal_fault + width: 1 + type: alert + async: "1" + module_name: gpio + lpg_name: peri_sys_io_div4_0 + lpg_idx: 1 + } + { + name: spi_device_fatal_fault + width: 1 + type: alert + async: "1" + module_name: spi_device + lpg_name: peri_spi_device_0 + lpg_idx: 2 + } + { + name: spi_host0_fatal_fault + width: 1 + type: alert + async: "1" + module_name: spi_host0 + lpg_name: peri_spi_host0_0 + lpg_idx: 3 + } + { + name: rv_timer_fatal_fault + width: 1 + type: alert + async: "1" + module_name: rv_timer + lpg_name: timers_sys_io_div4_0 + lpg_idx: 4 + } + { + name: usbdev_fatal_fault + width: 1 + type: alert + async: "1" + module_name: usbdev + lpg_name: peri_usb_0 + lpg_idx: 5 + } + { + name: pwrmgr_aon_fatal_fault + width: 1 + type: alert + async: "1" + module_name: pwrmgr_aon + lpg_name: powerup_por_io_div4_Aon + lpg_idx: 6 + } + { + name: rstmgr_aon_fatal_fault + width: 1 + type: alert + async: "1" + module_name: rstmgr_aon + lpg_name: powerup_lc_io_div4_Aon + lpg_idx: 7 + } + { + name: rstmgr_aon_fatal_cnsty_fault + width: 1 + type: alert + async: "1" + module_name: rstmgr_aon + lpg_name: powerup_lc_io_div4_Aon + lpg_idx: 7 + } + { + name: clkmgr_aon_recov_fault + width: 1 + type: alert + async: "1" + module_name: clkmgr_aon + lpg_name: powerup_por_io_div4_Aon + lpg_idx: 6 + } + { + name: clkmgr_aon_fatal_fault + width: 1 + type: alert + async: "1" + module_name: clkmgr_aon + lpg_name: powerup_por_io_div4_Aon + lpg_idx: 6 + } + { + name: pinmux_aon_fatal_fault + width: 1 + type: alert + async: "1" + module_name: pinmux_aon + lpg_name: powerup_lc_io_div4_Aon + lpg_idx: 7 + } + { + name: aon_timer_aon_fatal_fault + width: 1 + type: alert + async: "1" + module_name: aon_timer_aon + lpg_name: timers_sys_io_div4_Aon + lpg_idx: 8 + } + { + name: flash_ctrl_recov_err + width: 1 + type: alert + async: "1" + module_name: flash_ctrl + lpg_name: infra_lc_0 + lpg_idx: 10 + } + { + name: flash_ctrl_fatal_std_err + width: 1 + type: alert + async: "1" + module_name: flash_ctrl + lpg_name: infra_lc_0 + lpg_idx: 10 + } + { + name: flash_ctrl_fatal_err + width: 1 + type: alert + async: "1" + module_name: flash_ctrl + lpg_name: infra_lc_0 + lpg_idx: 10 + } + { + name: flash_ctrl_fatal_prim_flash_alert + width: 1 + type: alert + async: "1" + module_name: flash_ctrl + lpg_name: infra_lc_0 + lpg_idx: 10 + } + { + name: flash_ctrl_recov_prim_flash_alert + width: 1 + type: alert + async: "1" + module_name: flash_ctrl + lpg_name: infra_lc_0 + lpg_idx: 10 + } + { + name: rv_plic_fatal_fault + width: 1 + type: alert + async: "1" + module_name: rv_plic + lpg_name: secure_sys_0 + lpg_idx: 11 + } + { + name: aes_recov_ctrl_update_err + width: 1 + type: alert + async: "1" + module_name: aes + lpg_name: aes_trans_sys_0 + lpg_idx: 12 + } + { + name: aes_fatal_fault + width: 1 + type: alert + async: "1" + module_name: aes + lpg_name: aes_trans_sys_0 + lpg_idx: 12 + } + { + name: sram_ctrl_main_fatal_error + width: 1 + type: alert + async: "1" + module_name: sram_ctrl_main + lpg_name: secure_sys_0 + lpg_idx: 11 + } + { + name: rom_ctrl_fatal + width: 1 + type: alert + async: "1" + module_name: rom_ctrl + lpg_name: infra_sys_0 + lpg_idx: 13 + } + { + name: rv_core_ibex_fatal_sw_err + width: 1 + type: alert + async: "1" + module_name: rv_core_ibex + lpg_name: infra_sys_0 + lpg_idx: 13 + } + { + name: rv_core_ibex_recov_sw_err + width: 1 + type: alert + async: "1" + module_name: rv_core_ibex + lpg_name: infra_sys_0 + lpg_idx: 13 + } + { + name: rv_core_ibex_fatal_hw_err + width: 1 + type: alert + async: "1" + module_name: rv_core_ibex + lpg_name: infra_sys_0 + lpg_idx: 13 + } + { + name: rv_core_ibex_recov_hw_err + width: 1 + type: alert + async: "1" + module_name: rv_core_ibex + lpg_name: infra_sys_0 + lpg_idx: 13 + } + ] + outgoing_alert: {} + exported_rsts: {} + alert_lpgs: + [ + { + name: peri_lc_io_div4_0 + clock_group: + { + name: peri + src: top + sw_cg: yes + unique: no + clocks: + { + clk_io_div4_peri: io_div4 + clk_io_div2_peri: io_div2 + clk_io_peri: io + clk_usb_peri: usb + clk_aon_peri: aon + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_peri + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: lc_io_div4 + domain: "0" + } + } + { + name: peri_sys_io_div4_0 + clock_group: + { + name: peri + src: top + sw_cg: yes + unique: no + clocks: + { + clk_io_div4_peri: io_div4 + clk_io_div2_peri: io_div2 + clk_io_peri: io + clk_usb_peri: usb + clk_aon_peri: aon + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_peri + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: sys_io_div4 + domain: "0" + } + } + { + name: peri_spi_device_0 + clock_group: + { + name: peri + src: top + sw_cg: yes + unique: no + clocks: + { + clk_io_div4_peri: io_div4 + clk_io_div2_peri: io_div2 + clk_io_peri: io + clk_usb_peri: usb + clk_aon_peri: aon + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_peri + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: spi_device + domain: "0" + } + } + { + name: peri_spi_host0_0 + clock_group: + { + name: peri + src: top + sw_cg: yes + unique: no + clocks: + { + clk_io_div4_peri: io_div4 + clk_io_div2_peri: io_div2 + clk_io_peri: io + clk_usb_peri: usb + clk_aon_peri: aon + } + } + clock_connection: clkmgr_aon_clocks.clk_io_peri + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: spi_host0 + domain: "0" + } + } + { + name: timers_sys_io_div4_0 + clock_group: + { + name: timers + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_timers: io_div4 + clk_aon_timers: aon + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_timers + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: sys_io_div4 + domain: "0" + } + } + { + name: peri_usb_0 + clock_group: + { + name: peri + src: top + sw_cg: yes + unique: no + clocks: + { + clk_io_div4_peri: io_div4 + clk_io_div2_peri: io_div2 + clk_io_peri: io + clk_usb_peri: usb + clk_aon_peri: aon + } + } + clock_connection: clkmgr_aon_clocks.clk_usb_peri + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: usb + domain: "0" + } + } + { + name: powerup_por_io_div4_Aon + clock_group: + { + name: powerup + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_powerup: io_div4 + clk_aon_powerup: aon + clk_main_powerup: main + clk_io_powerup: io + clk_usb_powerup: usb + clk_io_div2_powerup: io_div2 + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_powerup + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: por_io_div4 + domain: Aon + } + } + { + name: powerup_lc_io_div4_Aon + clock_group: + { + name: powerup + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_powerup: io_div4 + clk_aon_powerup: aon + clk_main_powerup: main + clk_io_powerup: io + clk_usb_powerup: usb + clk_io_div2_powerup: io_div2 + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_powerup + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: lc_io_div4 + domain: Aon + } + } + { + name: timers_sys_io_div4_Aon + clock_group: + { + name: timers + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_timers: io_div4 + clk_aon_timers: aon + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_timers + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: sys_io_div4 + domain: Aon + } + } + { + name: secure_lc_io_div4_0 + clock_group: + { + name: secure + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_secure: io_div4 + clk_aon_secure: aon + clk_main_secure: main + } + } + clock_connection: clkmgr_aon_clocks.clk_io_div4_secure + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: lc_io_div4 + domain: "0" + } + } + { + name: infra_lc_0 + clock_group: + { + name: infra + src: top + sw_cg: no + unique: no + clocks: + { + clk_main_infra: main + clk_io_div4_infra: io_div4 + clk_io_infra: io + clk_usb_infra: usb + } + } + clock_connection: clkmgr_aon_clocks.clk_main_infra + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: lc + domain: "0" + } + } + { + name: secure_sys_0 + clock_group: + { + name: secure + src: top + sw_cg: no + unique: no + clocks: + { + clk_io_div4_secure: io_div4 + clk_aon_secure: aon + clk_main_secure: main + } + } + clock_connection: clkmgr_aon_clocks.clk_main_secure + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: sys + domain: "0" + } + } + { + name: aes_trans_sys_0 + clock_group: + { + name: trans + src: top + sw_cg: hint + unique: yes + clocks: + { + clk_main_aes: main + } + } + clock_connection: clkmgr_aon_clocks.clk_main_aes + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: sys + domain: "0" + } + } + { + name: infra_sys_0 + clock_group: + { + name: infra + src: top + sw_cg: no + unique: no + clocks: + { + clk_main_infra: main + clk_io_div4_infra: io_div4 + clk_io_infra: io + clk_usb_infra: usb + } + } + clock_connection: clkmgr_aon_clocks.clk_main_infra + unmanaged_clock: false + unmanaged_reset: false + reset_connection: + { + name: sys + domain: "0" + } + } + ] + outgoing_alert_lpgs: {} + inter_signal: + { + signals: + [ + { + name: lsio_trigger + desc: + ''' + Self-clearing status trigger for the DMA. + Set when RX or TX FIFOs are past their configured watermarks matching watermark interrupt behaviour. + ''' + struct: logic + type: uni + act: req + width: 1 + inst_name: uart0 + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: uart0 + default: "" + end_idx: -1 + top_signame: uart0_tl + index: -1 + } + { + name: lsio_trigger + desc: + ''' + Self-clearing status trigger for the DMA. + Set when RX or TX FIFOs are past their configured watermarks matching watermark interrupt behaviour. + ''' + struct: logic + type: uni + act: req + width: 1 + inst_name: uart1 + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: uart1 + default: "" + end_idx: -1 + top_signame: uart1_tl + index: -1 + } + { + name: strap_en + desc: This signal is pulsed high by the power manager after reset in order to sample the HW straps. + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: gpio + index: -1 + } + { + name: sampled_straps + desc: This vector contains the sampled strap values. + struct: gpio_straps + package: gpio_pkg + type: uni + act: req + width: 1 + default: "'0" + inst_name: gpio + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: gpio + default: "" + end_idx: -1 + top_signame: gpio_tl + index: -1 + } + { + name: ram_cfg_sys2spi + struct: ram_2p_cfg + package: prim_ram_2p_pkg + type: uni + act: rcv + width: 1 + inst_name: spi_device + index: -1 + } + { + name: ram_cfg_rsp_sys2spi + struct: ram_2p_cfg_rsp + package: prim_ram_2p_pkg + type: uni + act: req + width: 1 + inst_name: spi_device + index: -1 + } + { + name: ram_cfg_spi2sys + struct: ram_2p_cfg + package: prim_ram_2p_pkg + type: uni + act: rcv + width: 1 + inst_name: spi_device + index: -1 + } + { + name: ram_cfg_rsp_spi2sys + struct: ram_2p_cfg_rsp + package: prim_ram_2p_pkg + type: uni + act: req + width: 1 + inst_name: spi_device + index: -1 + } + { + name: passthrough + struct: passthrough + package: spi_device_pkg + type: req_rsp + act: req + width: 1 + inst_name: spi_device + default: "" + end_idx: -1 + top_signame: spi_device_passthrough + index: -1 + } + { + name: mbist_en + struct: logic + type: uni + act: rcv + width: 1 + inst_name: spi_device + index: -1 + } + { + name: sck_monitor + struct: logic + type: uni + act: req + width: 1 + inst_name: spi_device + default: "" + package: "" + external: true + top_signame: sck_monitor + conn_type: false + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: spi_device + default: "" + end_idx: -1 + top_signame: spi_device_tl + index: -1 + } + { + name: passthrough + struct: passthrough + package: spi_device_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: spi_host0 + default: "" + top_signame: spi_device_passthrough + index: -1 + } + { + name: lsio_trigger + desc: + ''' + Self-clearing status trigger for the DMA. + Set when RX or TX FIFOs are past their configured watermarks matching watermark interrupt behaviour. + ''' + struct: logic + type: uni + act: req + width: 1 + inst_name: spi_host0 + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: spi_host0 + default: "" + end_idx: -1 + top_signame: spi_host0_tl + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rv_timer + default: "" + end_idx: -1 + top_signame: rv_timer_tl + index: -1 + } + { + name: usb_rx_d + desc: USB RX data from an external differential receiver, if available + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_rx_d + conn_type: false + index: -1 + } + { + name: usb_tx_d + desc: USB transmit data value (not used if usb_tx_se0 is set) + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_tx_d + conn_type: false + index: -1 + } + { + name: usb_tx_se0 + desc: Force transmission of a USB single-ended zero (i.e. both D+ and D- are low) regardless of usb_tx_d + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_tx_se0 + conn_type: false + index: -1 + } + { + name: usb_tx_use_d_se0 + desc: Use the usb_tx_d and usb_tx_se0 TX interface, instead of usb_dp_o and usb_dn_o + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_tx_use_d_se0 + conn_type: false + index: -1 + } + { + name: usb_dp_pullup + desc: USB D+ pullup control + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_dp_pullup + index: -1 + } + { + name: usb_dn_pullup + desc: USB D- pullup control + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_dn_pullup + index: -1 + } + { + name: usb_rx_enable + desc: USB differential receiver enable + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_rx_enable + conn_type: false + index: -1 + } + { + name: usb_ref_val + desc: This indicates that USB timing reference signal 'usb_ref_pulse' is valid + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_ref_val + conn_type: false + index: -1 + } + { + name: usb_ref_pulse + desc: USB timing reference signal. This signal pulses for a single 48MHz clock every 1ms USB frame + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + external: true + top_signame: usbdev_usb_ref_pulse + conn_type: false + index: -1 + } + { + name: usb_aon_suspend_req + desc: Request to activate the AON/Wake module and take control of the USB pullups + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_suspend_req + index: -1 + } + { + name: usb_aon_wake_ack + desc: Acknowledge a wake signal from the AON/Wake and relinquish control of the USB pullups + struct: logic + type: uni + act: req + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_wake_ack + index: -1 + } + { + name: usb_aon_bus_reset + desc: Indicates that the reason for waking was that a USB Bus Reset occurred + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_bus_reset + index: -1 + } + { + name: usb_aon_sense_lost + desc: Indicates that the reason for waking was that the VBUS/SENSE signal became deasserted + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: usbdev_usb_aon_sense_lost + index: -1 + } + { + name: usb_aon_bus_not_idle + desc: Indicates that the reason for waking was that the USB is in a non-idle state + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + index: -1 + } + { + name: usb_aon_wake_detect_active + desc: Indicates that the external AON/Wake module is active and controlling the USB pullups + struct: logic + type: uni + act: rcv + width: 1 + inst_name: usbdev + default: "" + package: "" + top_signame: pinmux_aon_usbdev_wake_detect_active + index: -1 + } + { + name: ram_cfg + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: 1 + inst_name: usbdev + index: -1 + } + { + name: ram_cfg_rsp + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: 1 + inst_name: usbdev + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: usbdev + default: "" + end_idx: -1 + top_signame: usbdev_tl + index: -1 + } + { + name: pwr_ast + struct: pwr_ast + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + external: true + top_signame: pwrmgr_ast + conn_type: false + index: -1 + } + { + name: pwr_rst + struct: pwr_rst + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_signame: pwrmgr_aon_pwr_rst + index: -1 + } + { + name: pwr_clk + struct: pwr_clk + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_signame: pwrmgr_aon_pwr_clk + index: -1 + } + { + name: pwr_otp + struct: pwr_otp + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: pwr_lc + struct: pwr_lc + package: pwrmgr_pkg + type: req_rsp + act: req + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: pwr_flash + struct: pwr_flash + package: pwrmgr_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_pwr_flash + index: -1 + } + { + name: esc_rst_tx + struct: esc_tx + package: prim_esc_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: esc_rst_rx + struct: esc_rx + package: prim_esc_pkg + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: pwr_cpu + struct: cpu_pwrmgr + package: rv_core_ibex_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + top_signame: rv_core_ibex_pwrmgr + index: -1 + } + { + name: wakeups + struct: logic + type: uni + act: rcv + width: 3 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: one-to-N + top_signame: pwrmgr_aon_wakeups + index: -1 + } + { + name: rstreqs + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_rstreqs + index: -1 + } + { + name: ndmreset_req + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: strap + struct: logic + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_strap + index: -1 + } + { + name: low_power + struct: logic + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_low_power + index: -1 + } + { + name: rom_ctrl + struct: pwrmgr_data + package: rom_ctrl_pkg + type: uni + act: rcv + width: 1 + default: rom_ctrl_pkg::PWRMGR_DATA_DEFAULT + inst_name: pwrmgr_aon + index: -1 + } + { + name: fetch_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: pwrmgr_aon_fetch_en + index: -1 + } + { + name: lc_dft_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: lc_hw_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + index: -1 + } + { + name: sw_rst_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: pwrmgr_aon + default: "" + top_signame: rstmgr_aon_sw_rst_req + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: pwrmgr_aon + default: "" + end_idx: -1 + top_signame: pwrmgr_aon_tl + index: -1 + } + { + name: por_n + desc: + ''' + Root power on reset signals from ast. + There is one root reset signal for each core power domain. + ''' + struct: logic + type: uni + act: rcv + width: 2 + inst_name: rstmgr_aon + default: "" + package: "" + external: true + top_signame: por_n + conn_type: false + index: -1 + } + { + name: pwr + desc: + ''' + Reset request signals from power manager. + Power manager can request for specific domains of the lc/sys reset tree to assert. + ''' + struct: pwr_rst + type: req_rsp + act: rsp + width: 1 + inst_name: rstmgr_aon + default: "" + package: pwrmgr_pkg + top_signame: pwrmgr_aon_pwr_rst + index: -1 + } + { + name: resets + desc: Leaf resets fed to the system. + struct: rstmgr_out + package: rstmgr_pkg + type: uni + act: req + width: 1 + inst_name: rstmgr_aon + default: "" + top_signame: rstmgr_aon_resets + index: -1 + } + { + name: rst_en + desc: Low-power-group outputs used by alert handler. + struct: rstmgr_rst_en + package: rstmgr_pkg + type: uni + act: req + width: 1 + inst_name: rstmgr_aon + default: "" + top_signame: rstmgr_aon_rst_en + index: -1 + } + { + name: alert_dump + desc: Alert handler crash dump information. + struct: alert_crashdump + package: alert_pkg + type: uni + act: rcv + width: 1 + inst_name: rstmgr_aon + index: -1 + } + { + name: cpu_dump + desc: Main processing element crash dump information. + struct: cpu_crash_dump + package: rv_core_ibex_pkg + type: uni + act: rcv + width: 1 + inst_name: rstmgr_aon + default: "" + top_signame: rv_core_ibex_crash_dump + index: -1 + } + { + name: sw_rst_req + desc: Software requested system reset to pwrmgr. + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: rstmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: rstmgr_aon_sw_rst_req + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rstmgr_aon + default: "" + end_idx: -1 + top_signame: rstmgr_aon_tl + index: -1 + } + { + name: clocks + struct: clkmgr_out + package: clkmgr_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + top_signame: clkmgr_aon_clocks + index: -1 + } + { + name: cg_en + struct: clkmgr_cg_en + package: clkmgr_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + top_signame: clkmgr_aon_cg_en + index: -1 + } + { + name: lc_hw_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + index: -1 + } + { + name: io_clk_byp_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: io_clk_byp_req + conn_type: false + index: -1 + } + { + name: io_clk_byp_ack + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: io_clk_byp_ack + conn_type: false + index: -1 + } + { + name: all_clk_byp_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: all_clk_byp_req + conn_type: false + index: -1 + } + { + name: all_clk_byp_ack + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: all_clk_byp_ack + conn_type: false + index: -1 + } + { + name: hi_speed_sel + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: hi_speed_sel + conn_type: false + index: -1 + } + { + name: div_step_down_req + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: div_step_down_req + conn_type: false + index: -1 + } + { + name: lc_clk_byp_req + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + index: -1 + } + { + name: lc_clk_byp_ack + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + index: -1 + } + { + name: jitter_en + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: clkmgr_aon + default: "" + external: true + top_signame: clk_main_jitter_en + conn_type: false + index: -1 + } + { + name: pwr + struct: pwr_clk + type: req_rsp + act: rsp + width: 1 + inst_name: clkmgr_aon + default: "" + package: pwrmgr_pkg + top_signame: pwrmgr_aon_pwr_clk + index: -1 + } + { + name: idle + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: clkmgr_aon + default: "" + end_idx: -1 + top_type: broadcast + top_signame: clkmgr_aon_idle + index: -1 + } + { + name: calib_rdy + desc: Indicates clocks are calibrated and frequencies accurate + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + default: prim_mubi_pkg::MuBi4True + inst_name: clkmgr_aon + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: clkmgr_aon + default: "" + end_idx: -1 + top_signame: clkmgr_aon_tl + index: -1 + } + { + name: lc_hw_debug_en + desc: Debug enable qualifier coming from life cycle controller, used for HW strap qualification. + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_dft_en + desc: Test enable qualifier coming from life cycle controller, used for HW strap qualification. + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_escalate_en + desc: + ''' + Escalation enable signal coming from life cycle controller, used for invalidating + the latched lc_hw_debug_en state inside the strap sampling logic. + ''' + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_check_byp_en + desc: + ''' + Check bypass enable signal coming from life cycle controller, used for invalidating + the latched lc_hw_debug_en state inside the strap sampling logic. This signal is asserted + whenever the life cycle controller performs a life cycle transition. Its main use is + to skip any background checks inside the life cycle partition of the OTP controller while + a life cycle transition is in progress. + ''' + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: pinmux_hw_debug_en + desc: + ''' + This is the latched version of lc_hw_debug_en_i. We use it exclusively to gate the JTAG + signals and TAP side of the RV_DM so that RV_DM can remain live during an NDM reset cycle. + ''' + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + default: lc_ctrl_pkg::Off + inst_name: pinmux_aon + index: -1 + } + { + name: lc_jtag + desc: Qualified JTAG signals for life cycle controller TAP. + struct: jtag + package: jtag_pkg + type: req_rsp + act: req + width: 1 + inst_name: pinmux_aon + index: -1 + } + { + name: rv_jtag + desc: Qualified JTAG signals for RISC-V processor TAP. + struct: jtag + package: jtag_pkg + type: req_rsp + act: req + width: 1 + inst_name: pinmux_aon + index: -1 + } + { + name: dft_jtag + desc: Qualified JTAG signals for DFT TAP. + struct: jtag + package: jtag_pkg + type: req_rsp + act: req + width: 1 + inst_name: pinmux_aon + default: "" + top_signame: pinmux_aon_dft_jtag + index: -1 + } + { + name: dft_strap_test + desc: Sampled DFT strap values, going to the DFT TAP. + struct: dft_strap_test_req + package: pinmux_pkg + type: uni + act: req + width: 1 + default: "'0" + inst_name: pinmux_aon + external: true + top_signame: dft_strap_test + conn_type: false + index: -1 + } + { + name: dft_hold_tap_sel + desc: TAP selection hold indication, asserted by the DFT TAP during boundary scan. + struct: logic + type: uni + act: rcv + width: 1 + default: "'0" + inst_name: pinmux_aon + package: "" + external: true + top_signame: dft_hold_tap_sel + conn_type: false + index: -1 + } + { + name: sleep_en + desc: Level signal that is asserted when the power manager enters sleep. + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_low_power + index: -1 + } + { + name: strap_en + desc: This signal is pulsed high by the power manager after reset in order to sample the HW straps. + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_strap + index: -1 + } + { + name: strap_en_override + desc: + ''' + This signal transitions from 0 -> 1 by the lc_ctrl manager after volatile RAW_UNLOCK in order to re-sample the HW straps. + The signal must stay at 1 until reset. + Note that this is only used in test chips when SecVolatileRawUnlockEn = 1. + Otherwise this signal is unused. + ''' + struct: logic + type: uni + act: rcv + width: 1 + default: 1'b0 + inst_name: pinmux_aon + index: -1 + } + { + name: pin_wkup_req + desc: Wakeup request from wakeup detectors, to the power manager, running on the AON clock. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_wakeups + index: 0 + } + { + name: usbdev_dppullup_en + desc: Pullup enable signal coming from the USB IP. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_dp_pullup + index: -1 + } + { + name: usbdev_dnpullup_en + desc: Pullup enable signal coming from the USB IP. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_dn_pullup + index: -1 + } + { + name: usb_dppullup_en + desc: " Pullup enable signal going to USB PHY, needs to be maintained in low-power mode." + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + external: true + top_signame: usb_dp_pullup_en + conn_type: false + index: -1 + } + { + name: usb_dnpullup_en + desc: Pullup enable signal going to USB PHY, needs to be maintained in low-power mode. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + external: true + top_signame: usb_dn_pullup_en + conn_type: false + index: -1 + } + { + name: usb_wkup_req + desc: Wakeup request from USB wakeup detector, going to the power manager, running on the AON clock. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: pwrmgr_aon_wakeups + index: 1 + } + { + name: usbdev_suspend_req + desc: Indicates whether USB is in suspended state, coming from the USB device. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_aon_suspend_req + index: -1 + } + { + name: usbdev_wake_ack + desc: Acknowledges the USB wakeup request, coming from the USB device. + struct: logic + type: uni + act: rcv + width: 1 + inst_name: pinmux_aon + default: "" + package: "" + top_signame: usbdev_usb_aon_wake_ack + index: -1 + } + { + name: usbdev_bus_not_idle + desc: Event signal that indicates that the USB was not idle while monitoring. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + index: -1 + } + { + name: usbdev_bus_reset + desc: Event signal that indicates that the USB issued a Bus Reset while monitoring. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: usbdev_usb_aon_bus_reset + index: -1 + } + { + name: usbdev_sense_lost + desc: Event signal that indicates that USB SENSE signal was lost while monitoring. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + top_signame: usbdev_usb_aon_sense_lost + index: -1 + } + { + name: usbdev_wake_detect_active + desc: State debug information. + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: pinmux_aon + package: "" + end_idx: -1 + top_type: broadcast + top_signame: pinmux_aon_usbdev_wake_detect_active + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: pinmux_aon + default: "" + end_idx: -1 + top_signame: pinmux_aon_tl + index: -1 + } + { + name: nmi_wdog_timer_bark + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: aon_timer_aon + index: -1 + } + { + name: wkup_req + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: aon_timer_aon + package: "" + top_signame: pwrmgr_aon_wakeups + index: 2 + } + { + name: aon_timer_rst_req + struct: logic + type: uni + act: req + width: 1 + default: 1'b0 + inst_name: aon_timer_aon + package: "" + top_signame: pwrmgr_aon_rstreqs + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: aon_timer_aon + index: -1 + } + { + name: sleep_mode + struct: logic + type: uni + act: rcv + width: 1 + inst_name: aon_timer_aon + default: "" + package: "" + top_signame: pwrmgr_aon_low_power + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: aon_timer_aon + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: ast + index: -1 + } + { + name: otp + struct: flash_otp_key + package: otp_ctrl_pkg + type: req_rsp + act: req + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_nvm_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: flash_bist_enable + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + external: true + top_signame: flash_bist_enable + conn_type: false + index: -1 + } + { + name: flash_power_down_h + struct: logic + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + package: "" + external: true + top_signame: flash_power_down_h + conn_type: false + index: -1 + } + { + name: flash_power_ready_h + struct: logic + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + package: "" + external: true + top_signame: flash_power_ready_h + conn_type: false + index: -1 + } + { + name: flash_test_mode_a + struct: "" + type: io + act: none + width: 2 + inst_name: flash_ctrl + index: -1 + } + { + name: flash_test_voltage_h + struct: "" + type: io + act: none + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_creator_seed_sw_rw_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_owner_seed_sw_rw_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_iso_part_sw_rd_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_iso_part_sw_wr_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_seed_hw_rd_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: rma_req + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: rma_ack + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: rma_seed + struct: lc_flash_rma_seed + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: pwrmgr + struct: pwr_flash + package: pwrmgr_pkg + type: uni + act: req + width: 1 + inst_name: flash_ctrl + default: "" + top_signame: pwrmgr_aon_pwr_flash + index: -1 + } + { + name: keymgr + struct: keymgr_flash + package: flash_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: flash_ctrl + index: -1 + } + { + name: obs_ctrl + struct: ast_obs_ctrl + package: ast_pkg + type: uni + act: rcv + width: 1 + inst_name: flash_ctrl + default: "" + external: true + top_signame: obs_ctrl + conn_type: false + index: -1 + } + { + name: fla_obs + struct: logic + type: uni + act: req + width: 8 + inst_name: flash_ctrl + default: "" + package: "" + external: true + top_signame: flash_obs + conn_type: false + index: -1 + } + { + name: core_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: flash_ctrl + default: "" + end_idx: -1 + top_signame: flash_ctrl_core_tl + index: -1 + } + { + name: prim_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: flash_ctrl + default: "" + end_idx: -1 + top_signame: flash_ctrl_prim_tl + index: -1 + } + { + name: mem_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: flash_ctrl + default: "" + end_idx: -1 + top_signame: flash_ctrl_mem_tl + index: -1 + } + { + name: irq + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_plic + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_plic_irq + index: -1 + } + { + name: irq_id + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_plic + index: -1 + } + { + name: msip + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_plic + default: "" + package: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_plic_msip + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rv_plic + default: "" + end_idx: -1 + top_signame: rv_plic_tl + index: -1 + } + { + name: idle + struct: mubi4 + package: prim_mubi_pkg + type: uni + act: req + width: 1 + inst_name: aes + default: "" + top_signame: clkmgr_aon_idle + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: aes + index: -1 + } + { + name: edn + struct: edn + package: edn_pkg + type: req_rsp + act: req + width: 1 + inst_name: aes + index: -1 + } + { + name: keymgr_key + struct: hw_key_req + package: keymgr_pkg + type: uni + act: rcv + width: 1 + inst_name: aes + index: -1 + } + { + name: tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: aes + default: "" + end_idx: -1 + top_signame: aes_tl + index: -1 + } + { + name: sram_otp_key + struct: sram_otp_key + package: otp_ctrl_pkg + type: req_rsp + act: req + width: 1 + inst_name: sram_ctrl_main + index: -1 + } + { + name: cfg + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: + { + name: NumRamInst + desc: Number of internal RAM instances. Must be the same as ceil(MemSizeRam / InstSize) . + param_type: int + unpacked_dimensions: null + default: 1 + local: false + expose: true + name_top: SramCtrlMainNumRamInst + } + default: "'0" + inst_name: sram_ctrl_main + index: -1 + } + { + name: cfg_rsp + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: + { + name: NumRamInst + desc: Number of internal RAM instances. Must be the same as ceil(MemSizeRam / InstSize) . + param_type: int + unpacked_dimensions: null + default: 1 + local: false + expose: true + name_top: SramCtrlMainNumRamInst + } + default: "'0" + inst_name: sram_ctrl_main + index: -1 + } + { + name: lc_escalate_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: sram_ctrl_main + index: -1 + } + { + name: lc_hw_debug_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + default: lc_ctrl_pkg::Off + inst_name: sram_ctrl_main + index: -1 + } + { + name: otp_en_sram_ifetch + struct: mubi8 + package: prim_mubi_pkg + type: uni + act: rcv + width: 1 + default: prim_mubi_pkg::MuBi8False + inst_name: sram_ctrl_main + top_signame: sram_ctrl_main_otp_en_sram_ifetch + index: -1 + } + { + name: regs_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: sram_ctrl_main + default: "" + end_idx: -1 + top_signame: sram_ctrl_main_regs_tl + index: -1 + } + { + name: ram_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: sram_ctrl_main + default: "" + end_idx: -1 + top_signame: sram_ctrl_main_ram_tl + index: -1 + } + { + name: rom_cfg + struct: rom_cfg + package: prim_rom_pkg + type: uni + act: rcv + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: pwrmgr_data + struct: pwrmgr_data + package: rom_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: keymgr_data + struct: keymgr_data + package: rom_ctrl_pkg + type: uni + act: req + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: kmac_data + struct: app + package: kmac_pkg + type: req_rsp + act: req + width: 1 + inst_name: rom_ctrl + index: -1 + } + { + name: regs_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rom_ctrl + default: "" + end_idx: -1 + top_signame: rom_ctrl_regs_tl + index: -1 + } + { + name: rom_tl + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rom_ctrl + default: "" + end_idx: -1 + top_signame: rom_ctrl_rom_tl + index: -1 + } + { + name: rst_cpu_n + struct: logic + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_icache_tag + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_rsp_icache_tag + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: + { + name: ICacheNWays + desc: Number of instruction cache ways + param_type: int unsigned + unpacked_dimensions: null + default: 2 + local: false + expose: true + name_top: RvCoreIbexICacheNWays + } + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_icache_data + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: ram_cfg_rsp_icache_data + struct: ram_1p_cfg_rsp + package: prim_ram_1p_pkg + type: uni + act: req + width: + { + name: ICacheNWays + desc: Number of instruction cache ways + param_type: int unsigned + unpacked_dimensions: null + default: 2 + local: false + expose: true + name_top: RvCoreIbexICacheNWays + } + inst_name: rv_core_ibex + index: -1 + } + { + name: hart_id + struct: logic + type: uni + act: rcv + width: 32 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_core_ibex_hart_id + index: -1 + } + { + name: boot_addr + struct: logic + type: uni + act: rcv + width: 32 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_core_ibex_boot_addr + index: -1 + } + { + name: irq_software + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_plic_msip + index: -1 + } + { + name: irq_timer + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_core_ibex_irq_timer + index: -1 + } + { + name: irq_external + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + package: "" + top_signame: rv_plic_irq + index: -1 + } + { + name: esc_tx + struct: esc_tx + package: prim_esc_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: esc_rx + struct: esc_rx + package: prim_esc_pkg + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: debug_req + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: crash_dump + struct: cpu_crash_dump + package: rv_core_ibex_pkg + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_core_ibex_crash_dump + index: -1 + } + { + name: lc_cpu_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: rv_core_ibex_lc_cpu_en + index: -1 + } + { + name: pwrmgr_cpu_en + struct: lc_tx + package: lc_ctrl_pkg + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: pwrmgr_aon_fetch_en + index: -1 + } + { + name: pwrmgr + struct: cpu_pwrmgr + package: rv_core_ibex_pkg + type: uni + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + end_idx: -1 + top_type: broadcast + top_signame: rv_core_ibex_pwrmgr + index: -1 + } + { + name: nmi_wdog + struct: logic + type: uni + act: rcv + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: edn + struct: edn + package: edn_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: icache_otp_key + struct: sram_otp_key + package: otp_ctrl_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + index: -1 + } + { + name: fpga_info + struct: logic + type: uni + act: rcv + width: 32 + inst_name: rv_core_ibex + default: "" + package: "" + external: true + top_signame: fpga_info + conn_type: false + index: -1 + } + { + name: corei_tl_h + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: main_tl_rv_core_ibex__corei + index: -1 + } + { + name: cored_tl_h + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: rv_core_ibex + default: "" + top_signame: main_tl_rv_core_ibex__cored + index: -1 + } + { + name: cfg_tl_d + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: rv_core_ibex + default: "" + end_idx: -1 + top_signame: rv_core_ibex_cfg_tl_d + index: -1 + } + { + name: tl_rv_core_ibex__corei + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: main + default: "" + end_idx: -1 + top_signame: main_tl_rv_core_ibex__corei + index: -1 + } + { + name: tl_rv_core_ibex__cored + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: main + default: "" + end_idx: -1 + top_signame: main_tl_rv_core_ibex__cored + index: -1 + } + { + name: tl_rom_ctrl__rom + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rom_ctrl_rom_tl + index: -1 + } + { + name: tl_rom_ctrl__regs + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rom_ctrl_regs_tl + index: -1 + } + { + name: tl_peri + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + end_idx: -1 + top_signame: main_tl_peri + index: -1 + } + { + name: tl_flash_ctrl__core + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: flash_ctrl_core_tl + index: -1 + } + { + name: tl_flash_ctrl__prim + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: flash_ctrl_prim_tl + index: -1 + } + { + name: tl_flash_ctrl__mem + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: flash_ctrl_mem_tl + index: -1 + } + { + name: tl_aes + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: aes_tl + index: -1 + } + { + name: tl_rv_plic + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rv_plic_tl + index: -1 + } + { + name: tl_rv_core_ibex__cfg + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: rv_core_ibex_cfg_tl_d + index: -1 + } + { + name: tl_sram_ctrl_main__regs + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: sram_ctrl_main_regs_tl + index: -1 + } + { + name: tl_sram_ctrl_main__ram + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: main + default: "" + top_signame: sram_ctrl_main_ram_tl + index: -1 + } + { + name: tl_main + struct: tl + package: tlul_pkg + type: req_rsp + act: rsp + width: 1 + inst_name: peri + default: "" + top_signame: main_tl_peri + index: -1 + } + { + name: tl_uart0 + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: uart0_tl + index: -1 + } + { + name: tl_uart1 + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: uart1_tl + index: -1 + } + { + name: tl_gpio + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: gpio_tl + index: -1 + } + { + name: tl_spi_device + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: spi_device_tl + index: -1 + } + { + name: tl_spi_host0 + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: spi_host0_tl + index: -1 + } + { + name: tl_rv_timer + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: rv_timer_tl + index: -1 + } + { + name: tl_usbdev + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: usbdev_tl + index: -1 + } + { + name: tl_pwrmgr_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: pwrmgr_aon_tl + index: -1 + } + { + name: tl_rstmgr_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: rstmgr_aon_tl + index: -1 + } + { + name: tl_clkmgr_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: clkmgr_aon_tl + index: -1 + } + { + name: tl_pinmux_aon + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + top_signame: pinmux_aon_tl + index: -1 + } + { + name: tl_ast + struct: tl + package: tlul_pkg + type: req_rsp + act: req + width: 1 + inst_name: peri + default: "" + external: true + top_signame: ast_tl + conn_type: false + index: -1 + } + { + struct: edn + type: req_rsp + name: edn + act: rsp + package: edn_pkg + inst_name: ast + width: 1 + default: "" + external: true + top_signame: ast_edn + conn_type: false + index: -1 + } + { + struct: lc_tx + type: uni + name: lc_dft_en + act: req + package: lc_ctrl_pkg + inst_name: ast + width: 1 + default: "" + external: true + top_signame: ast_lc_dft_en + conn_type: false + index: -1 + } + { + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + name: ram_1p_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: ram_1p_cfg + conn_type: false + index: -1 + } + { + struct: ram_2p_cfg + package: prim_ram_2p_pkg + type: uni + name: spi_ram_2p_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: spi_ram_2p_cfg + conn_type: false + index: -1 + } + { + struct: ram_1p_cfg + package: prim_ram_1p_pkg + type: uni + name: usb_ram_1p_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: usb_ram_1p_cfg + conn_type: false + index: -1 + } + { + struct: rom_cfg + package: prim_rom_pkg + type: uni + name: rom_cfg + act: rcv + inst_name: ast + width: 1 + default: "" + external: true + top_signame: rom_cfg + conn_type: false + index: -1 + } + ] + external: + [ + { + package: edn_pkg + struct: edn_req + signame: ast_edn_req_i + width: 1 + type: req_rsp + default: "" + direction: in + conn_type: false + index: -1 + netname: ast_edn_req + } + { + package: edn_pkg + struct: edn_rsp + signame: ast_edn_rsp_o + width: 1 + type: req_rsp + default: "" + direction: out + conn_type: false + index: -1 + netname: ast_edn_rsp + } + { + package: lc_ctrl_pkg + struct: lc_tx + signame: ast_lc_dft_en_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: ast_lc_dft_en + } + { + package: prim_ram_1p_pkg + struct: ram_1p_cfg + signame: ram_1p_cfg_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: ram_1p_cfg + } + { + package: prim_ram_2p_pkg + struct: ram_2p_cfg + signame: spi_ram_2p_cfg_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: spi_ram_2p_cfg + } + { + package: prim_ram_1p_pkg + struct: ram_1p_cfg + signame: usb_ram_1p_cfg_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: usb_ram_1p_cfg + } + { + package: prim_rom_pkg + struct: rom_cfg + signame: rom_cfg_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: rom_cfg + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: clk_main_jitter_en_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: clk_main_jitter_en + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: hi_speed_sel_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: hi_speed_sel + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: div_step_down_req_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: div_step_down_req + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: all_clk_byp_req_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: all_clk_byp_req + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: all_clk_byp_ack_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: all_clk_byp_ack + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: io_clk_byp_req_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: io_clk_byp_req + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: io_clk_byp_ack_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: io_clk_byp_ack + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: flash_bist_enable_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: flash_bist_enable + } + { + package: "" + struct: logic + signame: flash_power_down_h_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: flash_power_down_h + } + { + package: "" + struct: logic + signame: flash_power_ready_h_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: flash_power_ready_h + } + { + package: ast_pkg + struct: ast_obs_ctrl + signame: obs_ctrl_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: obs_ctrl + } + { + package: "" + struct: logic + signame: flash_obs_o + width: 8 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: flash_obs + } + { + package: tlul_pkg + struct: tl_h2d + signame: ast_tl_req_o + width: 1 + type: req_rsp + default: "" + direction: out + conn_type: false + index: -1 + netname: ast_tl_h2d + } + { + package: tlul_pkg + struct: tl_d2h + signame: ast_tl_rsp_i + width: 1 + type: req_rsp + default: "" + direction: in + conn_type: false + index: -1 + netname: ast_tl_d2h + } + { + package: pinmux_pkg + struct: dft_strap_test_req + signame: dft_strap_test_o + width: 1 + type: uni + default: "'0" + direction: out + conn_type: false + index: -1 + netname: dft_strap_test + } + { + package: "" + struct: logic + signame: dft_hold_tap_sel_i + width: 1 + type: uni + default: "'0" + direction: in + conn_type: false + index: -1 + netname: dft_hold_tap_sel + } + { + package: "" + struct: logic + signame: usb_dp_pullup_en_o + width: 1 + type: uni + default: 1'b0 + direction: out + conn_type: false + index: -1 + netname: usb_dp_pullup_en + } + { + package: "" + struct: logic + signame: usb_dn_pullup_en_o + width: 1 + type: uni + default: 1'b0 + direction: out + conn_type: false + index: -1 + netname: usb_dn_pullup_en + } + { + package: pwrmgr_pkg + struct: pwr_ast_req + signame: pwrmgr_ast_req_o + width: 1 + type: req_rsp + default: "" + direction: out + conn_type: false + index: -1 + netname: pwrmgr_ast_req + } + { + package: pwrmgr_pkg + struct: pwr_ast_rsp + signame: pwrmgr_ast_rsp_i + width: 1 + type: req_rsp + default: "" + direction: in + conn_type: false + index: -1 + netname: pwrmgr_ast_rsp + } + { + package: "" + struct: logic + signame: por_n_i + width: 2 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: por_n + } + { + package: "" + struct: logic + signame: fpga_info_i + width: 32 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: fpga_info + } + { + package: "" + struct: logic + signame: usbdev_usb_rx_d_i + width: 1 + type: uni + default: "" + direction: in + conn_type: false + index: -1 + netname: usbdev_usb_rx_d + } + { + package: "" + struct: logic + signame: usbdev_usb_tx_d_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: usbdev_usb_tx_d + } + { + package: "" + struct: logic + signame: usbdev_usb_tx_se0_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: usbdev_usb_tx_se0 + } + { + package: "" + struct: logic + signame: usbdev_usb_tx_use_d_se0_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: usbdev_usb_tx_use_d_se0 + } + { + package: "" + struct: logic + signame: usbdev_usb_rx_enable_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: usbdev_usb_rx_enable + } + { + package: "" + struct: logic + signame: usbdev_usb_ref_val_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: usbdev_usb_ref_val + } + { + package: "" + struct: logic + signame: usbdev_usb_ref_pulse_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: usbdev_usb_ref_pulse + } + { + package: "" + struct: logic + signame: sck_monitor_o + width: 1 + type: uni + default: "" + direction: out + conn_type: false + index: -1 + netname: sck_monitor + } + ] + definitions: + [ + { + package: pwrmgr_pkg + struct: pwr_flash + signame: pwrmgr_aon_pwr_flash + width: 1 + type: uni + end_idx: -1 + act: rcv + suffix: "" + default: pwrmgr_pkg::PWR_FLASH_DEFAULT + } + { + package: pwrmgr_pkg + struct: pwr_rst_req + signame: pwrmgr_aon_pwr_rst_req + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: req + default: "" + } + { + package: pwrmgr_pkg + struct: pwr_rst_rsp + signame: pwrmgr_aon_pwr_rst_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: rsp + default: pwrmgr_pkg::PWR_RST_RSP_DEFAULT + } + { + package: pwrmgr_pkg + struct: pwr_clk_req + signame: pwrmgr_aon_pwr_clk_req + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: req + default: "" + } + { + package: pwrmgr_pkg + struct: pwr_clk_rsp + signame: pwrmgr_aon_pwr_clk_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: rsp + default: pwrmgr_pkg::PWR_CLK_RSP_DEFAULT + } + { + package: "" + struct: logic + signame: pwrmgr_aon_strap + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: pwrmgr_aon_low_power + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: lc_ctrl_pkg + struct: lc_tx + signame: pwrmgr_aon_fetch_en + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: lc_ctrl_pkg::LC_TX_DEFAULT + } + { + package: "" + struct: logic + signame: usbdev_usb_dp_pullup + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: usbdev_usb_dn_pullup + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: usbdev_usb_aon_suspend_req + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: usbdev_usb_aon_wake_ack + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: usbdev_usb_aon_bus_reset + width: 1 + type: uni + end_idx: -1 + act: rcv + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: usbdev_usb_aon_sense_lost + width: 1 + type: uni + end_idx: -1 + act: rcv + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: pinmux_aon_usbdev_wake_detect_active + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: 1'b0 + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: clkmgr_aon_idle + width: 1 + type: uni + end_idx: -1 + act: rcv + suffix: "" + default: prim_mubi_pkg::MUBI4_DEFAULT + } + { + package: "" + struct: logic + signame: rv_plic_msip + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: rv_plic_irq + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: "'0" + } + { + package: rv_core_ibex_pkg + struct: cpu_crash_dump + signame: rv_core_ibex_crash_dump + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: rv_core_ibex_pkg::CPU_CRASH_DUMP_DEFAULT + } + { + package: rv_core_ibex_pkg + struct: cpu_pwrmgr + signame: rv_core_ibex_pwrmgr + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: rv_core_ibex_pkg::CPU_PWRMGR_DEFAULT + } + { + package: spi_device_pkg + struct: passthrough_req + signame: spi_device_passthrough_req + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: req + default: "" + } + { + package: spi_device_pkg + struct: passthrough_rsp + signame: spi_device_passthrough_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: rsp + default: spi_device_pkg::PASSTHROUGH_RSP_DEFAULT + } + { + package: prim_mubi_pkg + struct: mubi4 + signame: rstmgr_aon_sw_rst_req + width: 1 + type: uni + end_idx: -1 + act: req + suffix: "" + default: prim_mubi_pkg::MUBI4_DEFAULT + } + { + package: "" + struct: logic + signame: pwrmgr_aon_wakeups + width: 3 + type: uni + end_idx: -1 + act: rcv + suffix: "" + default: "'0" + } + { + package: "" + struct: logic + signame: pwrmgr_aon_rstreqs + width: 1 + type: uni + end_idx: -1 + act: rcv + suffix: "" + default: "'0" + } + { + package: tlul_pkg + struct: tl_h2d + signame: main_tl_rv_core_ibex__corei_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: main_tl_rv_core_ibex__corei_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: main_tl_rv_core_ibex__cored_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: main_tl_rv_core_ibex__cored_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: rom_ctrl_rom_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: rom_ctrl_rom_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: rom_ctrl_regs_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: rom_ctrl_regs_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: main_tl_peri_req + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: req + default: "" + } + { + package: tlul_pkg + struct: tl_d2h + signame: main_tl_peri_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: req + suffix: rsp + default: tlul_pkg::TL_D2H_DEFAULT + } + { + package: tlul_pkg + struct: tl_h2d + signame: flash_ctrl_core_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: flash_ctrl_core_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: flash_ctrl_prim_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: flash_ctrl_prim_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: flash_ctrl_mem_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: flash_ctrl_mem_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: aes_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: aes_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: rv_plic_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: rv_plic_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: rv_core_ibex_cfg_tl_d_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: rv_core_ibex_cfg_tl_d_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: sram_ctrl_main_regs_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: sram_ctrl_main_regs_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: sram_ctrl_main_ram_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: sram_ctrl_main_ram_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: uart0_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: uart0_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: uart1_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: uart1_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: gpio_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: gpio_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: spi_device_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: spi_device_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: spi_host0_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: spi_host0_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: rv_timer_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: rv_timer_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: usbdev_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: usbdev_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: pwrmgr_aon_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: pwrmgr_aon_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: rstmgr_aon_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: rstmgr_aon_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: clkmgr_aon_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: clkmgr_aon_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: tlul_pkg + struct: tl_h2d + signame: pinmux_aon_tl_req + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: req + default: tlul_pkg::TL_H2D_DEFAULT + } + { + package: tlul_pkg + struct: tl_d2h + signame: pinmux_aon_tl_rsp + width: 1 + type: req_rsp + end_idx: -1 + act: rsp + suffix: rsp + default: "" + } + { + package: clkmgr_pkg + struct: clkmgr_out + signame: clkmgr_aon_clocks + width: 1 + type: uni + end_idx: -1 + default: "" + } + { + package: clkmgr_pkg + struct: clkmgr_cg_en + signame: clkmgr_aon_cg_en + width: 1 + type: uni + end_idx: -1 + default: "" + } + { + package: rstmgr_pkg + struct: rstmgr_out + signame: rstmgr_aon_resets + width: 1 + type: uni + end_idx: -1 + default: "" + } + { + package: rstmgr_pkg + struct: rstmgr_rst_en + signame: rstmgr_aon_rst_en + width: 1 + type: uni + end_idx: -1 + default: "" + } + { + package: "" + struct: logic + signame: rv_core_ibex_irq_timer + width: 1 + type: uni + end_idx: -1 + default: "" + } + { + package: "" + struct: logic + signame: rv_core_ibex_hart_id + width: 32 + type: uni + end_idx: -1 + default: "" + } + { + package: "" + struct: logic + signame: rv_core_ibex_boot_addr + width: 32 + type: uni + end_idx: -1 + default: "" + } + { + package: lc_ctrl_pkg + struct: lc_tx + signame: rv_core_ibex_lc_cpu_en + width: 1 + type: uni + end_idx: -1 + default: "" + } + { + package: jtag_pkg + struct: jtag_req + signame: pinmux_aon_dft_jtag_req + width: 1 + type: req_rsp + end_idx: -1 + default: "" + } + { + package: jtag_pkg + struct: jtag_rsp + signame: pinmux_aon_dft_jtag_rsp + width: 1 + type: req_rsp + end_idx: -1 + default: "" + } + { + package: prim_mubi_pkg + struct: mubi8 + signame: sram_ctrl_main_otp_en_sram_ifetch + width: 1 + type: uni + end_idx: -1 + default: prim_mubi_pkg::MuBi8False + } + ] + } +} diff --git a/hw/top_englishbreakfast/dv/autogen/rstmgr_tgl_excl.cfg b/hw/top_englishbreakfast/dv/autogen/rstmgr_tgl_excl.cfg new file mode 100644 index 0000000000000..19eea43942cd8 --- /dev/null +++ b/hw/top_englishbreakfast/dv/autogen/rstmgr_tgl_excl.cfg @@ -0,0 +1,31 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// rstmgr_tgl_excl.cfg generated by `topgen.py` tool +// +// ------------------- 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: +// +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson \ +// -o hw/top_englishbreakfast/ \ +// --rnd_cnst_seed \ +// 4881560218908238235 + +//========================================================= +// This file contains resets that are not used at top level +//========================================================= +-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_aon_n[1] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_n[1] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_io_n[1] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_io_div2_n[1] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_io_div4_n[1] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_io_div4_shadowed_n[1] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_usb_n[1] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_lc_n[0] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_lc_shadowed_n[0] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_sys_n[0] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_sys_shadowed_n[0] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_spi_device_n[0] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_spi_host0_n[0] +-node tb.dut*.u_rstmgr_aon.resets_o.rst_usb_n[0] diff --git a/hw/top_englishbreakfast/dv/autogen/tb__alert_handler_connect.sv b/hw/top_englishbreakfast/dv/autogen/tb__alert_handler_connect.sv new file mode 100644 index 0000000000000..e62ce731f39b7 --- /dev/null +++ b/hw/top_englishbreakfast/dv/autogen/tb__alert_handler_connect.sv @@ -0,0 +1,34 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// tb__alert_handler_connect.sv is auto-generated by `topgen.py` tool + +assign alert_if[0].alert_tx = `CHIP_HIER.u_uart0.alert_tx_o[0]; +assign alert_if[1].alert_tx = `CHIP_HIER.u_uart1.alert_tx_o[0]; +assign alert_if[2].alert_tx = `CHIP_HIER.u_gpio.alert_tx_o[0]; +assign alert_if[3].alert_tx = `CHIP_HIER.u_spi_device.alert_tx_o[0]; +assign alert_if[4].alert_tx = `CHIP_HIER.u_spi_host0.alert_tx_o[0]; +assign alert_if[5].alert_tx = `CHIP_HIER.u_rv_timer.alert_tx_o[0]; +assign alert_if[6].alert_tx = `CHIP_HIER.u_usbdev.alert_tx_o[0]; +assign alert_if[7].alert_tx = `CHIP_HIER.u_pwrmgr_aon.alert_tx_o[0]; +assign alert_if[8].alert_tx = `CHIP_HIER.u_rstmgr_aon.alert_tx_o[0]; +assign alert_if[9].alert_tx = `CHIP_HIER.u_rstmgr_aon.alert_tx_o[1]; +assign alert_if[10].alert_tx = `CHIP_HIER.u_clkmgr_aon.alert_tx_o[0]; +assign alert_if[11].alert_tx = `CHIP_HIER.u_clkmgr_aon.alert_tx_o[1]; +assign alert_if[12].alert_tx = `CHIP_HIER.u_pinmux_aon.alert_tx_o[0]; +assign alert_if[13].alert_tx = `CHIP_HIER.u_aon_timer_aon.alert_tx_o[0]; +assign alert_if[14].alert_tx = `CHIP_HIER.u_flash_ctrl.alert_tx_o[0]; +assign alert_if[15].alert_tx = `CHIP_HIER.u_flash_ctrl.alert_tx_o[1]; +assign alert_if[16].alert_tx = `CHIP_HIER.u_flash_ctrl.alert_tx_o[2]; +assign alert_if[17].alert_tx = `CHIP_HIER.u_flash_ctrl.alert_tx_o[3]; +assign alert_if[18].alert_tx = `CHIP_HIER.u_flash_ctrl.alert_tx_o[4]; +assign alert_if[19].alert_tx = `CHIP_HIER.u_rv_plic.alert_tx_o[0]; +assign alert_if[20].alert_tx = `CHIP_HIER.u_aes.alert_tx_o[0]; +assign alert_if[21].alert_tx = `CHIP_HIER.u_aes.alert_tx_o[1]; +assign alert_if[22].alert_tx = `CHIP_HIER.u_sram_ctrl_main.alert_tx_o[0]; +assign alert_if[23].alert_tx = `CHIP_HIER.u_rom_ctrl.alert_tx_o[0]; +assign alert_if[24].alert_tx = `CHIP_HIER.u_rv_core_ibex.alert_tx_o[0]; +assign alert_if[25].alert_tx = `CHIP_HIER.u_rv_core_ibex.alert_tx_o[1]; +assign alert_if[26].alert_tx = `CHIP_HIER.u_rv_core_ibex.alert_tx_o[2]; +assign alert_if[27].alert_tx = `CHIP_HIER.u_rv_core_ibex.alert_tx_o[3]; diff --git a/hw/top_englishbreakfast/dv/autogen/tb__xbar_connect.sv b/hw/top_englishbreakfast/dv/autogen/tb__xbar_connect.sv new file mode 100644 index 0000000000000..09f9b8bca382e --- /dev/null +++ b/hw/top_englishbreakfast/dv/autogen/tb__xbar_connect.sv @@ -0,0 +1,136 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// tb__xbar_connect generated by `topgen.py` tool + +// This file must be `included in `hw/top_/dv/tb/tb.sv. + +`define DRIVE_CHIP_TL_HOST_IF(tl_name, inst_name, sig_name) \ + force ``tl_name``_tl_if.d2h = dut.top_englishbreakfast.u_``inst_name``.``sig_name``_i; \ + force dut.top_englishbreakfast.u_``inst_name``.``sig_name``_o = ``tl_name``_tl_if.h2d; \ + force dut.top_englishbreakfast.u_``inst_name``.clk_i = 0; \ + uvm_config_db#(virtual tl_if)::set(null, $sformatf("*env.%0s_agent", `"tl_name`"), "vif", \ + ``tl_name``_tl_if); + +`define DRIVE_CHIP_TL_DEVICE_IF(tl_name, inst_name, sig_name) \ + force ``tl_name``_tl_if.h2d = dut.top_englishbreakfast.u_``inst_name``.``sig_name``_i; \ + force dut.top_englishbreakfast.u_``inst_name``.``sig_name``_o = ``tl_name``_tl_if.d2h; \ + force dut.top_englishbreakfast.u_``inst_name``.clk_i = 0; \ + uvm_config_db#(virtual tl_if)::set(null, $sformatf("*env.%0s_agent", `"tl_name`"), "vif", \ + ``tl_name``_tl_if); + +`define DRIVE_CHIP_TL_EXT_DEVICE_IF(tl_name, inst_name, port_name) \ + force ``tl_name``_tl_if.h2d = dut.u_``inst_name``.``port_name``_i; \ + force dut.u_``inst_name``.``port_name``_o = ``tl_name``_tl_if.d2h; \ + uvm_config_db#(virtual tl_if)::set(null, $sformatf("*env.%0s_agent", `"tl_name`"), "vif", \ + ``tl_name``_tl_if); + +wire clk_main; +clk_rst_if clk_rst_if_main(.clk(clk_main), .rst_n(rst_n)); +wire clk_io; +clk_rst_if clk_rst_if_io(.clk(clk_io), .rst_n(rst_n)); +wire clk_usb; +clk_rst_if clk_rst_if_usb(.clk(clk_usb), .rst_n(rst_n)); +wire clk_io_div4; +clk_rst_if clk_rst_if_io_div4(.clk(clk_io_div4), .rst_n(rst_n)); + +tl_if rv_core_ibex__corei_tl_if(clk_main, rst_n); +tl_if rv_core_ibex__cored_tl_if(clk_main, rst_n); + +tl_if rom_ctrl__rom_tl_if(clk_main, rst_n); +tl_if rom_ctrl__regs_tl_if(clk_main, rst_n); +tl_if flash_ctrl__core_tl_if(clk_main, rst_n); +tl_if flash_ctrl__prim_tl_if(clk_main, rst_n); +tl_if flash_ctrl__mem_tl_if(clk_main, rst_n); +tl_if aes_tl_if(clk_main, rst_n); +tl_if rv_plic_tl_if(clk_main, rst_n); +tl_if rv_core_ibex__cfg_tl_if(clk_main, rst_n); +tl_if sram_ctrl_main__regs_tl_if(clk_main, rst_n); +tl_if sram_ctrl_main__ram_tl_if(clk_main, rst_n); +tl_if uart0_tl_if(clk_io_div4, rst_n); +tl_if uart1_tl_if(clk_io_div4, rst_n); +tl_if gpio_tl_if(clk_io_div4, rst_n); +tl_if spi_device_tl_if(clk_io_div4, rst_n); +tl_if spi_host0_tl_if(clk_io, rst_n); +tl_if rv_timer_tl_if(clk_io_div4, rst_n); +tl_if usbdev_tl_if(clk_usb, rst_n); +tl_if pwrmgr_aon_tl_if(clk_io_div4, rst_n); +tl_if rstmgr_aon_tl_if(clk_io_div4, rst_n); +tl_if clkmgr_aon_tl_if(clk_io_div4, rst_n); +tl_if pinmux_aon_tl_if(clk_io_div4, rst_n); +tl_if ast_tl_if(clk_io_div4, rst_n); + +initial begin + wait (xbar_mode !== 1'bx); + if (xbar_mode) begin + // only enable assertions in xbar as many pins are unconnected + $assertoff(0, tb); + $asserton(0, tb.dut.top_englishbreakfast.u_xbar_main); + $asserton(0, tb.dut.top_englishbreakfast.u_xbar_peri); + + + // These are all zero-time: anything that consumes time go at the end. + + // bypass clkmgr, force clocks directly + force tb.dut.top_englishbreakfast.u_xbar_main.clk_main_i = clk_main; + force tb.dut.top_englishbreakfast.u_xbar_main.clk_fixed_i = clk_io_div4; + force tb.dut.top_englishbreakfast.u_xbar_peri.clk_peri_i = clk_io_div4; + force tb.dut.top_englishbreakfast.u_xbar_peri.clk_spi_host0_i = clk_io; + force tb.dut.top_englishbreakfast.u_xbar_peri.clk_usb_i = clk_usb; + + // bypass rstmgr, force resets directly + force tb.dut.top_englishbreakfast.u_xbar_main.rst_main_ni = rst_n; + force tb.dut.top_englishbreakfast.u_xbar_main.rst_fixed_ni = rst_n; + force tb.dut.top_englishbreakfast.u_xbar_peri.rst_peri_ni = rst_n; + force tb.dut.top_englishbreakfast.u_xbar_peri.rst_spi_host0_ni = rst_n; + force tb.dut.top_englishbreakfast.u_xbar_peri.rst_usb_ni = rst_n; + +`ifndef GATE_LEVEL + `DRIVE_CHIP_TL_HOST_IF(rv_core_ibex__corei, rv_core_ibex, corei_tl_h) + `DRIVE_CHIP_TL_HOST_IF(rv_core_ibex__cored, rv_core_ibex, cored_tl_h) + `DRIVE_CHIP_TL_DEVICE_IF(rom_ctrl__rom, rom_ctrl, rom_tl) + `DRIVE_CHIP_TL_DEVICE_IF(rom_ctrl__regs, rom_ctrl, regs_tl) + `DRIVE_CHIP_TL_DEVICE_IF(flash_ctrl__core, flash_ctrl, core_tl) + `DRIVE_CHIP_TL_DEVICE_IF(flash_ctrl__prim, flash_ctrl, prim_tl) + `DRIVE_CHIP_TL_DEVICE_IF(flash_ctrl__mem, flash_ctrl, mem_tl) + `DRIVE_CHIP_TL_DEVICE_IF(aes, aes, tl) + `DRIVE_CHIP_TL_DEVICE_IF(rv_plic, rv_plic, tl) + `DRIVE_CHIP_TL_DEVICE_IF(rv_core_ibex__cfg, rv_core_ibex, cfg_tl_d) + `DRIVE_CHIP_TL_DEVICE_IF(sram_ctrl_main__regs, sram_ctrl_main, regs_tl) + `DRIVE_CHIP_TL_DEVICE_IF(sram_ctrl_main__ram, sram_ctrl_main, ram_tl) + `DRIVE_CHIP_TL_DEVICE_IF(uart0, uart0, tl) + `DRIVE_CHIP_TL_DEVICE_IF(uart1, uart1, tl) + `DRIVE_CHIP_TL_DEVICE_IF(gpio, gpio, tl) + `DRIVE_CHIP_TL_DEVICE_IF(spi_device, spi_device, tl) + `DRIVE_CHIP_TL_DEVICE_IF(spi_host0, spi_host0, tl) + `DRIVE_CHIP_TL_DEVICE_IF(rv_timer, rv_timer, tl) + `DRIVE_CHIP_TL_DEVICE_IF(usbdev, usbdev, tl) + `DRIVE_CHIP_TL_DEVICE_IF(pwrmgr_aon, pwrmgr_aon, tl) + `DRIVE_CHIP_TL_DEVICE_IF(rstmgr_aon, rstmgr_aon, tl) + `DRIVE_CHIP_TL_DEVICE_IF(clkmgr_aon, clkmgr_aon, tl) + `DRIVE_CHIP_TL_DEVICE_IF(pinmux_aon, pinmux_aon, tl) + `DRIVE_CHIP_TL_EXT_DEVICE_IF(ast, ast, tl) +`endif + + // And this can consume time, so they go at the end of this block. + + // Wait for a negedge of rst_n, or else we will have clock edges before + // reset, which could capture 'X values. + xbar_clk_rst_if.wait_for_reset(.wait_posedge(1'b0)); + + clk_rst_if_main.set_active(.drive_rst_n_val(0)); + clk_rst_if_main.set_freq_khz(100000000 / 1000); + clk_rst_if_io.set_active(.drive_rst_n_val(0)); + clk_rst_if_io.set_freq_khz(96000000 / 1000); + clk_rst_if_usb.set_active(.drive_rst_n_val(0)); + clk_rst_if_usb.set_freq_khz(48000000 / 1000); + clk_rst_if_io_div4.set_active(.drive_rst_n_val(0)); + clk_rst_if_io_div4.set_freq_khz(24000000 / 1000); + + end +end + +`undef DRIVE_CHIP_TL_HOST_IF +`undef DRIVE_CHIP_TL_DEVICE_IF +`undef DRIVE_CHIP_TL_EXT_DEVICE_IF diff --git a/hw/top_englishbreakfast/dv/autogen/xbar_env_pkg__params.sv b/hw/top_englishbreakfast/dv/autogen/xbar_env_pkg__params.sv new file mode 100644 index 0000000000000..4067393df73dc --- /dev/null +++ b/hw/top_englishbreakfast/dv/autogen/xbar_env_pkg__params.sv @@ -0,0 +1,108 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_env_pkg__params generated by `topgen.py` tool + + +// List of Xbar device memory map +tl_device_t xbar_devices[$] = '{ + '{"rom_ctrl__rom", '{ + '{32'h00008000, 32'h0000ffff} + }}, + '{"rom_ctrl__regs", '{ + '{32'h411e0000, 32'h411e007f} + }}, + '{"flash_ctrl__core", '{ + '{32'h41000000, 32'h410001ff} + }}, + '{"flash_ctrl__prim", '{ + '{32'h41008000, 32'h4100807f} + }}, + '{"flash_ctrl__mem", '{ + '{32'h20000000, 32'h2000ffff} + }}, + '{"aes", '{ + '{32'h41100000, 32'h411000ff} + }}, + '{"rv_plic", '{ + '{32'h48000000, 32'h4fffffff} + }}, + '{"rv_core_ibex__cfg", '{ + '{32'h411f0000, 32'h411f00ff} + }}, + '{"sram_ctrl_main__regs", '{ + '{32'h411c0000, 32'h411c003f} + }}, + '{"sram_ctrl_main__ram", '{ + '{32'h10000000, 32'h1001ffff} + }}, + '{"uart0", '{ + '{32'h40000000, 32'h4000003f} + }}, + '{"uart1", '{ + '{32'h40010000, 32'h4001003f} + }}, + '{"gpio", '{ + '{32'h40040000, 32'h4004007f} + }}, + '{"spi_device", '{ + '{32'h40050000, 32'h40051fff} + }}, + '{"spi_host0", '{ + '{32'h40060000, 32'h4006003f} + }}, + '{"rv_timer", '{ + '{32'h40100000, 32'h401001ff} + }}, + '{"usbdev", '{ + '{32'h40320000, 32'h40320fff} + }}, + '{"pwrmgr_aon", '{ + '{32'h40400000, 32'h4040007f} + }}, + '{"rstmgr_aon", '{ + '{32'h40410000, 32'h4041007f} + }}, + '{"clkmgr_aon", '{ + '{32'h40420000, 32'h4042007f} + }}, + '{"pinmux_aon", '{ + '{32'h40460000, 32'h40460fff} + }}, + '{"ast", '{ + '{32'h40480000, 32'h404803ff} + }}}; + + // List of Xbar hosts +tl_host_t xbar_hosts[$] = '{ + '{"rv_core_ibex__corei", 0, '{ + "rom_ctrl__rom", + "sram_ctrl_main__ram", + "flash_ctrl__mem"}} + , + '{"rv_core_ibex__cored", 1, '{ + "rom_ctrl__rom", + "rom_ctrl__regs", + "sram_ctrl_main__ram", + "flash_ctrl__mem", + "uart0", + "uart1", + "gpio", + "spi_device", + "spi_host0", + "rv_timer", + "usbdev", + "pwrmgr_aon", + "rstmgr_aon", + "clkmgr_aon", + "pinmux_aon", + "ast", + "flash_ctrl__core", + "flash_ctrl__prim", + "aes", + "rv_plic", + "sram_ctrl_main__ram", + "sram_ctrl_main__regs", + "rv_core_ibex__cfg"}} +}; diff --git a/hw/top_englishbreakfast/dv/autogen/xbar_tgl_excl.cfg b/hw/top_englishbreakfast/dv/autogen/xbar_tgl_excl.cfg new file mode 100644 index 0000000000000..fdcaef860d892 --- /dev/null +++ b/hw/top_englishbreakfast/dv/autogen/xbar_tgl_excl.cfg @@ -0,0 +1,98 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_tgl_excl.cfg generated by `topgen.py` tool + +// [UNSUPPORTED] Exclude unused TL port signals at all hierarchies, wherever port toggle coverage is +// enabled. Exercising these reserved signals will result in assertion errors thrown by the design. +-node tb.dut*.u_* *tl_*.a_param +-node tb.dut*.u_* *tl_*.a_user.rsvd +-node tb.dut*.u_* *tl_*.d_param +-node tb.dut*.u_* *tl_*.d_opcode[2:1] +-node tb.dut*.u_* *tl_*.a_source[7:6] +-node tb.dut*.u_* *tl_*.d_source[7:6] +-node tb.dut.top_englishbreakfast *tl_*.a_param +-node tb.dut.top_englishbreakfast *tl_*.a_user.rsvd +-node tb.dut.top_englishbreakfast *tl_*.d_param +-node tb.dut.top_englishbreakfast *tl_*.d_opcode[2:1] +-node tb.dut.top_englishbreakfast *tl_*.a_source[7:6] +-node tb.dut.top_englishbreakfast *tl_*.d_source[7:6] + +// [LOW_RISK] Exclude the full TL a_address signal on all pass-through hierarchies. We instead look +// at the full coverage of this signal directly at the host or at the device. +-node tb.dut.top_englishbreakfast *tl_*.a_address +-node tb.dut.top_englishbreakfast.u_xbar_* tl_*.a_address + +// [UNR] Exclude unused address bits based on IP address range. It is not possible to cover this. +-node tb.dut*.u_rom_ctrl rom_tl_*i.a_address[31:16] +-node tb.dut*.u_rom_ctrl regs_tl_*i.a_address[16:7] +-node tb.dut*.u_rom_ctrl regs_tl_*i.a_address[23:21] +-node tb.dut*.u_rom_ctrl regs_tl_*i.a_address[29:25] +-node tb.dut*.u_rom_ctrl regs_tl_*i.a_address[31:31] +-node tb.dut*.u_flash_ctrl core_tl_*i.a_address[23:9] +-node tb.dut*.u_flash_ctrl core_tl_*i.a_address[29:25] +-node tb.dut*.u_flash_ctrl core_tl_*i.a_address[31:31] +-node tb.dut*.u_flash_ctrl prim_tl_*i.a_address[14:7] +-node tb.dut*.u_flash_ctrl prim_tl_*i.a_address[23:16] +-node tb.dut*.u_flash_ctrl prim_tl_*i.a_address[29:25] +-node tb.dut*.u_flash_ctrl prim_tl_*i.a_address[31:31] +-node tb.dut*.u_flash_ctrl mem_tl_*i.a_address[28:16] +-node tb.dut*.u_flash_ctrl mem_tl_*i.a_address[31:30] +-node tb.dut*.u_aes tl_*i.a_address[19:8] +-node tb.dut*.u_aes tl_*i.a_address[23:21] +-node tb.dut*.u_aes tl_*i.a_address[29:25] +-node tb.dut*.u_aes tl_*i.a_address[31:31] +-node tb.dut*.u_rv_plic tl_*i.a_address[29:28] +-node tb.dut*.u_rv_plic tl_*i.a_address[31:31] +-node tb.dut*.u_rv_core_ibex cfg_tl_*i.a_address[15:8] +-node tb.dut*.u_rv_core_ibex cfg_tl_*i.a_address[23:21] +-node tb.dut*.u_rv_core_ibex cfg_tl_*i.a_address[29:25] +-node tb.dut*.u_rv_core_ibex cfg_tl_*i.a_address[31:31] +-node tb.dut*.u_sram_ctrl_main regs_tl_*i.a_address[17:6] +-node tb.dut*.u_sram_ctrl_main regs_tl_*i.a_address[23:21] +-node tb.dut*.u_sram_ctrl_main regs_tl_*i.a_address[29:25] +-node tb.dut*.u_sram_ctrl_main regs_tl_*i.a_address[31:31] +-node tb.dut*.u_sram_ctrl_main ram_tl_*i.a_address[27:17] +-node tb.dut*.u_sram_ctrl_main ram_tl_*i.a_address[31:29] +-node tb.dut*.u_uart0 tl_*i.a_address[29:6] +-node tb.dut*.u_uart0 tl_*i.a_address[31:31] +-node tb.dut*.u_uart1 tl_*i.a_address[15:6] +-node tb.dut*.u_uart1 tl_*i.a_address[29:17] +-node tb.dut*.u_uart1 tl_*i.a_address[31:31] +-node tb.dut*.u_gpio tl_*i.a_address[17:7] +-node tb.dut*.u_gpio tl_*i.a_address[29:19] +-node tb.dut*.u_gpio tl_*i.a_address[31:31] +-node tb.dut*.u_spi_device tl_*i.a_address[15:13] +-node tb.dut*.u_spi_device tl_*i.a_address[17:17] +-node tb.dut*.u_spi_device tl_*i.a_address[29:19] +-node tb.dut*.u_spi_device tl_*i.a_address[31:31] +-node tb.dut*.u_spi_host0 tl_*i.a_address[16:6] +-node tb.dut*.u_spi_host0 tl_*i.a_address[29:19] +-node tb.dut*.u_spi_host0 tl_*i.a_address[31:31] +-node tb.dut*.u_rv_timer tl_*i.a_address[19:9] +-node tb.dut*.u_rv_timer tl_*i.a_address[29:21] +-node tb.dut*.u_rv_timer tl_*i.a_address[31:31] +-node tb.dut*.u_usbdev tl_*i.a_address[16:12] +-node tb.dut*.u_usbdev tl_*i.a_address[19:18] +-node tb.dut*.u_usbdev tl_*i.a_address[29:22] +-node tb.dut*.u_usbdev tl_*i.a_address[31:31] +-node tb.dut*.u_pwrmgr_aon tl_*i.a_address[21:7] +-node tb.dut*.u_pwrmgr_aon tl_*i.a_address[29:23] +-node tb.dut*.u_pwrmgr_aon tl_*i.a_address[31:31] +-node tb.dut*.u_rstmgr_aon tl_*i.a_address[15:7] +-node tb.dut*.u_rstmgr_aon tl_*i.a_address[21:17] +-node tb.dut*.u_rstmgr_aon tl_*i.a_address[29:23] +-node tb.dut*.u_rstmgr_aon tl_*i.a_address[31:31] +-node tb.dut*.u_clkmgr_aon tl_*i.a_address[16:7] +-node tb.dut*.u_clkmgr_aon tl_*i.a_address[21:18] +-node tb.dut*.u_clkmgr_aon tl_*i.a_address[29:23] +-node tb.dut*.u_clkmgr_aon tl_*i.a_address[31:31] +-node tb.dut*.u_pinmux_aon tl_*i.a_address[16:12] +-node tb.dut*.u_pinmux_aon tl_*i.a_address[21:19] +-node tb.dut*.u_pinmux_aon tl_*i.a_address[29:23] +-node tb.dut*.u_pinmux_aon tl_*i.a_address[31:31] +-node tb.dut*.u_ast tl_*i.a_address[18:10] +-node tb.dut*.u_ast tl_*i.a_address[21:20] +-node tb.dut*.u_ast tl_*i.a_address[29:23] +-node tb.dut*.u_ast tl_*i.a_address[31:31] diff --git a/hw/top_englishbreakfast/dv/env/autogen/chip_env_pkg__params.sv b/hw/top_englishbreakfast/dv/env/autogen/chip_env_pkg__params.sv new file mode 100644 index 0000000000000..418117971cb5c --- /dev/null +++ b/hw/top_englishbreakfast/dv/env/autogen/chip_env_pkg__params.sv @@ -0,0 +1,38 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Generated by topgen.py + +parameter string LIST_OF_ALERTS[] = { + "uart0_fatal_fault", + "uart1_fatal_fault", + "gpio_fatal_fault", + "spi_device_fatal_fault", + "spi_host0_fatal_fault", + "rv_timer_fatal_fault", + "usbdev_fatal_fault", + "pwrmgr_aon_fatal_fault", + "rstmgr_aon_fatal_fault", + "rstmgr_aon_fatal_cnsty_fault", + "clkmgr_aon_recov_fault", + "clkmgr_aon_fatal_fault", + "pinmux_aon_fatal_fault", + "aon_timer_aon_fatal_fault", + "flash_ctrl_recov_err", + "flash_ctrl_fatal_std_err", + "flash_ctrl_fatal_err", + "flash_ctrl_fatal_prim_flash_alert", + "flash_ctrl_recov_prim_flash_alert", + "rv_plic_fatal_fault", + "aes_recov_ctrl_update_err", + "aes_fatal_fault", + "sram_ctrl_main_fatal_error", + "rom_ctrl_fatal", + "rv_core_ibex_fatal_sw_err", + "rv_core_ibex_recov_sw_err", + "rv_core_ibex_fatal_hw_err", + "rv_core_ibex_recov_hw_err" +}; + +parameter uint NUM_ALERTS = 28; diff --git a/hw/top_englishbreakfast/ip/ast/README.md b/hw/top_englishbreakfast/ip/ast/README.md new file mode 120000 index 0000000000000..332e2c80df8cb --- /dev/null +++ b/hw/top_englishbreakfast/ip/ast/README.md @@ -0,0 +1 @@ +../../../top_earlgrey/ip/ast/README.md \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/ast/ast_regs.html b/hw/top_englishbreakfast/ip/ast/ast_regs.html new file mode 120000 index 0000000000000..0159a700f534c --- /dev/null +++ b/hw/top_englishbreakfast/ip/ast/ast_regs.html @@ -0,0 +1 @@ +../../../top_earlgrey/ip/ast/ast_regs.html \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/ast/data b/hw/top_englishbreakfast/ip/ast/data new file mode 120000 index 0000000000000..3282095af6a42 --- /dev/null +++ b/hw/top_englishbreakfast/ip/ast/data @@ -0,0 +1 @@ +../../../top_earlgrey/ip/ast/data \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/ast/data/ast.hjson b/hw/top_englishbreakfast/ip/ast/data/ast.hjson deleted file mode 120000 index e161656985461..0000000000000 --- a/hw/top_englishbreakfast/ip/ast/data/ast.hjson +++ /dev/null @@ -1 +0,0 @@ -../../../../top_earlgrey/ip/ast/data/ast.hjson \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/ast/doc b/hw/top_englishbreakfast/ip/ast/doc new file mode 120000 index 0000000000000..afc94c09c5446 --- /dev/null +++ b/hw/top_englishbreakfast/ip/ast/doc @@ -0,0 +1 @@ +../../../top_earlgrey/ip/ast/doc \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/ast/rtl/ast_reg_pkg.sv b/hw/top_englishbreakfast/ip/ast/rtl/ast_reg_pkg.sv new file mode 100644 index 0000000000000..e81894e3b767f --- /dev/null +++ b/hw/top_englishbreakfast/ip/ast/rtl/ast_reg_pkg.sv @@ -0,0 +1,380 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 ast_reg_pkg; + + // Param list + parameter int NumRegsB = 5; + parameter int NumUsbBeaconPulses = 8; + + // Address widths within the block + parameter int BlockAw = 10; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega0_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega1_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega2_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega3_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega4_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega5_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega6_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega7_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega8_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega9_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega10_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega11_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega12_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega13_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega14_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega15_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega16_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega17_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega18_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega19_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega20_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega21_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega22_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega23_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega24_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega25_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega26_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega27_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega28_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega29_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega30_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega31_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega32_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega33_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega34_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega35_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega36_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_rega37_reg_t; + + typedef struct packed { + logic [31:0] q; + logic qe; + } ast_reg2hw_regal_reg_t; + + typedef struct packed { + logic [31:0] q; + } ast_reg2hw_regb_mreg_t; + + typedef struct packed { + logic [31:0] d; + } ast_hw2reg_regal_reg_t; + + // Register -> HW type + typedef struct packed { + ast_reg2hw_rega0_reg_t rega0; // [1408:1377] + ast_reg2hw_rega1_reg_t rega1; // [1376:1345] + ast_reg2hw_rega2_reg_t rega2; // [1344:1313] + ast_reg2hw_rega3_reg_t rega3; // [1312:1281] + ast_reg2hw_rega4_reg_t rega4; // [1280:1249] + ast_reg2hw_rega5_reg_t rega5; // [1248:1217] + ast_reg2hw_rega6_reg_t rega6; // [1216:1185] + ast_reg2hw_rega7_reg_t rega7; // [1184:1153] + ast_reg2hw_rega8_reg_t rega8; // [1152:1121] + ast_reg2hw_rega9_reg_t rega9; // [1120:1089] + ast_reg2hw_rega10_reg_t rega10; // [1088:1057] + ast_reg2hw_rega11_reg_t rega11; // [1056:1025] + ast_reg2hw_rega12_reg_t rega12; // [1024:993] + ast_reg2hw_rega13_reg_t rega13; // [992:961] + ast_reg2hw_rega14_reg_t rega14; // [960:929] + ast_reg2hw_rega15_reg_t rega15; // [928:897] + ast_reg2hw_rega16_reg_t rega16; // [896:865] + ast_reg2hw_rega17_reg_t rega17; // [864:833] + ast_reg2hw_rega18_reg_t rega18; // [832:801] + ast_reg2hw_rega19_reg_t rega19; // [800:769] + ast_reg2hw_rega20_reg_t rega20; // [768:737] + ast_reg2hw_rega21_reg_t rega21; // [736:705] + ast_reg2hw_rega22_reg_t rega22; // [704:673] + ast_reg2hw_rega23_reg_t rega23; // [672:641] + ast_reg2hw_rega24_reg_t rega24; // [640:609] + ast_reg2hw_rega25_reg_t rega25; // [608:577] + ast_reg2hw_rega26_reg_t rega26; // [576:545] + ast_reg2hw_rega27_reg_t rega27; // [544:513] + ast_reg2hw_rega28_reg_t rega28; // [512:481] + ast_reg2hw_rega29_reg_t rega29; // [480:449] + ast_reg2hw_rega30_reg_t rega30; // [448:417] + ast_reg2hw_rega31_reg_t rega31; // [416:385] + ast_reg2hw_rega32_reg_t rega32; // [384:353] + ast_reg2hw_rega33_reg_t rega33; // [352:321] + ast_reg2hw_rega34_reg_t rega34; // [320:289] + ast_reg2hw_rega35_reg_t rega35; // [288:257] + ast_reg2hw_rega36_reg_t rega36; // [256:225] + ast_reg2hw_rega37_reg_t rega37; // [224:193] + ast_reg2hw_regal_reg_t regal; // [192:160] + ast_reg2hw_regb_mreg_t [4:0] regb; // [159:0] + } ast_reg2hw_t; + + // HW -> register type + typedef struct packed { + ast_hw2reg_regal_reg_t regal; // [31:0] + } ast_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] AST_REGA0_OFFSET = 10'h 0; + parameter logic [BlockAw-1:0] AST_REGA1_OFFSET = 10'h 4; + parameter logic [BlockAw-1:0] AST_REGA2_OFFSET = 10'h 8; + parameter logic [BlockAw-1:0] AST_REGA3_OFFSET = 10'h c; + parameter logic [BlockAw-1:0] AST_REGA4_OFFSET = 10'h 10; + parameter logic [BlockAw-1:0] AST_REGA5_OFFSET = 10'h 14; + parameter logic [BlockAw-1:0] AST_REGA6_OFFSET = 10'h 18; + parameter logic [BlockAw-1:0] AST_REGA7_OFFSET = 10'h 1c; + parameter logic [BlockAw-1:0] AST_REGA8_OFFSET = 10'h 20; + parameter logic [BlockAw-1:0] AST_REGA9_OFFSET = 10'h 24; + parameter logic [BlockAw-1:0] AST_REGA10_OFFSET = 10'h 28; + parameter logic [BlockAw-1:0] AST_REGA11_OFFSET = 10'h 2c; + parameter logic [BlockAw-1:0] AST_REGA12_OFFSET = 10'h 30; + parameter logic [BlockAw-1:0] AST_REGA13_OFFSET = 10'h 34; + parameter logic [BlockAw-1:0] AST_REGA14_OFFSET = 10'h 38; + parameter logic [BlockAw-1:0] AST_REGA15_OFFSET = 10'h 3c; + parameter logic [BlockAw-1:0] AST_REGA16_OFFSET = 10'h 40; + parameter logic [BlockAw-1:0] AST_REGA17_OFFSET = 10'h 44; + parameter logic [BlockAw-1:0] AST_REGA18_OFFSET = 10'h 48; + parameter logic [BlockAw-1:0] AST_REGA19_OFFSET = 10'h 4c; + parameter logic [BlockAw-1:0] AST_REGA20_OFFSET = 10'h 50; + parameter logic [BlockAw-1:0] AST_REGA21_OFFSET = 10'h 54; + parameter logic [BlockAw-1:0] AST_REGA22_OFFSET = 10'h 58; + parameter logic [BlockAw-1:0] AST_REGA23_OFFSET = 10'h 5c; + parameter logic [BlockAw-1:0] AST_REGA24_OFFSET = 10'h 60; + parameter logic [BlockAw-1:0] AST_REGA25_OFFSET = 10'h 64; + parameter logic [BlockAw-1:0] AST_REGA26_OFFSET = 10'h 68; + parameter logic [BlockAw-1:0] AST_REGA27_OFFSET = 10'h 6c; + parameter logic [BlockAw-1:0] AST_REGA28_OFFSET = 10'h 70; + parameter logic [BlockAw-1:0] AST_REGA29_OFFSET = 10'h 74; + parameter logic [BlockAw-1:0] AST_REGA30_OFFSET = 10'h 78; + parameter logic [BlockAw-1:0] AST_REGA31_OFFSET = 10'h 7c; + parameter logic [BlockAw-1:0] AST_REGA32_OFFSET = 10'h 80; + parameter logic [BlockAw-1:0] AST_REGA33_OFFSET = 10'h 84; + parameter logic [BlockAw-1:0] AST_REGA34_OFFSET = 10'h 88; + parameter logic [BlockAw-1:0] AST_REGA35_OFFSET = 10'h 8c; + parameter logic [BlockAw-1:0] AST_REGA36_OFFSET = 10'h 90; + parameter logic [BlockAw-1:0] AST_REGA37_OFFSET = 10'h 94; + parameter logic [BlockAw-1:0] AST_REGAL_OFFSET = 10'h 98; + parameter logic [BlockAw-1:0] AST_REGB_0_OFFSET = 10'h 200; + parameter logic [BlockAw-1:0] AST_REGB_1_OFFSET = 10'h 204; + parameter logic [BlockAw-1:0] AST_REGB_2_OFFSET = 10'h 208; + parameter logic [BlockAw-1:0] AST_REGB_3_OFFSET = 10'h 20c; + parameter logic [BlockAw-1:0] AST_REGB_4_OFFSET = 10'h 210; + + // Reset values for hwext registers and their fields + parameter logic [31:0] AST_REGAL_RESVAL = 32'h 26; + parameter logic [31:0] AST_REGAL_REG32_RESVAL = 32'h 26; + + // Register index + typedef enum int { + AST_REGA0, + AST_REGA1, + AST_REGA2, + AST_REGA3, + AST_REGA4, + AST_REGA5, + AST_REGA6, + AST_REGA7, + AST_REGA8, + AST_REGA9, + AST_REGA10, + AST_REGA11, + AST_REGA12, + AST_REGA13, + AST_REGA14, + AST_REGA15, + AST_REGA16, + AST_REGA17, + AST_REGA18, + AST_REGA19, + AST_REGA20, + AST_REGA21, + AST_REGA22, + AST_REGA23, + AST_REGA24, + AST_REGA25, + AST_REGA26, + AST_REGA27, + AST_REGA28, + AST_REGA29, + AST_REGA30, + AST_REGA31, + AST_REGA32, + AST_REGA33, + AST_REGA34, + AST_REGA35, + AST_REGA36, + AST_REGA37, + AST_REGAL, + AST_REGB_0, + AST_REGB_1, + AST_REGB_2, + AST_REGB_3, + AST_REGB_4 + } ast_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] AST_PERMIT [44] = '{ + 4'b 1111, // index[ 0] AST_REGA0 + 4'b 1111, // index[ 1] AST_REGA1 + 4'b 1111, // index[ 2] AST_REGA2 + 4'b 1111, // index[ 3] AST_REGA3 + 4'b 1111, // index[ 4] AST_REGA4 + 4'b 1111, // index[ 5] AST_REGA5 + 4'b 1111, // index[ 6] AST_REGA6 + 4'b 1111, // index[ 7] AST_REGA7 + 4'b 1111, // index[ 8] AST_REGA8 + 4'b 1111, // index[ 9] AST_REGA9 + 4'b 1111, // index[10] AST_REGA10 + 4'b 1111, // index[11] AST_REGA11 + 4'b 1111, // index[12] AST_REGA12 + 4'b 1111, // index[13] AST_REGA13 + 4'b 1111, // index[14] AST_REGA14 + 4'b 1111, // index[15] AST_REGA15 + 4'b 1111, // index[16] AST_REGA16 + 4'b 1111, // index[17] AST_REGA17 + 4'b 1111, // index[18] AST_REGA18 + 4'b 1111, // index[19] AST_REGA19 + 4'b 1111, // index[20] AST_REGA20 + 4'b 1111, // index[21] AST_REGA21 + 4'b 1111, // index[22] AST_REGA22 + 4'b 1111, // index[23] AST_REGA23 + 4'b 1111, // index[24] AST_REGA24 + 4'b 1111, // index[25] AST_REGA25 + 4'b 1111, // index[26] AST_REGA26 + 4'b 1111, // index[27] AST_REGA27 + 4'b 1111, // index[28] AST_REGA28 + 4'b 1111, // index[29] AST_REGA29 + 4'b 1111, // index[30] AST_REGA30 + 4'b 1111, // index[31] AST_REGA31 + 4'b 1111, // index[32] AST_REGA32 + 4'b 1111, // index[33] AST_REGA33 + 4'b 1111, // index[34] AST_REGA34 + 4'b 1111, // index[35] AST_REGA35 + 4'b 1111, // index[36] AST_REGA36 + 4'b 1111, // index[37] AST_REGA37 + 4'b 1111, // index[38] AST_REGAL + 4'b 1111, // index[39] AST_REGB_0 + 4'b 1111, // index[40] AST_REGB_1 + 4'b 1111, // index[41] AST_REGB_2 + 4'b 1111, // index[42] AST_REGB_3 + 4'b 1111 // index[43] AST_REGB_4 + }; + +endpackage diff --git a/hw/top_englishbreakfast/ip/ast/rtl/ast_reg_top.sv b/hw/top_englishbreakfast/ip/ast/rtl/ast_reg_top.sv new file mode 100644 index 0000000000000..921beb385a4f5 --- /dev/null +++ b/hw/top_englishbreakfast/ip/ast/rtl/ast_reg_top.sv @@ -0,0 +1,1969 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 ast_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 ast_reg_pkg::ast_reg2hw_t reg2hw, // Write + input ast_reg_pkg::ast_hw2reg_t hw2reg, // Read + + // Integrity check errors + output logic intg_err_o +); + + import ast_reg_pkg::* ; + + localparam int AW = 10; + 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 [43:0] reg_we_check; + prim_reg_we_check #( + .OneHotWidth(44) + ) 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 = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic [31:0] rega0_qs; + logic [31:0] rega1_qs; + logic rega2_we; + logic [31:0] rega2_qs; + logic [31:0] rega2_wd; + logic rega3_we; + logic [31:0] rega3_qs; + logic [31:0] rega3_wd; + logic rega4_we; + logic [31:0] rega4_qs; + logic [31:0] rega4_wd; + logic rega5_we; + logic [31:0] rega5_qs; + logic [31:0] rega5_wd; + logic rega6_we; + logic [31:0] rega6_qs; + logic [31:0] rega6_wd; + logic rega7_we; + logic [31:0] rega7_qs; + logic [31:0] rega7_wd; + logic rega8_we; + logic [31:0] rega8_qs; + logic [31:0] rega8_wd; + logic rega9_we; + logic [31:0] rega9_qs; + logic [31:0] rega9_wd; + logic rega10_we; + logic [31:0] rega10_qs; + logic [31:0] rega10_wd; + logic rega11_we; + logic [31:0] rega11_qs; + logic [31:0] rega11_wd; + logic rega12_we; + logic [31:0] rega12_qs; + logic [31:0] rega12_wd; + logic rega13_we; + logic [31:0] rega13_qs; + logic [31:0] rega13_wd; + logic rega14_we; + logic [31:0] rega14_qs; + logic [31:0] rega14_wd; + logic rega15_we; + logic [31:0] rega15_qs; + logic [31:0] rega15_wd; + logic rega16_we; + logic [31:0] rega16_qs; + logic [31:0] rega16_wd; + logic rega17_we; + logic [31:0] rega17_qs; + logic [31:0] rega17_wd; + logic rega18_we; + logic [31:0] rega18_qs; + logic [31:0] rega18_wd; + logic rega19_we; + logic [31:0] rega19_qs; + logic [31:0] rega19_wd; + logic rega20_we; + logic [31:0] rega20_qs; + logic [31:0] rega20_wd; + logic rega21_we; + logic [31:0] rega21_qs; + logic [31:0] rega21_wd; + logic rega22_we; + logic [31:0] rega22_qs; + logic [31:0] rega22_wd; + logic rega23_we; + logic [31:0] rega23_qs; + logic [31:0] rega23_wd; + logic rega24_we; + logic [31:0] rega24_qs; + logic [31:0] rega24_wd; + logic rega25_we; + logic [31:0] rega25_qs; + logic [31:0] rega25_wd; + logic rega26_we; + logic [31:0] rega26_qs; + logic [31:0] rega26_wd; + logic rega27_we; + logic [31:0] rega27_qs; + logic [31:0] rega27_wd; + logic [31:0] rega28_qs; + logic rega29_we; + logic [31:0] rega29_qs; + logic [31:0] rega29_wd; + logic rega30_we; + logic [31:0] rega30_qs; + logic [31:0] rega30_wd; + logic rega31_we; + logic [31:0] rega31_qs; + logic [31:0] rega31_wd; + logic rega32_we; + logic [31:0] rega32_qs; + logic [31:0] rega32_wd; + logic rega33_we; + logic [31:0] rega33_qs; + logic [31:0] rega33_wd; + logic rega34_we; + logic [31:0] rega34_qs; + logic [31:0] rega34_wd; + logic rega35_we; + logic [31:0] rega35_qs; + logic [31:0] rega35_wd; + logic rega36_we; + logic [31:0] rega36_qs; + logic [31:0] rega36_wd; + logic rega37_we; + logic [31:0] rega37_qs; + logic [31:0] rega37_wd; + logic regal_we; + logic [31:0] regal_wd; + logic regb_0_we; + logic [31:0] regb_0_qs; + logic [31:0] regb_0_wd; + logic regb_1_we; + logic [31:0] regb_1_qs; + logic [31:0] regb_1_wd; + logic regb_2_we; + logic [31:0] regb_2_qs; + logic [31:0] regb_2_wd; + logic regb_3_we; + logic [31:0] regb_3_qs; + logic [31:0] regb_3_wd; + logic regb_4_we; + logic [31:0] regb_4_qs; + logic [31:0] regb_4_wd; + + // Register instances + // R[rega0]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_rega0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega0.q), + .ds (), + + // to register interface (read) + .qs (rega0_qs) + ); + + + // R[rega1]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (32'h1), + .Mubi (1'b0) + ) u_rega1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega1.q), + .ds (), + + // to register interface (read) + .qs (rega1_qs) + ); + + + // R[rega2]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h2), + .Mubi (1'b0) + ) u_rega2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega2_we), + .wd (rega2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega2.q), + .ds (), + + // to register interface (read) + .qs (rega2_qs) + ); + + + // R[rega3]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h3), + .Mubi (1'b0) + ) u_rega3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega3_we), + .wd (rega3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega3.q), + .ds (), + + // to register interface (read) + .qs (rega3_qs) + ); + + + // R[rega4]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h4), + .Mubi (1'b0) + ) u_rega4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega4_we), + .wd (rega4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega4.q), + .ds (), + + // to register interface (read) + .qs (rega4_qs) + ); + + + // R[rega5]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h5), + .Mubi (1'b0) + ) u_rega5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega5_we), + .wd (rega5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega5.q), + .ds (), + + // to register interface (read) + .qs (rega5_qs) + ); + + + // R[rega6]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h6), + .Mubi (1'b0) + ) u_rega6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega6_we), + .wd (rega6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega6.q), + .ds (), + + // to register interface (read) + .qs (rega6_qs) + ); + + + // R[rega7]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h7), + .Mubi (1'b0) + ) u_rega7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega7_we), + .wd (rega7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega7.q), + .ds (), + + // to register interface (read) + .qs (rega7_qs) + ); + + + // R[rega8]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h8), + .Mubi (1'b0) + ) u_rega8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega8_we), + .wd (rega8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega8.q), + .ds (), + + // to register interface (read) + .qs (rega8_qs) + ); + + + // R[rega9]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h9), + .Mubi (1'b0) + ) u_rega9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega9_we), + .wd (rega9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega9.q), + .ds (), + + // to register interface (read) + .qs (rega9_qs) + ); + + + // R[rega10]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'ha), + .Mubi (1'b0) + ) u_rega10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega10_we), + .wd (rega10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega10.q), + .ds (), + + // to register interface (read) + .qs (rega10_qs) + ); + + + // R[rega11]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'hb), + .Mubi (1'b0) + ) u_rega11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega11_we), + .wd (rega11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega11.q), + .ds (), + + // to register interface (read) + .qs (rega11_qs) + ); + + + // R[rega12]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'hc), + .Mubi (1'b0) + ) u_rega12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega12_we), + .wd (rega12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega12.q), + .ds (), + + // to register interface (read) + .qs (rega12_qs) + ); + + + // R[rega13]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'hd), + .Mubi (1'b0) + ) u_rega13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega13_we), + .wd (rega13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega13.q), + .ds (), + + // to register interface (read) + .qs (rega13_qs) + ); + + + // R[rega14]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'he), + .Mubi (1'b0) + ) u_rega14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega14_we), + .wd (rega14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega14.q), + .ds (), + + // to register interface (read) + .qs (rega14_qs) + ); + + + // R[rega15]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'hf), + .Mubi (1'b0) + ) u_rega15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega15_we), + .wd (rega15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega15.q), + .ds (), + + // to register interface (read) + .qs (rega15_qs) + ); + + + // R[rega16]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h10), + .Mubi (1'b0) + ) u_rega16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega16_we), + .wd (rega16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega16.q), + .ds (), + + // to register interface (read) + .qs (rega16_qs) + ); + + + // R[rega17]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h11), + .Mubi (1'b0) + ) u_rega17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega17_we), + .wd (rega17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega17.q), + .ds (), + + // to register interface (read) + .qs (rega17_qs) + ); + + + // R[rega18]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h12), + .Mubi (1'b0) + ) u_rega18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega18_we), + .wd (rega18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega18.q), + .ds (), + + // to register interface (read) + .qs (rega18_qs) + ); + + + // R[rega19]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h13), + .Mubi (1'b0) + ) u_rega19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega19_we), + .wd (rega19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega19.q), + .ds (), + + // to register interface (read) + .qs (rega19_qs) + ); + + + // R[rega20]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h14), + .Mubi (1'b0) + ) u_rega20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega20_we), + .wd (rega20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega20.q), + .ds (), + + // to register interface (read) + .qs (rega20_qs) + ); + + + // R[rega21]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h15), + .Mubi (1'b0) + ) u_rega21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega21_we), + .wd (rega21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega21.q), + .ds (), + + // to register interface (read) + .qs (rega21_qs) + ); + + + // R[rega22]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h16), + .Mubi (1'b0) + ) u_rega22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega22_we), + .wd (rega22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega22.q), + .ds (), + + // to register interface (read) + .qs (rega22_qs) + ); + + + // R[rega23]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h17), + .Mubi (1'b0) + ) u_rega23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega23_we), + .wd (rega23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega23.q), + .ds (), + + // to register interface (read) + .qs (rega23_qs) + ); + + + // R[rega24]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h18), + .Mubi (1'b0) + ) u_rega24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega24_we), + .wd (rega24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega24.q), + .ds (), + + // to register interface (read) + .qs (rega24_qs) + ); + + + // R[rega25]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h19), + .Mubi (1'b0) + ) u_rega25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega25_we), + .wd (rega25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega25.q), + .ds (), + + // to register interface (read) + .qs (rega25_qs) + ); + + + // R[rega26]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h1a), + .Mubi (1'b0) + ) u_rega26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega26_we), + .wd (rega26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega26.q), + .ds (), + + // to register interface (read) + .qs (rega26_qs) + ); + + + // R[rega27]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h1b), + .Mubi (1'b0) + ) u_rega27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega27_we), + .wd (rega27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega27.q), + .ds (), + + // to register interface (read) + .qs (rega27_qs) + ); + + + // R[rega28]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (32'h1c), + .Mubi (1'b0) + ) u_rega28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega28.q), + .ds (), + + // to register interface (read) + .qs (rega28_qs) + ); + + + // R[rega29]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h1d), + .Mubi (1'b0) + ) u_rega29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega29_we), + .wd (rega29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega29.q), + .ds (), + + // to register interface (read) + .qs (rega29_qs) + ); + + + // R[rega30]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h1e), + .Mubi (1'b0) + ) u_rega30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega30_we), + .wd (rega30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega30.q), + .ds (), + + // to register interface (read) + .qs (rega30_qs) + ); + + + // R[rega31]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h1f), + .Mubi (1'b0) + ) u_rega31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega31_we), + .wd (rega31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega31.q), + .ds (), + + // to register interface (read) + .qs (rega31_qs) + ); + + + // R[rega32]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h20), + .Mubi (1'b0) + ) u_rega32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega32_we), + .wd (rega32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega32.q), + .ds (), + + // to register interface (read) + .qs (rega32_qs) + ); + + + // R[rega33]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h21), + .Mubi (1'b0) + ) u_rega33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega33_we), + .wd (rega33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega33.q), + .ds (), + + // to register interface (read) + .qs (rega33_qs) + ); + + + // R[rega34]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h22), + .Mubi (1'b0) + ) u_rega34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega34_we), + .wd (rega34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega34.q), + .ds (), + + // to register interface (read) + .qs (rega34_qs) + ); + + + // R[rega35]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h23), + .Mubi (1'b0) + ) u_rega35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega35_we), + .wd (rega35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega35.q), + .ds (), + + // to register interface (read) + .qs (rega35_qs) + ); + + + // R[rega36]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h24), + .Mubi (1'b0) + ) u_rega36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega36_we), + .wd (rega36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega36.q), + .ds (), + + // to register interface (read) + .qs (rega36_qs) + ); + + + // R[rega37]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h25), + .Mubi (1'b0) + ) u_rega37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (rega37_we), + .wd (rega37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.rega37.q), + .ds (), + + // to register interface (read) + .qs (rega37_qs) + ); + + + // R[regal]: V(True) + logic regal_qe; + logic [0:0] regal_flds_we; + assign regal_qe = ®al_flds_we; + prim_subreg_ext #( + .DW (32) + ) u_regal ( + .re (1'b0), + .we (regal_we), + .wd (regal_wd), + .d (hw2reg.regal.d), + .qre (), + .qe (regal_flds_we[0]), + .q (reg2hw.regal.q), + .ds (), + .qs () + ); + assign reg2hw.regal.qe = regal_qe; + + + // Subregister 0 of Multireg regb + // R[regb_0]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_regb_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (regb_0_we), + .wd (regb_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.regb[0].q), + .ds (), + + // to register interface (read) + .qs (regb_0_qs) + ); + + + // Subregister 1 of Multireg regb + // R[regb_1]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_regb_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (regb_1_we), + .wd (regb_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.regb[1].q), + .ds (), + + // to register interface (read) + .qs (regb_1_qs) + ); + + + // Subregister 2 of Multireg regb + // R[regb_2]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_regb_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (regb_2_we), + .wd (regb_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.regb[2].q), + .ds (), + + // to register interface (read) + .qs (regb_2_qs) + ); + + + // Subregister 3 of Multireg regb + // R[regb_3]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_regb_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (regb_3_we), + .wd (regb_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.regb[3].q), + .ds (), + + // to register interface (read) + .qs (regb_3_qs) + ); + + + // Subregister 4 of Multireg regb + // R[regb_4]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_regb_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (regb_4_we), + .wd (regb_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.regb[4].q), + .ds (), + + // to register interface (read) + .qs (regb_4_qs) + ); + + + + logic [43:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == AST_REGA0_OFFSET); + addr_hit[ 1] = (reg_addr == AST_REGA1_OFFSET); + addr_hit[ 2] = (reg_addr == AST_REGA2_OFFSET); + addr_hit[ 3] = (reg_addr == AST_REGA3_OFFSET); + addr_hit[ 4] = (reg_addr == AST_REGA4_OFFSET); + addr_hit[ 5] = (reg_addr == AST_REGA5_OFFSET); + addr_hit[ 6] = (reg_addr == AST_REGA6_OFFSET); + addr_hit[ 7] = (reg_addr == AST_REGA7_OFFSET); + addr_hit[ 8] = (reg_addr == AST_REGA8_OFFSET); + addr_hit[ 9] = (reg_addr == AST_REGA9_OFFSET); + addr_hit[10] = (reg_addr == AST_REGA10_OFFSET); + addr_hit[11] = (reg_addr == AST_REGA11_OFFSET); + addr_hit[12] = (reg_addr == AST_REGA12_OFFSET); + addr_hit[13] = (reg_addr == AST_REGA13_OFFSET); + addr_hit[14] = (reg_addr == AST_REGA14_OFFSET); + addr_hit[15] = (reg_addr == AST_REGA15_OFFSET); + addr_hit[16] = (reg_addr == AST_REGA16_OFFSET); + addr_hit[17] = (reg_addr == AST_REGA17_OFFSET); + addr_hit[18] = (reg_addr == AST_REGA18_OFFSET); + addr_hit[19] = (reg_addr == AST_REGA19_OFFSET); + addr_hit[20] = (reg_addr == AST_REGA20_OFFSET); + addr_hit[21] = (reg_addr == AST_REGA21_OFFSET); + addr_hit[22] = (reg_addr == AST_REGA22_OFFSET); + addr_hit[23] = (reg_addr == AST_REGA23_OFFSET); + addr_hit[24] = (reg_addr == AST_REGA24_OFFSET); + addr_hit[25] = (reg_addr == AST_REGA25_OFFSET); + addr_hit[26] = (reg_addr == AST_REGA26_OFFSET); + addr_hit[27] = (reg_addr == AST_REGA27_OFFSET); + addr_hit[28] = (reg_addr == AST_REGA28_OFFSET); + addr_hit[29] = (reg_addr == AST_REGA29_OFFSET); + addr_hit[30] = (reg_addr == AST_REGA30_OFFSET); + addr_hit[31] = (reg_addr == AST_REGA31_OFFSET); + addr_hit[32] = (reg_addr == AST_REGA32_OFFSET); + addr_hit[33] = (reg_addr == AST_REGA33_OFFSET); + addr_hit[34] = (reg_addr == AST_REGA34_OFFSET); + addr_hit[35] = (reg_addr == AST_REGA35_OFFSET); + addr_hit[36] = (reg_addr == AST_REGA36_OFFSET); + addr_hit[37] = (reg_addr == AST_REGA37_OFFSET); + addr_hit[38] = (reg_addr == AST_REGAL_OFFSET); + addr_hit[39] = (reg_addr == AST_REGB_0_OFFSET); + addr_hit[40] = (reg_addr == AST_REGB_1_OFFSET); + addr_hit[41] = (reg_addr == AST_REGB_2_OFFSET); + addr_hit[42] = (reg_addr == AST_REGB_3_OFFSET); + addr_hit[43] = (reg_addr == AST_REGB_4_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] & (|(AST_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(AST_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(AST_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(AST_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(AST_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(AST_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(AST_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(AST_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(AST_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(AST_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(AST_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(AST_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(AST_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(AST_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(AST_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(AST_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(AST_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(AST_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(AST_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(AST_PERMIT[19] & ~reg_be))) | + (addr_hit[20] & (|(AST_PERMIT[20] & ~reg_be))) | + (addr_hit[21] & (|(AST_PERMIT[21] & ~reg_be))) | + (addr_hit[22] & (|(AST_PERMIT[22] & ~reg_be))) | + (addr_hit[23] & (|(AST_PERMIT[23] & ~reg_be))) | + (addr_hit[24] & (|(AST_PERMIT[24] & ~reg_be))) | + (addr_hit[25] & (|(AST_PERMIT[25] & ~reg_be))) | + (addr_hit[26] & (|(AST_PERMIT[26] & ~reg_be))) | + (addr_hit[27] & (|(AST_PERMIT[27] & ~reg_be))) | + (addr_hit[28] & (|(AST_PERMIT[28] & ~reg_be))) | + (addr_hit[29] & (|(AST_PERMIT[29] & ~reg_be))) | + (addr_hit[30] & (|(AST_PERMIT[30] & ~reg_be))) | + (addr_hit[31] & (|(AST_PERMIT[31] & ~reg_be))) | + (addr_hit[32] & (|(AST_PERMIT[32] & ~reg_be))) | + (addr_hit[33] & (|(AST_PERMIT[33] & ~reg_be))) | + (addr_hit[34] & (|(AST_PERMIT[34] & ~reg_be))) | + (addr_hit[35] & (|(AST_PERMIT[35] & ~reg_be))) | + (addr_hit[36] & (|(AST_PERMIT[36] & ~reg_be))) | + (addr_hit[37] & (|(AST_PERMIT[37] & ~reg_be))) | + (addr_hit[38] & (|(AST_PERMIT[38] & ~reg_be))) | + (addr_hit[39] & (|(AST_PERMIT[39] & ~reg_be))) | + (addr_hit[40] & (|(AST_PERMIT[40] & ~reg_be))) | + (addr_hit[41] & (|(AST_PERMIT[41] & ~reg_be))) | + (addr_hit[42] & (|(AST_PERMIT[42] & ~reg_be))) | + (addr_hit[43] & (|(AST_PERMIT[43] & ~reg_be))))); + end + + // Generate write-enables + assign rega2_we = addr_hit[2] & reg_we & !reg_error; + + assign rega2_wd = reg_wdata[31:0]; + assign rega3_we = addr_hit[3] & reg_we & !reg_error; + + assign rega3_wd = reg_wdata[31:0]; + assign rega4_we = addr_hit[4] & reg_we & !reg_error; + + assign rega4_wd = reg_wdata[31:0]; + assign rega5_we = addr_hit[5] & reg_we & !reg_error; + + assign rega5_wd = reg_wdata[31:0]; + assign rega6_we = addr_hit[6] & reg_we & !reg_error; + + assign rega6_wd = reg_wdata[31:0]; + assign rega7_we = addr_hit[7] & reg_we & !reg_error; + + assign rega7_wd = reg_wdata[31:0]; + assign rega8_we = addr_hit[8] & reg_we & !reg_error; + + assign rega8_wd = reg_wdata[31:0]; + assign rega9_we = addr_hit[9] & reg_we & !reg_error; + + assign rega9_wd = reg_wdata[31:0]; + assign rega10_we = addr_hit[10] & reg_we & !reg_error; + + assign rega10_wd = reg_wdata[31:0]; + assign rega11_we = addr_hit[11] & reg_we & !reg_error; + + assign rega11_wd = reg_wdata[31:0]; + assign rega12_we = addr_hit[12] & reg_we & !reg_error; + + assign rega12_wd = reg_wdata[31:0]; + assign rega13_we = addr_hit[13] & reg_we & !reg_error; + + assign rega13_wd = reg_wdata[31:0]; + assign rega14_we = addr_hit[14] & reg_we & !reg_error; + + assign rega14_wd = reg_wdata[31:0]; + assign rega15_we = addr_hit[15] & reg_we & !reg_error; + + assign rega15_wd = reg_wdata[31:0]; + assign rega16_we = addr_hit[16] & reg_we & !reg_error; + + assign rega16_wd = reg_wdata[31:0]; + assign rega17_we = addr_hit[17] & reg_we & !reg_error; + + assign rega17_wd = reg_wdata[31:0]; + assign rega18_we = addr_hit[18] & reg_we & !reg_error; + + assign rega18_wd = reg_wdata[31:0]; + assign rega19_we = addr_hit[19] & reg_we & !reg_error; + + assign rega19_wd = reg_wdata[31:0]; + assign rega20_we = addr_hit[20] & reg_we & !reg_error; + + assign rega20_wd = reg_wdata[31:0]; + assign rega21_we = addr_hit[21] & reg_we & !reg_error; + + assign rega21_wd = reg_wdata[31:0]; + assign rega22_we = addr_hit[22] & reg_we & !reg_error; + + assign rega22_wd = reg_wdata[31:0]; + assign rega23_we = addr_hit[23] & reg_we & !reg_error; + + assign rega23_wd = reg_wdata[31:0]; + assign rega24_we = addr_hit[24] & reg_we & !reg_error; + + assign rega24_wd = reg_wdata[31:0]; + assign rega25_we = addr_hit[25] & reg_we & !reg_error; + + assign rega25_wd = reg_wdata[31:0]; + assign rega26_we = addr_hit[26] & reg_we & !reg_error; + + assign rega26_wd = reg_wdata[31:0]; + assign rega27_we = addr_hit[27] & reg_we & !reg_error; + + assign rega27_wd = reg_wdata[31:0]; + assign rega29_we = addr_hit[29] & reg_we & !reg_error; + + assign rega29_wd = reg_wdata[31:0]; + assign rega30_we = addr_hit[30] & reg_we & !reg_error; + + assign rega30_wd = reg_wdata[31:0]; + assign rega31_we = addr_hit[31] & reg_we & !reg_error; + + assign rega31_wd = reg_wdata[31:0]; + assign rega32_we = addr_hit[32] & reg_we & !reg_error; + + assign rega32_wd = reg_wdata[31:0]; + assign rega33_we = addr_hit[33] & reg_we & !reg_error; + + assign rega33_wd = reg_wdata[31:0]; + assign rega34_we = addr_hit[34] & reg_we & !reg_error; + + assign rega34_wd = reg_wdata[31:0]; + assign rega35_we = addr_hit[35] & reg_we & !reg_error; + + assign rega35_wd = reg_wdata[31:0]; + assign rega36_we = addr_hit[36] & reg_we & !reg_error; + + assign rega36_wd = reg_wdata[31:0]; + assign rega37_we = addr_hit[37] & reg_we & !reg_error; + + assign rega37_wd = reg_wdata[31:0]; + assign regal_we = addr_hit[38] & reg_we & !reg_error; + + assign regal_wd = reg_wdata[31:0]; + assign regb_0_we = addr_hit[39] & reg_we & !reg_error; + + assign regb_0_wd = reg_wdata[31:0]; + assign regb_1_we = addr_hit[40] & reg_we & !reg_error; + + assign regb_1_wd = reg_wdata[31:0]; + assign regb_2_we = addr_hit[41] & reg_we & !reg_error; + + assign regb_2_wd = reg_wdata[31:0]; + assign regb_3_we = addr_hit[42] & reg_we & !reg_error; + + assign regb_3_wd = reg_wdata[31:0]; + assign regb_4_we = addr_hit[43] & reg_we & !reg_error; + + assign regb_4_wd = reg_wdata[31:0]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = 1'b0; + reg_we_check[1] = 1'b0; + reg_we_check[2] = rega2_we; + reg_we_check[3] = rega3_we; + reg_we_check[4] = rega4_we; + reg_we_check[5] = rega5_we; + reg_we_check[6] = rega6_we; + reg_we_check[7] = rega7_we; + reg_we_check[8] = rega8_we; + reg_we_check[9] = rega9_we; + reg_we_check[10] = rega10_we; + reg_we_check[11] = rega11_we; + reg_we_check[12] = rega12_we; + reg_we_check[13] = rega13_we; + reg_we_check[14] = rega14_we; + reg_we_check[15] = rega15_we; + reg_we_check[16] = rega16_we; + reg_we_check[17] = rega17_we; + reg_we_check[18] = rega18_we; + reg_we_check[19] = rega19_we; + reg_we_check[20] = rega20_we; + reg_we_check[21] = rega21_we; + reg_we_check[22] = rega22_we; + reg_we_check[23] = rega23_we; + reg_we_check[24] = rega24_we; + reg_we_check[25] = rega25_we; + reg_we_check[26] = rega26_we; + reg_we_check[27] = rega27_we; + reg_we_check[28] = 1'b0; + reg_we_check[29] = rega29_we; + reg_we_check[30] = rega30_we; + reg_we_check[31] = rega31_we; + reg_we_check[32] = rega32_we; + reg_we_check[33] = rega33_we; + reg_we_check[34] = rega34_we; + reg_we_check[35] = rega35_we; + reg_we_check[36] = rega36_we; + reg_we_check[37] = rega37_we; + reg_we_check[38] = regal_we; + reg_we_check[39] = regb_0_we; + reg_we_check[40] = regb_1_we; + reg_we_check[41] = regb_2_we; + reg_we_check[42] = regb_3_we; + reg_we_check[43] = regb_4_we; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (1'b1) + addr_hit[0]: begin + reg_rdata_next[31:0] = rega0_qs; + end + + addr_hit[1]: begin + reg_rdata_next[31:0] = rega1_qs; + end + + addr_hit[2]: begin + reg_rdata_next[31:0] = rega2_qs; + end + + addr_hit[3]: begin + reg_rdata_next[31:0] = rega3_qs; + end + + addr_hit[4]: begin + reg_rdata_next[31:0] = rega4_qs; + end + + addr_hit[5]: begin + reg_rdata_next[31:0] = rega5_qs; + end + + addr_hit[6]: begin + reg_rdata_next[31:0] = rega6_qs; + end + + addr_hit[7]: begin + reg_rdata_next[31:0] = rega7_qs; + end + + addr_hit[8]: begin + reg_rdata_next[31:0] = rega8_qs; + end + + addr_hit[9]: begin + reg_rdata_next[31:0] = rega9_qs; + end + + addr_hit[10]: begin + reg_rdata_next[31:0] = rega10_qs; + end + + addr_hit[11]: begin + reg_rdata_next[31:0] = rega11_qs; + end + + addr_hit[12]: begin + reg_rdata_next[31:0] = rega12_qs; + end + + addr_hit[13]: begin + reg_rdata_next[31:0] = rega13_qs; + end + + addr_hit[14]: begin + reg_rdata_next[31:0] = rega14_qs; + end + + addr_hit[15]: begin + reg_rdata_next[31:0] = rega15_qs; + end + + addr_hit[16]: begin + reg_rdata_next[31:0] = rega16_qs; + end + + addr_hit[17]: begin + reg_rdata_next[31:0] = rega17_qs; + end + + addr_hit[18]: begin + reg_rdata_next[31:0] = rega18_qs; + end + + addr_hit[19]: begin + reg_rdata_next[31:0] = rega19_qs; + end + + addr_hit[20]: begin + reg_rdata_next[31:0] = rega20_qs; + end + + addr_hit[21]: begin + reg_rdata_next[31:0] = rega21_qs; + end + + addr_hit[22]: begin + reg_rdata_next[31:0] = rega22_qs; + end + + addr_hit[23]: begin + reg_rdata_next[31:0] = rega23_qs; + end + + addr_hit[24]: begin + reg_rdata_next[31:0] = rega24_qs; + end + + addr_hit[25]: begin + reg_rdata_next[31:0] = rega25_qs; + end + + addr_hit[26]: begin + reg_rdata_next[31:0] = rega26_qs; + end + + addr_hit[27]: begin + reg_rdata_next[31:0] = rega27_qs; + end + + addr_hit[28]: begin + reg_rdata_next[31:0] = rega28_qs; + end + + addr_hit[29]: begin + reg_rdata_next[31:0] = rega29_qs; + end + + addr_hit[30]: begin + reg_rdata_next[31:0] = rega30_qs; + end + + addr_hit[31]: begin + reg_rdata_next[31:0] = rega31_qs; + end + + addr_hit[32]: begin + reg_rdata_next[31:0] = rega32_qs; + end + + addr_hit[33]: begin + reg_rdata_next[31:0] = rega33_qs; + end + + addr_hit[34]: begin + reg_rdata_next[31:0] = rega34_qs; + end + + addr_hit[35]: begin + reg_rdata_next[31:0] = rega35_qs; + end + + addr_hit[36]: begin + reg_rdata_next[31:0] = rega36_qs; + end + + addr_hit[37]: begin + reg_rdata_next[31:0] = rega37_qs; + end + + addr_hit[38]: begin + reg_rdata_next[31:0] = '0; + end + + addr_hit[39]: begin + reg_rdata_next[31:0] = regb_0_qs; + end + + addr_hit[40]: begin + reg_rdata_next[31:0] = regb_1_qs; + end + + addr_hit[41]: begin + reg_rdata_next[31:0] = regb_2_qs; + end + + addr_hit[42]: begin + reg_rdata_next[31:0] = regb_3_qs; + end + + addr_hit[43]: begin + reg_rdata_next[31:0] = regb_4_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_englishbreakfast/ip/sensor_ctrl/README.md b/hw/top_englishbreakfast/ip/sensor_ctrl/README.md new file mode 120000 index 0000000000000..34b632a501fca --- /dev/null +++ b/hw/top_englishbreakfast/ip/sensor_ctrl/README.md @@ -0,0 +1 @@ +../../../top_earlgrey/ip/sensor_ctrl/README.md \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/sensor_ctrl/data b/hw/top_englishbreakfast/ip/sensor_ctrl/data new file mode 120000 index 0000000000000..0f3079bf389d3 --- /dev/null +++ b/hw/top_englishbreakfast/ip/sensor_ctrl/data @@ -0,0 +1 @@ +../../../top_earlgrey/ip/sensor_ctrl/data \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/sensor_ctrl/data/sensor_ctrl.hjson b/hw/top_englishbreakfast/ip/sensor_ctrl/data/sensor_ctrl.hjson deleted file mode 120000 index bdbb600ff862a..0000000000000 --- a/hw/top_englishbreakfast/ip/sensor_ctrl/data/sensor_ctrl.hjson +++ /dev/null @@ -1 +0,0 @@ -../../../../top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/sensor_ctrl/doc b/hw/top_englishbreakfast/ip/sensor_ctrl/doc new file mode 120000 index 0000000000000..1c49b4447c085 --- /dev/null +++ b/hw/top_englishbreakfast/ip/sensor_ctrl/doc @@ -0,0 +1 @@ +../../../top_earlgrey/ip/sensor_ctrl/doc \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.gen.hjson b/hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.gen.hjson new file mode 100644 index 0000000000000..6de197113ce91 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.gen.hjson @@ -0,0 +1,333 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson -o hw/top_englishbreakfast/ + +{ + name: main + clock_srcs: + { + clk_main_i: main + clk_fixed_i: io_div4 + } + clock_group: infra + reset: rst_main_ni + reset_connections: + { + rst_main_ni: + { + name: sys + domain: "0" + } + rst_fixed_ni: + { + name: sys_io_div4 + domain: "0" + } + } + clock_connections: + { + clk_main_i: clkmgr_aon_clocks.clk_main_infra + clk_fixed_i: clkmgr_aon_clocks.clk_io_div4_infra + } + domain: + [ + "0" + ] + connections: + { + rv_core_ibex.corei: + [ + rom_ctrl.rom + sram_ctrl_main.ram + flash_ctrl.mem + ] + rv_core_ibex.cored: + [ + rom_ctrl.rom + rom_ctrl.regs + sram_ctrl_main.ram + flash_ctrl.mem + peri + flash_ctrl.core + flash_ctrl.prim + aes + rv_plic + sram_ctrl_main.ram + sram_ctrl_main.regs + rv_core_ibex.cfg + ] + } + nodes: + [ + { + name: rv_core_ibex.corei + type: host + addr_space: hart + clock: clk_main_i + reset: rst_main_ni + pipeline: false + xbar: false + stub: false + inst_type: "" + req_fifo_pass: true + rsp_fifo_pass: true + } + { + name: rv_core_ibex.cored + type: host + addr_space: hart + clock: clk_main_i + reset: rst_main_ni + pipeline: false + xbar: false + stub: false + inst_type: "" + req_fifo_pass: true + rsp_fifo_pass: true + } + { + name: rom_ctrl.rom + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: rom_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x8000 + } + size_byte: 0x8000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rom_ctrl.regs + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: rom_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x411e0000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: peri + type: device + clock: clk_fixed_i + reset: rst_fixed_ni + pipeline: false + xbar: true + stub: false + req_fifo_pass: true + addr_space: hart + addr_range: + [ + { + base_addrs: + { + hart: 0x40000000 + } + size_byte: 0x800000 + } + ] + } + { + name: flash_ctrl.core + type: device + clock: clk_main_i + reset: rst_main_ni + req_fifo_pass: true + rsp_fifo_pass: false + inst_type: flash_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x41000000 + } + size_byte: 0x200 + } + ] + xbar: false + stub: false + pipeline: true + } + { + name: flash_ctrl.prim + type: device + clock: clk_main_i + reset: rst_main_ni + req_fifo_pass: true + rsp_fifo_pass: false + inst_type: flash_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x41008000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + pipeline: true + } + { + name: flash_ctrl.mem + type: device + clock: clk_main_i + reset: rst_main_ni + req_fifo_pass: true + rsp_fifo_pass: false + inst_type: flash_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x20000000 + } + size_byte: 0x10000 + } + ] + xbar: false + stub: false + pipeline: true + } + { + name: aes + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: aes + addr_range: + [ + { + base_addrs: + { + hart: 0x41100000 + } + size_byte: 0x100 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rv_plic + type: device + clock: clk_main_i + reset: rst_main_ni + inst_type: rv_plic + pipeline: false + addr_range: + [ + { + base_addrs: + { + hart: 0x48000000 + } + size_byte: 0x8000000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rv_core_ibex.cfg + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: rv_core_ibex + addr_range: + [ + { + base_addrs: + { + hart: 0x411f0000 + } + size_byte: 0x100 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: sram_ctrl_main.regs + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: sram_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x411c0000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: sram_ctrl_main.ram + type: device + clock: clk_main_i + reset: rst_main_ni + pipeline: false + inst_type: sram_ctrl + addr_range: + [ + { + base_addrs: + { + hart: 0x10000000 + } + size_byte: 0x20000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + ] + addr_spaces: + [ + hart + ] + clock: clk_main_i + type: xbar +} diff --git a/hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.hjson b/hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.hjson new file mode 100644 index 0000000000000..cad263d455c3f --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/data/autogen/xbar_main.hjson @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_main comportable IP spec generated by `tlgen.py` tool +{ name: "xbar_main" + clock_primary: "" + other_clock_list: [] + reset_primary: "" + other_reset_list: [] + //available_input_list: [] + + inter_signal_list: [ + // host + { struct: "tl" + type: "req_rsp" + name: "tl_rv_core_ibex__corei" + act: "rsp" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_rv_core_ibex__cored" + act: "rsp" + package: "tlul_pkg" + } + // device + { struct: "tl" + type: "req_rsp" + name: "tl_rom_ctrl__rom" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_rom_ctrl__regs" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_peri" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_flash_ctrl__core" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_flash_ctrl__prim" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_flash_ctrl__mem" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_aes" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_rv_plic" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_rv_core_ibex__cfg" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_sram_ctrl_main__regs" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_sram_ctrl_main__ram" + act: "req" + package: "tlul_pkg" + } + ] +} diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/tb__xbar_connect.sv b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/tb__xbar_connect.sv new file mode 100644 index 0000000000000..459034d58685c --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/tb__xbar_connect.sv @@ -0,0 +1,34 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// tb__xbar_connect generated by `tlgen.py` tool + +xbar_main dut(); + +`DRIVE_CLK(clk_main_i) +`DRIVE_CLK(clk_fixed_i) + +initial force dut.clk_main_i = clk_main_i; +initial force dut.clk_fixed_i = clk_fixed_i; + +// TODO, all resets tie together +initial force dut.rst_main_ni = rst_n; +initial force dut.rst_fixed_ni = rst_n; + +// Host TileLink interface connections +`CONNECT_TL_HOST_IF(rv_core_ibex__corei, dut, clk_main_i, rst_n) +`CONNECT_TL_HOST_IF(rv_core_ibex__cored, dut, clk_main_i, rst_n) + +// Device TileLink interface connections +`CONNECT_TL_DEVICE_IF(rom_ctrl__rom, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(rom_ctrl__regs, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(peri, dut, clk_fixed_i, rst_n) +`CONNECT_TL_DEVICE_IF(flash_ctrl__core, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(flash_ctrl__prim, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(flash_ctrl__mem, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(aes, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(rv_plic, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(rv_core_ibex__cfg, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(sram_ctrl_main__regs, dut, clk_main_i, rst_n) +`CONNECT_TL_DEVICE_IF(sram_ctrl_main__ram, dut, clk_main_i, rst_n) diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cov_excl.el b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cov_excl.el new file mode 100644 index 0000000000000..658e6eca510a1 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cov_excl.el @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_cov_excl.el generated by `tlgen.py` tool + +ANNOTATION: "[NON_RTL]" +MODULE: uvm_pkg +Assert \uvm_reg_map::do_write .unnamed$$_0.unnamed$$_1 "assertion" +Assert \uvm_reg_map::do_read .unnamed$$_0.unnamed$$_1 "assertion" + +ANNOTATION: "[UNSUPPORTED] scan mode isn't available in RTL sim" +MODULE: xbar_main +Block 1 "0" "assign unused_scanmode = scanmode_i;" + +ANNOTATION: "[UNR]" +MODULE: prim_fifo_sync +Branch 2 "2323268504" "(!rst_ni)" (1) "(!rst_ni) 0,1,-,-" +Branch 3 "3736627057" "(!rst_ni)" (1) "(!rst_ni) 0,1,-,-" + +ANNOTATION: "[UNR]" +MODULE: prim_arbiter_ppc ( parameter N=2,DW=102,EnDataPort=1,EnReqStabA=0 ) +Condition 2 "175047464" "(valid_o && ((!ready_i))) 1 -1" (2 "10") diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cover.cfg b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cover.cfg new file mode 100644 index 0000000000000..b7e05ce8d6d59 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_cover.cfg @@ -0,0 +1,63 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_cover.cfg generated by `tlgen.py` tool + ++tree tb.dut +-module pins_if // DV construct. +-module clk_rst_if // DV construct. + +-assert legalAOpcodeErr_A +-assert sizeGTEMaskErr_A +-assert sizeMatchesMaskErr_A +-assert addrSizeAlignedErr_A + +// due to VCS issue (fixed at VCS/2020.12), can't move this part into begin...end (tgl) or after. +-node tb.dut tl_*.a_param +-node tb.dut tl_*.d_param +-node tb.dut tl_*.d_opcode[2:1] + +-moduletree prim_cdc_rand_delay // exclude DV construct. + +// [UNR] these device address bits are always 0 +-node tb.dut tl_rom_ctrl__rom_o.a_address[31:16] +-node tb.dut tl_rom_ctrl__regs_o.a_address[16:7] +-node tb.dut tl_rom_ctrl__regs_o.a_address[23:21] +-node tb.dut tl_rom_ctrl__regs_o.a_address[29:25] +-node tb.dut tl_rom_ctrl__regs_o.a_address[31:31] +-node tb.dut tl_peri_o.a_address[29:23] +-node tb.dut tl_peri_o.a_address[31:31] +-node tb.dut tl_flash_ctrl__core_o.a_address[23:9] +-node tb.dut tl_flash_ctrl__core_o.a_address[29:25] +-node tb.dut tl_flash_ctrl__core_o.a_address[31:31] +-node tb.dut tl_flash_ctrl__prim_o.a_address[14:7] +-node tb.dut tl_flash_ctrl__prim_o.a_address[23:16] +-node tb.dut tl_flash_ctrl__prim_o.a_address[29:25] +-node tb.dut tl_flash_ctrl__prim_o.a_address[31:31] +-node tb.dut tl_flash_ctrl__mem_o.a_address[28:16] +-node tb.dut tl_flash_ctrl__mem_o.a_address[31:30] +-node tb.dut tl_aes_o.a_address[19:8] +-node tb.dut tl_aes_o.a_address[23:21] +-node tb.dut tl_aes_o.a_address[29:25] +-node tb.dut tl_aes_o.a_address[31:31] +-node tb.dut tl_rv_plic_o.a_address[29:28] +-node tb.dut tl_rv_plic_o.a_address[31:31] +-node tb.dut tl_rv_core_ibex__cfg_o.a_address[15:8] +-node tb.dut tl_rv_core_ibex__cfg_o.a_address[23:21] +-node tb.dut tl_rv_core_ibex__cfg_o.a_address[29:25] +-node tb.dut tl_rv_core_ibex__cfg_o.a_address[31:31] +-node tb.dut tl_sram_ctrl_main__regs_o.a_address[17:6] +-node tb.dut tl_sram_ctrl_main__regs_o.a_address[23:21] +-node tb.dut tl_sram_ctrl_main__regs_o.a_address[29:25] +-node tb.dut tl_sram_ctrl_main__regs_o.a_address[31:31] +-node tb.dut tl_sram_ctrl_main__ram_o.a_address[27:17] +-node tb.dut tl_sram_ctrl_main__ram_o.a_address[31:29] + +-node tb.dut tl_*.a_source[7:7] +-node tb.dut tl_*.d_source[7:7] +begin tgl + -tree tb + +tree tb.dut 1 + -node tb.dut.scanmode_i +end diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv new file mode 100644 index 0000000000000..c726067b1e623 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_env_pkg__params.sv @@ -0,0 +1,63 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_env_pkg__params generated by `tlgen.py` tool + + +// List of Xbar device memory map +tl_device_t xbar_devices[$] = '{ + '{"rom_ctrl__rom", '{ + '{32'h00008000, 32'h0000ffff} + }}, + '{"rom_ctrl__regs", '{ + '{32'h411e0000, 32'h411e007f} + }}, + '{"peri", '{ + '{32'h40000000, 32'h407fffff} + }}, + '{"flash_ctrl__core", '{ + '{32'h41000000, 32'h410001ff} + }}, + '{"flash_ctrl__prim", '{ + '{32'h41008000, 32'h4100807f} + }}, + '{"flash_ctrl__mem", '{ + '{32'h20000000, 32'h2000ffff} + }}, + '{"aes", '{ + '{32'h41100000, 32'h411000ff} + }}, + '{"rv_plic", '{ + '{32'h48000000, 32'h4fffffff} + }}, + '{"rv_core_ibex__cfg", '{ + '{32'h411f0000, 32'h411f00ff} + }}, + '{"sram_ctrl_main__regs", '{ + '{32'h411c0000, 32'h411c003f} + }}, + '{"sram_ctrl_main__ram", '{ + '{32'h10000000, 32'h1001ffff} +}}}; + + // List of Xbar hosts +tl_host_t xbar_hosts[$] = '{ + '{"rv_core_ibex__corei", 0, '{ + "rom_ctrl__rom", + "sram_ctrl_main__ram", + "flash_ctrl__mem"}} + , + '{"rv_core_ibex__cored", 1, '{ + "rom_ctrl__rom", + "rom_ctrl__regs", + "sram_ctrl_main__ram", + "flash_ctrl__mem", + "peri", + "flash_ctrl__core", + "flash_ctrl__prim", + "aes", + "rv_plic", + "sram_ctrl_main__regs", + "rv_core_ibex__cfg"}} +}; diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.core b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.core new file mode 100644 index 0000000000000..2f12171831b75 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# xbar_main_sim core file generated by `tlgen.py` tool +name: "lowrisc:dv:top_englishbreakfast_xbar_main_bind:0.1" +description: "XBAR main assertion bind" +filesets: + files_dv: + files: + - xbar_main_bind.sv + file_type: systemVerilogSource + + +targets: + default: &default_target + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.sv b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.sv new file mode 100644 index 0000000000000..d3264fb17c8b5 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_bind.sv @@ -0,0 +1,90 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_main_bind module generated by `tlgen.py` tool for assertions +module xbar_main_bind; +`ifndef GATE_LEVEL + // Host interfaces + bind xbar_main tlul_assert #(.EndpointType("Device")) tlul_assert_host_rv_core_ibex__corei ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_rv_core_ibex__corei_i), + .d2h (tl_rv_core_ibex__corei_o) + ); + bind xbar_main tlul_assert #(.EndpointType("Device")) tlul_assert_host_rv_core_ibex__cored ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_rv_core_ibex__cored_i), + .d2h (tl_rv_core_ibex__cored_o) + ); + + // Device interfaces + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_rom_ctrl__rom ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_rom_ctrl__rom_o), + .d2h (tl_rom_ctrl__rom_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_rom_ctrl__regs ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_rom_ctrl__regs_o), + .d2h (tl_rom_ctrl__regs_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_peri ( + .clk_i (clk_fixed_i), + .rst_ni (rst_fixed_ni), + .h2d (tl_peri_o), + .d2h (tl_peri_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_flash_ctrl__core ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_flash_ctrl__core_o), + .d2h (tl_flash_ctrl__core_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_flash_ctrl__prim ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_flash_ctrl__prim_o), + .d2h (tl_flash_ctrl__prim_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_flash_ctrl__mem ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_flash_ctrl__mem_o), + .d2h (tl_flash_ctrl__mem_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_aes ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_aes_o), + .d2h (tl_aes_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_rv_plic ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_rv_plic_o), + .d2h (tl_rv_plic_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_rv_core_ibex__cfg ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_rv_core_ibex__cfg_o), + .d2h (tl_rv_core_ibex__cfg_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_sram_ctrl_main__regs ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_sram_ctrl_main__regs_o), + .d2h (tl_sram_ctrl_main__regs_i) + ); + bind xbar_main tlul_assert #(.EndpointType("Host")) tlul_assert_device_sram_ctrl_main__ram ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .h2d (tl_sram_ctrl_main__ram_o), + .d2h (tl_sram_ctrl_main__ram_i) + ); +`endif +endmodule diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim.core b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim.core new file mode 100644 index 0000000000000..10b661776ab94 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim.core @@ -0,0 +1,30 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# xbar_main_sim core file generated by `tlgen.py` tool +name: "lowrisc:dv:top_englishbreakfast_xbar_main_sim:0.1" +description: "XBAR DV sim target" +filesets: + files_dv: + depend: + - lowrisc:top_englishbreakfast:xbar_main + - lowrisc:dv:dv_utils + - lowrisc:dv:xbar_tb + - lowrisc:dv:top_englishbreakfast_xbar_main_bind + files: + - tb__xbar_connect.sv: {is_include_file: true} + - xbar_env_pkg__params.sv: {is_include_file: true} + file_type: systemVerilogSource + + +targets: + sim: &sim_target + toplevel: xbar_tb_top + filesets: + - files_dv + default_tool: vcs + + lint: + <<: *sim_target diff --git a/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson new file mode 100644 index 0000000000000..e785780baf2af --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/dv/autogen/xbar_main_sim_cfg.hjson @@ -0,0 +1,31 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_main_sim_cfg.hjson file generated by `tlgen.py` tool +{ + name: xbar_main + + // Top level dut name (sv module). + dut: xbar_main + + // The name of the chip this XBAR configuration is made for. + top_chip: top_englishbreakfast + + // Testplan hjson file. + testplan: "{proj_root}/hw/ip/tlul/data/tlul_testplan.hjson" + + // Add xbar_main specific exclusion files. + vcs_cov_excl_files: ["{proj_root}/hw/top_englishbreakfast/ip/{dut}/dv/autogen/xbar_cov_excl.el"] + + // replace common cover.cfg with a generated one, which includes xbar toggle exclusions + overrides: [ + { + name: default_vcs_cov_cfg_file + value: "-cm_hier {proj_root}/hw/top_englishbreakfast/ip/{dut}/dv/autogen/xbar_cover.cfg" + } + ] + // Import additional common sim cfg files. + import_cfgs: [// xbar common sim cfg file + "{proj_root}/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson"] +} diff --git a/hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/tl_main_pkg.sv b/hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/tl_main_pkg.sv new file mode 100644 index 0000000000000..893a33d267aed --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/tl_main_pkg.sv @@ -0,0 +1,59 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// tl_main package generated by `tlgen.py` tool + +package tl_main_pkg; + + localparam logic [31:0] ADDR_SPACE_ROM_CTRL__ROM = 32'h 00008000; + localparam logic [31:0] ADDR_SPACE_ROM_CTRL__REGS = 32'h 411e0000; + localparam logic [0:0][31:0] ADDR_SPACE_PERI = { + 32'h 40000000 + }; + localparam logic [31:0] ADDR_SPACE_FLASH_CTRL__CORE = 32'h 41000000; + localparam logic [31:0] ADDR_SPACE_FLASH_CTRL__PRIM = 32'h 41008000; + localparam logic [31:0] ADDR_SPACE_FLASH_CTRL__MEM = 32'h 20000000; + localparam logic [31:0] ADDR_SPACE_AES = 32'h 41100000; + localparam logic [31:0] ADDR_SPACE_RV_PLIC = 32'h 48000000; + localparam logic [31:0] ADDR_SPACE_RV_CORE_IBEX__CFG = 32'h 411f0000; + localparam logic [31:0] ADDR_SPACE_SRAM_CTRL_MAIN__REGS = 32'h 411c0000; + localparam logic [31:0] ADDR_SPACE_SRAM_CTRL_MAIN__RAM = 32'h 10000000; + + localparam logic [31:0] ADDR_MASK_ROM_CTRL__ROM = 32'h 00007fff; + localparam logic [31:0] ADDR_MASK_ROM_CTRL__REGS = 32'h 0000007f; + localparam logic [0:0][31:0] ADDR_MASK_PERI = { + 32'h 007fffff + }; + localparam logic [31:0] ADDR_MASK_FLASH_CTRL__CORE = 32'h 000001ff; + localparam logic [31:0] ADDR_MASK_FLASH_CTRL__PRIM = 32'h 0000007f; + localparam logic [31:0] ADDR_MASK_FLASH_CTRL__MEM = 32'h 0000ffff; + localparam logic [31:0] ADDR_MASK_AES = 32'h 000000ff; + localparam logic [31:0] ADDR_MASK_RV_PLIC = 32'h 07ffffff; + localparam logic [31:0] ADDR_MASK_RV_CORE_IBEX__CFG = 32'h 000000ff; + localparam logic [31:0] ADDR_MASK_SRAM_CTRL_MAIN__REGS = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_SRAM_CTRL_MAIN__RAM = 32'h 0001ffff; + + localparam int N_HOST = 2; + localparam int N_DEVICE = 11; + + typedef enum int { + TlRomCtrlRom = 0, + TlRomCtrlRegs = 1, + TlPeri = 2, + TlFlashCtrlCore = 3, + TlFlashCtrlPrim = 4, + TlFlashCtrlMem = 5, + TlAes = 6, + TlRvPlic = 7, + TlRvCoreIbexCfg = 8, + TlSramCtrlMainRegs = 9, + TlSramCtrlMainRam = 10 + } tl_device_e; + + typedef enum int { + TlRvCoreIbexCorei = 0, + TlRvCoreIbexCored = 1 + } tl_host_e; + +endpackage diff --git a/hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/xbar_main.sv b/hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/xbar_main.sv new file mode 100644 index 0000000000000..a4d10b5003962 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/rtl/autogen/xbar_main.sv @@ -0,0 +1,344 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_main module generated by `tlgen.py` tool +// all reset signals should be generated from one reset signal to not make any deadlock +// +// Interconnect +// rv_core_ibex.corei +// -> s1n_13 +// -> sm1_14 +// -> rom_ctrl.rom +// -> sm1_15 +// -> sram_ctrl_main.ram +// -> sm1_16 +// -> flash_ctrl.mem +// rv_core_ibex.cored +// -> s1n_17 +// -> sm1_14 +// -> rom_ctrl.rom +// -> rom_ctrl.regs +// -> sm1_15 +// -> sram_ctrl_main.ram +// -> sm1_16 +// -> flash_ctrl.mem +// -> asf_18 +// -> peri +// -> flash_ctrl.core +// -> flash_ctrl.prim +// -> aes +// -> rv_plic +// -> sram_ctrl_main.regs +// -> rv_core_ibex.cfg + +module xbar_main ( + input clk_main_i, + input clk_fixed_i, + input rst_main_ni, + input rst_fixed_ni, + + // Host interfaces + input tlul_pkg::tl_h2d_t tl_rv_core_ibex__corei_i, + output tlul_pkg::tl_d2h_t tl_rv_core_ibex__corei_o, + input tlul_pkg::tl_h2d_t tl_rv_core_ibex__cored_i, + output tlul_pkg::tl_d2h_t tl_rv_core_ibex__cored_o, + + // Device interfaces + output tlul_pkg::tl_h2d_t tl_rom_ctrl__rom_o, + input tlul_pkg::tl_d2h_t tl_rom_ctrl__rom_i, + output tlul_pkg::tl_h2d_t tl_rom_ctrl__regs_o, + input tlul_pkg::tl_d2h_t tl_rom_ctrl__regs_i, + output tlul_pkg::tl_h2d_t tl_peri_o, + input tlul_pkg::tl_d2h_t tl_peri_i, + output tlul_pkg::tl_h2d_t tl_flash_ctrl__core_o, + input tlul_pkg::tl_d2h_t tl_flash_ctrl__core_i, + output tlul_pkg::tl_h2d_t tl_flash_ctrl__prim_o, + input tlul_pkg::tl_d2h_t tl_flash_ctrl__prim_i, + output tlul_pkg::tl_h2d_t tl_flash_ctrl__mem_o, + input tlul_pkg::tl_d2h_t tl_flash_ctrl__mem_i, + output tlul_pkg::tl_h2d_t tl_aes_o, + input tlul_pkg::tl_d2h_t tl_aes_i, + output tlul_pkg::tl_h2d_t tl_rv_plic_o, + input tlul_pkg::tl_d2h_t tl_rv_plic_i, + output tlul_pkg::tl_h2d_t tl_rv_core_ibex__cfg_o, + input tlul_pkg::tl_d2h_t tl_rv_core_ibex__cfg_i, + output tlul_pkg::tl_h2d_t tl_sram_ctrl_main__regs_o, + input tlul_pkg::tl_d2h_t tl_sram_ctrl_main__regs_i, + output tlul_pkg::tl_h2d_t tl_sram_ctrl_main__ram_o, + input tlul_pkg::tl_d2h_t tl_sram_ctrl_main__ram_i, + + input prim_mubi_pkg::mubi4_t scanmode_i +); + + import tlul_pkg::*; + import tl_main_pkg::*; + + // scanmode_i is currently not used, but provisioned for future use + // this assignment prevents lint warnings + logic unused_scanmode; + assign unused_scanmode = ^scanmode_i; + + tl_h2d_t tl_s1n_13_us_h2d ; + tl_d2h_t tl_s1n_13_us_d2h ; + + + tl_h2d_t tl_s1n_13_ds_h2d [3]; + tl_d2h_t tl_s1n_13_ds_d2h [3]; + + // Create steering signal + logic [1:0] dev_sel_s1n_13; + + + tl_h2d_t tl_sm1_14_us_h2d [2]; + tl_d2h_t tl_sm1_14_us_d2h [2]; + + tl_h2d_t tl_sm1_14_ds_h2d ; + tl_d2h_t tl_sm1_14_ds_d2h ; + + + tl_h2d_t tl_sm1_15_us_h2d [2]; + tl_d2h_t tl_sm1_15_us_d2h [2]; + + tl_h2d_t tl_sm1_15_ds_h2d ; + tl_d2h_t tl_sm1_15_ds_d2h ; + + + tl_h2d_t tl_sm1_16_us_h2d [2]; + tl_d2h_t tl_sm1_16_us_d2h [2]; + + tl_h2d_t tl_sm1_16_ds_h2d ; + tl_d2h_t tl_sm1_16_ds_d2h ; + + tl_h2d_t tl_s1n_17_us_h2d ; + tl_d2h_t tl_s1n_17_us_d2h ; + + + tl_h2d_t tl_s1n_17_ds_h2d [11]; + tl_d2h_t tl_s1n_17_ds_d2h [11]; + + // Create steering signal + logic [3:0] dev_sel_s1n_17; + + tl_h2d_t tl_asf_18_us_h2d ; + tl_d2h_t tl_asf_18_us_d2h ; + tl_h2d_t tl_asf_18_ds_h2d ; + tl_d2h_t tl_asf_18_ds_d2h ; + + + + assign tl_sm1_14_us_h2d[0] = tl_s1n_13_ds_h2d[0]; + assign tl_s1n_13_ds_d2h[0] = tl_sm1_14_us_d2h[0]; + + assign tl_sm1_15_us_h2d[0] = tl_s1n_13_ds_h2d[1]; + assign tl_s1n_13_ds_d2h[1] = tl_sm1_15_us_d2h[0]; + + assign tl_sm1_16_us_h2d[0] = tl_s1n_13_ds_h2d[2]; + assign tl_s1n_13_ds_d2h[2] = tl_sm1_16_us_d2h[0]; + + assign tl_sm1_14_us_h2d[1] = tl_s1n_17_ds_h2d[0]; + assign tl_s1n_17_ds_d2h[0] = tl_sm1_14_us_d2h[1]; + + assign tl_rom_ctrl__regs_o = tl_s1n_17_ds_h2d[1]; + assign tl_s1n_17_ds_d2h[1] = tl_rom_ctrl__regs_i; + + assign tl_sm1_15_us_h2d[1] = tl_s1n_17_ds_h2d[2]; + assign tl_s1n_17_ds_d2h[2] = tl_sm1_15_us_d2h[1]; + + assign tl_sm1_16_us_h2d[1] = tl_s1n_17_ds_h2d[3]; + assign tl_s1n_17_ds_d2h[3] = tl_sm1_16_us_d2h[1]; + + assign tl_asf_18_us_h2d = tl_s1n_17_ds_h2d[4]; + assign tl_s1n_17_ds_d2h[4] = tl_asf_18_us_d2h; + + assign tl_flash_ctrl__core_o = tl_s1n_17_ds_h2d[5]; + assign tl_s1n_17_ds_d2h[5] = tl_flash_ctrl__core_i; + + assign tl_flash_ctrl__prim_o = tl_s1n_17_ds_h2d[6]; + assign tl_s1n_17_ds_d2h[6] = tl_flash_ctrl__prim_i; + + assign tl_aes_o = tl_s1n_17_ds_h2d[7]; + assign tl_s1n_17_ds_d2h[7] = tl_aes_i; + + assign tl_rv_plic_o = tl_s1n_17_ds_h2d[8]; + assign tl_s1n_17_ds_d2h[8] = tl_rv_plic_i; + + assign tl_sram_ctrl_main__regs_o = tl_s1n_17_ds_h2d[9]; + assign tl_s1n_17_ds_d2h[9] = tl_sram_ctrl_main__regs_i; + + assign tl_rv_core_ibex__cfg_o = tl_s1n_17_ds_h2d[10]; + assign tl_s1n_17_ds_d2h[10] = tl_rv_core_ibex__cfg_i; + + assign tl_s1n_13_us_h2d = tl_rv_core_ibex__corei_i; + assign tl_rv_core_ibex__corei_o = tl_s1n_13_us_d2h; + + assign tl_rom_ctrl__rom_o = tl_sm1_14_ds_h2d; + assign tl_sm1_14_ds_d2h = tl_rom_ctrl__rom_i; + + assign tl_sram_ctrl_main__ram_o = tl_sm1_15_ds_h2d; + assign tl_sm1_15_ds_d2h = tl_sram_ctrl_main__ram_i; + + assign tl_flash_ctrl__mem_o = tl_sm1_16_ds_h2d; + assign tl_sm1_16_ds_d2h = tl_flash_ctrl__mem_i; + + assign tl_s1n_17_us_h2d = tl_rv_core_ibex__cored_i; + assign tl_rv_core_ibex__cored_o = tl_s1n_17_us_d2h; + + assign tl_peri_o = tl_asf_18_ds_h2d; + assign tl_asf_18_ds_d2h = tl_peri_i; + + always_comb begin + // default steering to generate error response if address is not within the range + dev_sel_s1n_13 = 2'd3; + if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_ROM_CTRL__ROM)) == ADDR_SPACE_ROM_CTRL__ROM) begin + dev_sel_s1n_13 = 2'd0; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_SRAM_CTRL_MAIN__RAM)) == ADDR_SPACE_SRAM_CTRL_MAIN__RAM) begin + dev_sel_s1n_13 = 2'd1; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_FLASH_CTRL__MEM)) == ADDR_SPACE_FLASH_CTRL__MEM) begin + dev_sel_s1n_13 = 2'd2; +end + end + + always_comb begin + // default steering to generate error response if address is not within the range + dev_sel_s1n_17 = 4'd11; + if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_ROM_CTRL__ROM)) == ADDR_SPACE_ROM_CTRL__ROM) begin + dev_sel_s1n_17 = 4'd0; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_ROM_CTRL__REGS)) == ADDR_SPACE_ROM_CTRL__REGS) begin + dev_sel_s1n_17 = 4'd1; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_SRAM_CTRL_MAIN__RAM)) == ADDR_SPACE_SRAM_CTRL_MAIN__RAM) begin + dev_sel_s1n_17 = 4'd2; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_FLASH_CTRL__MEM)) == ADDR_SPACE_FLASH_CTRL__MEM) begin + dev_sel_s1n_17 = 4'd3; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_PERI)) == ADDR_SPACE_PERI) begin + dev_sel_s1n_17 = 4'd4; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_FLASH_CTRL__CORE)) == ADDR_SPACE_FLASH_CTRL__CORE) begin + dev_sel_s1n_17 = 4'd5; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_FLASH_CTRL__PRIM)) == ADDR_SPACE_FLASH_CTRL__PRIM) begin + dev_sel_s1n_17 = 4'd6; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_AES)) == ADDR_SPACE_AES) begin + dev_sel_s1n_17 = 4'd7; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_RV_PLIC)) == ADDR_SPACE_RV_PLIC) begin + dev_sel_s1n_17 = 4'd8; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_SRAM_CTRL_MAIN__REGS)) == ADDR_SPACE_SRAM_CTRL_MAIN__REGS) begin + dev_sel_s1n_17 = 4'd9; + + end else if ((tl_s1n_17_us_h2d.a_address & + ~(ADDR_MASK_RV_CORE_IBEX__CFG)) == ADDR_SPACE_RV_CORE_IBEX__CFG) begin + dev_sel_s1n_17 = 4'd10; +end + end + + + // Instantiation phase + tlul_socket_1n #( + .HReqDepth (4'h0), + .HRspDepth (4'h0), + .DReqDepth (12'h0), + .DRspDepth (12'h0), + .N (3) + ) u_s1n_13 ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .tl_h_i (tl_s1n_13_us_h2d), + .tl_h_o (tl_s1n_13_us_d2h), + .tl_d_o (tl_s1n_13_ds_h2d), + .tl_d_i (tl_s1n_13_ds_d2h), + .dev_select_i (dev_sel_s1n_13) + ); + tlul_socket_m1 #( + .HReqDepth (8'h0), + .HRspDepth (8'h0), + .DReqDepth (4'h0), + .DRspDepth (4'h0), + .M (2) + ) u_sm1_14 ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .tl_h_i (tl_sm1_14_us_h2d), + .tl_h_o (tl_sm1_14_us_d2h), + .tl_d_o (tl_sm1_14_ds_h2d), + .tl_d_i (tl_sm1_14_ds_d2h) + ); + tlul_socket_m1 #( + .HReqDepth (8'h0), + .HRspDepth (8'h0), + .DReqDepth (4'h0), + .DRspDepth (4'h0), + .M (2) + ) u_sm1_15 ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .tl_h_i (tl_sm1_15_us_h2d), + .tl_h_o (tl_sm1_15_us_d2h), + .tl_d_o (tl_sm1_15_ds_h2d), + .tl_d_i (tl_sm1_15_ds_d2h) + ); + tlul_socket_m1 #( + .HReqDepth (8'h0), + .HRspDepth (8'h0), + .DRspPass (1'b0), + .M (2) + ) u_sm1_16 ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .tl_h_i (tl_sm1_16_us_h2d), + .tl_h_o (tl_sm1_16_us_d2h), + .tl_d_o (tl_sm1_16_ds_h2d), + .tl_d_i (tl_sm1_16_ds_d2h) + ); + tlul_socket_1n #( + .HReqDepth (4'h0), + .HRspDepth (4'h0), + .DRspPass (11'h79f), + .DReqDepth (44'h1100000), + .DRspDepth (44'h1100000), + .N (11) + ) u_s1n_17 ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .tl_h_i (tl_s1n_17_us_h2d), + .tl_h_o (tl_s1n_17_us_d2h), + .tl_d_o (tl_s1n_17_ds_h2d), + .tl_d_i (tl_s1n_17_ds_d2h), + .dev_select_i (dev_sel_s1n_17) + ); + tlul_fifo_async #( + .ReqDepth (1), + .RspDepth (1) + ) u_asf_18 ( + .clk_h_i (clk_main_i), + .rst_h_ni (rst_main_ni), + .clk_d_i (clk_fixed_i), + .rst_d_ni (rst_fixed_ni), + .tl_h_i (tl_asf_18_us_h2d), + .tl_h_o (tl_asf_18_us_d2h), + .tl_d_o (tl_asf_18_ds_h2d), + .tl_d_i (tl_asf_18_ds_d2h) + ); + +endmodule diff --git a/hw/top_englishbreakfast/ip/xbar_main/xbar_main.core b/hw/top_englishbreakfast/ip/xbar_main/xbar_main.core new file mode 100644 index 0000000000000..3dfc47fc172d1 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_main/xbar_main.core @@ -0,0 +1,25 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# xbar_main core file generated by `tlgen.py` tool +name: "lowrisc:top_englishbreakfast:xbar_main:0.1" +description: "Generated RTL xbar_main" + +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:ip:lc_ctrl_pkg + files: + - rtl/autogen/tl_main_pkg.sv + - rtl/autogen/xbar_main.sv + file_type: systemVerilogSource + + +targets: + default: &default_target + filesets: + - files_rtl + toplevel: xbar_main diff --git a/hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.gen.hjson b/hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.gen.hjson new file mode 100644 index 0000000000000..f4d272ee58660 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.gen.hjson @@ -0,0 +1,339 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson -o hw/top_englishbreakfast/ + +{ + name: peri + clock_srcs: + { + clk_peri_i: io_div4 + clk_spi_host0_i: io + clk_usb_i: usb + } + clock_group: infra + reset: rst_peri_ni + reset_connections: + { + rst_peri_ni: + { + name: sys_io_div4 + domain: "0" + } + rst_spi_host0_ni: + { + name: spi_host0 + domain: "0" + } + rst_usb_ni: + { + name: usb + domain: "0" + } + } + clock_connections: + { + clk_peri_i: clkmgr_aon_clocks.clk_io_div4_infra + clk_spi_host0_i: clkmgr_aon_clocks.clk_io_infra + clk_usb_i: clkmgr_aon_clocks.clk_usb_infra + } + domain: + [ + "0" + ] + connections: + { + main: + [ + uart0 + uart1 + gpio + spi_device + spi_host0 + rv_timer + usbdev + pwrmgr_aon + rstmgr_aon + clkmgr_aon + pinmux_aon + ast + ] + } + nodes: + [ + { + name: main + type: host + addr_space: hart + clock: clk_peri_i + reset: rst_peri_ni + xbar: true + pipeline: false + stub: false + inst_type: "" + req_fifo_pass: true + rsp_fifo_pass: true + } + { + name: uart0 + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: uart + addr_range: + [ + { + base_addrs: + { + hart: 0x40000000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: uart1 + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: uart + addr_range: + [ + { + base_addrs: + { + hart: 0x40010000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: gpio + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: gpio + addr_range: + [ + { + base_addrs: + { + hart: 0x40040000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: spi_device + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: spi_device + addr_range: + [ + { + base_addrs: + { + hart: 0x40050000 + } + size_byte: 0x2000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: spi_host0 + type: device + clock: clk_spi_host0_i + reset: rst_spi_host0_ni + pipeline: false + inst_type: spi_host + addr_range: + [ + { + base_addrs: + { + hart: 0x40060000 + } + size_byte: 0x40 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rv_timer + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: rv_timer + addr_range: + [ + { + base_addrs: + { + hart: 0x40100000 + } + size_byte: 0x200 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: usbdev + type: device + clock: clk_usb_i + reset: rst_usb_ni + pipeline: false + inst_type: usbdev + addr_range: + [ + { + base_addrs: + { + hart: 0x40320000 + } + size_byte: 0x1000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: pwrmgr_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: pwrmgr + addr_range: + [ + { + base_addrs: + { + hart: 0x40400000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: rstmgr_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: rstmgr + addr_range: + [ + { + base_addrs: + { + hart: 0x40410000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: clkmgr_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: clkmgr + addr_range: + [ + { + base_addrs: + { + hart: 0x40420000 + } + size_byte: 0x80 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: pinmux_aon + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: pinmux + addr_range: + [ + { + base_addrs: + { + hart: 0x40460000 + } + size_byte: 0x1000 + } + ] + xbar: false + stub: false + req_fifo_pass: true + } + { + name: ast + type: device + clock: clk_peri_i + reset: rst_peri_ni + pipeline: false + inst_type: ast + addr_range: + [ + { + base_addrs: + { + hart: 0x40480000 + } + size_byte: 0x400 + } + ] + xbar: false + stub: true + req_fifo_pass: true + } + ] + addr_spaces: + [ + hart + ] + clock: clk_peri_i + type: xbar +} diff --git a/hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.hjson b/hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.hjson new file mode 100644 index 0000000000000..3a9370f97561a --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/data/autogen/xbar_peri.hjson @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_peri comportable IP spec generated by `tlgen.py` tool +{ name: "xbar_peri" + clock_primary: "" + other_clock_list: [] + reset_primary: "" + other_reset_list: [] + //available_input_list: [] + + inter_signal_list: [ + // host + { struct: "tl" + type: "req_rsp" + name: "tl_main" + act: "rsp" + package: "tlul_pkg" + } + // device + { struct: "tl" + type: "req_rsp" + name: "tl_uart0" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_uart1" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_gpio" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_spi_device" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_spi_host0" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_rv_timer" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_usbdev" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_pwrmgr_aon" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_rstmgr_aon" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_clkmgr_aon" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_pinmux_aon" + act: "req" + package: "tlul_pkg" + } + { struct: "tl" + type: "req_rsp" + name: "tl_ast" + act: "req" + package: "tlul_pkg" + } + ] +} diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/tb__xbar_connect.sv b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/tb__xbar_connect.sv new file mode 100644 index 0000000000000..7dd31480e9eb5 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/tb__xbar_connect.sv @@ -0,0 +1,37 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// tb__xbar_connect generated by `tlgen.py` tool + +xbar_peri dut(); + +`DRIVE_CLK(clk_peri_i) +`DRIVE_CLK(clk_spi_host0_i) +`DRIVE_CLK(clk_usb_i) + +initial force dut.clk_peri_i = clk_peri_i; +initial force dut.clk_spi_host0_i = clk_spi_host0_i; +initial force dut.clk_usb_i = clk_usb_i; + +// TODO, all resets tie together +initial force dut.rst_peri_ni = rst_n; +initial force dut.rst_spi_host0_ni = rst_n; +initial force dut.rst_usb_ni = rst_n; + +// Host TileLink interface connections +`CONNECT_TL_HOST_IF(main, dut, clk_peri_i, rst_n) + +// Device TileLink interface connections +`CONNECT_TL_DEVICE_IF(uart0, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(uart1, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(gpio, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(spi_device, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(spi_host0, dut, clk_spi_host0_i, rst_n) +`CONNECT_TL_DEVICE_IF(rv_timer, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(usbdev, dut, clk_usb_i, rst_n) +`CONNECT_TL_DEVICE_IF(pwrmgr_aon, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(rstmgr_aon, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(clkmgr_aon, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(pinmux_aon, dut, clk_peri_i, rst_n) +`CONNECT_TL_DEVICE_IF(ast, dut, clk_peri_i, rst_n) diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cov_excl.el b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cov_excl.el new file mode 100644 index 0000000000000..645d899b062dc --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cov_excl.el @@ -0,0 +1,14 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_cov_excl.el generated by `tlgen.py` tool + +ANNOTATION: "[NON_RTL]" +MODULE: uvm_pkg +Assert \uvm_reg_map::do_write .unnamed$$_0.unnamed$$_1 "assertion" +Assert \uvm_reg_map::do_read .unnamed$$_0.unnamed$$_1 "assertion" + +ANNOTATION: "[UNSUPPORTED] scan mode isn't available in RTL sim" +MODULE: xbar_peri +Block 1 "0" "assign unused_scanmode = scanmode_i;" diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cover.cfg b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cover.cfg new file mode 100644 index 0000000000000..237fa015132a0 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_cover.cfg @@ -0,0 +1,70 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_cover.cfg generated by `tlgen.py` tool + ++tree tb.dut +-module pins_if // DV construct. +-module clk_rst_if // DV construct. + +-assert legalAOpcodeErr_A +-assert sizeGTEMaskErr_A +-assert sizeMatchesMaskErr_A +-assert addrSizeAlignedErr_A + +// due to VCS issue (fixed at VCS/2020.12), can't move this part into begin...end (tgl) or after. +-node tb.dut tl_*.a_param +-node tb.dut tl_*.d_param +-node tb.dut tl_*.d_opcode[2:1] + +-moduletree prim_cdc_rand_delay // exclude DV construct. + +// [UNR] these device address bits are always 0 +-node tb.dut tl_uart0_o.a_address[29:6] +-node tb.dut tl_uart0_o.a_address[31:31] +-node tb.dut tl_uart1_o.a_address[15:6] +-node tb.dut tl_uart1_o.a_address[29:17] +-node tb.dut tl_uart1_o.a_address[31:31] +-node tb.dut tl_gpio_o.a_address[17:7] +-node tb.dut tl_gpio_o.a_address[29:19] +-node tb.dut tl_gpio_o.a_address[31:31] +-node tb.dut tl_spi_device_o.a_address[15:13] +-node tb.dut tl_spi_device_o.a_address[17:17] +-node tb.dut tl_spi_device_o.a_address[29:19] +-node tb.dut tl_spi_device_o.a_address[31:31] +-node tb.dut tl_spi_host0_o.a_address[16:6] +-node tb.dut tl_spi_host0_o.a_address[29:19] +-node tb.dut tl_spi_host0_o.a_address[31:31] +-node tb.dut tl_rv_timer_o.a_address[19:9] +-node tb.dut tl_rv_timer_o.a_address[29:21] +-node tb.dut tl_rv_timer_o.a_address[31:31] +-node tb.dut tl_usbdev_o.a_address[16:12] +-node tb.dut tl_usbdev_o.a_address[19:18] +-node tb.dut tl_usbdev_o.a_address[29:22] +-node tb.dut tl_usbdev_o.a_address[31:31] +-node tb.dut tl_pwrmgr_aon_o.a_address[21:7] +-node tb.dut tl_pwrmgr_aon_o.a_address[29:23] +-node tb.dut tl_pwrmgr_aon_o.a_address[31:31] +-node tb.dut tl_rstmgr_aon_o.a_address[15:7] +-node tb.dut tl_rstmgr_aon_o.a_address[21:17] +-node tb.dut tl_rstmgr_aon_o.a_address[29:23] +-node tb.dut tl_rstmgr_aon_o.a_address[31:31] +-node tb.dut tl_clkmgr_aon_o.a_address[16:7] +-node tb.dut tl_clkmgr_aon_o.a_address[21:18] +-node tb.dut tl_clkmgr_aon_o.a_address[29:23] +-node tb.dut tl_clkmgr_aon_o.a_address[31:31] +-node tb.dut tl_pinmux_aon_o.a_address[16:12] +-node tb.dut tl_pinmux_aon_o.a_address[21:19] +-node tb.dut tl_pinmux_aon_o.a_address[29:23] +-node tb.dut tl_pinmux_aon_o.a_address[31:31] +-node tb.dut tl_ast_o.a_address[18:10] +-node tb.dut tl_ast_o.a_address[21:20] +-node tb.dut tl_ast_o.a_address[29:23] +-node tb.dut tl_ast_o.a_address[31:31] + +begin tgl + -tree tb + +tree tb.dut 1 + -node tb.dut.scanmode_i +end diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_env_pkg__params.sv b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_env_pkg__params.sv new file mode 100644 index 0000000000000..8d20c8b6438bc --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_env_pkg__params.sv @@ -0,0 +1,62 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_env_pkg__params generated by `tlgen.py` tool + + +// List of Xbar device memory map +tl_device_t xbar_devices[$] = '{ + '{"uart0", '{ + '{32'h40000000, 32'h4000003f} + }}, + '{"uart1", '{ + '{32'h40010000, 32'h4001003f} + }}, + '{"gpio", '{ + '{32'h40040000, 32'h4004007f} + }}, + '{"spi_device", '{ + '{32'h40050000, 32'h40051fff} + }}, + '{"spi_host0", '{ + '{32'h40060000, 32'h4006003f} + }}, + '{"rv_timer", '{ + '{32'h40100000, 32'h401001ff} + }}, + '{"usbdev", '{ + '{32'h40320000, 32'h40320fff} + }}, + '{"pwrmgr_aon", '{ + '{32'h40400000, 32'h4040007f} + }}, + '{"rstmgr_aon", '{ + '{32'h40410000, 32'h4041007f} + }}, + '{"clkmgr_aon", '{ + '{32'h40420000, 32'h4042007f} + }}, + '{"pinmux_aon", '{ + '{32'h40460000, 32'h40460fff} + }}, + '{"ast", '{ + '{32'h40480000, 32'h404803ff} +}}}; + + // List of Xbar hosts +tl_host_t xbar_hosts[$] = '{ + '{"main", 0, '{ + "uart0", + "uart1", + "gpio", + "spi_device", + "spi_host0", + "rv_timer", + "usbdev", + "pwrmgr_aon", + "rstmgr_aon", + "clkmgr_aon", + "pinmux_aon", + "ast"}} +}; diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.core b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.core new file mode 100644 index 0000000000000..f69b7345896a0 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# xbar_peri_sim core file generated by `tlgen.py` tool +name: "lowrisc:dv:top_englishbreakfast_xbar_peri_bind:0.1" +description: "XBAR peri assertion bind" +filesets: + files_dv: + files: + - xbar_peri_bind.sv + file_type: systemVerilogSource + + +targets: + default: &default_target + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.sv b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.sv new file mode 100644 index 0000000000000..e7278ce0baced --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_bind.sv @@ -0,0 +1,90 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_peri_bind module generated by `tlgen.py` tool for assertions +module xbar_peri_bind; +`ifndef GATE_LEVEL + // Host interfaces + bind xbar_peri tlul_assert #(.EndpointType("Device")) tlul_assert_host_main ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_main_i), + .d2h (tl_main_o) + ); + + // Device interfaces + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_uart0 ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_uart0_o), + .d2h (tl_uart0_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_uart1 ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_uart1_o), + .d2h (tl_uart1_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_gpio ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_gpio_o), + .d2h (tl_gpio_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_spi_device ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_spi_device_o), + .d2h (tl_spi_device_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_spi_host0 ( + .clk_i (clk_spi_host0_i), + .rst_ni (rst_spi_host0_ni), + .h2d (tl_spi_host0_o), + .d2h (tl_spi_host0_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_rv_timer ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_rv_timer_o), + .d2h (tl_rv_timer_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_usbdev ( + .clk_i (clk_usb_i), + .rst_ni (rst_usb_ni), + .h2d (tl_usbdev_o), + .d2h (tl_usbdev_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_pwrmgr_aon ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_pwrmgr_aon_o), + .d2h (tl_pwrmgr_aon_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_rstmgr_aon ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_rstmgr_aon_o), + .d2h (tl_rstmgr_aon_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_clkmgr_aon ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_clkmgr_aon_o), + .d2h (tl_clkmgr_aon_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_pinmux_aon ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_pinmux_aon_o), + .d2h (tl_pinmux_aon_i) + ); + bind xbar_peri tlul_assert #(.EndpointType("Host")) tlul_assert_device_ast ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .h2d (tl_ast_o), + .d2h (tl_ast_i) + ); +`endif +endmodule diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim.core b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim.core new file mode 100644 index 0000000000000..5031f94fe62ee --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim.core @@ -0,0 +1,30 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# xbar_peri_sim core file generated by `tlgen.py` tool +name: "lowrisc:dv:top_englishbreakfast_xbar_peri_sim:0.1" +description: "XBAR DV sim target" +filesets: + files_dv: + depend: + - lowrisc:top_englishbreakfast:xbar_peri + - lowrisc:dv:dv_utils + - lowrisc:dv:xbar_tb + - lowrisc:dv:top_englishbreakfast_xbar_peri_bind + files: + - tb__xbar_connect.sv: {is_include_file: true} + - xbar_env_pkg__params.sv: {is_include_file: true} + file_type: systemVerilogSource + + +targets: + sim: &sim_target + toplevel: xbar_tb_top + filesets: + - files_dv + default_tool: vcs + + lint: + <<: *sim_target diff --git a/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson new file mode 100644 index 0000000000000..e65341f299c18 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/dv/autogen/xbar_peri_sim_cfg.hjson @@ -0,0 +1,31 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_peri_sim_cfg.hjson file generated by `tlgen.py` tool +{ + name: xbar_peri + + // Top level dut name (sv module). + dut: xbar_peri + + // The name of the chip this XBAR configuration is made for. + top_chip: top_englishbreakfast + + // Testplan hjson file. + testplan: "{proj_root}/hw/ip/tlul/data/tlul_testplan.hjson" + + // Add xbar_main specific exclusion files. + vcs_cov_excl_files: ["{proj_root}/hw/top_englishbreakfast/ip/{dut}/dv/autogen/xbar_cov_excl.el"] + + // replace common cover.cfg with a generated one, which includes xbar toggle exclusions + overrides: [ + { + name: default_vcs_cov_cfg_file + value: "-cm_hier {proj_root}/hw/top_englishbreakfast/ip/{dut}/dv/autogen/xbar_cover.cfg" + } + ] + // Import additional common sim cfg files. + import_cfgs: [// xbar common sim cfg file + "{proj_root}/hw/ip/tlul/generic_dv/xbar_sim_cfg.hjson"] +} diff --git a/hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/tl_peri_pkg.sv b/hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/tl_peri_pkg.sv new file mode 100644 index 0000000000000..b5713396993d1 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/tl_peri_pkg.sv @@ -0,0 +1,57 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// tl_peri package generated by `tlgen.py` tool + +package tl_peri_pkg; + + localparam logic [31:0] ADDR_SPACE_UART0 = 32'h 40000000; + localparam logic [31:0] ADDR_SPACE_UART1 = 32'h 40010000; + localparam logic [31:0] ADDR_SPACE_GPIO = 32'h 40040000; + localparam logic [31:0] ADDR_SPACE_SPI_DEVICE = 32'h 40050000; + localparam logic [31:0] ADDR_SPACE_SPI_HOST0 = 32'h 40060000; + localparam logic [31:0] ADDR_SPACE_RV_TIMER = 32'h 40100000; + localparam logic [31:0] ADDR_SPACE_USBDEV = 32'h 40320000; + localparam logic [31:0] ADDR_SPACE_PWRMGR_AON = 32'h 40400000; + localparam logic [31:0] ADDR_SPACE_RSTMGR_AON = 32'h 40410000; + localparam logic [31:0] ADDR_SPACE_CLKMGR_AON = 32'h 40420000; + localparam logic [31:0] ADDR_SPACE_PINMUX_AON = 32'h 40460000; + localparam logic [31:0] ADDR_SPACE_AST = 32'h 40480000; + + localparam logic [31:0] ADDR_MASK_UART0 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_UART1 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_GPIO = 32'h 0000007f; + localparam logic [31:0] ADDR_MASK_SPI_DEVICE = 32'h 00001fff; + localparam logic [31:0] ADDR_MASK_SPI_HOST0 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_RV_TIMER = 32'h 000001ff; + localparam logic [31:0] ADDR_MASK_USBDEV = 32'h 00000fff; + localparam logic [31:0] ADDR_MASK_PWRMGR_AON = 32'h 0000007f; + localparam logic [31:0] ADDR_MASK_RSTMGR_AON = 32'h 0000007f; + localparam logic [31:0] ADDR_MASK_CLKMGR_AON = 32'h 0000007f; + localparam logic [31:0] ADDR_MASK_PINMUX_AON = 32'h 00000fff; + localparam logic [31:0] ADDR_MASK_AST = 32'h 000003ff; + + localparam int N_HOST = 1; + localparam int N_DEVICE = 12; + + typedef enum int { + TlUart0 = 0, + TlUart1 = 1, + TlGpio = 2, + TlSpiDevice = 3, + TlSpiHost0 = 4, + TlRvTimer = 5, + TlUsbdev = 6, + TlPwrmgrAon = 7, + TlRstmgrAon = 8, + TlClkmgrAon = 9, + TlPinmuxAon = 10, + TlAst = 11 + } tl_device_e; + + typedef enum int { + TlMain = 0 + } tl_host_e; + +endpackage diff --git a/hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/xbar_peri.sv b/hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/xbar_peri.sv new file mode 100644 index 0000000000000..c57e6f7a70aa0 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/rtl/autogen/xbar_peri.sv @@ -0,0 +1,239 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// xbar_peri module generated by `tlgen.py` tool +// all reset signals should be generated from one reset signal to not make any deadlock +// +// Interconnect +// main +// -> s1n_13 +// -> uart0 +// -> uart1 +// -> gpio +// -> spi_device +// -> asf_14 +// -> spi_host0 +// -> rv_timer +// -> asf_15 +// -> usbdev +// -> pwrmgr_aon +// -> rstmgr_aon +// -> clkmgr_aon +// -> pinmux_aon +// -> ast + +module xbar_peri ( + input clk_peri_i, + input clk_spi_host0_i, + input clk_usb_i, + input rst_peri_ni, + input rst_spi_host0_ni, + input rst_usb_ni, + + // Host interfaces + input tlul_pkg::tl_h2d_t tl_main_i, + output tlul_pkg::tl_d2h_t tl_main_o, + + // Device interfaces + output tlul_pkg::tl_h2d_t tl_uart0_o, + input tlul_pkg::tl_d2h_t tl_uart0_i, + output tlul_pkg::tl_h2d_t tl_uart1_o, + input tlul_pkg::tl_d2h_t tl_uart1_i, + output tlul_pkg::tl_h2d_t tl_gpio_o, + input tlul_pkg::tl_d2h_t tl_gpio_i, + output tlul_pkg::tl_h2d_t tl_spi_device_o, + input tlul_pkg::tl_d2h_t tl_spi_device_i, + output tlul_pkg::tl_h2d_t tl_spi_host0_o, + input tlul_pkg::tl_d2h_t tl_spi_host0_i, + output tlul_pkg::tl_h2d_t tl_rv_timer_o, + input tlul_pkg::tl_d2h_t tl_rv_timer_i, + output tlul_pkg::tl_h2d_t tl_usbdev_o, + input tlul_pkg::tl_d2h_t tl_usbdev_i, + output tlul_pkg::tl_h2d_t tl_pwrmgr_aon_o, + input tlul_pkg::tl_d2h_t tl_pwrmgr_aon_i, + output tlul_pkg::tl_h2d_t tl_rstmgr_aon_o, + input tlul_pkg::tl_d2h_t tl_rstmgr_aon_i, + output tlul_pkg::tl_h2d_t tl_clkmgr_aon_o, + input tlul_pkg::tl_d2h_t tl_clkmgr_aon_i, + output tlul_pkg::tl_h2d_t tl_pinmux_aon_o, + input tlul_pkg::tl_d2h_t tl_pinmux_aon_i, + output tlul_pkg::tl_h2d_t tl_ast_o, + input tlul_pkg::tl_d2h_t tl_ast_i, + + input prim_mubi_pkg::mubi4_t scanmode_i +); + + import tlul_pkg::*; + import tl_peri_pkg::*; + + // scanmode_i is currently not used, but provisioned for future use + // this assignment prevents lint warnings + logic unused_scanmode; + assign unused_scanmode = ^scanmode_i; + + tl_h2d_t tl_s1n_13_us_h2d ; + tl_d2h_t tl_s1n_13_us_d2h ; + + + tl_h2d_t tl_s1n_13_ds_h2d [12]; + tl_d2h_t tl_s1n_13_ds_d2h [12]; + + // Create steering signal + logic [3:0] dev_sel_s1n_13; + + tl_h2d_t tl_asf_14_us_h2d ; + tl_d2h_t tl_asf_14_us_d2h ; + tl_h2d_t tl_asf_14_ds_h2d ; + tl_d2h_t tl_asf_14_ds_d2h ; + + tl_h2d_t tl_asf_15_us_h2d ; + tl_d2h_t tl_asf_15_us_d2h ; + tl_h2d_t tl_asf_15_ds_h2d ; + tl_d2h_t tl_asf_15_ds_d2h ; + + + + assign tl_uart0_o = tl_s1n_13_ds_h2d[0]; + assign tl_s1n_13_ds_d2h[0] = tl_uart0_i; + + assign tl_uart1_o = tl_s1n_13_ds_h2d[1]; + assign tl_s1n_13_ds_d2h[1] = tl_uart1_i; + + assign tl_gpio_o = tl_s1n_13_ds_h2d[2]; + assign tl_s1n_13_ds_d2h[2] = tl_gpio_i; + + assign tl_spi_device_o = tl_s1n_13_ds_h2d[3]; + assign tl_s1n_13_ds_d2h[3] = tl_spi_device_i; + + assign tl_asf_14_us_h2d = tl_s1n_13_ds_h2d[4]; + assign tl_s1n_13_ds_d2h[4] = tl_asf_14_us_d2h; + + assign tl_rv_timer_o = tl_s1n_13_ds_h2d[5]; + assign tl_s1n_13_ds_d2h[5] = tl_rv_timer_i; + + assign tl_asf_15_us_h2d = tl_s1n_13_ds_h2d[6]; + assign tl_s1n_13_ds_d2h[6] = tl_asf_15_us_d2h; + + assign tl_pwrmgr_aon_o = tl_s1n_13_ds_h2d[7]; + assign tl_s1n_13_ds_d2h[7] = tl_pwrmgr_aon_i; + + assign tl_rstmgr_aon_o = tl_s1n_13_ds_h2d[8]; + assign tl_s1n_13_ds_d2h[8] = tl_rstmgr_aon_i; + + assign tl_clkmgr_aon_o = tl_s1n_13_ds_h2d[9]; + assign tl_s1n_13_ds_d2h[9] = tl_clkmgr_aon_i; + + assign tl_pinmux_aon_o = tl_s1n_13_ds_h2d[10]; + assign tl_s1n_13_ds_d2h[10] = tl_pinmux_aon_i; + + assign tl_ast_o = tl_s1n_13_ds_h2d[11]; + assign tl_s1n_13_ds_d2h[11] = tl_ast_i; + + assign tl_s1n_13_us_h2d = tl_main_i; + assign tl_main_o = tl_s1n_13_us_d2h; + + assign tl_spi_host0_o = tl_asf_14_ds_h2d; + assign tl_asf_14_ds_d2h = tl_spi_host0_i; + + assign tl_usbdev_o = tl_asf_15_ds_h2d; + assign tl_asf_15_ds_d2h = tl_usbdev_i; + + always_comb begin + // default steering to generate error response if address is not within the range + dev_sel_s1n_13 = 4'd12; + if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_UART0)) == ADDR_SPACE_UART0) begin + dev_sel_s1n_13 = 4'd0; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_UART1)) == ADDR_SPACE_UART1) begin + dev_sel_s1n_13 = 4'd1; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_GPIO)) == ADDR_SPACE_GPIO) begin + dev_sel_s1n_13 = 4'd2; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_SPI_DEVICE)) == ADDR_SPACE_SPI_DEVICE) begin + dev_sel_s1n_13 = 4'd3; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_SPI_HOST0)) == ADDR_SPACE_SPI_HOST0) begin + dev_sel_s1n_13 = 4'd4; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_RV_TIMER)) == ADDR_SPACE_RV_TIMER) begin + dev_sel_s1n_13 = 4'd5; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_USBDEV)) == ADDR_SPACE_USBDEV) begin + dev_sel_s1n_13 = 4'd6; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_PWRMGR_AON)) == ADDR_SPACE_PWRMGR_AON) begin + dev_sel_s1n_13 = 4'd7; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_RSTMGR_AON)) == ADDR_SPACE_RSTMGR_AON) begin + dev_sel_s1n_13 = 4'd8; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_CLKMGR_AON)) == ADDR_SPACE_CLKMGR_AON) begin + dev_sel_s1n_13 = 4'd9; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_PINMUX_AON)) == ADDR_SPACE_PINMUX_AON) begin + dev_sel_s1n_13 = 4'd10; + + end else if ((tl_s1n_13_us_h2d.a_address & + ~(ADDR_MASK_AST)) == ADDR_SPACE_AST) begin + dev_sel_s1n_13 = 4'd11; +end + end + + + // Instantiation phase + tlul_socket_1n #( + .HReqDepth (4'h0), + .HRspDepth (4'h0), + .DReqDepth (48'h0), + .DRspDepth (48'h0), + .N (12) + ) u_s1n_13 ( + .clk_i (clk_peri_i), + .rst_ni (rst_peri_ni), + .tl_h_i (tl_s1n_13_us_h2d), + .tl_h_o (tl_s1n_13_us_d2h), + .tl_d_o (tl_s1n_13_ds_h2d), + .tl_d_i (tl_s1n_13_ds_d2h), + .dev_select_i (dev_sel_s1n_13) + ); + tlul_fifo_async #( + .ReqDepth (1), + .RspDepth (1) + ) u_asf_14 ( + .clk_h_i (clk_peri_i), + .rst_h_ni (rst_peri_ni), + .clk_d_i (clk_spi_host0_i), + .rst_d_ni (rst_spi_host0_ni), + .tl_h_i (tl_asf_14_us_h2d), + .tl_h_o (tl_asf_14_us_d2h), + .tl_d_o (tl_asf_14_ds_h2d), + .tl_d_i (tl_asf_14_ds_d2h) + ); + tlul_fifo_async #( + .ReqDepth (1), + .RspDepth (1) + ) u_asf_15 ( + .clk_h_i (clk_peri_i), + .rst_h_ni (rst_peri_ni), + .clk_d_i (clk_usb_i), + .rst_d_ni (rst_usb_ni), + .tl_h_i (tl_asf_15_us_h2d), + .tl_h_o (tl_asf_15_us_d2h), + .tl_d_o (tl_asf_15_ds_h2d), + .tl_d_i (tl_asf_15_ds_d2h) + ); + +endmodule diff --git a/hw/top_englishbreakfast/ip/xbar_peri/xbar_peri.core b/hw/top_englishbreakfast/ip/xbar_peri/xbar_peri.core new file mode 100644 index 0000000000000..d70980626cce2 --- /dev/null +++ b/hw/top_englishbreakfast/ip/xbar_peri/xbar_peri.core @@ -0,0 +1,25 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# xbar_peri core file generated by `tlgen.py` tool +name: "lowrisc:top_englishbreakfast:xbar_peri:0.1" +description: "Generated RTL xbar_peri" + +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:ip:lc_ctrl_pkg + files: + - rtl/autogen/tl_peri_pkg.sv + - rtl/autogen/xbar_peri.sv + file_type: systemVerilogSource + + +targets: + default: &default_target + filesets: + - files_rtl + toplevel: xbar_peri diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/BUILD b/hw/top_englishbreakfast/ip_autogen/clkmgr/BUILD new file mode 100644 index 0000000000000..dda56de039e27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/clkmgr/README.md b/hw/top_englishbreakfast/ip_autogen/clkmgr/README.md new file mode 100644 index 0000000000000..ab8fbd74f3878 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/README.md @@ -0,0 +1,18 @@ +# Clock Manager HWIP Technical Specification + +[`clkmgr`](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/latest/report.html): +![](https://dashboards.lowrisc.org/badges/dv/clkmgr/test.svg) +![](https://dashboards.lowrisc.org/badges/dv/clkmgr/passing.svg) +![](https://dashboards.lowrisc.org/badges/dv/clkmgr/functional.svg) +![](https://dashboards.lowrisc.org/badges/dv/clkmgr/code.svg) + +# Overview + +This document specifies the functionality of the OpenTitan clock manager. + +## Features + +- Attribute based controls of OpenTitan clocks. +- Minimal software clock controls to reduce risks in clock manipulation. +- External clock switch support +- Clock frequency /time-out measurement diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr.core new file mode 100644 index 0000000000000..21db3b5bcf8c3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr.core @@ -0,0 +1,71 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr:0.1 +description: "Top specific clock manager " + +filesets: + files_rtl: + depend: + - lowrisc:ip:lc_ctrl_pkg + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + - lowrisc:ip:tlul + - lowrisc:prim:all + - lowrisc:prim:buf + - lowrisc:prim:clock_buf + - lowrisc:prim:clock_div + - lowrisc:prim:clock_gating + - lowrisc:prim:edge_detector + - lowrisc:prim:lc_sync + - lowrisc:prim:lc_sender + - lowrisc:prim:measure + - lowrisc:opentitan:top_englishbreakfast_clkmgr_pkg:0.1 + - lowrisc:opentitan:top_englishbreakfast_clkmgr_reg:0.1 + files: + - rtl/clkmgr.sv + - rtl/clkmgr_byp.sv + - rtl/clkmgr_clk_status.sv + - rtl/clkmgr_meas_chk.sv + - rtl/clkmgr_root_ctrl.sv + - rtl/clkmgr_trans.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/clkmgr.waiver + file_type: waiver + +parameters: + SYNTHESIS: + datatype: bool + paramtype: vlogdefine + +targets: + default: &default_target + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - files_rtl + toplevel: clkmgr + + lint: + <<: *default_target + default_tool: verilator + parameters: + - SYNTHESIS=true + tools: + verilator: + mode: lint-only + verilator_options: + - "-Wall" diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_pkg.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_pkg.core new file mode 100644 index 0000000000000..8e1a50993813d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_pkg.core @@ -0,0 +1,21 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr_pkg:0.1 +description: "Top specific clock manager package" +virtual: + - lowrisc:ip_interfaces:clkmgr_pkg + +filesets: + files_rtl: + depend: + - lowrisc:prim:mubi + files: + - rtl/clkmgr_pkg.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_reg.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_reg.core new file mode 100644 index 0000000000000..75054bc297e11 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/clkmgr_reg.core @@ -0,0 +1,23 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr_reg:0.1 +description: "Clock manager registers" + +filesets: + files_rtl: + depend: + - lowrisc:tlul:headers + - lowrisc:prim:assert + - lowrisc:prim:mubi_pkg + - lowrisc:prim:subreg + files: + - rtl/clkmgr_reg_pkg.sv + - rtl/clkmgr_reg_top.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr.hjson b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr.hjson new file mode 100644 index 0000000000000..15bbac3a63678 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr.hjson @@ -0,0 +1,884 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +# CLKMGR register template +# +{ + name: "clkmgr", + human_name: "Clock Manager", + one_line_desc: "Derives and monitors on-chip clock signals, handles clock gating requests from power manager and software", + one_paragraph_desc: ''' + Clock Manager derives on-chip clocks from root clock signals provided by Analog Sensor Top (AST). + Input and output clocks may be asynchronous to each other. + During clock derivation, Clock Manager can divide clocks to lower frequencies and gate clocks based on control signals from the power manager and to a limited extent from software. + For example, the idle status of relevant hardware blocks is tracked and clock gating requests from software are ignored as long as these blocks are active. + Further security features include switchable clock jitter, continuous monitoring of clock frequencies, and various countermeasures to deter fault injection (FI) attacks. + ''' + // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. + cip_id: "4", + design_spec: "../doc", + dv_doc: "../doc/dv", + hw_checklist: "../doc/checklist", + sw_checklist: "/sw/device/lib/dif/dif_clkmgr", + revisions: [ + { + version: "1.0.1", + life_stage: "L1", + design_stage: "D3", + verification_stage: "V2S", + dif_stage: "S2", + } + ] + scan: "true", + clocking: [ + {clock: "clk_i", reset: "rst_ni", primary: true}, + {reset: "rst_root_ni"}, + {clock: "clk_main_i", reset: "rst_main_ni"}, + {clock: "clk_io_i", reset: "rst_io_ni"}, + {clock: "clk_usb_i", reset: "rst_usb_ni"}, + {clock: "clk_aon_i", reset: "rst_aon_ni"}, + {clock: "clk_io_div2_i", reset: "rst_io_div2_ni", internal: true}, + {clock: "clk_io_div4_i", reset: "rst_io_div4_ni", internal: true}, + {reset: "rst_root_main_ni"}, + {reset: "rst_root_io_ni"}, + {reset: "rst_root_io_div2_ni"}, + {reset: "rst_root_io_div4_ni"}, + {reset: "rst_root_usb_ni"}, + ] + bus_interfaces: [ + { protocol: "tlul", direction: "device" } + ], + alert_list: [ + { name: "recov_fault", + desc: ''' + This recoverable alert is triggered when there are measurement errors. + ''' + } + { name: "fatal_fault", + desc: ''' + This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. + ''' + } + ], + regwidth: "32", + param_list: [ + { name: "NumGroups", + desc: "Number of clock groups", + type: "int", + default: "8", + local: "true" + }, + { name: "NumSwGateableClocks", + desc: "Number of SW gateable clocks", + type: "int", + default: "4", + local: "true" + }, + { name: "NumHintableClocks", + desc: "Number of hintable clocks", + type: "int", + default: "1", + local: "true" + }, + ], + + features: [ + { name: "CLKMGR.ENABLE.IO_DIV4", + desc: "Gating of IO_DIV4 peripheral clock." + } + { name: "CLKMGR.ENABLE.IO_DIV2", + desc: "Gating of IO_DIV2 peripheral clock." + } + { name: "CLKMGR.ENABLE.IO", + desc: "Gating of IO peripheral clock." + } + { name: "CLKMGR.ENABLE.USB", + desc: "Gating of USB peripheral clock." + } + { name: "CLKMGR.HINT.AES", + desc: "Gating of AES transactional clock." + } + { name: "CLKMGR.MEAS_CTRL.REGWEN", + desc: '''Control modification of all clock frequency and timeout + measurements. + ''' + } + { name: "CLKMGR.MEAS_CTRL.IO", + desc: "Frequency and timeout measurements of IO clock." + } + { name: "CLKMGR.MEAS_CTRL.IO_DIV4", + desc: "Frequency and timeout measurements of IO_DIV4 clock." + } + { name: "CLKMGR.MEAS_CTRL.MAIN", + desc: "Frequency and timeout measurements of MAIN clock." + } + { name: "CLKMGR.MEAS_CTRL.USB", + desc: "Frequency and timeout measurements of USB clock." + } + { name: "CLKMGR.MEAS_CTRL.RECOV_ERR", + desc: "Frequency and timeout measurements can flag recoverable errors." + } + { name: "CLKMGR.LC_EXTCLK.SPEED", + desc: "Speed of LC controlled modification of external clock." + } + { name: "CLKMGR.SW_EXTCLK.REGWEN", + desc: "Control software modification of external clock configuration." + } + { name: "CLKMGR.SW_EXTCLK.HIGH_SPEED", + desc: "Software configuration of external clock running at 96 MHz." + } + { name: "CLKMGR.SW_EXTCLK.LOW_SPEED", + desc: "Software configuration of external clock running at 48 MHz." + } + { name: "CLKMGR.JITTER.REGWEN", + desc: "Control modification of clock jitter enable." + } + { name: "CLKMGR.JITTER.ENABLE", + desc: "Enable clock jitter." + } + { name: "CLKMGR.ALERT_HANDLER.CLOCK_STATUS", + desc: "Inform alert handler about clock enable status for each clock." + } +] + + inter_signal_list: [ + { struct: "clkmgr_out", + type: "uni", + name: "clocks", + act: "req", + package: "clkmgr_pkg", + }, + + { struct: "clkmgr_cg_en", + type: "uni", + name: "cg_en", + act: "req", + package: "clkmgr_pkg", + }, + + { struct: "lc_tx", + type: "uni", + name: "lc_hw_debug_en", + act: "rcv", + package: "lc_ctrl_pkg", + }, + + { struct: "mubi4", + type: "uni", + name: "io_clk_byp_req", + act: "req", + package: "prim_mubi_pkg", + }, + + { struct: "mubi4", + type: "uni", + name: "io_clk_byp_ack", + act: "rcv", + package: "prim_mubi_pkg", + }, + + { struct: "mubi4", + type: "uni", + name: "all_clk_byp_req", + act: "req", + package: "prim_mubi_pkg", + }, + + { struct: "mubi4", + type: "uni", + name: "all_clk_byp_ack", + act: "rcv", + package: "prim_mubi_pkg", + }, + + { struct: "mubi4", + type: "uni", + name: "hi_speed_sel", + act: "req", + package: "prim_mubi_pkg", + }, + + { struct: "mubi4", + type: "uni", + name: "div_step_down_req", + act: "rcv", + package: "prim_mubi_pkg", + }, + + { struct: "lc_tx", + type: "uni", + name: "lc_clk_byp_req", + act: "rcv", + package: "lc_ctrl_pkg", + }, + + { struct: "lc_tx", + type: "uni", + name: "lc_clk_byp_ack", + act: "req", + package: "lc_ctrl_pkg", + }, + + { struct: "mubi4", + type: "uni", + name: "jitter_en", + act: "req", + package: "prim_mubi_pkg" + }, + + // Exported clocks + + { struct: "pwr_clk", + type: "req_rsp", + name: "pwr", + act: "rsp", + }, + + { struct: "mubi4", + type: "uni", + name: "idle", + act: "rcv", + package: "prim_mubi_pkg", + width: "1" + }, + + { struct: "mubi4", + desc: "Indicates clocks are calibrated and frequencies accurate", + type: "uni", + name: "calib_rdy", + act: "rcv", + package: "prim_mubi_pkg", + default: "prim_mubi_pkg::MuBi4True" + }, + ], + + countermeasures: [ + { name: "BUS.INTEGRITY", + desc: "End-to-end bus integrity scheme." + }, + { name: "TIMEOUT.CLK.BKGN_CHK", + desc: "Background check for clock timeout." + }, + { name: "MEAS.CLK.BKGN_CHK", + desc: "Background check for clock frequency." + }, + { name: "MEAS.CONFIG.SHADOW", + desc: "Measurement configurations are shadowed." + } + { name: "IDLE.INTERSIG.MUBI", + desc: "Idle inputs are multibit encoded." + } + { name: "LC_CTRL.INTERSIG.MUBI", + desc: "The life cycle control signals are multibit encoded." + } + { name: "LC_CTRL_CLK_HANDSHAKE.INTERSIG.MUBI", + desc: "The life cycle clock req/ack signals are multibit encoded." + } + { name: "CLK_HANDSHAKE.INTERSIG.MUBI", + desc: "The external clock req/ack signals are multibit encoded." + } + { name: "DIV.INTERSIG.MUBI", + desc: "Divider step down request is multibit encoded." + } + { name: "JITTER.CONFIG.MUBI", + desc: "The jitter enable configuration is multibit encoded." + } + { name: "IDLE.CTR.REDUN", + desc: "Idle counter is duplicated." + } + { name: "MEAS.CONFIG.REGWEN", + desc: "The measurement controls protected with regwen." + } + { name: "CLK_CTRL.CONFIG.REGWEN", + desc: "Software controlled clock requests are proteced with regwen." + } + + ] + + registers: [ + { name: "EXTCLK_CTRL_REGWEN", + desc: "External clock control write enable", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1" + desc: ''' + When 1, the value of !!EXTCLK_CTRL can be set. When 0, writes to !!EXTCLK_CTRL have no + effect. + ''' + }, + ] + }, + + { name: "EXTCLK_CTRL", + desc: ''' + Select external clock + ''', + regwen: "EXTCLK_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { + bits: "3:0", + name: "SEL", + mubi: true, + desc: ''' + When the current value is not kMultiBitBool4True, writing a value of kMultiBitBool4True + selects external clock as clock for the system. Writing any other value has + no impact. + + When the current value is kMultiBitBool4True, writing a value of kMultiBitBool4False + selects internal clock as clock for the system. Writing any other value during this stage + has no impact. + + While this register can always be programmed, it only takes effect when debug functions are enabled + in life cycle TEST, DEV or RMA states. + ''' + resval: "false" + }, + { + bits: "7:4", + name: "HI_SPEED_SEL", + mubi: true, + desc: ''' + A value of kMultiBitBool4True selects nominal speed external clock. + All other values selects low speed clocks. + + Note this field only has an effect when the !!EXTCLK_CTRL.SEL field is set to + kMultiBitBool4True. + + Nominal speed means the external clock is approximately the same frequency as + the internal oscillator source. When this option is used, all clocks operate + at roughly the nominal frequency. + + Low speed means the external clock is approximately half the frequency of the + internal oscillator source. When this option is used, the internal dividers are + stepped down. As a result, previously undivided clocks now run at half frequency, + while previously divided clocks run at roughly the nominal frequency. + + See external clock switch support in documentation for more details. + ''' + resval: false + } + ] + // avoid writing random values to this register as it could trigger transient checks + // in mubi sync + tags: ["excl:CsrAllTests:CsrExclWrite"] + }, + + { name: "EXTCLK_STATUS", + desc: ''' + Status of requested external clock switch + ''', + swaccess: "ro", + hwaccess: "hwo", + hwext: "true", + fields: [ + { + bits: "3:0", + name: "ACK", + mubi: true, + desc: ''' + When !!EXTCLK_CTRL.SEL is set to kMultiBitBool4True, this field reflects + whether the clock has been switched the external source. + + kMultiBitBool4True indicates the switch is complete. + kMultiBitBool4False indicates the switch is either not possible or still ongoing. + ''' + resval: "false" + }, + ] + }, + + { name: "JITTER_REGWEN", + desc: "Jitter write enable", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1" + desc: ''' + When 1, the value of !!JITTER_ENABLE can be changed. When 0, writes have no + effect. + ''' + }, + ] + }, + + { name: "JITTER_ENABLE", + desc: ''' + Enable jittery clock + ''', + swaccess: "rw", + hwaccess: "hro", + fields: [ + { + mubi: true, + bits: "3:0", + name: "VAL", + desc: ''' + Enable jittery clock. + A value of kMultiBitBool4False disables the jittery clock, + while all other values enable jittery clock. + ''', + resval: false + // avoid writing random values to this register as it could trigger transient checks + // in mubi sync + tags: ["excl:CsrAllTests:CsrExclWrite"] + } + ] + }, + + { name: "CLK_ENABLES", + desc: ''' + Clock enable for software gateable clocks. + These clocks are directly controlled by software. + ''', + swaccess: "rw", + hwaccess: "hro", + fields: [ + { + bits: "0", + name: "CLK_IO_DIV4_PERI_EN", + resval: 1, + desc: ''' + 0 CLK_IO_DIV4_PERI is disabled. + 1 CLK_IO_DIV4_PERI is enabled. + ''' + } + { + bits: "1", + name: "CLK_IO_DIV2_PERI_EN", + resval: 1, + desc: ''' + 0 CLK_IO_DIV2_PERI is disabled. + 1 CLK_IO_DIV2_PERI is enabled. + ''' + } + { + bits: "2", + name: "CLK_IO_PERI_EN", + resval: 1, + desc: ''' + 0 CLK_IO_PERI is disabled. + 1 CLK_IO_PERI is enabled. + ''' + } + { + bits: "3", + name: "CLK_USB_PERI_EN", + resval: 1, + desc: ''' + 0 CLK_USB_PERI is disabled. + 1 CLK_USB_PERI is enabled. + ''' + } + ] + // the CLK_ENABLE register cannot be written. + // During top level randomized tests, it is possible to disable the clocks and then access + // a register in the disabled block. This would lead to a top level hang. + tags: ["excl:CsrAllTests:CsrExclAll"] + }, + + { name: "CLK_HINTS", + desc: ''' + Clock hint for software gateable transactional clocks during active mode. + During low power mode, all clocks are gated off regardless of the software hint. + + Transactional clocks are not fully controlled by software. Instead software provides only a disable hint. + + When software provides a disable hint, the clock manager checks to see if the associated hardware block is idle. + If the hardware block is idle, then the clock is disabled. + If the hardware block is not idle, the clock is kept on. + + For the enable case, the software hint is immediately honored and the clock turned on. Hardware does not provide any + feedback in this case. + ''', + swaccess: "rw", + hwaccess: "hro", + fields: [ + { + bits: "0", + name: "CLK_MAIN_AES_HINT", + resval: 1, + desc: ''' + 0 CLK_MAIN_AES can be disabled. + 1 CLK_MAIN_AES is enabled. + ''' + } + ] + // the CLK_HINT register cannot be written. + // During top level randomized tests, it is possible to disable the clocks to transactional blocks + // and then access a register in the disabled block. This would lead to a top level hang. + tags: ["excl:CsrAllTests:CsrExclAll"] + }, + + { name: "CLK_HINTS_STATUS", + desc: ''' + Since the final state of !!CLK_HINTS is not always determined by software, + this register provides read feedback for the current clock state. + + ''', + swaccess: "ro", + hwaccess: "hwo", + fields: [ + { + bits: "0", + name: "CLK_MAIN_AES_VAL", + resval: 1, + desc: ''' + 0 CLK_MAIN_AES is disabled. + 1 CLK_MAIN_AES is enabled. + ''' + } + ] + // the CLK_HINT_STATUS register is read-only and cannot be checked. + // This register's value depends on the IDLE inputs, so cannot be predicted. + tags: ["excl:CsrNonInitTests:CsrExclCheck:CsrExclCheck"] + }, + + { name: "MEASURE_CTRL_REGWEN", + desc: "Measurement control write enable", + swaccess: "rw0c", + hwaccess: "hrw", + fields: [ + { bits: "0", + name: "EN", + resval: "1" + desc: ''' + When 1, the value of the measurement control can be set. When 0, writes have no + effect. + ''' + }, + ] + }, + { name: "IO_MEAS_CTRL_EN", + desc: ''' + Enable for measurement control + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hrw", + async: "clk_io_i", + fields: [ + { + bits: "3:0", + name: "EN", + desc: "Enable measurement for io", + mubi: true, + resval: false, + }, + ] + // Measurements can cause recoverable errors depending on the + // thresholds which randomized CSR tests will not predict correctly. + // To provide better CSR coverage we allow writing the threshold + // fields, but not enabling the counters. + tags: ["excl:CsrAllTests:CsrExclWrite"] + }, + + { name: "IO_MEAS_CTRL_SHADOWED", + desc: ''' + Configuration controls for io measurement. + + The threshold fields are made wider than required (by 1 bit) to ensure + there is room to adjust for measurement inaccuracies. + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hro", + async: "clk_io_i", + shadowed: "true", + update_err_alert: "recov_fault", + storage_err_alert: "fatal_fault", + fields: [ + { + bits: "9:0", + name: "HI", + desc: "Max threshold for io measurement", + resval: "490" + }, + + { + bits: "19:10", + name: "LO", + desc: "Min threshold for io measurement", + resval: "470" + }, + ] + }, + { name: "IO_DIV4_MEAS_CTRL_EN", + desc: ''' + Enable for measurement control + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hrw", + async: "clk_io_div4_i", + fields: [ + { + bits: "3:0", + name: "EN", + desc: "Enable measurement for io_div4", + mubi: true, + resval: false, + }, + ] + // Measurements can cause recoverable errors depending on the + // thresholds which randomized CSR tests will not predict correctly. + // To provide better CSR coverage we allow writing the threshold + // fields, but not enabling the counters. + tags: ["excl:CsrAllTests:CsrExclWrite"] + }, + + { name: "IO_DIV4_MEAS_CTRL_SHADOWED", + desc: ''' + Configuration controls for io_div4 measurement. + + The threshold fields are made wider than required (by 1 bit) to ensure + there is room to adjust for measurement inaccuracies. + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hro", + async: "clk_io_div4_i", + shadowed: "true", + update_err_alert: "recov_fault", + storage_err_alert: "fatal_fault", + fields: [ + { + bits: "7:0", + name: "HI", + desc: "Max threshold for io_div4 measurement", + resval: "130" + }, + + { + bits: "15:8", + name: "LO", + desc: "Min threshold for io_div4 measurement", + resval: "110" + }, + ] + }, + { name: "MAIN_MEAS_CTRL_EN", + desc: ''' + Enable for measurement control + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hrw", + async: "clk_main_i", + fields: [ + { + bits: "3:0", + name: "EN", + desc: "Enable measurement for main", + mubi: true, + resval: false, + }, + ] + // Measurements can cause recoverable errors depending on the + // thresholds which randomized CSR tests will not predict correctly. + // To provide better CSR coverage we allow writing the threshold + // fields, but not enabling the counters. + tags: ["excl:CsrAllTests:CsrExclWrite"] + }, + + { name: "MAIN_MEAS_CTRL_SHADOWED", + desc: ''' + Configuration controls for main measurement. + + The threshold fields are made wider than required (by 1 bit) to ensure + there is room to adjust for measurement inaccuracies. + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hro", + async: "clk_main_i", + shadowed: "true", + update_err_alert: "recov_fault", + storage_err_alert: "fatal_fault", + fields: [ + { + bits: "9:0", + name: "HI", + desc: "Max threshold for main measurement", + resval: "510" + }, + + { + bits: "19:10", + name: "LO", + desc: "Min threshold for main measurement", + resval: "490" + }, + ] + }, + { name: "USB_MEAS_CTRL_EN", + desc: ''' + Enable for measurement control + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hrw", + async: "clk_usb_i", + fields: [ + { + bits: "3:0", + name: "EN", + desc: "Enable measurement for usb", + mubi: true, + resval: false, + }, + ] + // Measurements can cause recoverable errors depending on the + // thresholds which randomized CSR tests will not predict correctly. + // To provide better CSR coverage we allow writing the threshold + // fields, but not enabling the counters. + tags: ["excl:CsrAllTests:CsrExclWrite"] + }, + + { name: "USB_MEAS_CTRL_SHADOWED", + desc: ''' + Configuration controls for usb measurement. + + The threshold fields are made wider than required (by 1 bit) to ensure + there is room to adjust for measurement inaccuracies. + ''', + regwen: "MEASURE_CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hro", + async: "clk_usb_i", + shadowed: "true", + update_err_alert: "recov_fault", + storage_err_alert: "fatal_fault", + fields: [ + { + bits: "8:0", + name: "HI", + desc: "Max threshold for usb measurement", + resval: "250" + }, + + { + bits: "17:9", + name: "LO", + desc: "Min threshold for usb measurement", + resval: "230" + }, + ] + }, + + { name: "RECOV_ERR_CODE", + desc: "Recoverable Error code", + swaccess: "rw1c", + hwaccess: "hwo", + fields: [ + { bits: "0", + name: "SHADOW_UPDATE_ERR", + resval: 0 + desc: ''' + One of the shadow registers encountered an update error. + ''' + }, + { + bits: "1", + name: "IO_MEASURE_ERR", + resval: 0, + desc: ''' + io has encountered a measurement error. + ''' + }, + { + bits: "2", + name: "IO_DIV4_MEASURE_ERR", + resval: 0, + desc: ''' + io_div4 has encountered a measurement error. + ''' + }, + { + bits: "3", + name: "MAIN_MEASURE_ERR", + resval: 0, + desc: ''' + main has encountered a measurement error. + ''' + }, + { + bits: "4", + name: "USB_MEASURE_ERR", + resval: 0, + desc: ''' + usb has encountered a measurement error. + ''' + }, + { + bits: "5", + name: "IO_TIMEOUT_ERR", + resval: 0, + desc: ''' + io has timed out. + ''' + } + { + bits: "6", + name: "IO_DIV4_TIMEOUT_ERR", + resval: 0, + desc: ''' + io_div4 has timed out. + ''' + } + { + bits: "7", + name: "MAIN_TIMEOUT_ERR", + resval: 0, + desc: ''' + main has timed out. + ''' + } + { + bits: "8", + name: "USB_TIMEOUT_ERR", + resval: 0, + desc: ''' + usb has timed out. + ''' + } + ] + }, + + { name: "FATAL_ERR_CODE", + desc: "Error code", + swaccess: "ro", + hwaccess: "hrw", + fields: [ + { bits: "0", + name: "REG_INTG", + resval: 0 + desc: ''' + Register file has experienced a fatal integrity error. + ''' + }, + { bits: "1", + name: "IDLE_CNT", + resval: 0 + desc: ''' + One of the idle counts encountered a duplicate error. + ''' + }, + { bits: "2", + name: "SHADOW_STORAGE_ERR", + resval: 0 + desc: ''' + One of the shadow registers encountered a storage error. + ''' + }, + ] + }, + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson new file mode 100644 index 0000000000000..f9c12d7d8f4ef --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_sec_cm_testplan.hjson @@ -0,0 +1,190 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// .../clkmgr/data/clkmgr.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: +// .../clkmgr/data/clkmgr_testplan.hjson +{ + testpoints: [ + { + name: sec_cm_bus_integrity + desc: '''Verify the countermeasure(s) BUS.INTEGRITY. + This entry is covered by tl_access_test. + ''' + stage: V2S + tests: ["clkmgr_tl_intg_err"] + } + { + name: sec_cm_meas_clk_bkgn_chk + desc: '''Verify the countermeasure(s) MEAS.CLK.BKGN_CHK. + - Test measurement feature of clkmgr_meas_chk modules. + For all test clocks (clk_main, clk_usb, clk_io, clk_io_div2 + and clk_io_div4), do measurement with normal configuration. + Then change either min or max threshold value to see + whether the module can detect measurement error for each test + clock. + - Measurement error should trigger a recoverable alert + ''' + stage: V2S + tests: ["clkmgr_frequency"] + } + { + name: sec_cm_timeout_clk_bkgn_chk + desc: '''Verify the countermeasure(s) TIMEOUT.CLK.BKGN_CHK. + - Test timeout feature of clkmgr_meas_chk modules. + While frequency measurement, one of + clk_main, clk_usb, clk_io, clk_io_div2 and clk_io_div4 are choose + and stopped. This will leads to timeout event. + - Timeout should cause a recoverable alert + ''' + stage: V2S + tests: ["clkmgr_frequency_timeout"] + } + { + name: sec_cm_meas_config_shadow + desc: ''' + Verify the countermeasure(s) MEAS.CONFIG.SHADOW. + + This is covered by shadow_reg_errors_tests + (https://github.com/lowRISC/opentitan/blob/master/ + hw/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson) + ''' + stage: V2S + tests: ["clkmgr_shadow_reg_errors"] + } + { + name: sec_cm_idle_intersig_mubi + desc: '''Verify the countermeasure(s) IDLE.INTERSIG.MUBI. + It uses true_strict and false_loose. + **Stimulus**: + Use same sequence as trans_enables test. + Randomize dut.idle_i ports with illegal values. + **Check**: + - hins_status check: + When clk_hints update from '1' to '0', + clk_hints_status has to wait idle becomes 'true'. So check + clk_hints_status with random idle value, then check again + after set all idle values to 'true'. + + - clock output check: + When clk_hints_status go to '0', check clocks_o + to see if clock is really off + ''' + stage: V2S + tests: ["clkmgr_idle_intersig_mubi"] + } + { + name: sec_cm_lc_ctrl_intersig_mubi + desc: '''Verify the countermeasure(s) LC_CTRL.INTERSIG.MUBI. + It compares to lc_ctrl_pkg::On only. + Use clkmgr_extclk test as in testplan.extclk but randomize + dut.lc_hw_debug_en_i s.t. all 16 values can be generated with equal priority. + + **Checks**: + When dut sees invalid values of lc_hw_debug_en_i, + all_clk_byp_req should not be asserted. Covered by assertion checker. + ''' + stage: V2S + tests: ["clkmgr_lc_ctrl_intersig_mubi"] + } + { + name: sec_cm_lc_ctrl_clk_handshake_intersig_mubi + desc: '''Verify the countermeasure(s) LC_CTRL_CLK_HANDSHAKE.INTERSIG.MUBI. + It compared to lc_ctrl_pkg::On only. + Use clkmgr_extclk test but randomize lc_clk_byp_req s.t. + all 16 values can be generated with equal priority. + lc_clk_byp_req drives dut.lc_clk_byp_req_i in the test. + **Checks**: + When dut sees invalid values of lc_clk_byp_req_i, + io_clk_byp_req_o should not be asserted. Covered by assertion checker. + ''' + stage: V2S + tests: ["clkmgr_lc_clk_byp_req_intersig_mubi"] + } + { + name: sec_cm_clk_handshake_intersig_mubi + desc: '''Verify the countermeasure(s) CLK_HANDSHAKE.INTERSIG.MUBI. + It uses true_strict. + Use clkmgr_extclk test. Upon receiving [io|all]_clk_byp_req_o from dut, + assert invalid [io|all]_clk_byp_ack values to dut. + + **Check**: + all_clk_byp_ack is copied to CLKGMR.EXTCLK_STATUS as is. So read extclk + status and compare. + io_clk_byp_ack is evaluated with step_down_acks_syn. + When both are true, lc_clk_byp_req is assigned to lc_clk_byp_ack. + Covered by assertion checker. + ''' + stage: V2S + tests: ["clkmgr_clk_handshake_intersig_mubi"] + } + { + name: sec_cm_div_intersig_mubi + desc: '''Verify the countermeasure(s) DIV.INTERSIG.MUBI. + use true_strict. + Use clkmgr_extclk test. Before, test drive dut.div_step_down_req_i + with 'true', sends invalid values. + **Check**: + dut should ignore invalid req values. Covered by assertion checker. + ''' + stage: V2S + tests: ["clkmgr_div_intersig_mubi"] + } + { + name: sec_cm_jitter_config_mubi + desc: '''Verify the countermeasure(s) JITTER.CONFIG.MUBI. + use false_strict. + This doesn't do any function in the dut but indicating + jittery clock is enabled. So it can be covered by default + csr test. + ''' + stage: V2S + tests: ["clkmgr_csr_rw"] + } + { + name: sec_cm_idle_ctr_redun + desc: '''Verify the countermeasure(s) IDLE.CTR.REDUN. + This is triggered by common cm primitives (SecCmPrimCount). + **Check**: + read check CLKMGR.FATAL_ERR_CODE.IDLE_CNT == 1 + ''' + stage: V2S + tests: ["clkmgr_sec_cm"] + } + { + name: sec_cm_meas_config_regwen + desc: '''Verify the countermeasure(s) MEAS.CONFIG.REGWEN. + + This is covered by auto csr test. + ''' + stage: V2S + tests: ["clkmgr_csr_rw"] + } + { + name: sec_cm_clk_ctrl_config_regwen + desc: '''Verify the countermeasure(s) CLK_CTRL.CONFIG.REGWEN. + + This is covered by auto csr test. + ''' + stage: V2S + tests: ["clkmgr_csr_rw"] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_testplan.hjson new file mode 100644 index 0000000000000..af05156616edc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_testplan.hjson @@ -0,0 +1,334 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "clkmgr" + import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", + "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", + "hw/dv/tools/dvsim/testplans/alert_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/shadow_reg_errors_testplan.hjson", + "clkmgr_sec_cm_testplan.hjson", + "hw/dv/tools/dvsim/testplans/sec_cm_count_testplan.hjson"] + testpoints: [ + { + name: smoke + desc: ''' + Smoke test disabling peripheral and transactional clocks. + + - Disables all peripheral clocks from their enabled reset state. + - Transactional clocks gating depends on whether they are idle. + - Initializes all units as busy (not idle). + - Clears each unit's `clk_hints` bit, which has no effect until + the unit becomes idle. + - Sets the unit's `idle_i` bit, which should disable the clock. + - Writes both values of the `jitter_enable` CSR. + + **Stimulus**: + - CSR writes to `clk_enables` and `clk_hints`. + - Setting `idle_i` clkmgr input. + + **Checks**: + - SVA assertions for peripheral clocks enable and disable + properties. + - Transactional clocks check SVA properties as follows: + - If the hint enables it, the clock becomes active. + - If the hint disables it but the unit is busy, the clock remains + active. + - If the hint disables it and the unit is idle, the clock stops. + - For transactional units the CSR `clk_hints_status` is checked + to correspond to `clk_hints` once the units are idle. + - Check in scoreboard the `jitter_en_o` output tracks updates of the + `jitter_enable` CSR. + ''' + stage: V1 + tests: ["clkmgr_smoke"] + } + { + name: peri_enables + desc: ''' + Peripheral clocks are disabled if its `clk_enables` bit is off, + or the corresponding `pwr_i.*_ip_clk_en` is off, and `scanmode_i` + is not `lc_ctrl_pkg::On`. + + This test runs multiple rounds which do the following: + - Randomize `pwr_i.usb_ip_clk_en` and `scanmode_i`, and the initial + setting of `clk_enables`. + - Send a CSR write to `clk_enables` with its initial value. + - Send a CSR write to `clk_enables` that flips all bits. + + It makes no sense to have `pwr_i.io_ip_clk_en` set to zero since + that would prevent the CPU from running and sending CSR updates. + + **Checks**: + - SVA assertions for peripheral clocks enable and disable + properties. + ''' + stage: V2 + tests: ["clkmgr_peri"] + } + { + name: trans_enables + desc: ''' + Transactional unit clocks are disabled if they are idle and + their CSR `clk_hints` bit is off, or `pwr_i.main_ip_clk_en` is off, + and `scanmode_i` is not `lc_ctrl_pkg::On`. + This test randomizes the initial setting of `idle_i` and the + desired value of `clk_hints`. Each round performs this sequence: + - Writes the desired value to CSR `clk_hints` and checks that the + CSR `clk_hints_status` reflects CSR `clk_hints` except for the + units not-idle. + - Marks all units as idle, and checks that `csr_hints_status` + matches `clk_hints`. + - Writes `clk_hints` to all ones and checks that `csr_hints_status` + is all ones. + - Writes `clk_hints` with its reset value. + + **Checks**: + - SVA assertions for transactional unit clocks described in + clkmgr_smoke. + ''' + stage: V2 + tests: ["clkmgr_trans"] + } + { + name: extclk + desc: ''' + Tests the functionality of enabling external clocks. + + - External clock is enabled if the `lc_clk_byp_req_i` input from + `lc_ctrl` is `lc_ctrl_pkg::On`. + - External clock is also be enabled when CSR `extclk_ctrl.sel` is + set to + `lc_ctrl_pkg::On` and the `lc_dtl_en_i` input from `lc_ctrl` is + `lc_ctrl_pkg::On`. + - Notice writes to the `extclk_ctrl.sel` register are ignored unless + the CSR `extclk_ctrl_regwen` is 1. + - A successful switch to external clocks due to `lc_clk_byl_req_i` + will cause the clkmgr to undo a divide by 2 for io_div4 and + io_div2 clocks except when `(scanmode_i == prim_mubi_pkg::MuBi4True)`. + - A software triggered switch to external clock will undo divides + by 2 if `extclk_ctrl.hi_speed_sel` is set to `prim_mubi_pkg::MuBi4True`. + + **Stimulus**: + - CSR writes to `extclk_ctrl` and `extclk_ctrl_regwen`. + - Setting `lc_hw_debug_en_i`, `lc_clk_byp_req_i`, and the handshake to + ast via `ast_clk_byp_req_o` and `ast_clk_byp_ack_i`. + - Setting `scanmode_i`. + + **Checks**: + Clock divider checks are done with SVA assertions. + - When the external clock is selected (and not defeated by + `scanmode_i` for scoreboard checks): + - The `clk_io_div2_powerup` output matches the `clk_io_powerup` + output. + - The `clk_io_div4_powerup` output matches the `clk_io_powerup` + output at half its frequency. + - When the external clock is not selected or division is defeated: + - The `clk_io_div2_powerup` output matches the `clk_io_powerup` + output at half its frequency. + - The `clk_io_div4_powerup` output matches the `clk_io_powerup` + output at a quarter of its frequency. + LC / AST handshake: + - When the external clock functionality is triggered the + `ast_clk_byp_req_o` output pin is set to `lc_ctrl_pkg::On`. + - When `ast_clk_byp_ack_i` is set to `lc_ctrl_pkg::On` in response + to a corresponding request: + - The clock dividers are stepped down, unless defeated by + `scanmode_i` being `lc_ctrl_pkg::On`. + - If the initial request was due to the assertion of the + `lc_clk_byp_req_i`, the `lc_clk_byp_ack_o` output is set to + `lc_ctrl_pkg::On`. + ''' + stage: V2 + tests: ["clkmgr_extclk"] + } + { + name: clk_status + desc: ''' + This tests the three `pwr_o.*_status` output ports, for the + `io`, `main`, and `usb` clocks. + + The `pwr_o.*_status` output must track the correspponding + `pwr_i.*_ip_clk_en` input. + + **Stimulus**: + - Randomize the `pwr_i.*_ip_clk_en` setting for each clock. + + **Check**: + - The checks are done in SVA at `clkmgr_pwrmgr_sva_if.sv`. + ''' + stage: V2 + tests: ["clkmgr_clk_status"] + } + { + name: jitter + desc: ''' + This tests the jitter functionality. + + The jitter functionality is implemented by the AST block, but + controlled by the `jitter_enable` CSR in this block. This CSR + directly drives the `jitter_en_o` output pin. + + **Stimulus**: + - CSR write to `jitter_enable`. + + **Check**: + - The `jitter_en_o` output pin reflects the `jitter_enable` CSR. + Test is implemented in the scoreboard, and is always running. + ''' + stage: V2 + tests: ["clkmgr_smoke"] + } + { + name: frequency + desc: '''This tests the frequency counters measured count functionality. + + These counters compute the number of cycles of each clock relative + to the aon timer, and compares it to the corresponding + thresholds written into the `*_meas_ctrl_shadowed` CSR. Measurements + beyond these thresholds trigger a recoverable alert and set a bit + in the `recov_err_code` CSR. Also, if the counters reach their + maximum value they don't wrap around. + + If clock calibration is lost, indicated by the `calib_rdy_i` input + being `prim_mubi_pkg::MuBi4False`, the measurements stop, no + error is triggered, and `measure_ctrl_regwen` is set to 1. + + **Stimulus**: + - Randomly set slow, correct, and fast interval for each counter + and test. + - Randomly set the `calib_rdy_i` input. + - Randomly trigger a clock saturation by forcing its cycle count + to be near its maximum value while counting. + + **Check**: + - Slow and fast intervals should cause a recoverable alert. + - Coverage collected per clock. + ''' + stage: V2 + tests: ["clkmgr_frequency"] + } + { + name: frequency_timeout + desc: '''This tests the frequency counters timeout functionality. + + These counters compute the number of cycles of some clock relative + to the aon timer. It should trigger a recoverable alert when there + is no valid measurement when enabled, leading to a timeout. This is + separate from the `frequenty` testpoint to simplify the test checks. + + **Stimulus**: + - Randomly stop measured clocks to trigger a timeout. + + **Check**: + - Timeout should cause a recoverable alert. + - Coverage collected per clock. + ''' + stage: V2 + tests: ["clkmgr_frequency_timeout"] + } + { + name: frequency_overflow + desc: '''This tests the overflow feature in prim_clock_meas. + + This needs to modify the state of the counter to trigger the + feature. + + **Stimulus**: + - Program the counter. Whenever it hits the value of 1, set it to + the range - 2. + + **Check**: + - The internal cnt_ovfl flop is set. + - The fast_o output should be set. + ''' + stage: V2 + tests: ["clkmgr_frequency"] + } + { + name: regwen + desc: '''This tests the behavior of the regwen CSRs. + + When a regwen is clear, any write to CSRs it locks are ignored. + Once a regwen is cleared, it will only be set again after a full + reset. + + **Stimulus**: + - Clear each regwen. + - Write to the corresponding locked CSRs. + + **Check**: + - The locked CSR value is not updated. + ''' + stage: V3 + tests: ["clkmgr_regwen"] + } + { + name: stress_all + desc: '''This runs random sequences in succession. + + Randomly chooses from the following sequences: + - clkmgr_extclk_vseq, + - clkmgr_frequency_timeout_vseq, + - clkmgr_frequency_vseq, + - clkmgr_peri_vseq, + - clkmgr_smoke_vseq, + - clkmgr_trans_vseq + ''' + stage: V2 + tests: ["clkmgr_stress_all"] + } + ] + + covergroups: [ + { + name: peri_cg + desc: ''' + Collects coverage for each peripheral clock. + + The peripheral clocks depend on a bit in the clk_enables CSR, + the ip_clk_en input from pwrmgr, and the scanmode input. + This collects the cross of them for each peripheral. + + FIXME This is collected in an array, one instance for each clock, + but the dvsim coverage flow doesn't yet support arrays. + ''' + } + { + name: trans_cg + desc: ''' + Collects coverage for each transactional unit clock. + + The transactional unit clocks depend on a bit in the clk_hints CSR, + the ip_clk_en input from pwrmgr, the respective idle input bit from + the unit, and the scanmode input. + This collects the cross of them for each transactional unit. + + FIXME This is collected in an array, one instance for each clock, + but the dvsim coverage flow doesn't yet support arrays. + ''' + } + { + name: extclk_cg + desc: ''' + Collects coverage for the external clock selection. + + The external clock selection depends on the `extclk_ctrl` CSR + fields `sel` and `hi_speed_sel`, and the `lc_hw_debug_en_i`, + `lc_clk_byp_req_i`, and `scanmode_i` input pins. This covergroup + collects their cross. + ''' + } + { + name: freq_measure_cg + desc: ''' + Collects coverage for the frequency measurement counters. + + The relevant information is whether it got an okay, slow, or + fast measurement, or a timeout. + ''' + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/data/top_englishbreakfast_clkmgr.ipconfig.hjson b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/top_englishbreakfast_clkmgr.ipconfig.hjson new file mode 100644 index 0000000000000..bb877e4e9a59c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/data/top_englishbreakfast_clkmgr.ipconfig.hjson @@ -0,0 +1,243 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + instance_name: top_englishbreakfast_clkmgr + param_values: + { + src_clks: + { + main: + { + name: main + aon: false + freq: 100000000 + ref: false + } + io: + { + name: io + aon: false + freq: 96000000 + ref: false + } + usb: + { + name: usb + aon: false + freq: 48000000 + ref: false + } + aon: + { + name: aon + aon: true + freq: 200000 + ref: false + } + } + derived_clks: + { + io_div2: + { + name: io_div2 + aon: false + freq: 48000000 + ref: false + div: 2 + src: + { + name: io + aon: no + freq: "96000000" + ref: false + } + } + io_div4: + { + name: io_div4 + aon: false + freq: 24000000 + ref: false + div: 4 + src: + { + name: io + aon: no + freq: "96000000" + ref: false + } + } + } + typed_clocks: + { + ast_clks: + { + clk_main_i: + { + src_name: main + endpoint_ip: clkmgr_aon + } + clk_io_i: + { + src_name: io + endpoint_ip: clkmgr_aon + } + clk_usb_i: + { + src_name: usb + endpoint_ip: clkmgr_aon + } + clk_aon_i: + { + src_name: aon + endpoint_ip: clkmgr_aon + } + } + ft_clks: + { + clk_io_div4_powerup: + { + src_name: io_div4 + endpoint_ip: pwrmgr_aon + } + clk_aon_powerup: + { + src_name: aon + endpoint_ip: pwrmgr_aon + } + clk_main_powerup: + { + src_name: main + endpoint_ip: rstmgr_aon + } + clk_io_powerup: + { + src_name: io + endpoint_ip: rstmgr_aon + } + clk_usb_powerup: + { + src_name: usb + endpoint_ip: rstmgr_aon + } + clk_io_div2_powerup: + { + src_name: io_div2 + endpoint_ip: rstmgr_aon + } + clk_aon_secure: + { + src_name: aon + endpoint_ip: ast + } + clk_aon_peri: + { + src_name: aon + endpoint_ip: usbdev + } + clk_aon_timers: + { + src_name: aon + endpoint_ip: aon_timer_aon + } + } + rg_clks: + { + clk_main_infra: + { + src_name: main + endpoint_ip: flash_ctrl + } + clk_io_div4_infra: + { + src_name: io_div4 + endpoint_ip: flash_ctrl + } + clk_io_infra: + { + src_name: io + endpoint_ip: peri + } + clk_usb_infra: + { + src_name: usb + endpoint_ip: peri + } + clk_io_div4_secure: + { + src_name: io_div4 + endpoint_ip: ast + } + clk_main_secure: + { + src_name: main + endpoint_ip: ast + } + clk_io_div4_timers: + { + src_name: io_div4 + endpoint_ip: rv_timer + } + } + sw_clks: + { + clk_io_div4_peri: + { + src_name: io_div4 + endpoint_ip: uart0 + } + clk_io_div2_peri: + { + src_name: io_div2 + endpoint_ip: spi_device + } + clk_io_peri: + { + src_name: io + endpoint_ip: spi_host0 + } + clk_usb_peri: + { + src_name: usb + endpoint_ip: usbdev + } + } + hint_clks: + { + clk_main_aes: + { + src_name: main + endpoint_ip: aes + } + } + } + hint_names: + { + clk_main_aes: HintMainAes + } + parent_child_clks: + { + main: + [ + main + ] + io: + [ + io + io_div2 + io_div4 + ] + usb: + [ + usb + ] + } + exported_clks: {} + number_of_clock_groups: 8 + with_alert_handler: false + pwrmgr_vlnv_prefix: top_englishbreakfast_ + top_pkg_vlnv: lowrisc:constants:top_englishbreakfast_top_pkg + topname: englishbreakfast + } +} diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/defs.bzl b/hw/top_englishbreakfast/ip_autogen/clkmgr/defs.bzl new file mode 100644 index 0000000000000..68bc755b798c2 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +load("//rules/opentitan:hw.bzl", "opentitan_ip") + +CLKMGR = opentitan_ip( + name = "clkmgr", + hjson = "//hw/top_englishbreakfast/ip_autogen/clkmgr:data/clkmgr.hjson", +) diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/checklist.md b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/checklist.md new file mode 100644 index 0000000000000..28ac5395584b9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/checklist.md @@ -0,0 +1,271 @@ +# CLKMGR Checklist + + +This checklist is for [Hardware Stage](../../../../../doc/project_governance/development_stages.md) transitions for the [CLKMGR 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 | [CLKMGR 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][] | NA | +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][] | Done | +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][] | Done | +RTL | [TODO_COMPLETE][] | Done | +Code Quality | [LINT_COMPLETE][] | Done | With waivers approved by TC on 2024-08-08 +Code Quality | [CDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Code Quality | [RDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Review | [REVIEW_RTL][] | Done | +Review | [REVIEW_DELETED_FF][] | Done | +Review | [REVIEW_SW_CHANGE][] | Done | +Review | [REVIEW_SW_ERRATA][] | Done | +Review | Reviewer(s) | Done | matutem@, vogelpi@, adk@ +Review | Signoff date | Done | 2024-08-08 + +[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 | [CLKMGR DV document](../dv/README.md) +Documentation | [TESTPLAN_COMPLETED][] | Done | [CLKMGR 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][] | NA | +Tests | [FPV_MAIN_ASSERTIONS_PROVEN][] | NA | +Tool Setup | [SIM_ALT_TOOL_SETUP][] | Done | xcelium +Regression | [SIM_SMOKE_REGRESSION_SETUP][] | Done | +Regression | [SIM_NIGHTLY_REGRESSION_SETUP][] | Done | +Regression | [FPV_REGRESSION_SETUP][] | NA | +Coverage | [SIM_COVERAGE_MODEL_ADDED][] | Done | +Code Quality | [TB_LINT_SETUP][] | Done | +Integration | [PRE_VERIFIED_SUB_MODULES_V1][] | NA | +Review | [DESIGN_SPEC_REVIEWED][] | Done | +Review | [TESTPLAN_REVIEWED][] | Done | +Review | [STD_TEST_CATEGORIES_PLANNED][] | Done | +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][] | NA | +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 | +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/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_block_diagram.svg b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_block_diagram.svg new file mode 100644 index 0000000000000..b3977b5124cae --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_block_diagram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_rst_domain.svg b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_rst_domain.svg new file mode 100644 index 0000000000000..2e5276cc7c218 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/clkmgr_rst_domain.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/example_chip_partition.svg b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/example_chip_partition.svg new file mode 100644 index 0000000000000..2c8bc65081b17 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/example_chip_partition.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/interfaces.md b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/interfaces.md new file mode 100644 index 0000000000000..4aec47b700f39 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/interfaces.md @@ -0,0 +1,59 @@ +# Hardware Interfaces + + +Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`clkmgr`** has the following hardware interfaces defined +- Primary Clock: **`clk_i`** +- Other Clocks: **`clk_main_i`**, **`clk_io_i`**, **`clk_usb_i`**, **`clk_aon_i`**, **`clk_io_div2_i`**, **`clk_io_div4_i`** +- Bus Device Interfaces (TL-UL): **`tl`** +- Bus Host Interfaces (TL-UL): *none* +- Peripheral Pins for Chip IO: *none* +- Interrupts: *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 | +|:------------------|:-------------------------|:--------|:------|--------:|:---------------------------------------------------------| +| clocks | clkmgr_pkg::clkmgr_out | uni | req | 1 | | +| cg_en | clkmgr_pkg::clkmgr_cg_en | uni | req | 1 | | +| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| io_clk_byp_req | prim_mubi_pkg::mubi4 | uni | req | 1 | | +| io_clk_byp_ack | prim_mubi_pkg::mubi4 | uni | rcv | 1 | | +| all_clk_byp_req | prim_mubi_pkg::mubi4 | uni | req | 1 | | +| all_clk_byp_ack | prim_mubi_pkg::mubi4 | uni | rcv | 1 | | +| hi_speed_sel | prim_mubi_pkg::mubi4 | uni | req | 1 | | +| div_step_down_req | prim_mubi_pkg::mubi4 | uni | rcv | 1 | | +| lc_clk_byp_req | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| lc_clk_byp_ack | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| jitter_en | prim_mubi_pkg::mubi4 | uni | req | 1 | | +| pwr | pwr_clk | req_rsp | rsp | 1 | | +| idle | prim_mubi_pkg::mubi4 | uni | rcv | 1 | | +| calib_rdy | prim_mubi_pkg::mubi4 | uni | rcv | 1 | Indicates clocks are calibrated and frequencies accurate | +| tl | tlul_pkg::tl | req_rsp | rsp | 1 | | + +## Security Alerts + +| Alert Name | Description | +|:-------------|:----------------------------------------------------------------------------------| +| recov_fault | This recoverable alert is triggered when there are measurement errors. | +| fatal_fault | This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. | + +## Security Countermeasures + +| Countermeasure ID | Description | +|:-------------------------------------------|:-------------------------------------------------------------| +| CLKMGR.BUS.INTEGRITY | End-to-end bus integrity scheme. | +| CLKMGR.TIMEOUT.CLK.BKGN_CHK | Background check for clock timeout. | +| CLKMGR.MEAS.CLK.BKGN_CHK | Background check for clock frequency. | +| CLKMGR.MEAS.CONFIG.SHADOW | Measurement configurations are shadowed. | +| CLKMGR.IDLE.INTERSIG.MUBI | Idle inputs are multibit encoded. | +| CLKMGR.LC_CTRL.INTERSIG.MUBI | The life cycle control signals are multibit encoded. | +| CLKMGR.LC_CTRL_CLK_HANDSHAKE.INTERSIG.MUBI | The life cycle clock req/ack signals are multibit encoded. | +| CLKMGR.CLK_HANDSHAKE.INTERSIG.MUBI | The external clock req/ack signals are multibit encoded. | +| CLKMGR.DIV.INTERSIG.MUBI | Divider step down request is multibit encoded. | +| CLKMGR.JITTER.CONFIG.MUBI | The jitter enable configuration is multibit encoded. | +| CLKMGR.IDLE.CTR.REDUN | Idle counter is duplicated. | +| CLKMGR.MEAS.CONFIG.REGWEN | The measurement controls protected with regwen. | +| CLKMGR.CLK_CTRL.CONFIG.REGWEN | Software controlled clock requests are proteced with regwen. | + + + diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/programmers_guide.md b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/programmers_guide.md new file mode 100644 index 0000000000000..eea3386a2e234 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/programmers_guide.md @@ -0,0 +1,17 @@ +# Programmer's Guide + +There are in general only two software controllable functions in the clock manager. + + +## Transactional Clock Hints + +To enable a transactional clock, set the corresponding hint in [`CLK_HINTS`](registers.md#clk_hints) to `1`. +To disable a transactional clock, set the corresponding hint in [`CLK_HINTS`](registers.md#clk_hints) to `0`. +Note, a `0` does not indicate clock is actually disabled, software can thus check [`CLK_HINTS_STATUS`](registers.md#clk_hints_status) for the actual state of the clock. + +## Peripheral Clock Controls +To control peripheral clocks, directly change the bits in [`CLK_ENABLES`](registers.md#clk_enables). + +## Device Interface Functions (DIFs) + +- [Device Interface Functions](../../../../../sw/device/lib/dif/dif_clkmgr.h) diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/registers.md b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/registers.md new file mode 100644 index 0000000000000..1ae9db8684cd4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/registers.md @@ -0,0 +1,460 @@ +# Registers + + +## Summary + +| Name | Offset | Length | Description | +|:-------------------------------------------------------------------|:---------|---------:|:---------------------------------------------------------------------------| +| clkmgr.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | +| clkmgr.[`EXTCLK_CTRL_REGWEN`](#extclk_ctrl_regwen) | 0x4 | 4 | External clock control write enable | +| clkmgr.[`EXTCLK_CTRL`](#extclk_ctrl) | 0x8 | 4 | Select external clock | +| clkmgr.[`EXTCLK_STATUS`](#extclk_status) | 0xc | 4 | Status of requested external clock switch | +| clkmgr.[`JITTER_REGWEN`](#jitter_regwen) | 0x10 | 4 | Jitter write enable | +| clkmgr.[`JITTER_ENABLE`](#jitter_enable) | 0x14 | 4 | Enable jittery clock | +| clkmgr.[`CLK_ENABLES`](#clk_enables) | 0x18 | 4 | Clock enable for software gateable clocks. | +| clkmgr.[`CLK_HINTS`](#clk_hints) | 0x1c | 4 | Clock hint for software gateable transactional clocks during active mode. | +| clkmgr.[`CLK_HINTS_STATUS`](#clk_hints_status) | 0x20 | 4 | Since the final state of !!CLK_HINTS is not always determined by software, | +| clkmgr.[`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) | 0x24 | 4 | Measurement control write enable | +| clkmgr.[`IO_MEAS_CTRL_EN`](#io_meas_ctrl_en) | 0x28 | 4 | Enable for measurement control | +| clkmgr.[`IO_MEAS_CTRL_SHADOWED`](#io_meas_ctrl_shadowed) | 0x2c | 4 | Configuration controls for io measurement. | +| clkmgr.[`IO_DIV4_MEAS_CTRL_EN`](#io_div4_meas_ctrl_en) | 0x30 | 4 | Enable for measurement control | +| clkmgr.[`IO_DIV4_MEAS_CTRL_SHADOWED`](#io_div4_meas_ctrl_shadowed) | 0x34 | 4 | Configuration controls for io_div4 measurement. | +| clkmgr.[`MAIN_MEAS_CTRL_EN`](#main_meas_ctrl_en) | 0x38 | 4 | Enable for measurement control | +| clkmgr.[`MAIN_MEAS_CTRL_SHADOWED`](#main_meas_ctrl_shadowed) | 0x3c | 4 | Configuration controls for main measurement. | +| clkmgr.[`USB_MEAS_CTRL_EN`](#usb_meas_ctrl_en) | 0x40 | 4 | Enable for measurement control | +| clkmgr.[`USB_MEAS_CTRL_SHADOWED`](#usb_meas_ctrl_shadowed) | 0x44 | 4 | Configuration controls for usb measurement. | +| clkmgr.[`RECOV_ERR_CODE`](#recov_err_code) | 0x48 | 4 | Recoverable Error code | +| clkmgr.[`FATAL_ERR_CODE`](#fatal_err_code) | 0x4c | 4 | Error code | + +## ALERT_TEST +Alert Test Register +- Offset: `0x0` +- Reset default: `0x0` +- Reset mask: `0x3` + +### Fields + +```wavejson +{"reg": [{"name": "recov_fault", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_fault", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:-------------------------------------------------| +| 31:2 | | | | Reserved | +| 1 | wo | 0x0 | fatal_fault | Write 1 to trigger one alert event of this kind. | +| 0 | wo | 0x0 | recov_fault | Write 1 to trigger one alert event of this kind. | + +## EXTCLK_CTRL_REGWEN +External clock control write enable +- Offset: `0x4` +- 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, the value of [`EXTCLK_CTRL`](#extclk_ctrl) can be set. When 0, writes to [`EXTCLK_CTRL`](#extclk_ctrl) have no effect. | + +## EXTCLK_CTRL +Select external clock +- Offset: `0x8` +- Reset default: `0x99` +- Reset mask: `0xff` +- Register enable: [`EXTCLK_CTRL_REGWEN`](#extclk_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "SEL", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HI_SPEED_SEL", "bits": 4, "attr": ["rw"], "rotate": -90}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 140}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------------------------| +| 31:8 | | | Reserved | +| 7:4 | rw | 0x9 | [HI_SPEED_SEL](#extclk_ctrl--hi_speed_sel) | +| 3:0 | rw | 0x9 | [SEL](#extclk_ctrl--sel) | + +### EXTCLK_CTRL . HI_SPEED_SEL +A value of kMultiBitBool4True selects nominal speed external clock. +All other values selects low speed clocks. + +Note this field only has an effect when the [`EXTCLK_CTRL.SEL`](#extclk_ctrl) field is set to +kMultiBitBool4True. + +Nominal speed means the external clock is approximately the same frequency as +the internal oscillator source. When this option is used, all clocks operate +at roughly the nominal frequency. + +Low speed means the external clock is approximately half the frequency of the +internal oscillator source. When this option is used, the internal dividers are +stepped down. As a result, previously undivided clocks now run at half frequency, +while previously divided clocks run at roughly the nominal frequency. + +See external clock switch support in documentation for more details. + +### EXTCLK_CTRL . SEL +When the current value is not kMultiBitBool4True, writing a value of kMultiBitBool4True +selects external clock as clock for the system. Writing any other value has +no impact. + +When the current value is kMultiBitBool4True, writing a value of kMultiBitBool4False +selects internal clock as clock for the system. Writing any other value during this stage +has no impact. + +While this register can always be programmed, it only takes effect when debug functions are enabled +in life cycle TEST, DEV or RMA states. + +## EXTCLK_STATUS +Status of requested external clock switch +- Offset: `0xc` +- Reset default: `0x9` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "ACK", "bits": 4, "attr": ["ro"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:---------------------------| +| 31:4 | | | Reserved | +| 3:0 | ro | 0x9 | [ACK](#extclk_status--ack) | + +### EXTCLK_STATUS . ACK +When [`EXTCLK_CTRL.SEL`](#extclk_ctrl) is set to kMultiBitBool4True, this field reflects +whether the clock has been switched the external source. + +kMultiBitBool4True indicates the switch is complete. +kMultiBitBool4False indicates the switch is either not possible or still ongoing. + +## JITTER_REGWEN +Jitter write enable +- Offset: `0x10` +- 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, the value of [`JITTER_ENABLE`](#jitter_enable) can be changed. When 0, writes have no effect. | + +## JITTER_ENABLE +Enable jittery clock +- Offset: `0x14` +- Reset default: `0x9` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:------------------------------------------------------------------------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x9 | VAL | Enable jittery clock. A value of kMultiBitBool4False disables the jittery clock, while all other values enable jittery clock. | + +## CLK_ENABLES +Clock enable for software gateable clocks. +These clocks are directly controlled by software. +- Offset: `0x18` +- Reset default: `0xf` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "CLK_IO_DIV4_PERI_EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "CLK_IO_DIV2_PERI_EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "CLK_IO_PERI_EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "CLK_USB_PERI_EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 210}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:--------------------|:---------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3 | rw | 0x1 | CLK_USB_PERI_EN | 0 CLK_USB_PERI is disabled. 1 CLK_USB_PERI is enabled. | +| 2 | rw | 0x1 | CLK_IO_PERI_EN | 0 CLK_IO_PERI is disabled. 1 CLK_IO_PERI is enabled. | +| 1 | rw | 0x1 | CLK_IO_DIV2_PERI_EN | 0 CLK_IO_DIV2_PERI is disabled. 1 CLK_IO_DIV2_PERI is enabled. | +| 0 | rw | 0x1 | CLK_IO_DIV4_PERI_EN | 0 CLK_IO_DIV4_PERI is disabled. 1 CLK_IO_DIV4_PERI is enabled. | + +## CLK_HINTS +Clock hint for software gateable transactional clocks during active mode. +During low power mode, all clocks are gated off regardless of the software hint. + +Transactional clocks are not fully controlled by software. Instead software provides only a disable hint. + +When software provides a disable hint, the clock manager checks to see if the associated hardware block is idle. +If the hardware block is idle, then the clock is disabled. +If the hardware block is not idle, the clock is kept on. + +For the enable case, the software hint is immediately honored and the clock turned on. Hardware does not provide any +feedback in this case. +- Offset: `0x1c` +- Reset default: `0x1` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "CLK_MAIN_AES_HINT", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 190}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------------|:-----------------------------------------------------------| +| 31:1 | | | | Reserved | +| 0 | rw | 0x1 | CLK_MAIN_AES_HINT | 0 CLK_MAIN_AES can be disabled. 1 CLK_MAIN_AES is enabled. | + +## CLK_HINTS_STATUS +Since the final state of [`CLK_HINTS`](#clk_hints) is not always determined by software, +this register provides read feedback for the current clock state. + +- Offset: `0x20` +- Reset default: `0x1` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "CLK_MAIN_AES_VAL", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 180}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-----------------|:-------------------------------------------------------| +| 31:1 | | | | Reserved | +| 0 | ro | 0x1 | CLK_MAIN_AES_VAL | 0 CLK_MAIN_AES is disabled. 1 CLK_MAIN_AES is enabled. | + +## MEASURE_CTRL_REGWEN +Measurement control write enable +- Offset: `0x24` +- 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, the value of the measurement control can be set. When 0, writes have no effect. | + +## IO_MEAS_CTRL_EN +Enable for measurement control +- Offset: `0x28` +- Reset default: `0x9` +- Reset mask: `0xf` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x9 | EN | Enable measurement for io | + +## IO_MEAS_CTRL_SHADOWED +Configuration controls for io measurement. + +The threshold fields are made wider than required (by 1 bit) to ensure +there is room to adjust for measurement inaccuracies. +- Offset: `0x2c` +- Reset default: `0x759ea` +- Reset mask: `0xfffff` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "HI", "bits": 10, "attr": ["rw"], "rotate": 0}, {"name": "LO", "bits": 10, "attr": ["rw"], "rotate": 0}, {"bits": 12}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:---------------------------------| +| 31:20 | | | | Reserved | +| 19:10 | rw | 0x1d6 | LO | Min threshold for io measurement | +| 9:0 | rw | 0x1ea | HI | Max threshold for io measurement | + +## IO_DIV4_MEAS_CTRL_EN +Enable for measurement control +- Offset: `0x30` +- Reset default: `0x9` +- Reset mask: `0xf` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:-------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x9 | EN | Enable measurement for io_div4 | + +## IO_DIV4_MEAS_CTRL_SHADOWED +Configuration controls for io_div4 measurement. + +The threshold fields are made wider than required (by 1 bit) to ensure +there is room to adjust for measurement inaccuracies. +- Offset: `0x34` +- Reset default: `0x6e82` +- Reset mask: `0xffff` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "HI", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "LO", "bits": 8, "attr": ["rw"], "rotate": 0}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------------------------------| +| 31:16 | | | | Reserved | +| 15:8 | rw | 0x6e | LO | Min threshold for io_div4 measurement | +| 7:0 | rw | 0x82 | HI | Max threshold for io_div4 measurement | + +## MAIN_MEAS_CTRL_EN +Enable for measurement control +- Offset: `0x38` +- Reset default: `0x9` +- Reset mask: `0xf` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x9 | EN | Enable measurement for main | + +## MAIN_MEAS_CTRL_SHADOWED +Configuration controls for main measurement. + +The threshold fields are made wider than required (by 1 bit) to ensure +there is room to adjust for measurement inaccuracies. +- Offset: `0x3c` +- Reset default: `0x7a9fe` +- Reset mask: `0xfffff` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "HI", "bits": 10, "attr": ["rw"], "rotate": 0}, {"name": "LO", "bits": 10, "attr": ["rw"], "rotate": 0}, {"bits": 12}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:-----------------------------------| +| 31:20 | | | | Reserved | +| 19:10 | rw | 0x1ea | LO | Min threshold for main measurement | +| 9:0 | rw | 0x1fe | HI | Max threshold for main measurement | + +## USB_MEAS_CTRL_EN +Enable for measurement control +- Offset: `0x40` +- Reset default: `0x9` +- Reset mask: `0xf` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:---------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x9 | EN | Enable measurement for usb | + +## USB_MEAS_CTRL_SHADOWED +Configuration controls for usb measurement. + +The threshold fields are made wider than required (by 1 bit) to ensure +there is room to adjust for measurement inaccuracies. +- Offset: `0x44` +- Reset default: `0x1ccfa` +- Reset mask: `0x3ffff` +- Register enable: [`MEASURE_CTRL_REGWEN`](#measure_ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "HI", "bits": 9, "attr": ["rw"], "rotate": 0}, {"name": "LO", "bits": 9, "attr": ["rw"], "rotate": 0}, {"bits": 14}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------------| +| 31:18 | | | | Reserved | +| 17:9 | rw | 0xe6 | LO | Min threshold for usb measurement | +| 8:0 | rw | 0xfa | HI | Max threshold for usb measurement | + +## RECOV_ERR_CODE +Recoverable Error code +- Offset: `0x48` +- Reset default: `0x0` +- Reset mask: `0x1ff` + +### Fields + +```wavejson +{"reg": [{"name": "SHADOW_UPDATE_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "IO_MEASURE_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "IO_DIV4_MEASURE_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "MAIN_MEASURE_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "USB_MEASURE_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "IO_TIMEOUT_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "IO_DIV4_TIMEOUT_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "MAIN_TIMEOUT_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "USB_TIMEOUT_ERR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 210}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:--------------------|:---------------------------------------------------------| +| 31:9 | | | | Reserved | +| 8 | rw1c | 0x0 | USB_TIMEOUT_ERR | usb has timed out. | +| 7 | rw1c | 0x0 | MAIN_TIMEOUT_ERR | main has timed out. | +| 6 | rw1c | 0x0 | IO_DIV4_TIMEOUT_ERR | io_div4 has timed out. | +| 5 | rw1c | 0x0 | IO_TIMEOUT_ERR | io has timed out. | +| 4 | rw1c | 0x0 | USB_MEASURE_ERR | usb has encountered a measurement error. | +| 3 | rw1c | 0x0 | MAIN_MEASURE_ERR | main has encountered a measurement error. | +| 2 | rw1c | 0x0 | IO_DIV4_MEASURE_ERR | io_div4 has encountered a measurement error. | +| 1 | rw1c | 0x0 | IO_MEASURE_ERR | io has encountered a measurement error. | +| 0 | rw1c | 0x0 | SHADOW_UPDATE_ERR | One of the shadow registers encountered an update error. | + +## FATAL_ERR_CODE +Error code +- Offset: `0x4c` +- Reset default: `0x0` +- Reset mask: `0x7` + +### Fields + +```wavejson +{"reg": [{"name": "REG_INTG", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "IDLE_CNT", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "SHADOW_STORAGE_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 200}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------------------|:---------------------------------------------------------| +| 31:3 | | | | Reserved | +| 2 | ro | 0x0 | SHADOW_STORAGE_ERR | One of the shadow registers encountered a storage error. | +| 1 | ro | 0x0 | IDLE_CNT | One of the idle counts encountered a duplicate error. | +| 0 | ro | 0x0 | REG_INTG | Register file has experienced a fatal integrity error. | + + + diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/theory_of_operation.md b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/theory_of_operation.md new file mode 100644 index 0000000000000..ae4738dfb9261 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/doc/theory_of_operation.md @@ -0,0 +1,293 @@ +# Theory of Operation + +Clock management in OpenTitan is divided into groups. +Each group has specific attributes and controls whether software is allowed to influence individual clocks during the active power state. +For low power states, please see [power manager](../../pwrmgr/README.md). + +The grouping is derived from the chip partition and related security properties. +For illustrative purposes, this document uses the following assumed chip partition + +![Example chip partition](example_chip_partition.svg) + +The actual partition may differ per design, however the general principles are assumed to be the same. +Each group can be made up of more than 1 source clock. +The clocks themselves may be asynchronous - the grouping is thus a logical grouping instead of a physical one. + +The grouping is summarized in the table below and described in more detail afterwards. +The table shows the group name, the modules that belong to each group, and whether SW can directly (via register control) or indirectly (via wait-for-interrupt) influence the state of the clock in the form of clock gating. + +| Group | Frequencies | Modules | Software | Wait for Interrupt | +| ------------- | ------------------------------ | -------------------------------------------------------------- | -------------- | ------------------ | +| Power-up | 100~200KHz, 24MHz | Clock Manager, Power Manager, Reset Manager, Pinmux | No | No | +| Transactional | ~100MHz | Aes, Kmac, Hmac, Key Manager, Otbn | Yes (1) | Yes (2) | +| Infrastructural | 24MHz, ~100MHz | Fabric, Fabric gaskets (iopmp), Memories | No | Yes (3) | +| Security | 24MHz, ~100MHz | Alert handler, Entropy, Life cycle, Plic, Sensors | No | No | +| Peripheral | 24MHz, 48MHz, 96MHz | I2c, Spi, Uart, Usb, others | Yes | Yes | +| Timers | 100-200KHz, 24MHz | AON timers, Timers, Watchdog | No | No | + +* 1 - Transactional clock group's software control is only a software hint. +* 2 - Transactional clock group's wait-for-interrupt control is only a hint. +* 3 - May require additional complexity to handle multi-host (non-wait-for-interrupt) scenarios + +## Power-up Clock Group + +The group refers to modules responsible for power up, such as power, reset and clock managers. +Large portions of these modules operate to release clocks and resets for the rest of the design, thus cannot operate on gated versions of the clocks themselves. +They are the only group running clocks directly from the source. +All follow groups are derived after root clock gating. +See [block diagram](#block-diagram) for more details. + +## Transactional Clock Group + +This group refers to the collection of modules that are transactional by nature (example: `Hmac` / `Aes` / `Kmac`). +This means these modules perform specific tasks (for example encrypt, decrypt or hashing). +While performing these tasks, it is unsafe to manipulate or change the clocks. +Once these tasks are complete, the clocks can be safely shut-off. + +To ensure such behavior on the clocks, The final clock enable is qualified with an `Idle` indication to signify that a transaction is ongoing and manipulation of the clock is not permitted. +The `Idle` signal must be sourced from the transactional modules and sent to the clock manager. + +For this group software can only express its intent to shut-off, and does not have full control over the final state. +This intent is indicated with a register in the clock manager register file, see [`CLK_HINTS`](registers.md#clk_hints). + +Even when the hint is set, the `Idle` does not directly manipulate the clock. +When an idle indication is received, the `clkmgr` counts for a period of 10 local clocks to ensure the idle was not a glitch. + +Wait-for-interrupt based control is already a software hint, it can thus be applied to this group with the same `Idle` requirement. + +For modules in this group, each module can be individually influenced, and thus each has its own dedicated clock gating logic. +The added benefit of allowing software control in this group is to save power, as some transactional modules can be both power and area hungry. + +## Infrastructure Clock Group + +This group refers to the collection of modules that support infrastructure functions. + +If the clocks to these modules are turned off, there may not be a way to turn them back on and could thus result in system deadlock. +This includes but is not limited to: +* Turning off fabric / gasket clocks, and thus having no way to access the fabric and resume the clock. +* Turning off memory clocks such that there is no way to execute code that would resume the clocks. + +For this group, there is no reason to allow software control over the clocks, as it could be used to create a system deadlock where after disabling infrastructure clocks there is no way to turn them back on. +Wait-for-interrupt controls however can be used, as long as there is a way to break the processor out of wait-for-interrupt and handle other bus hosts, while also separating the functional portions from bus access. +See Wait-for-interrupt clock gating for more details. + +## Security Clock Group + +The security clock group is made up of security modules that either have background functions (entropy, alert manager, sensors) or perform critical security functions where disabling clocks could have unexpected side effects (life cycle, otp, pinmux, plic). + +For this group, no software influence over the clock state is allowed during the active state. +The clocks are always running as long as the source is on. + +This group is not functionally identical to the power-up group. +The power-up group is run on clocks directly from the clock source, while the security group is derived after root clock gating. + +## Timer Clock Group + +The timer clock group is composed of modules that track time for various purposes. +As influencing time can change the perspective of software and potentially reveal security vulnerabilities, the clock state for these modules cannot be directly or indirectly influenced by software. + +Functionally, this group is identical to the security group. + +## Peripheral Clock Group + +The peripheral clock group is composed of I/O peripherals modules. +By their nature, I/O peripherals are both transactional and most of the time not security critical - so long as proper care is taken to sandbox peripherals from the system. + +These modules can be both directly and indirectly controlled by software. +The controls can also be individual to each peripheral. + +## Wait-for-Interrupt (wfi) Gating + +Wait-for-interrupt clock gating refers to the mechanism of using a processor's sleep indication to actively gate off module clocks. +Of the groups enumerated, only transactional, infrastructural and peripheral groups can be influenced by `wfi`. + +As `wfi` is effectively a processor clock request, there are subtleties related to its use. +The interaction with each clock group is briefly described below. + +### Transactional Clock Group + +While `wfi` gating can be applied to this group, the modules in this category are already expected to be turned off and on by software depending on usage. +Specifically, these modules are already completely managed by software when not in use, thus may not see significant benefit from `wfi` gating. + +### Peripheral Clock Group + +Since peripherals, especially those in device mode, are often operated in an interrupt driven way, the peripheral's core operating clock frequently must stay alive even if the processor is asleep. +This implies that in order for peripherals to completely support `wfi` clock gating, they must be split between functional clocks and bus clocks. + +The bus clocks represent the software interface and can be turned off based on `wfi gating`, while the functional clocks should be kept running to ensure outside activity can be captured and interrupts created. +In this scenario, it is important to ensure the functional clocks are responsible for creating interrupts and not the bus clocks, as the latter may not be available during `wfi`. + +This division may only be beneficial for peripherals where register and local fabric size is large relative to the functional component. + +### Infrastructural Clock Group + +This clock group matches `wfi` functionality well. +Most infrastructural components such as fabric, gaskets and memories, have no need to be clocked when the processor is idle. +Some components such as flash controller however would also need to be split into bus and functional halves to support long, background activities while the processor is idle. + +However, there are additional complications. +In systems where the processor is not the only bus host, `wfi` can only be used as the software request and not final clock state decision. +Hardware driven requests, such as those coming from a `dma` or any peripheral driven bus host, would also need to be included as part of the equation. +Further, since it is possible hardware may issue requests at the boundary of a clock state changes, additional fabric gaskets would be required to protect hosts when destinations are temporarily clocked off. +The bus requests themselves thus become dynamic clock request signals to help enable components in its path. + +There is thus a moderate design and high verification cost to supporting `wfi` gating for the infrastructural group. + +## Block Diagram + +The following is a high level block diagram of the clock manager. + +![Clock Manager Block Diagram](clkmgr_block_diagram.svg) + +### Reset Domains + +Since the function of the clock manager is tied closely into the power-up behavior of the device, the reset domain selection must also be purposefully done. +To ensure that default clocks are available for the [power manager to release resets and initialize memories](../../pwrmgr/README.md#fast-clock-domain-fsm), the clock dividers inside the clock manager directly use `por` (power-on-reset) derived resets. +This ensures that the root clocks are freely running after power-up and its status can be communicated to the `pwrmgr` regardless of any other activity in the device. + +The other functions inside the clock manager operate on the `life cycle reset` domain. +This ensures that other clock manager functions still release early relative to most functions in the system, and that a user or escalation initiated reset still restores the clock manager to a default clean slate. + +The escalation reset restoration is especially important as the clock manager can generate fatal faults that lead to escalation. +If there were not a mechanism that allows escalation to clear the original fault, the system would simply remain in a faulted state until a user initiated a `por` event. + +For a detailed breakdown between `por` and `life cycle` resets, please see the [reset manager](../../rstmgr/README.md). + +The following diagram enhances the block diagram to illustrate the overall reset domains of the clock manager. +![Clock Manager Block Diagram](clkmgr_rst_domain.svg) + + +## Design Details + +### Root Clock Gating and Interface with Power Manager + +All clock groups except the power-up group run from gated source clocks. +The source clocks are gated off during low power states as controlled by the power manager. +When the power manager makes a clock enable request, the clock manager ensures all root clock gates are enabled before acknowledging. +Likewise, when the power manager makes a clock disable request, the clock manager ensures all root clock gates off disabled before acknowledging. + +Note, the power manager's request to turn off clocks supersedes all other local controls in the clock manager. +This means even if a particular clock is turned on by the clock manager (for example a transactional unit that is ongoing or a peripheral that is enabled), the power manager requests will still turn clocks on / off at the root. + +This makes it software's responsibility to ensure low power entry requests (which can only be initiated by software) do not conflict with any ongoing activities controlled by software. +For example, software should ensure that Aes / Otbn activities have completed before initializing a low power entry process. + +### Clock Division + +Not all peripherals run at the full IO clock speed, hence the IO clock is divided down by 2x and 4x in normal operation. +This division ratio can be modified to 1x and 2x when switching to an external clock, since the external clock may be slower than the internal clock source. +See also [external clock switch support](#external-clock-switch-support). + +The divided clock is not assumed to be synchronous with its source and is thus treated like another asynchronous branch. +Further, the clock dividers are hardwired and have no software control, this is to further ensure there are no simple paths for faulty or malicious software to tamper. + +Note that for debug purposes, `ast` can also request a change in the clock division ratio via a dedicated hardware interface (`div_step_down_req_i`). + +### Wait-for-Interrupt Support + +Given the marginal benefits and the increased complexity of `wfi` support, the first version of this design does not support `wfi` gating. +All `wfi CG` modules in the block diagram are thus drawn with dashed lines to indicate it can be theoretically supported but currently not implemented. + +It may be added for future more complex systems where there is a need to tightly control infrastructural power consumption as a result from clocks. + +### External Clock Switch Support + +Clock manager supports the ability to request root clocks switch to an external clock. +There are two occasions where this is required: +- Life cycle transition from `RAW` / `TEST_LOCKED*` to `TEST_UNLOCKED*` [states](../../../../ip/lc_ctrl/README.md#clk_byp_req). +- Software request for external clocks during normal functional mode. + + +#### Life Cycle Requested External Clock + +The life cycle controller only requests the io clock input to be switched. +When the life cycle controller requests external clock, a request signal `lc_clk_byp_req_i` is sent from `lc_ctrl` to `clkmgr`. +`clkmgr` then forwards the request to `ast` through `io_clk_byp_req_o`, which performs the actual clock switch and is acknowledged through `io_clk_byp_ack_i`. +When the clock switch is complete, the clock dividers are stepped down by a factor of 2 and the life cycle controller is acknowledged through `lc_clk_byp_ack_o`. + +Note that this division factor change is done since the external clock is expected to be 48MHz while the nominal frequency of the internal clock is 96MHz. +I.e. this division factor change keeps the nominal frequencies of the div_2 and div_4 clocks stable at 48Mhz and 24MHz, respectively. +See [Clock Frequency Summary](#clock-frequency-summary) for more details. + +#### Software Requested External Clocks + +Unlike the life cycle controller, a software request for external clocks switches all clock sources to an external source. +Software request for external clocks is not always valid. +Software is only able to request for external clocks when hardware debug functions are [allowed](../../../../ip/lc_ctrl/README.md#hw_debug_en). + +When software requests the external clock switch, it also provides an indication how fast the external clock is through [`EXTCLK_CTRL.HI_SPEED_SEL`](registers.md#extclk_ctrl). +There are two supported clock speeds: +* High speed - external clock is close to nominal speeds (e.g. external clock is 96MHz and nominal frequency is 96MHz-100MHz) +* Low speed - external clock is half of nominal speeds (e.g. external clock is 48MHz and nominal frequency is 96MHz-100MHz) + +When software requests external clock, the register bit [`EXTCLK_CTRL.SEL`](registers.md#extclk_ctrl) is written. +If hardware debug functions are allowed, the `clkmgr` sends a request signal `all_clk_byp_req_o` to `ast` and is acknowledged through `all_clk_byp_ack_i`. + +If software requests a low speed external clock, at the completion of the switch, internal dividers are also stepped down. +When the divider is stepped down, a divide-by-4 clock becomes divide-by-2 clock , and a divide-by-2 becomes a divide-by-1 clock. + +If software requests a high speed external clock, the dividers are kept as is. + + +Note, software external clock switch support is meant to be a debug / evaluation feature, and should not be used in conjunction with the clock frequency and timeout measurement features. +This is because if the clock frequency suddenly changes, the thresholds used for timeout / measurement checks will no longer apply. +There is currently no support in hardware to dynamically synchronize a threshold change to the expected frequency. + +#### Clock Frequency Summary + +The table below summarises the valid modes and the settings required. + +| Mode | `lc_clk_byp_req_i` | `extclk_ctrl.sel` | `extclk_ctrl.hi_speed_sel` | life cycle state | +| ------------- | --------------------- | ----------------- | ----------------------------| -------------------------------| +| Life cycle in `RAW`, `TEST*` and `RMA` states | `lc_ctrl_pkg::On` | `kMultiBit4False` | Don't care | Controlled by `lc_ctrl` | +| Internal Clocks | `lc_ctrl_pkg::Off` | `kMultiBit4False` | Don't care | All | +| Software external high speed | `lc_ctrl_pkg::Off` | `kMultiBit4True` | `kMultiBit4True` | `TEST_UNLOCKED*`, `DEV`, `RMA` | +| Software external low speed | `lc_ctrl_pkg::Off` | `kMultiBit4True` | `kMultiBit4False` | `TEST_UNLOCKED*`, `DEV`, `RMA` | + +The table below summarizes the frequencies in each mode. +This table assumes that the internal clock source is 96MHz. +This table also assumes that high speed external clock is 96MHz, while low speed external clock is 48MHz. + +| Mode | External Clock Frequency | div_1_clock | div_2_clock | div_4_clock | +| ------------- | ------------------------ | ------------- | --------------- | -------------| +| Internal Clocks | Not applicable | 96MHz | 48MHz | 24MHz | +| Life cycle transition | 48MHz | 48MHz | 48MHz | 24MHz | +| Software external high speed | 96MHz | 96MHz | 48MHz | 24MHz | +| Software external low speed | 48MHz | 48MHz | 48MHz | 24MHz | + +As can be seen from the table, the external clock switch scheme prioritizes the stability of the divided clocks, while allowing the undivided clocks to slow down. + + +### Clock Frequency / Time-out Measurements + +Clock manager can continuously measure root clock frequencies to see if any of the root clocks have deviated from the expected frequency. +This feature can be enabled through the various measurement control registers such as [`IO_MEASURE_CTRL`](registers.md#io_measure_ctrl). + +The root clocks, specifically the clocks supplied from `ast` and their divided variants, are constantly measured against the `always on clock` when this feature is enabled. +Software sets both an expected maximum and minimum for each measured clock. + +Clock manager then counts the number of relevant root clock cycles in each always-on clock period. +If the resulting count differs from the programmed thresholds, a recoverable error is registered. + +Since the counts are measured against a single cycle of always on clock, the minimal error that can be detected is dependent on the clock ratio between the measured clock and 1 cycle of the always on clock. +Assume a 24MHz clock and an always-on clock of 200KHz. +The minimal error detection is then 200KHz / 24MHz, or approximately 0.83%. + +This means if the clock's actual value is between 23.8MHz and 24.2MHz, this deviation will not be detected. +Conversely, if the clock's natural operation has an error range wider than this resolution, the min / max counts must be adjusted to account for this error. + +Additionally, clock manager uses a similar time-out mechanism to see if any of the root clocks have stopped toggling for an extended period of time. +This is done by creating an artificial handshake between the root clock domain and the always on clock domain that must complete within a certain amount of time based on known clock ratios. +Based on the nature of the handshake and the margin window, the minimal timeout detection window is approximately 2-4 always on clock cycles. +If the root clock domain stops and resumes in significantly less time than this window, the time-out may not be detected. + +There are three types of errors: +* Clock too fast error +* Clock too slow error +* Clock time-out error + +Clock too fast is registered when the clock cycle count is greater than the software programmed max threshold. +Clock too slow is registered when the clock cycle count is less than the software programmed min threshold. +Clock time-out is registered when the clock stops toggling and the timeout threshold is reached. + +As these are all software supplied values, the entire measurement control can be locked from further programming through [`MEASURE_CTRL_REGWEN`](registers.md#measure_ctrl_regwen). diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/README.md b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/README.md new file mode 100644 index 0000000000000..acbda582b99ae --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/README.md @@ -0,0 +1,187 @@ +# CLKMGR DV document + +## Goals +* **DV** + * Verify all CLKMGR 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. + * Verify clock gating assertions. + +## Current status +* [Design & verification stage](../../../../README.md) + * [HW development stages](../../../../../doc/project_governance/development_stages.md) +* [Simulation results](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/latest/report.html) + +## Design features +The detailed information on CLKMGR design features is at [CLKMGR HWIP technical specification](../README.md). + +## Testbench architecture +CLKMGR 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/top_englishbreakfast/ip_autogen/clkmgr/dv/tb.sv`. +It instantiates the CLKMGR DUT module `hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr.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) +* CLKMGR IOs: `hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_if.sv` + +### 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 +`clkmgr_env_pkg`. Some of them in use are: + +```systemverilog + localparam int NUM_PERI = 4; + localparam int NUM_TRANS = 5; + localparam int NUM_ALERTS = 2; + + typedef logic [NUM_PERI-1:0] peri_enables_t; + typedef logic [NUM_TRANS-1:0] hintables_t; + + typedef virtual clkmgr_if clkmgr_vif; + typedef virtual clk_rst_if clk_rst_vif; + typedef enum int {PeriDiv4, PeriDiv2, PeriIo, PeriUsb} peri_e; + typedef enum int {TransAes, TransHmac, TransKmac, TransOtbnIoDiv4, TransOtbnMain} trans_e; +``` + +### TL_agent +CLKMGR 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 CLKMGR device. + +### UVM RAL Model +The CLKMGR 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 +This module is rather simple: the stimulus is just the external pins and the CSR updates. +There are a couple stages for synchronization of the CSR updates for clock gating controls, but scanmode is used asynchronously. +These go to the clock gating latches. +The external pins controlling the external clock selection need no synchronization. +The tests randomize the inputs and issue CSR updates affecting the specific functions being tested. + +### Test sequences +All test sequences reside in `hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib`. +The `clkmgr_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 that the test sequences can use or call. +Some of the most commonly used tasks / functions are as follows: +* `clkmgr_init`: Sets the frequencies of the various clocks. +* `control_ip_clocks`: Turns on or off the input clocks based on the various clock enable and status ports to and from the `pwrmgr` IP. + +All test sequences are extended from `clkmgr_base_vseq`, and are described below. + +#### clkmgr_peri_vseq + +The sequence `clkmgr_peri_vseq` randomizes the stimuli that drive the four peripheral clocks. +These clocks are mutually independent so they are tested in parallel. +They depend on +* The `clk_enables` CSR, which has a dedicated enable for each peripheral clock +* The pwrmgr's `_ip_clk_en` which has a dedicated bit controlling `io`, `main`, and `usb` clocks +* The `scanmode_i` input, which is used asynchronously and also controls all. + +The sequence runs a number of iterations, each randomizing the above except for `io_ip_clk_en` since that would imply the processor is disabled. + +#### clkmgr_trans_vseq + +The sequence `clkmgr_trans_vseq` randomizes the stimuli that drive the five transactional unit clocks. +These are also mutually independent so they are tested in parallel. +They depend on the `clk_hints` CSR, which has a separate bit for each, `main_ip_clk_en` and `scanmode_i`, similar to the peripheral clocks. +They also depend on the `idle_i` input, which also has a separate multi-bit value for each unit. +Units are considered busy when their corresponding `idle_i` value is not `mubi_pkg::MuBi4True`, and this prevents its clock turning off until it becomes idle. + +#### clkmgr_extclk_vseq + +The sequence `clkmgr_extclk_vseq` randomizes the stimuli that drive the external clock selection. +The selection is controlled by software if the `extclk_ctrl.sel` CSR is `prim_mubi_pkg::MuBi4True`, provided the `lc_hw_debug_en_i` input is also set to `lc_ctrl_pkg::On`. +Alternatively, the external clock is selected by the life cycle controller if the `lc_ctrl_byp_req_i` input is `lc_ctrl_pkg::On`. +When the external clock is selected and `scanmode_i` is not set to `prim_mubi_pkg::MuBi4True`, the clock dividers for the clk_io_div2 and clk_io_div4 output clocks are stepped down: +* If `lc_ctrl_byp_req_i` is on, or +* If `extclk_ctrl.hi_speed_sel` CSR is `prim_mubi_pkg::MuBi4True`, when the selection is enabled by software. + +#### clkmgr_frequency_vseq + +The sequence `clkmgr_frequency_vseq` randomly programs the frequency measurement for each clock so its measurement is either okay, slow, or fast. +It checks the recoverable alerts trigger as expected when a measurement is not okay. +It also checks the `recov_err_code` CSR sets bits for clocks whose measurement is out of bounds. +It also checks that loss of calibration stops clock measurements and doesn't trigger errors. + +#### clkmgr_frequency_timeout_vseq + +The sequence `clkmgr_frequency_timeout_vseq` programs the frequency measurement for each clock so its measurement is okay. +It randomly stops one of the clocks, and checks the corresponding bit in the `recov_err_code` show a timeout. +It also checks the recoverable alerts trigger as expected for a timeout. + +#### clkmgr_clk_status_vseq + +This checks that the `pwr_o.*_status` outputs track the `pwr_i.*_ip_clk_en` inputs. +The inputs are set at random and the outputs are checked via SVA. + +### 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: + +* Covergroups for inputs to each software gated peripheral clock. + These are wrapped in class `clkmgr_peri_cg_wrap` and instantiated in `clkmgr_env_cov`. +* Covergroups for inputs to each transactional gated unit clock. + These are wrapped in class `clkmgr_trans_cg_wrap` and instantiated in `clkmgr_env_cov`. +* Covergroups for the outcome of each clock measurement. + These are wrapped in class `freq_measure_cg_wrap` and instantiated in `clkmgr_env_cov`. +* Covergroup for the external clock selection logic: `extclk_cg` in `clkmgr_env_cov`. + +See more detailed description at `hw/top_englishbreakfast/ip_autogen/clkmgr/data/clkmgr_testplan.hjson`. + +## Self-checking strategy + +Most of the checking is done using SVA for input to output, or CSR update to output behavior. +Some of the CLKMGR outputs are gated clocks, which are controlled by both synchronous logic and asynchronous enables. +These asynchronous enables become synchronous because of the SVA semantics. +This is fine since the assertions allow some cycles for the expected behavior to occur. + +### Scoreboard +The `clkmgr_scoreboard` combines CSR updates and signals from the clkmgr vif to instrument some checks and coverage collection. +The CSR updates are determined using the TLUL analysis port. + +The CSR controlled output clocks can be separated into two groups: peripheral ip clocks and transactional unit clocks. +Please refer to the [Test sequences section](#test-sequences) above. +The clock gating logic is pretty similar across units in each group. +For each peripheral and transactional clock the scoreboard samples their coverage based on clocking blocks instantiated in `clkmgr_if`. +Most other other functional coverage groups are also sampled in the scoreboard. + +The `jitter_en_o` output is checked to match the `jitter_enable` CSR. + +### Assertions +* Pwrmgr enable-status assertions: Interface `clkmgr_pwrmgr_sva_if` contains concurrent SVA that checks that edges of the various ip_clk_en are followed by corresponding edges of their clk_status. + The clocks checked are `main`, `io`, and `usb`. +* Gated clock assertions: Interface `clkmgr_gated_clock_sva_if` contains concurrent SVA that checks each gated clock is either running or stopped based on their control logic. + There is one assertion for each of the four peripheral clock and four hintable clocks. +* Transactional clock assertions: Interface `clkmgr_trans_sva_if` contains concurrent SVA that checks each transactional clock is either running or stopped based on their control logic. + There is one assertion for each of the four hintable clocks. +* Clock divider assertions: Interface `clkmgr_div_sva_if` contains concurrent SVA that checks the `io_div2` and `io_div4` clocks are running at nominal frequency, or are divided by two each in response to the `extclk` logic. +* External clock assertions: Interface `clkmgr_extclk_sva_if` contains concurrent SVA that checks the external control outputs respond correctly to the various CSR or inputs that control them. +* Clock gating assertions: Interface `clkmgr_cg_en_sva_if` contains concurrent assertions that check a clock's cg_en output is active when the clock is disabled, and viceversa. + As a special case, interface `clkmgr_aon_cg_en_sva_if` checks cg_en is never active for an aon clock. +* Lost calibration assertions: Interfaces `clkmgr_lost_calib_ctrl_en_sva_if` and `clkmgr_lost_calib_regwen_sva_if` check that losing calibration turns off clock measurements and re-enables measure control writes. +* TLUL assertions: `clkmgr_bind.sv` binds the `tlul_assert` [assertions](../../../../ip/tlul/doc/TlulProtocolChecker.md) to the IP to ensure TileLink interface protocol compliance. +* Unknown checks on DUT outputs: 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/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson -i clkmgr_smoke +``` + +## Testplan +[Testplan](../data/clkmgr_testplan.hjson) diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim.core new file mode 100644 index 0000000000000..06cf747760ef2 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim.core @@ -0,0 +1,30 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr_sim:0.1 +description: "CLKMGR DV sim target" +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_clkmgr + + files_dv: + depend: + - lowrisc:opentitan:top_englishbreakfast_clkmgr_test:0.1 + - lowrisc:opentitan:top_englishbreakfast_clkmgr_sva:0.1 + files: + - tb.sv + - cov/clkmgr_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/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson new file mode 100644 index 0000000000000..8b0923c9aafed --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/clkmgr_sim_cfg.hjson @@ -0,0 +1,136 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: clkmgr + + // Top level dut name (sv module). + dut: clkmgr + + // 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:opentitan:top_englishbreakfast_clkmgr_sim:0.1 + + // Testplan hjson file. + testplan: "{self_dir}/../data/clkmgr_testplan.hjson" + + // RAL spec - used to generate the RAL model. + ral_spec: "{self_dir}/../data/clkmgr.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/alert_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.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/shadow_reg_errors_tests.hjson" + ] + + // Add additional tops for simulation. + sim_tops: ["clkmgr_bind", + "clkmgr_cov_bind", + "sec_cm_prim_count_bind", + "sec_cm_prim_onehot_check_bind"] + + // Default iterations for all tests - each test entry can override this. + reseed: 50 + + // CLKMGR exclusion files. + vcs_cov_excl_files: ["{self_dir}/cov/clkmgr_cov_manual_excl.el", + "{self_dir}/cov/clkmgr_cov_unr_excl.el"] + + // Handle generated coverage exclusion. + overrides: [ + { + name: default_vcs_cov_cfg_file + value: "-cm_hier {dv_root}/tools/vcs/cover.cfg+{dv_root}/tools/vcs/common_cov_excl.cfg+{self_dir}/cov/clkmgr_tgl_excl.cfg" + } + ] + // Default UVM test and seq class name. + uvm_test: clkmgr_base_test + uvm_test_seq: clkmgr_base_vseq + + // Disable clearing interrupts since clkmgr doesn't have any. + run_opts: ["+do_clear_all_interrupts=0", + // Enable cdc instrumentation. + "+cdc_instrumentation_enabled=1"] + + // List of test specifications. + tests: [ + { + name: clkmgr_smoke + uvm_test_seq: clkmgr_smoke_vseq + } + { + name: clkmgr_extclk + uvm_test_seq: clkmgr_extclk_vseq + } + { + name: clkmgr_frequency + uvm_test_seq: clkmgr_frequency_vseq + } + { + name: clkmgr_frequency_timeout + uvm_test_seq: clkmgr_frequency_timeout_vseq + } + { + name: clkmgr_peri + uvm_test_seq: clkmgr_peri_vseq + } + { + name: clkmgr_trans + uvm_test_seq: clkmgr_trans_vseq + } + { + name: clkmgr_clk_status + uvm_test_seq: clkmgr_clk_status_vseq + } + { + name: clkmgr_idle_intersig_mubi + uvm_test_seq: clkmgr_trans_vseq + run_opts: ["+clkmgr_mubi_mode=ClkmgrMubiIdle"] + } + { + name: clkmgr_lc_ctrl_intersig_mubi + uvm_test_seq: clkmgr_extclk_vseq + run_opts: ["+clkmgr_mubi_mode=ClkmgrMubiLcCtrl"] + } + { + name: clkmgr_lc_clk_byp_req_intersig_mubi + uvm_test_seq: clkmgr_extclk_vseq + run_opts: ["+clkmgr_mubi_mode=ClkmgrMubiLcHand"] + } + { + name: clkmgr_clk_handshake_intersig_mubi + uvm_test_seq: clkmgr_extclk_vseq + run_opts: ["+clkmgr_mubi_mode=ClkmgrMubiHand"] + } + { + name: clkmgr_div_intersig_mubi + uvm_test_seq: clkmgr_extclk_vseq + run_opts: ["+clkmgr_mubi_mode=ClkmgrMubiDiv"] + } + { + name: clkmgr_regwen + uvm_test_seq: clkmgr_regwen_vseq + } + ] + + // List of regressions. + regressions: [ + { + name: smoke + tests: ["clkmgr_smoke"] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_bind.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_bind.sv new file mode 100644 index 0000000000000..83bdeea3af9c5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_bind.sv @@ -0,0 +1,38 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: +// Clock manager coverage bindings for multi bus input +module clkmgr_cov_bind; + bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_idle_0_mubi_cov_if ( + .rst_ni (rst_ni), + .mubi (idle_i[0]) + ); + + bind clkmgr cip_lc_tx_cov_if u_lc_hw_debug_en_mubi_cov_if ( + .rst_ni (rst_ni), + .val (lc_hw_debug_en_i) + ); + + bind clkmgr cip_lc_tx_cov_if u_lc_clk_byp_req_mubi_cov_if ( + .rst_ni (rst_ni), + .val (lc_clk_byp_req_i) + ); + + bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_io_clk_byp_ack_mubi_cov_if ( + .rst_ni (rst_ni), + .mubi (io_clk_byp_ack_i) + ); + + bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_all_clk_byp_ack_mubi_cov_if ( + .rst_ni (rst_ni), + .mubi (all_clk_byp_ack_i) + ); + + bind clkmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_div_step_down_req_mubi_cov_if ( + .rst_ni (rst_ni), + .mubi (div_step_down_req_i) + ); + +endmodule // clkmgr_cov_bind diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_manual_excl.el b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_manual_excl.el new file mode 100644 index 0000000000000..ca5f99828dd8e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_manual_excl.el @@ -0,0 +1,49 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This contains some obvious exclusions the UNR tool didn't flag. + +//================================================== +// This file contains the Excluded objects +// Generated By User: maturana +// Format Version: 2 +// Date: Thu Sep 29 13:57:41 2022 +// ExclMode: default +//================================================== +CHECKSUM: "2301929872 1660332954" +INSTANCE: tb.dut.u_clk_main_aes_trans.u_idle_cnt +ANNOTATION: "[UNR] Input tied to a constant, and unr doesn't detect it." +Toggle step_i "net step_i[3:0]" +CHECKSUM: "2301929872 1660332954" +INSTANCE: tb.dut.u_clk_main_hmac_trans.u_idle_cnt +ANNOTATION: "[UNR] Input tied to a constant, and unr doesn't detect it." +Toggle step_i "net step_i[3:0]" +CHECKSUM: "2301929872 1660332954" +INSTANCE: tb.dut.u_clk_main_kmac_trans.u_idle_cnt +ANNOTATION: "[UNR] Input tied to a constant, and unr doesn't detect it." +Toggle step_i "net step_i[3:0]" +CHECKSUM: "2301929872 1660332954" +INSTANCE: tb.dut.u_clk_main_otbn_trans.u_idle_cnt +ANNOTATION: "[UNR] Input tied to a constant, and unr doesn't detect it." +Toggle step_i "net step_i[3:0]" +CHECKSUM: "953655365 3155586170" +INSTANCE: tb.dut +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.aon_powerup "logic cg_en_o.aon_powerup[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.usb_powerup "logic cg_en_o.usb_powerup[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.main_powerup "logic cg_en_o.main_powerup[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.io_powerup "logic cg_en_o.io_powerup[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.io_div2_powerup "logic cg_en_o.io_div2_powerup[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.io_div4_powerup "logic cg_en_o.io_div4_powerup[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.aon_peri "logic cg_en_o.aon_peri[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.aon_timers "logic cg_en_o.aon_timers[3:0]" +ANNOTATION: "[UNR] This is driven by a constant, and unr doesn't detect it." +Toggle cg_en_o.aon_secure "logic cg_en_o.aon_secure[3:0]" diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_unr_excl.el b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_unr_excl.el new file mode 100644 index 0000000000000..85e292d7a9fa5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_cov_unr_excl.el @@ -0,0 +1,200 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generated UNR file from Synopsys UNR tool with security modules being +// black-boxed. + +//================================================== +// This file contains the Excluded objects +// Generated By User: maturana +// Format Version: 2 +// Date: Wed Jan 18 15:59:24 2023 +// ExclMode: default +//================================================== +CHECKSUM: "2972535896 3274445021" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_aes_val +ANNOTATION: "VC_COV_UNR" +Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (1 "0") +CHECKSUM: "2972535896 3274445021" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_hmac_val +ANNOTATION: "VC_COV_UNR" +Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (1 "0") +CHECKSUM: "2972535896 3274445021" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_kmac_val +ANNOTATION: "VC_COV_UNR" +Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (1 "0") +CHECKSUM: "2972535896 3274445021" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_otbn_val +ANNOTATION: "VC_COV_UNR" +Condition 1 "2397158838" "(wr_en ? wr_data : qs) 1 -1" (1 "0") +CHECKSUM: "2972535896 3554514034" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_aes_val +ANNOTATION: "VC_COV_UNR" +Branch 0 "3759852512" "wr_en" (1) "wr_en 0" +ANNOTATION: "VC_COV_UNR" +Branch 1 "1017474648" "(!rst_ni)" (2) "(!rst_ni) 0,0" +CHECKSUM: "2972535896 3554514034" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_hmac_val +ANNOTATION: "VC_COV_UNR" +Branch 0 "3759852512" "wr_en" (1) "wr_en 0" +ANNOTATION: "VC_COV_UNR" +Branch 1 "1017474648" "(!rst_ni)" (2) "(!rst_ni) 0,0" +CHECKSUM: "2972535896 3554514034" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_kmac_val +ANNOTATION: "VC_COV_UNR" +Branch 0 "3759852512" "wr_en" (1) "wr_en 0" +ANNOTATION: "VC_COV_UNR" +Branch 1 "1017474648" "(!rst_ni)" (2) "(!rst_ni) 0,0" +CHECKSUM: "2972535896 3554514034" +INSTANCE: tb.dut.u_reg.u_clk_hints_status_clk_main_otbn_val +ANNOTATION: "VC_COV_UNR" +Branch 0 "3759852512" "wr_en" (1) "wr_en 0" +ANNOTATION: "VC_COV_UNR" +Branch 1 "1017474648" "(!rst_ni)" (2) "(!rst_ni) 0,0" +CHECKSUM: "215202837 3193272610" +INSTANCE: tb.dut.u_io_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk +ANNOTATION: "VC_COV_UNR" +Branch 0 "3003057152" "(!rst_ni)" (4) "(!rst_ni) 0,0,0,0" +CHECKSUM: "215202837 3193272610" +INSTANCE: tb.dut.u_io_div2_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk +ANNOTATION: "VC_COV_UNR" +Branch 0 "3003057152" "(!rst_ni)" (4) "(!rst_ni) 0,0,0,0" +CHECKSUM: "215202837 3193272610" +INSTANCE: tb.dut.u_io_div4_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk +ANNOTATION: "VC_COV_UNR" +Branch 0 "3003057152" "(!rst_ni)" (4) "(!rst_ni) 0,0,0,0" +CHECKSUM: "215202837 3193272610" +INSTANCE: tb.dut.u_main_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk +ANNOTATION: "VC_COV_UNR" +Branch 0 "3003057152" "(!rst_ni)" (4) "(!rst_ni) 0,0,0,0" +CHECKSUM: "215202837 3193272610" +INSTANCE: tb.dut.u_usb_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk +ANNOTATION: "VC_COV_UNR" +Branch 0 "3003057152" "(!rst_ni)" (4) "(!rst_ni) 0,0,0,0" +CHECKSUM: "2970503351 1213720317" +INSTANCE: tb.dut.u_reg +ANNOTATION: "VC_COV_UNR" +Condition 53 "2949805610" "(io_io_meas_ctrl_en_we & io_io_meas_ctrl_en_regwen) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 55 "3453311186" "(io_div2_io_div2_meas_ctrl_en_we & io_div2_io_div2_meas_ctrl_en_regwen) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 57 "3988383834" "(io_div4_io_div4_meas_ctrl_en_we & io_div4_io_div4_meas_ctrl_en_regwen) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 59 "1995093715" "(main_main_meas_ctrl_en_we & main_main_meas_ctrl_en_regwen) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 61 "2462107587" "(usb_usb_meas_ctrl_en_we & usb_usb_meas_ctrl_en_regwen) 1 -1" (1 "01") +CHECKSUM: "74367784 3785313510" +INSTANCE: tb.dut.u_reg.u_reg_if +ANNOTATION: "VC_COV_UNR" +Condition 18 "3340270436" "(addr_align_err | malformed_meta_err | tl_err | instr_error | intg_error) 1 -1" (5 "01000") +CHECKSUM: "2928260248 4109606122" +INSTANCE: tb.dut.u_reg.u_io_meas_ctrl_en_cdc.u_arb +ANNOTATION: "VC_COV_UNR" +Condition 5 "593451913" "(((!gen_wr_req.dst_req)) && gen_wr_req.dst_lat_d) 1 -1" (1 "01") +CHECKSUM: "2928260248 4109606122" +INSTANCE: tb.dut.u_reg.u_io_div2_meas_ctrl_en_cdc.u_arb +ANNOTATION: "VC_COV_UNR" +Condition 5 "593451913" "(((!gen_wr_req.dst_req)) && gen_wr_req.dst_lat_d) 1 -1" (1 "01") +CHECKSUM: "2928260248 4109606122" +INSTANCE: tb.dut.u_reg.u_io_div4_meas_ctrl_en_cdc.u_arb +ANNOTATION: "VC_COV_UNR" +Condition 5 "593451913" "(((!gen_wr_req.dst_req)) && gen_wr_req.dst_lat_d) 1 -1" (1 "01") +CHECKSUM: "2928260248 4109606122" +INSTANCE: tb.dut.u_reg.u_main_meas_ctrl_en_cdc.u_arb +ANNOTATION: "VC_COV_UNR" +Condition 5 "593451913" "(((!gen_wr_req.dst_req)) && gen_wr_req.dst_lat_d) 1 -1" (1 "01") +CHECKSUM: "2928260248 4109606122" +INSTANCE: tb.dut.u_reg.u_usb_meas_ctrl_en_cdc.u_arb +ANNOTATION: "VC_COV_UNR" +Condition 5 "593451913" "(((!gen_wr_req.dst_req)) && gen_wr_req.dst_lat_d) 1 -1" (1 "01") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_reg.u_io_meas_ctrl_en_cdc.u_arb.gen_wr_req.u_dst_update_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_reg.u_io_div2_meas_ctrl_en_cdc.u_arb.gen_wr_req.u_dst_update_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_reg.u_io_div4_meas_ctrl_en_cdc.u_arb.gen_wr_req.u_dst_update_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_reg.u_main_meas_ctrl_en_cdc.u_arb.gen_wr_req.u_dst_update_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_reg.u_usb_meas_ctrl_en_cdc.u_arb.gen_wr_req.u_dst_update_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_io_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk.u_ref_timeout +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_io_meas.u_err_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_io_div2_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk.u_ref_timeout +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_io_div2_meas.u_err_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_io_div4_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk.u_ref_timeout +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_io_div4_meas.u_err_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_main_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk.u_ref_timeout +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_main_meas.u_err_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_usb_meas.u_meas.gen_clk_timeout_chk.u_timeout_ref_to_clk.u_ref_timeout +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") +CHECKSUM: "704952876 1147758610" +INSTANCE: tb.dut.u_usb_meas.u_err_sync +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (1 "01") +ANNOTATION: "VC_COV_UNR" +Condition 2 "700807773" "(dst_req_o & dst_ack_i) 1 -1" (2 "10") diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_tgl_excl.cfg b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_tgl_excl.cfg new file mode 100644 index 0000000000000..075afb2c4624c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/cov/clkmgr_tgl_excl.cfg @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +//====================================================================== +// This file contains outputs of clkmgr tied to constants. +//====================================================================== + +-module_node clkmgr cg_en_o.io_div4_powerup +-module_node clkmgr cg_en_o.aon_powerup +-module_node clkmgr cg_en_o.main_powerup +-module_node clkmgr cg_en_o.io_powerup +-module_node clkmgr cg_en_o.usb_powerup +-module_node clkmgr cg_en_o.io_div2_powerup +-module_node clkmgr cg_en_o.aon_secure +-module_node clkmgr cg_en_o.aon_peri +-module_node clkmgr cg_en_o.aon_timers diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/doc/tb.svg b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/doc/tb.svg new file mode 100644 index 0000000000000..3f48ecc3accf2 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/doc/tb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_csrs_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_csrs_if.sv new file mode 100644 index 0000000000000..df369fdf59cfb --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_csrs_if.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This interface is used to sample some csr values directly from the rtl +// to avoid any confusion. + +interface clkmgr_csrs_if ( + input logic clk, + input logic [10:0] recov_err_csr, + input logic [2:0] fatal_err_csr, + input logic [3:0] clk_enables, + input logic [3:0] clk_hints +); + +clocking csrs_cb @(posedge clk); + input recov_err_csr; + input fatal_err_csr; + input clk_enables; + input clk_hints; +endclocking + +endinterface : clkmgr_csrs_if diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.core new file mode 100644 index 0000000000000..dc69c9c6605f6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.core @@ -0,0 +1,50 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr_env:0.1 +description: "CLKMGR DV UVM environment" +filesets: + files_dv: + depend: + - lowrisc:dv:ralgen + - lowrisc:dv:cip_lib + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + - lowrisc:opentitan:top_englishbreakfast_clkmgr_pkg + - lowrisc:constants:top_englishbreakfast_top_pkg + files: + - clkmgr_csrs_if.sv + - clkmgr_env_pkg.sv + - clkmgr_env_cfg.sv: {is_include_file: true} + - clkmgr_env_cov.sv: {is_include_file: true} + - clkmgr_virtual_sequencer.sv: {is_include_file: true} + - clkmgr_scoreboard.sv: {is_include_file: true} + - clkmgr_env.sv: {is_include_file: true} + - seq_lib/clkmgr_vseq_list.sv: {is_include_file: true} + - seq_lib/clkmgr_base_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_clk_status_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_common_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_extclk_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_frequency_timeout_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_frequency_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_peri_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_regwen_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_smoke_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_stress_all_vseq.sv: {is_include_file: true} + - seq_lib/clkmgr_trans_vseq.sv: {is_include_file: true} + - clkmgr_if.sv + file_type: systemVerilogSource + +generate: + ral: + generator: ralgen + parameters: + name: clkmgr + ip_hjson: ../../data/clkmgr.hjson + +targets: + default: + filesets: + - files_dv + generate: + - ral diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.sv new file mode 100644 index 0000000000000..e730a933c134c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env.sv @@ -0,0 +1,67 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class clkmgr_env extends cip_base_env #( + .CFG_T (clkmgr_env_cfg), + .COV_T (clkmgr_env_cov), + .VIRTUAL_SEQUENCER_T(clkmgr_virtual_sequencer), + .SCOREBOARD_T (clkmgr_scoreboard) +); + `uvm_component_utils(clkmgr_env) + + `uvm_component_new + + function void build_phase(uvm_phase phase); + super.build_phase(phase); + + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "main_clk_rst_vif", cfg.main_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get main_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "io_clk_rst_vif", cfg.io_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get io_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "usb_clk_rst_vif", cfg.usb_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get usb_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "aon_clk_rst_vif", cfg.aon_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get aon_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "root_io_clk_rst_vif", cfg.root_io_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get root_io_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "root_main_clk_rst_vif", cfg.root_main_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get root_main_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "root_usb_clk_rst_vif", cfg.root_usb_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get root_usb_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clkmgr_if)::get(this, "", "clkmgr_vif", cfg.clkmgr_vif)) begin + `uvm_fatal(`gfn, "failed to get clkmgr_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clkmgr_csrs_if)::get( + this, "", "clkmgr_csrs_vif", cfg.clkmgr_csrs_vif + )) begin + `uvm_fatal(`gfn, "failed to get clkmgr_csrs_vif from uvm_config_db") + end + endfunction + + function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + endfunction + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cfg.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cfg.sv new file mode 100644 index 0000000000000..9477e59af048a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cfg.sv @@ -0,0 +1,45 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class clkmgr_env_cfg extends cip_base_env_cfg #( + .RAL_T(clkmgr_reg_block) +); + + // This scoreboard handle is used to flag expected errors. + clkmgr_scoreboard scoreboard; + + // ext component cfgs + + // ext interfaces + virtual clkmgr_if clkmgr_vif; + virtual clkmgr_csrs_if clkmgr_csrs_vif; + virtual clk_rst_if main_clk_rst_vif; + virtual clk_rst_if io_clk_rst_vif; + virtual clk_rst_if usb_clk_rst_vif; + virtual clk_rst_if aon_clk_rst_vif; + + virtual clk_rst_if root_io_clk_rst_vif; + virtual clk_rst_if root_main_clk_rst_vif; + virtual clk_rst_if root_usb_clk_rst_vif; + + `uvm_object_utils_begin(clkmgr_env_cfg) + `uvm_object_utils_end + + `uvm_object_new + + virtual function void initialize(bit [31:0] csr_base_addr = '1); + list_of_alerts = clkmgr_env_pkg::LIST_OF_ALERTS; + super.initialize(csr_base_addr); + + // This is for the integrity error test. + tl_intg_alert_name = "fatal_fault"; + tl_intg_alert_fields[ral.fatal_err_code.reg_intg] = 1; + m_tl_agent_cfg.max_outstanding_req = 1; + + // shadow registers + shadow_update_err_status_fields[ral.recov_err_code.shadow_update_err] = 1; + shadow_storage_err_status_fields[ral.fatal_err_code.shadow_storage_err] = 1; + endfunction + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cov.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cov.sv new file mode 100644 index 0000000000000..a28c2bdf10e02 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_cov.sv @@ -0,0 +1,190 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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. + */ + +// Wrapper class for peripheral clock covergroup. +class clkmgr_peri_cg_wrap; + // This covergroup collects signals affecting peripheral clock. + covergroup peri_cg(string name) with function sample (bit enable, bit ip_clk_en, bit scanmode); + option.name = name; + option.per_instance = 1; + + csr_enable_cp: coverpoint enable; + ip_clk_en_cp: coverpoint ip_clk_en; + scanmode_cp: coverpoint scanmode; + + peri_cross: cross csr_enable_cp, ip_clk_en_cp, scanmode_cp{ + // The enable CSRs cannot be manipulated in low power mode. + ignore_bins ignore_enable_off = peri_cross with (csr_enable_cp == 1 && ip_clk_en_cp == 0); + } + endgroup + + function new(string name); + peri_cg = new(name); + endfunction + + function void sample (bit enable, bit ip_clk_en, bit scanmode); + peri_cg.sample(enable, ip_clk_en, scanmode); + endfunction +endclass + +// Wrapper class for transactional unit clock covergroup. +class clkmgr_trans_cg_wrap; + // This covergroup collects signals affecting transactional clock. + covergroup trans_cg( + string name + ) with function sample ( + bit hint, bit ip_clk_en, bit scanmode, bit idle + ); + option.name = name; + option.per_instance = 1; + + csr_hint_cp: coverpoint hint; + ip_clk_en_cp: coverpoint ip_clk_en; + scanmode_cp: coverpoint scanmode; + idle_cp: coverpoint idle; + + trans_cross: cross csr_hint_cp, ip_clk_en_cp, scanmode_cp, idle_cp{ + // If the clock is disabled the unit must be idle. + ignore_bins ignore_idle_off = trans_cross with (idle_cp == 0 && ip_clk_en_cp == 0); + // The hint CSRs cannot be manipulated in low power mode. + ignore_bins ignore_enable_off = trans_cross with (csr_hint_cp == 1 && ip_clk_en_cp == 0); + } + endgroup + + function new(string name); + trans_cg = new(name); + endfunction + + function void sample (bit hint, bit ip_clk_en, bit scanmode, bit idle); + trans_cg.sample(hint, ip_clk_en, scanmode, idle); + endfunction +endclass + +// Wrapper class for frequency measurement covergroup. +class freq_measure_cg_wrap; + // This covergroup collects outcomes of clock frequency measurements. + covergroup freq_measure_cg( + string name + ) with function sample ( + bit okay, bit slow, bit fast, bit timeout + ); + option.name = name; + option.per_instance = 1; + + okay_cp: coverpoint okay; + slow_cp: coverpoint slow; + fast_cp: coverpoint fast; + timeout_cp: coverpoint timeout; + endgroup + + function new(string name); + freq_measure_cg = new(name); + endfunction + + function void sample (bit okay, bit slow, bit fast, bit timeout); + freq_measure_cg.sample(okay, slow, fast, timeout); + endfunction +endclass + +class clkmgr_env_cov extends cip_base_env_cov #( + .CFG_T(clkmgr_env_cfg) +); + `uvm_component_utils(clkmgr_env_cov) + + // the base class provides the following handles for use: + // clkmgr_env_cfg: cfg + + // These covergroups collect signals affecting peripheral clocks. + clkmgr_peri_cg_wrap peri_cg_wrap[NUM_PERI]; + + // These covergroups collect signals affecting transactional clocks. + clkmgr_trans_cg_wrap trans_cg_wrap[NUM_TRANS]; + + // These covergroups collect outcomes of clock frequency measurements. + freq_measure_cg_wrap freq_measure_cg_wrap[5]; + + // This embeded covergroup collects coverage for the external clock functionality. + covergroup extclk_cg with function sample ( + bit csr_sel, bit csr_low_speed, bit hw_debug_en, bit byp_req, bit scanmode + ); + csr_sel_cp: coverpoint csr_sel; + csr_low_speed_cp: coverpoint csr_low_speed; + hw_debug_en_cp: coverpoint hw_debug_en; + byp_req_cp: coverpoint byp_req; + scanmode_cp: coverpoint scanmode; + + extclk_cross: cross csr_sel_cp, csr_low_speed_cp, hw_debug_en_cp, byp_req_cp, scanmode_cp; + endgroup + + // This collects coverage for recoverable errors. + covergroup recov_err_cg with function sample ( + bit usb_timeout, + bit main_timeout, + bit io_div4_timeout, + bit io_div2_timeout, + bit io_timeout, + bit usb_measure, + bit main_measure, + bit io_div4_measure, + bit io_div2_measure, + bit io_measure, + bit shadow_update + ); + shadow_update_cp: coverpoint shadow_update; + io_measure_cp: coverpoint io_measure; + io_div2_measure_cp: coverpoint io_div2_measure; + io_div4_measure_cp: coverpoint io_div4_measure; + main_measure_cp: coverpoint main_measure; + usb_measure_cp: coverpoint usb_measure; + io_timeout_cp: coverpoint io_timeout; + io_div2_timeout_cp: coverpoint io_div2_timeout; + io_div4_timeout_cp: coverpoint io_div4_timeout; + main_timeout_cp: coverpoint main_timeout; + usb_timeout_cp: coverpoint usb_timeout; + endgroup + + // This collects coverage for fatal errors. + covergroup fatal_err_cg with function sample ( + bit shadow_storage, bit idle_cnt, bit reg_integ + ); + reg_integ_cp: coverpoint reg_integ; + idle_cnt_cp: coverpoint idle_cnt; + shadow_storage_cp: coverpoint shadow_storage; + endgroup + + function new(string name, uvm_component parent); + super.new(name, parent); + // The peripheral covergoups. + foreach (peri_cg_wrap[i]) begin + clkmgr_env_pkg::peri_e peri = clkmgr_env_pkg::peri_e'(i); + peri_cg_wrap[i] = new(peri.name); + end + // The transactional covergroups. + foreach (trans_cg_wrap[i]) begin + clkmgr_env_pkg::trans_e trans = clkmgr_env_pkg::trans_e'(i); + trans_cg_wrap[i] = new(trans.name); + end + foreach (ExpectedCounts[i]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(i); + freq_measure_cg_wrap[i] = new(clk_mesr.name); + end + extclk_cg = new(); + recov_err_cg = new(); + fatal_err_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/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_pkg.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_pkg.sv new file mode 100644 index 0000000000000..9ea95973da389 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_env_pkg.sv @@ -0,0 +1,151 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package clkmgr_env_pkg; + // dep packages + import uvm_pkg::*; + import sec_cm_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 clkmgr_ral_pkg::*; + import prim_mubi_pkg::mubi4_t; + import prim_mubi_pkg::MuBi4False; + import prim_mubi_pkg::MuBi4True; + + import lc_ctrl_pkg::lc_tx_t; + import lc_ctrl_pkg::On; + import lc_ctrl_pkg::Off; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + typedef virtual clkmgr_if clkmgr_vif; + typedef virtual clk_rst_if clk_rst_vif; + + // parameters + parameter int NUM_PERI = 4; + parameter int NUM_TRANS = 4; + + typedef logic [NUM_PERI-1:0] peri_enables_t; + typedef logic [NUM_TRANS-1:0] hintables_t; + typedef mubi4_t [NUM_TRANS-1:0] mubi_hintables_t; + parameter mubi_hintables_t IdleAllBusy = {NUM_TRANS{prim_mubi_pkg::MuBi4False}}; + + parameter int MainClkHz = 100_000_000; + parameter int IoClkHz = 96_000_000; + parameter int UsbClkHz = 48_000_000; + parameter int AonClkHz = 200_000; + parameter int FakeAonClkHz = 7_000_000; + + // alerts + parameter uint NUM_ALERTS = 2; + parameter string LIST_OF_ALERTS[] = {"recov_fault", "fatal_fault"}; + + // types + + // Forward class decl to enable cfg to hold a scoreboard handle. + typedef class clkmgr_scoreboard; + + // The enum values for these match the bit order in the CSRs. + typedef enum int { + PeriDiv4, + PeriDiv2, + PeriUsb, + PeriIo + } peri_e; + typedef struct packed { + logic usb_peri_en; + logic io_peri_en; + logic io_div2_peri_en; + logic io_div4_peri_en; + } clk_enables_t; + + typedef enum int { + TransAes, + TransHmac, + TransKmac, + TransOtbn + } trans_e; + typedef struct packed { + logic otbn_main; + logic kmac; + logic hmac; + logic aes; + } clk_hints_t; + + typedef struct { + logic valid; + logic slow; + logic fast; + } freq_measurement_t; + + // These are ordered per the bits in the recov_err_code register. + typedef enum int { + ClkMesrIo, + ClkMesrIoDiv2, + ClkMesrIoDiv4, + ClkMesrMain, + ClkMesrUsb + } clk_mesr_e; + + // Mubi test mode + typedef enum int { + ClkmgrMubiNone = 0, + ClkmgrMubiIdle = 1, + ClkmgrMubiLcCtrl = 2, + ClkmgrMubiLcHand = 3, + ClkmgrMubiHand = 4, + ClkmgrMubiDiv = 5 + } clkmgr_mubi_e; + + // This is to examine separately the measurement and timeout recoverable error bits. + typedef logic [ClkMesrUsb:0] recov_bits_t; + + typedef struct packed { + recov_bits_t timeouts; + recov_bits_t measures; + logic shadow_update; + } clkmgr_recov_err_t; + + // These must be after the declaration of clk_mesr_e for sizing. + parameter int ClkInHz[ClkMesrUsb+1] = {IoClkHz, IoClkHz / 2, IoClkHz / 4, MainClkHz, UsbClkHz}; + + parameter int ExpectedCounts[ClkMesrUsb+1] = { + ClkInHz[ClkMesrIo] / AonClkHz - 1, + ClkInHz[ClkMesrIoDiv2] / AonClkHz - 1, + ClkInHz[ClkMesrIoDiv4] / AonClkHz - 1, + ClkInHz[ClkMesrMain] / AonClkHz - 1, + ClkInHz[ClkMesrUsb] / AonClkHz - 1 + }; + + // functions + function automatic void print_hintable(hintables_t tbl); + foreach (tbl[i]) begin + `uvm_info("HINTBL", $sformatf("entry%0d : %b", i, tbl[i]), UVM_LOW) + end + endfunction : print_hintable + + function automatic void print_mubi_hintable(mubi_hintables_t tbl); + string val = "INVALID"; + foreach (tbl[i]) begin + if (tbl[i].name != "") val = tbl[i].name; + `uvm_info("MUBIHINTBL", $sformatf("entry%0d : %s", i, val), UVM_LOW) + end + endfunction : print_mubi_hintable + + // package sources + `include "clkmgr_env_cfg.sv" + `include "clkmgr_env_cov.sv" + `include "clkmgr_virtual_sequencer.sv" + `include "clkmgr_scoreboard.sv" + `include "clkmgr_env.sv" + `include "clkmgr_vseq_list.sv" + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_if.sv new file mode 100644 index 0000000000000..c6d8aa8d8f5dd --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_if.sv @@ -0,0 +1,362 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// clkmgr interface. + +interface clkmgr_if ( + input logic clk, + input logic rst_n, + input logic clk_main, + input logic rst_io_n, + input logic rst_main_n, + input logic rst_usb_n +); + import uvm_pkg::*; + import clkmgr_env_pkg::*; + + // The ports to the dut side. + + localparam int LcTxTWidth = $bits(lc_ctrl_pkg::lc_tx_t); + + // Encodes the transactional units that are idle. + mubi_hintables_t idle_i; + + // pwrmgr req contains ip_clk_en, set to enable the gated clocks. + pwrmgr_pkg::pwr_clk_req_t pwr_i; + + // outputs clk_status: transitions to 1 if all clocks are enabled, and + // to 0 when all are disabled. + pwrmgr_pkg::pwr_clk_rsp_t pwr_o; + + // scanmode_i == MuBi4True defeats all clock gating. + prim_mubi_pkg::mubi4_t scanmode_i; + + // Life cycle enables clock bypass functionality. + lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i; + + // Life cycle clock bypass request and clkmgr ack. + lc_ctrl_pkg::lc_tx_t lc_clk_byp_req; + lc_ctrl_pkg::lc_tx_t lc_clk_byp_ack; + // clkmgr clock bypass request for io clocks and ast ack: triggered by lc_clk_byp_req. + prim_mubi_pkg::mubi4_t io_clk_byp_req; + prim_mubi_pkg::mubi4_t io_clk_byp_ack; + // clkmgr clock bypass request for all clocks and ast ack: triggered by software. + prim_mubi_pkg::mubi4_t all_clk_byp_req; + prim_mubi_pkg::mubi4_t all_clk_byp_ack; + + prim_mubi_pkg::mubi4_t div_step_down_req; + + prim_mubi_pkg::mubi4_t jitter_en_o; + clkmgr_pkg::clkmgr_out_t clocks_o; + + prim_mubi_pkg::mubi4_t calib_rdy; + prim_mubi_pkg::mubi4_t hi_speed_sel; + + // Internal DUT signals. + // ICEBOX(lowrisc/opentitan#18379): This is a core env component (i.e. reusable entity) that + // makes hierarchical references into the DUT. A better strategy would be to bind this interface + // to the DUT in tb.sv and use relative paths instead. +`ifndef CLKMGR_HIER + `define CLKMGR_HIER tb.dut +`endif + + // The CSR values from the testbench side. + clk_enables_t clk_enables_csr; + always_comb + clk_enables_csr = '{ + usb_peri_en: `CLKMGR_HIER.reg2hw.clk_enables.clk_usb_peri_en.q, + io_peri_en: `CLKMGR_HIER.reg2hw.clk_enables.clk_io_peri_en.q, + io_div2_peri_en: `CLKMGR_HIER.reg2hw.clk_enables.clk_io_div2_peri_en.q, + io_div4_peri_en: `CLKMGR_HIER.reg2hw.clk_enables.clk_io_div4_peri_en.q + }; + + clk_hints_t clk_hints_csr; + always_comb + clk_hints_csr = '{ + otbn_main: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_otbn_hint.q, + kmac: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_kmac_hint.q, + hmac: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_hmac_hint.q, + aes: `CLKMGR_HIER.reg2hw.clk_hints.clk_main_aes_hint.q + }; + + clk_hints_t clk_hints_status_csr; + always_comb + clk_hints_status_csr = '{ + otbn_main: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_otbn_val_qs, + kmac: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_kmac_val_qs, + hmac: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_hmac_val_qs, + aes: `CLKMGR_HIER.u_reg.clk_hints_status_clk_main_aes_val_qs + }; + + prim_mubi_pkg::mubi4_t extclk_ctrl_csr_sel; + always_comb begin + extclk_ctrl_csr_sel = prim_mubi_pkg::mubi4_t'(`CLKMGR_HIER.reg2hw.extclk_ctrl.sel.q); + end + + prim_mubi_pkg::mubi4_t extclk_ctrl_csr_step_down; + always_comb begin + extclk_ctrl_csr_step_down = prim_mubi_pkg::mubi4_t'( + `CLKMGR_HIER.reg2hw.extclk_ctrl.hi_speed_sel.q); + end + + prim_mubi_pkg::mubi4_t jitter_enable_csr; + always_comb begin + jitter_enable_csr = prim_mubi_pkg::mubi4_t'(`CLKMGR_HIER.reg2hw.jitter_enable.q); + end + + freq_measurement_t io_freq_measurement; + logic io_timeout_err; + always @(posedge `CLKMGR_HIER.u_io_meas.u_meas.clk_i) begin + if (`CLKMGR_HIER.u_io_meas.u_meas.valid_o) begin + io_freq_measurement = '{valid: `CLKMGR_HIER.u_io_meas.u_meas.valid_o, + slow: `CLKMGR_HIER.u_io_meas.u_meas.slow_o, + fast: `CLKMGR_HIER.u_io_meas.u_meas.fast_o}; + `uvm_info("clkmgr_if", $sformatf("Sampled coverage for ClkMesrIo as %p", io_freq_measurement), + UVM_HIGH) + end + end + always_comb io_timeout_err = `CLKMGR_HIER.u_io_meas.timeout_err_o; + + freq_measurement_t io_div2_freq_measurement; + logic io_div2_timeout_err; + always @(posedge `CLKMGR_HIER.u_io_div2_meas.u_meas.clk_i) begin + if (`CLKMGR_HIER.u_io_div2_meas.u_meas.valid_o) begin + io_div2_freq_measurement = '{valid: `CLKMGR_HIER.u_io_div2_meas.u_meas.valid_o, + slow: `CLKMGR_HIER.u_io_div2_meas.u_meas.slow_o, + fast: `CLKMGR_HIER.u_io_div2_meas.u_meas.fast_o}; + `uvm_info("clkmgr_if", $sformatf( + "Sampled coverage for ClkMesrIoDiv2 as %p", io_div2_freq_measurement), UVM_HIGH) + end + end + always_comb io_div2_timeout_err = `CLKMGR_HIER.u_io_div2_meas.timeout_err_o; + + freq_measurement_t io_div4_freq_measurement; + logic io_div4_timeout_err; + always @(posedge `CLKMGR_HIER.u_io_div4_meas.u_meas.clk_i) begin + if (`CLKMGR_HIER.u_io_div4_meas.u_meas.valid_o) begin + io_div4_freq_measurement = '{valid: `CLKMGR_HIER.u_io_div4_meas.u_meas.valid_o, + slow: `CLKMGR_HIER.u_io_div4_meas.u_meas.slow_o, + fast: `CLKMGR_HIER.u_io_div4_meas.u_meas.fast_o}; + `uvm_info("clkmgr_if", $sformatf( + "Sampled coverage for ClkMesrIoDiv4 as %p", io_div4_freq_measurement), UVM_HIGH) + end + end + always_comb io_div4_timeout_err = `CLKMGR_HIER.u_io_div4_meas.timeout_err_o; + + freq_measurement_t main_freq_measurement; + logic main_timeout_err; + always @(posedge `CLKMGR_HIER.u_main_meas.u_meas.clk_i) begin + if (`CLKMGR_HIER.u_main_meas.u_meas.valid_o) begin + main_freq_measurement = '{valid: `CLKMGR_HIER.u_main_meas.u_meas.valid_o, + slow: `CLKMGR_HIER.u_main_meas.u_meas.slow_o, + fast: `CLKMGR_HIER.u_main_meas.u_meas.fast_o}; + `uvm_info("clkmgr_if", $sformatf( + "Sampled coverage for ClkMesrMain as %p", main_freq_measurement), UVM_HIGH) + end + end + always_comb main_timeout_err = `CLKMGR_HIER.u_main_meas.timeout_err_o; + + freq_measurement_t usb_freq_measurement; + logic usb_timeout_err; + always @(posedge `CLKMGR_HIER.u_usb_meas.u_meas.clk_i) begin + if (`CLKMGR_HIER.u_usb_meas.u_meas.valid_o) begin + usb_freq_measurement = '{valid: `CLKMGR_HIER.u_usb_meas.u_meas.valid_o, + slow: `CLKMGR_HIER.u_usb_meas.u_meas.slow_o, + fast: `CLKMGR_HIER.u_usb_meas.u_meas.fast_o}; + `uvm_info("clkmgr_if", $sformatf("Sampled coverage for ClkMesrUsb as %p", usb_freq_measurement + ), UVM_HIGH) + end + end + always_comb usb_timeout_err = `CLKMGR_HIER.u_usb_meas.timeout_err_o; + + function automatic void update_calib_rdy(prim_mubi_pkg::mubi4_t value); + calib_rdy = value; + endfunction + + function automatic void update_idle(mubi_hintables_t value); + idle_i = value; + endfunction + + function automatic void update_io_ip_clk_en(bit value); + pwr_i.io_ip_clk_en = value; + endfunction + + function automatic void update_main_ip_clk_en(bit value); + pwr_i.main_ip_clk_en = value; + endfunction + + function automatic void update_usb_ip_clk_en(bit value); + pwr_i.usb_ip_clk_en = value; + endfunction + + function automatic void update_scanmode(prim_mubi_pkg::mubi4_t value); + scanmode_i = value; + endfunction + + function automatic void update_lc_debug_en(lc_ctrl_pkg::lc_tx_t value); + lc_hw_debug_en_i = value; + endfunction + + function automatic void update_lc_clk_byp_req(lc_ctrl_pkg::lc_tx_t value); + lc_clk_byp_req = value; + endfunction + + function automatic void update_all_clk_byp_ack(prim_mubi_pkg::mubi4_t value); + `uvm_info("clkmgr_if", $sformatf("In clkmgr_if update_all_clk_byp_ack with %b", value), + UVM_MEDIUM) + all_clk_byp_ack = value; + endfunction + + function automatic void update_div_step_down_req(prim_mubi_pkg::mubi4_t value); + `uvm_info("clkmgr_if", $sformatf("In clkmgr_if update_div_step_down_req with %b", value), + UVM_MEDIUM) + div_step_down_req = value; + endfunction + + function automatic void update_io_clk_byp_ack(prim_mubi_pkg::mubi4_t value); + io_clk_byp_ack = value; + endfunction + + function automatic void force_high_starting_count(clk_mesr_e clk); + `uvm_info("clkmgr_if", $sformatf("Forcing count of %0s to all 1.", clk.name()), UVM_MEDIUM) + case (clk) + ClkMesrIo: `CLKMGR_HIER.u_io_meas.u_meas.cnt = '1; + ClkMesrIoDiv2: `CLKMGR_HIER.u_io_div2_meas.u_meas.cnt = '1; + ClkMesrIoDiv4: `CLKMGR_HIER.u_io_div4_meas.u_meas.cnt = '1; + ClkMesrMain: `CLKMGR_HIER.u_main_meas.u_meas.cnt = '1; + ClkMesrUsb: `CLKMGR_HIER.u_usb_meas.u_meas.cnt = '1; + default: ; + endcase + endfunction + + task automatic init(mubi_hintables_t idle, prim_mubi_pkg::mubi4_t scanmode, + lc_ctrl_pkg::lc_tx_t lc_debug_en = lc_ctrl_pkg::Off, + lc_ctrl_pkg::lc_tx_t lc_clk_byp_req = lc_ctrl_pkg::Off, + prim_mubi_pkg::mubi4_t calib_rdy = prim_mubi_pkg::MuBi4True); + `uvm_info("clkmgr_if", "In clkmgr_if init", UVM_MEDIUM) + update_calib_rdy(calib_rdy); + update_idle(idle); + update_lc_clk_byp_req(lc_clk_byp_req); + update_lc_debug_en(lc_debug_en); + update_scanmode(scanmode); + endtask + + // Pipeline signals that go through synchronizers with the target clock domain's clock. + // thus the PIPELINE_DEPTH is 2. + + // Use clocking blocks clocked by the target clock domain's clock to transfer relevant + // control signals back to the scoreboard. + localparam int PIPELINE_DEPTH = 2; + + // Pipelines and clocking blocks for peripheral clocks. + + logic [PIPELINE_DEPTH-1:0] clk_enable_div4_ffs; + logic [PIPELINE_DEPTH-1:0] ip_clk_en_div4_ffs; + always @(posedge clocks_o.clk_io_div4_powerup or negedge rst_io_n) begin + if (rst_io_n) begin + clk_enable_div4_ffs <= { + clk_enable_div4_ffs[PIPELINE_DEPTH-2:0], clk_enables_csr.io_div4_peri_en + }; + ip_clk_en_div4_ffs <= {ip_clk_en_div4_ffs[PIPELINE_DEPTH-2:0], pwr_i.io_ip_clk_en}; + end else begin + clk_enable_div4_ffs <= '0; + ip_clk_en_div4_ffs <= '0; + end + end + clocking peri_div4_cb @(posedge clocks_o.clk_io_div4_powerup or negedge rst_io_n); + input ip_clk_en = ip_clk_en_div4_ffs[PIPELINE_DEPTH-1]; + input clk_enable = clk_enable_div4_ffs[PIPELINE_DEPTH-1]; + endclocking + + logic [PIPELINE_DEPTH-1:0] clk_enable_div2_ffs; + logic [PIPELINE_DEPTH-1:0] ip_clk_en_div2_ffs; + always @(posedge clocks_o.clk_io_div2_powerup or negedge rst_io_n) begin + if (rst_io_n) begin + clk_enable_div2_ffs <= { + clk_enable_div2_ffs[PIPELINE_DEPTH-2:0], clk_enables_csr.io_div2_peri_en + }; + ip_clk_en_div2_ffs <= {ip_clk_en_div2_ffs[PIPELINE_DEPTH-2:0], pwr_i.io_ip_clk_en}; + end else begin + clk_enable_div2_ffs <= '0; + ip_clk_en_div2_ffs <= '0; + end + end + clocking peri_div2_cb @(posedge clocks_o.clk_io_div2_powerup or negedge rst_io_n); + input ip_clk_en = ip_clk_en_div2_ffs[PIPELINE_DEPTH-1]; + input clk_enable = clk_enable_div2_ffs[PIPELINE_DEPTH-1]; + endclocking + + logic [PIPELINE_DEPTH-1:0] clk_enable_io_ffs; + logic [PIPELINE_DEPTH-1:0] ip_clk_en_io_ffs; + always @(posedge clocks_o.clk_io_powerup or negedge rst_io_n) begin + if (rst_io_n) begin + clk_enable_io_ffs <= {clk_enable_io_ffs[PIPELINE_DEPTH-2:0], clk_enables_csr.io_peri_en}; + ip_clk_en_io_ffs <= {ip_clk_en_io_ffs[PIPELINE_DEPTH-2:0], pwr_i.io_ip_clk_en}; + end else begin + clk_enable_io_ffs <= '0; + ip_clk_en_io_ffs <= '0; + end + end + clocking peri_io_cb @(posedge clocks_o.clk_io_powerup or negedge rst_io_n); + input ip_clk_en = ip_clk_en_io_ffs[PIPELINE_DEPTH-1]; + input clk_enable = clk_enable_io_ffs[PIPELINE_DEPTH-1]; + endclocking + + logic [PIPELINE_DEPTH-1:0] clk_enable_usb_ffs; + logic [PIPELINE_DEPTH-1:0] ip_clk_en_usb_ffs; + always @(posedge clocks_o.clk_usb_powerup or negedge rst_usb_n) begin + if (rst_usb_n) begin + clk_enable_usb_ffs <= {clk_enable_usb_ffs[PIPELINE_DEPTH-2:0], clk_enables_csr.usb_peri_en}; + ip_clk_en_usb_ffs <= {ip_clk_en_usb_ffs[PIPELINE_DEPTH-2:0], pwr_i.usb_ip_clk_en}; + end else begin + clk_enable_usb_ffs <= '0; + ip_clk_en_usb_ffs <= '0; + end + end + clocking peri_usb_cb @(posedge clocks_o.clk_usb_powerup or negedge rst_usb_n); + input ip_clk_en = ip_clk_en_usb_ffs[PIPELINE_DEPTH-1]; + input clk_enable = clk_enable_usb_ffs[PIPELINE_DEPTH-1]; + endclocking + + // Pipelining and clocking block for transactional unit clocks. + logic [PIPELINE_DEPTH-1:0][NUM_TRANS-1:0] clk_hints_ffs; + logic [PIPELINE_DEPTH-1:0] trans_clk_en_ffs; + always @(posedge clocks_o.clk_main_powerup or negedge rst_main_n) begin + if (rst_main_n) begin + clk_hints_ffs <= {clk_hints_ffs[PIPELINE_DEPTH-2:0], clk_hints_csr}; + trans_clk_en_ffs <= {trans_clk_en_ffs[PIPELINE_DEPTH-2:0], pwr_i.main_ip_clk_en}; + end else begin + clk_hints_ffs <= '0; + trans_clk_en_ffs <= '0; + end + end + clocking trans_cb @(posedge clocks_o.clk_main_powerup or negedge rst_main_n); + input ip_clk_en = trans_clk_en_ffs[PIPELINE_DEPTH-1]; + input clk_hints = clk_hints_ffs[PIPELINE_DEPTH-1]; + input idle_i; + endclocking + + // Pipelining and clocking block for external clock bypass. The divisor control is + // triggered by an ast ack, which goes through synchronizers. + logic step_down_ff; + always @(posedge clk) begin + if (rst_n) begin + step_down_ff <= io_clk_byp_ack == prim_mubi_pkg::MuBi4True; + end else begin + step_down_ff <= 1'b0; + end + end + + clocking clk_cb @(posedge clk); + input calib_rdy; + input extclk_ctrl_csr_sel; + input extclk_ctrl_csr_step_down; + input lc_hw_debug_en_i; + input io_clk_byp_req; + input lc_clk_byp_req; + input step_down = step_down_ff; + input jitter_enable_csr; + endclocking + +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_scoreboard.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_scoreboard.sv new file mode 100644 index 0000000000000..820925dd9af5b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_scoreboard.sv @@ -0,0 +1,398 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// The scoreboard checks the jitter_an_o output, and processes CSR checks. +// It also samples most functional coverage groups. +class clkmgr_scoreboard extends cip_base_scoreboard #( + .CFG_T(clkmgr_env_cfg), + .RAL_T(clkmgr_reg_block), + .COV_T(clkmgr_env_cov) +); + `uvm_component_utils(clkmgr_scoreboard) + + // local variables + logic extclk_ctrl_regwen; + logic measure_ctrl_regwen; + + // TLM agent fifos + + // local queues to hold incoming packets pending comparison + + `uvm_component_new + + function void build_phase(uvm_phase phase); + super.build_phase(phase); + endfunction + + function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + cfg.scoreboard = this; + endfunction + + task run_phase(uvm_phase phase); + super.run_phase(phase); + fork + monitor_all_clk_byp(); + monitor_io_clk_byp(); + monitor_jitter_en(); + sample_peri_covs(); + sample_trans_covs(); + sample_freq_measurement_covs(); + sample_fatal_err_cov(); + sample_recov_err_cov(); + join_none + endtask + + task monitor_all_clk_byp(); + mubi4_t prev_all_clk_byp_req = MuBi4False; + forever + @cfg.clkmgr_vif.clk_cb begin + if (cfg.clkmgr_vif.all_clk_byp_req != prev_all_clk_byp_req) begin + `uvm_info(`gfn, $sformatf( + "Got all_clk_byp_req %s", + cfg.clkmgr_vif.all_clk_byp_req == MuBi4True ? "True" : "False" + ), UVM_MEDIUM) + prev_all_clk_byp_req = cfg.clkmgr_vif.all_clk_byp_req; + end + if (cfg.clk_rst_vif.rst_n) begin + if (cfg.en_cov) begin + cov.extclk_cg.sample(cfg.clkmgr_vif.clk_cb.extclk_ctrl_csr_sel == MuBi4True, + cfg.clkmgr_vif.clk_cb.extclk_ctrl_csr_step_down == MuBi4True, + cfg.clkmgr_vif.clk_cb.lc_hw_debug_en_i == On, + cfg.clkmgr_vif.clk_cb.lc_clk_byp_req == On, + cfg.clkmgr_vif.scanmode_i == MuBi4True); + end + end + end + endtask + + task monitor_io_clk_byp(); + lc_tx_t prev_lc_clk_byp_req = Off; + forever + @cfg.clkmgr_vif.clk_cb begin + if (cfg.clkmgr_vif.lc_clk_byp_req != prev_lc_clk_byp_req) begin + `uvm_info(`gfn, $sformatf( + "Got lc_clk_byp_req %s", cfg.clkmgr_vif.lc_clk_byp_req == On ? "On" : "Off"), + UVM_MEDIUM) + prev_lc_clk_byp_req = cfg.clkmgr_vif.lc_clk_byp_req; + end + if (cfg.clk_rst_vif.rst_n) begin + if (cfg.en_cov) begin + cov.extclk_cg.sample(cfg.clkmgr_vif.clk_cb.extclk_ctrl_csr_sel == MuBi4True, + cfg.clkmgr_vif.clk_cb.extclk_ctrl_csr_step_down == MuBi4True, + cfg.clkmgr_vif.clk_cb.lc_hw_debug_en_i == On, + cfg.clkmgr_vif.clk_cb.lc_clk_byp_req == On, + cfg.clkmgr_vif.scanmode_i == MuBi4True); + end + end + end + endtask + + task monitor_jitter_en(); + fork + forever + @cfg.clkmgr_vif.clk_cb begin + if (cfg.clk_rst_vif.rst_n) begin + @cfg.clkmgr_vif.jitter_enable_csr begin + cfg.clk_rst_vif.wait_clks(2); + `DV_CHECK_EQ(cfg.clkmgr_vif.jitter_en_o, cfg.clkmgr_vif.jitter_enable_csr, + "Mismatching jitter enable output") + end + end + end + forever + @cfg.clkmgr_vif.clk_cb begin + if (cfg.clk_rst_vif.rst_n) begin + @cfg.clkmgr_vif.jitter_en_o begin + cfg.clk_rst_vif.wait_clks(2); + `DV_CHECK_EQ(cfg.clkmgr_vif.jitter_en_o, cfg.clkmgr_vif.jitter_enable_csr, + "Mismatching jitter enable output") + end + end + end + join + endtask + + task sample_peri_covs(); + fork + forever + @cfg.clkmgr_vif.peri_io_cb begin + if (cfg.io_clk_rst_vif.rst_n && cfg.en_cov) begin + cov.peri_cg_wrap[PeriIo].sample(cfg.clkmgr_vif.peri_io_cb.clk_enable, + cfg.clkmgr_vif.peri_io_cb.ip_clk_en, + cfg.clkmgr_vif.scanmode_i == MuBi4True); + end + end + forever + @cfg.clkmgr_vif.peri_div2_cb begin + if (cfg.io_clk_rst_vif.rst_n && cfg.en_cov) begin + cov.peri_cg_wrap[PeriDiv2].sample(cfg.clkmgr_vif.peri_div2_cb.clk_enable, + cfg.clkmgr_vif.peri_div2_cb.ip_clk_en, + cfg.clkmgr_vif.scanmode_i == MuBi4True); + end + end + forever + @cfg.clkmgr_vif.peri_div4_cb begin + if (cfg.io_clk_rst_vif.rst_n && cfg.en_cov) begin + cov.peri_cg_wrap[PeriDiv4].sample(cfg.clkmgr_vif.peri_div4_cb.clk_enable, + cfg.clkmgr_vif.peri_div4_cb.ip_clk_en, + cfg.clkmgr_vif.scanmode_i == MuBi4True); + end + end + forever + @cfg.clkmgr_vif.peri_usb_cb begin + if (cfg.io_clk_rst_vif.rst_n && cfg.en_cov) begin + cov.peri_cg_wrap[PeriUsb].sample(cfg.clkmgr_vif.peri_usb_cb.clk_enable, + cfg.clkmgr_vif.peri_usb_cb.ip_clk_en, + cfg.clkmgr_vif.scanmode_i == MuBi4True); + end + end + join + endtask + + task sample_trans_cov(int trans_index); + logic hint, clk_en, idle, src_rst_en; + trans_e trans = trans_e'(trans_index); + forever begin + @cfg.clkmgr_vif.trans_cb; + hint = cfg.clkmgr_vif.trans_cb.clk_hints[trans_index]; + idle = cfg.clkmgr_vif.trans_cb.idle_i[trans_index]; + clk_en = cfg.clkmgr_vif.trans_cb.ip_clk_en; + src_rst_en = cfg.main_clk_rst_vif.rst_n; + if (src_rst_en && cfg.en_cov) begin + logic scan_en = cfg.clkmgr_vif.scanmode_i == prim_mubi_pkg::MuBi4True; + cov.trans_cg_wrap[trans].sample(hint, clk_en, scan_en, idle); + end + end + endtask + + task sample_trans_covs(); + for (int i = 0; i < $bits(hintables_t); ++i) begin + fork + automatic int trans_index = i; + sample_trans_cov(trans_index); + join_none + end + endtask + + local task sample_freq_measurement_cov(clk_mesr_e clk, ref freq_measurement_t measurement, + logic timeout); + if (cfg.en_cov) begin + cov.freq_measure_cg_wrap[clk].sample(!measurement.slow && !measurement.fast, measurement.slow, + measurement.fast, timeout); + `uvm_info(`gfn, $sformatf( + "Cov for %0s: %0s", + clk.name(), + measurement.slow ? "slow" : measurement.fast ? "fast" : "okay" + ), UVM_MEDIUM) + measurement = '{default: 0}; + end + endtask + + task sample_freq_measurement_covs(); + fork + forever + @(posedge cfg.clkmgr_vif.io_freq_measurement.valid or + posedge cfg.clkmgr_vif.io_timeout_err) begin + sample_freq_measurement_cov(ClkMesrIo, cfg.clkmgr_vif.io_freq_measurement, + cfg.clkmgr_vif.io_timeout_err); + end + + forever + @(posedge cfg.clkmgr_vif.io_div2_freq_measurement.valid or + posedge cfg.clkmgr_vif.io_div2_timeout_err) begin + sample_freq_measurement_cov(ClkMesrIoDiv2, cfg.clkmgr_vif.io_div2_freq_measurement, + cfg.clkmgr_vif.io_div2_timeout_err); + + end + forever + @(posedge cfg.clkmgr_vif.io_div4_freq_measurement.valid or + posedge cfg.clkmgr_vif.io_div4_timeout_err) begin + sample_freq_measurement_cov(ClkMesrIoDiv4, cfg.clkmgr_vif.io_div4_freq_measurement, + cfg.clkmgr_vif.io_div4_timeout_err); + end + forever + @(posedge cfg.clkmgr_vif.main_freq_measurement.valid or + posedge cfg.clkmgr_vif.main_timeout_err) begin + sample_freq_measurement_cov(ClkMesrMain, cfg.clkmgr_vif.main_freq_measurement, + cfg.clkmgr_vif.main_timeout_err); + end + forever + @(posedge cfg.clkmgr_vif.usb_freq_measurement.valid or + posedge cfg.clkmgr_vif.usb_timeout_err) begin + sample_freq_measurement_cov(ClkMesrUsb, cfg.clkmgr_vif.usb_freq_measurement, + cfg.clkmgr_vif.usb_timeout_err); + end + join_none + endtask + + task sample_recov_err_cov(); + fork + forever + @cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr if (cfg.en_cov) begin + cov.recov_err_cg.sample( + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[10], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[9], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[8], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[7], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[6], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[5], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[4], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[3], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[2], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[1], + cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr[0]); + `uvm_info(`gfn, $sformatf( + "Recoverable errors sampled: 0x%x", cfg.clkmgr_csrs_vif.csrs_cb.recov_err_csr), + UVM_MEDIUM) + end + join_none + endtask + + task sample_fatal_err_cov(); + fork + forever + @cfg.clkmgr_csrs_vif.csrs_cb.fatal_err_csr if (cfg.en_cov) begin + cov.fatal_err_cg.sample( + cfg.clkmgr_csrs_vif.csrs_cb.fatal_err_csr[2], + cfg.clkmgr_csrs_vif.csrs_cb.fatal_err_csr[1], + cfg.clkmgr_csrs_vif.csrs_cb.fatal_err_csr[0]); + `uvm_info(`gfn, $sformatf( + "Fatal errors sampled: 0x%x", cfg.clkmgr_csrs_vif.csrs_cb.fatal_err_csr), + UVM_MEDIUM) + end + join_none + endtask + + virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name); + uvm_reg csr; + bit do_read_check = 1'b1; + 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); + + string access_str = write ? "write" : "read"; + string channel_str = channel == AddrChannel ? "address" : "data"; + + // 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, update prediction right away. + if (addr_phase_write) begin + `uvm_info(`gfn, $sformatf("Writing 0x%0x to %s", item.a_data, csr.get_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 + "alert_test": begin + // FIXME + end + "extclk_ctrl_regwen": begin + if (addr_phase_write) extclk_ctrl_regwen = item.a_data; + end + "extclk_ctrl": begin + typedef logic [2*$bits(prim_mubi_pkg::mubi4_t) - 1:0] extclk_ctrl_t; + if (addr_phase_write && extclk_ctrl_regwen) begin + `DV_CHECK_EQ(extclk_ctrl_t'(item.a_data), { + cfg.clkmgr_vif.extclk_ctrl_csr_step_down, cfg.clkmgr_vif.extclk_ctrl_csr_sel + }) + end + end + "extclk_status": begin + do_read_check = 1'b0; + end + "jitter_regwen": begin + end + "jitter_enable": begin + if (addr_phase_write && `gmv(ral.jitter_regwen)) begin + `DV_CHECK_EQ(prim_mubi_pkg::mubi4_t'(item.a_data), cfg.clkmgr_vif.jitter_enable_csr) + end + end + "clk_enables": begin + if (addr_phase_write) begin + `DV_CHECK_EQ(clk_enables_t'(item.a_data), cfg.clkmgr_vif.clk_enables_csr) + end + end + "clk_hints": begin + // Clearing a hint sets an expectation for the status to transition to zero. + if (addr_phase_write) begin + `DV_CHECK_EQ(clk_hints_t'(item.a_data), cfg.clkmgr_vif.clk_hints_csr) + end + end + "clk_hints_status": begin + // The status will respond to the hint once the target unit is idle. We check it in + // the sequence. + do_read_check = 1'b0; + end + "measure_ctrl_regwen": begin + if (addr_phase_write) measure_ctrl_regwen = item.a_data; + end + "io_meas_ctrl_en": begin + end + "io_div2_meas_ctrl_en": begin + end + "io_div4_meas_ctrl_en": begin + end + "main_meas_ctrl_en": begin + end + "usb_meas_ctrl_en": begin + end + "io_meas_ctrl_shadowed": begin + end + "io_div2_meas_ctrl_shadowed": begin + end + "io_div4_meas_ctrl_shadowed": begin + end + "main_meas_ctrl_shadowed": begin + end + "usb_meas_ctrl_shadowed": begin + end + "recov_err_code": begin + do_read_check = 1'b0; + end + "fatal_err_code": begin + 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%0x from %s", item.d_data, csr.get_name()), UVM_MEDIUM) + 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 + extclk_ctrl_regwen = ral.extclk_ctrl_regwen.get_reset(); + measure_ctrl_regwen = ral.measure_ctrl_regwen.get_reset(); + 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/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_virtual_sequencer.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_virtual_sequencer.sv new file mode 100644 index 0000000000000..8239de0df3ab0 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/clkmgr_virtual_sequencer.sv @@ -0,0 +1,14 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class clkmgr_virtual_sequencer extends cip_base_virtual_sequencer #( + .CFG_T(clkmgr_env_cfg), + .COV_T(clkmgr_env_cov) +); + `uvm_component_utils(clkmgr_virtual_sequencer) + + + `uvm_component_new + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv new file mode 100644 index 0000000000000..6b87fd054022d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_base_vseq.sv @@ -0,0 +1,456 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class clkmgr_base_vseq extends cip_base_vseq #( + .RAL_T (clkmgr_reg_block), + .CFG_T (clkmgr_env_cfg), + .COV_T (clkmgr_env_cov), + .VIRTUAL_SEQUENCER_T(clkmgr_virtual_sequencer) +); + + `uvm_object_utils(clkmgr_base_vseq) + `uvm_object_new + + // The extra cycles to wait after reset before starting any test, required so some CSRs (notably + // hints_status) are properly set when inputs go through synchronizers. + localparam int POST_APPLY_RESET_CYCLES = 10; + + // This delay is needed to allow updates to the idle inputs to go through synchronizers and + // counters. + localparam int IDLE_SYNC_CYCLES = 20; + + // This is the timeout for the various clk status outputs to react to their inputs. + localparam int CLK_STATUS_TIMEOUT_NS = 100_000; + + rand bit io_ip_clk_en; + rand bit main_ip_clk_en; + rand bit usb_ip_clk_en; + + rand mubi_hintables_t idle; + + // Override this from cip_base_vseq, since clkmgr tests are relatively short. + constraint rand_reset_delay_c { + rand_reset_delay dist { + [1 : 1000] :/ 1, + [1001 : 100_000] :/ 2, + [100_001 : 1_000_000] :/ 6 + }; + } + + mubi4_t scanmode; + int scanmode_on_weight = 8; + + mubi4_t extclk_ctrl_high_speed_sel; + mubi4_t extclk_ctrl_sel; + clkmgr_mubi_e mubi_mode; + + // This holds the necessary per measure control CSR info. + typedef struct { + string name; + dv_base_reg en; + dv_base_reg_field ctrl_hi; + dv_base_reg_field ctrl_lo; + } meas_ctrl_regs_t; + meas_ctrl_regs_t meas_ctrl_regs[clk_mesr_e]; + + virtual function void set_scanmode_on_low_weight(); + scanmode_on_weight = 2; + endfunction + + function void post_randomize(); + extclk_ctrl_high_speed_sel = get_rand_mubi4_val(6, 2, 2); + extclk_ctrl_sel = get_rand_mubi4_val(4, 2, 2); + scanmode = get_rand_mubi4_val(scanmode_on_weight, 4, 4); + `uvm_info(`gfn, $sformatf( + "randomize: extclk_ctrl_sel=0x%x, extclk_ctrl_high_speed_sel=0x%x, scanmode=0x%x", + extclk_ctrl_sel, + extclk_ctrl_high_speed_sel, + scanmode + ), UVM_MEDIUM) + super.post_randomize(); + endfunction + + virtual task initialize_on_start(); + `uvm_info(`gfn, "In clkmgr_if initialize_on_start", UVM_MEDIUM) + idle = {NUM_TRANS{MuBi4True}}; + scanmode = MuBi4False; + cfg.clkmgr_vif.init(.idle(idle), .scanmode(scanmode), .lc_debug_en(Off)); + io_ip_clk_en = 1'b1; + main_ip_clk_en = 1'b1; + usb_ip_clk_en = 1'b1; + start_ip_clocks(); + endtask + + // Converts to bool with strict true. + protected function hintables_t mubi_hintables_to_hintables(mubi_hintables_t mubi_hints); + hintables_t ret; + foreach (mubi_hints[i]) ret[i] = prim_mubi_pkg::mubi4_test_true_strict(mubi_hints[i]); + return ret; + endfunction + + local function void disable_unnecessary_exclusions(); + ral.get_excl_item().enable_excl("clkmgr_reg_block.clk_enables", 0); + ral.get_excl_item().enable_excl("clkmgr_reg_block.clk_hints", 0); + `uvm_info(`gfn, "Adjusted exclusions", UVM_MEDIUM) + ral.get_excl_item().print_exclusions(UVM_MEDIUM); + endfunction + + task pre_start(); + meas_ctrl_regs[ClkMesrIo] = '{"io", ral.io_meas_ctrl_en, ral.io_meas_ctrl_shadowed.hi, + ral.io_meas_ctrl_shadowed.lo}; + meas_ctrl_regs[ClkMesrIoDiv2] = '{"io div2", ral.io_div2_meas_ctrl_en, + ral.io_div2_meas_ctrl_shadowed.hi, + ral.io_div2_meas_ctrl_shadowed.lo}; + meas_ctrl_regs[ClkMesrIoDiv4] = '{"io div4", ral.io_div4_meas_ctrl_en, + ral.io_div4_meas_ctrl_shadowed.hi, + ral.io_div4_meas_ctrl_shadowed.lo}; + meas_ctrl_regs[ClkMesrMain] = '{"main", ral.main_meas_ctrl_en, ral.main_meas_ctrl_shadowed.hi, + ral.main_meas_ctrl_shadowed.lo}; + meas_ctrl_regs[ClkMesrUsb] = '{"usb", ral.usb_meas_ctrl_en, ral.usb_meas_ctrl_shadowed.hi, + ral.usb_meas_ctrl_shadowed.lo}; + + mubi_mode = ClkmgrMubiNone; + `DV_GET_ENUM_PLUSARG(clkmgr_mubi_e, mubi_mode, clkmgr_mubi_mode) + `uvm_info(`gfn, $sformatf("mubi_mode = %s", mubi_mode.name), UVM_MEDIUM) + cfg.clkmgr_vif.init(.idle({NUM_TRANS{MuBi4True}}), .scanmode(scanmode), .lc_debug_en(Off)); + cfg.clkmgr_vif.update_io_ip_clk_en(1'b1); + cfg.clkmgr_vif.update_main_ip_clk_en(1'b1); + cfg.clkmgr_vif.update_usb_ip_clk_en(1'b1); + cfg.clkmgr_vif.update_all_clk_byp_ack(MuBi4False); + cfg.clkmgr_vif.update_div_step_down_req(MuBi4False); + cfg.clkmgr_vif.update_io_clk_byp_ack(MuBi4False); + + disable_unnecessary_exclusions(); + clkmgr_init(); + super.pre_start(); + if (common_seq_type inside {"shadow_reg_errors", "shadow_reg_errors_with_csr_rw"}) begin + expect_fatal_alerts = 1; + end + endtask + + virtual task dut_init(string reset_kind = "HARD"); + super.dut_init(reset_kind); + endtask + + virtual task dut_shutdown(); + // check for pending clkmgr operations and wait for them to complete + endtask + + // This turns on the actual input clocks, as the pwrmgr would. + task start_ip_clocks(); + fork + start_io_ip_clock(); + start_main_ip_clock(); + start_usb_ip_clock(); + join + endtask + + task start_io_ip_clock(); + `uvm_info(`gfn, $sformatf( + "starting io clk_en with current status %b", cfg.clkmgr_vif.pwr_o.io_status), + UVM_MEDIUM) + cfg.io_clk_rst_vif.start_clk(); + cfg.clkmgr_vif.pwr_i.io_ip_clk_en = io_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.io_status == 1'b1);, + "timeout waiting for io_status to raise", CLK_STATUS_TIMEOUT_NS) + `uvm_info(`gfn, "starting io clock done", UVM_MEDIUM) + endtask + + task start_main_ip_clock(); + `uvm_info(`gfn, $sformatf( + "starting main clk_en with current status %b", cfg.clkmgr_vif.pwr_o.main_status), + UVM_MEDIUM) + cfg.main_clk_rst_vif.start_clk(); + cfg.clkmgr_vif.pwr_i.main_ip_clk_en = main_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.main_status == 1'b1);, + "timeout waiting for main_status to raise", CLK_STATUS_TIMEOUT_NS) + `uvm_info(`gfn, "starting main clock done", UVM_MEDIUM) + endtask + + task start_usb_ip_clock(); + `uvm_info(`gfn, $sformatf( + "starting usb clk_en with current status %b", cfg.clkmgr_vif.pwr_o.usb_status), + UVM_MEDIUM) + cfg.usb_clk_rst_vif.start_clk(); + cfg.clkmgr_vif.pwr_i.usb_ip_clk_en = usb_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.usb_status == 1'b1);, + "timeout waiting for usb_status to raise", CLK_STATUS_TIMEOUT_NS) + `uvm_info(`gfn, "starting usb clock done", UVM_MEDIUM) + endtask + + // This turns on or off the actual input clocks, as the pwrmgr would. + task control_ip_clocks(); + fork + control_io_ip_clock(); + control_main_ip_clock(); + control_usb_ip_clock(); + join + endtask + + task control_io_ip_clock(); + // Do nothing if nothing interesting changed. + if (cfg.clkmgr_vif.pwr_i.io_ip_clk_en == io_ip_clk_en) return; + `uvm_info(`gfn, $sformatf( + "controlling io clk_en from %b to %b with current status %b", + cfg.clkmgr_vif.pwr_i.io_ip_clk_en, + io_ip_clk_en, + cfg.clkmgr_vif.pwr_o.io_status + ), UVM_MEDIUM) + if (!io_ip_clk_en) begin + cfg.clkmgr_vif.pwr_i.io_ip_clk_en = io_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.io_status == 1'b0);, + "timeout waiting for io_status to fall", CLK_STATUS_TIMEOUT_NS) + cfg.io_clk_rst_vif.stop_clk(); + end else begin + cfg.io_clk_rst_vif.start_clk(); + cfg.clkmgr_vif.pwr_i.io_ip_clk_en = io_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.io_status == 1'b1);, + "timeout waiting for io_status to raise", CLK_STATUS_TIMEOUT_NS) + end + `uvm_info(`gfn, "controlling io clock done", UVM_MEDIUM) + endtask + + task control_main_ip_clock(); + // Do nothing if nothing interesting changed. + if (cfg.clkmgr_vif.pwr_i.main_ip_clk_en == main_ip_clk_en) return; + `uvm_info(`gfn, $sformatf( + "controlling main clk_en from %b to %b with current status %b", + cfg.clkmgr_vif.pwr_i.main_ip_clk_en, + main_ip_clk_en, + cfg.clkmgr_vif.pwr_o.main_status + ), UVM_MEDIUM) + if (!main_ip_clk_en) begin + cfg.clkmgr_vif.pwr_i.main_ip_clk_en = main_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.main_status == 1'b0);, + "timeout waiting for main_status to fall", CLK_STATUS_TIMEOUT_NS) + cfg.main_clk_rst_vif.stop_clk(); + end else begin + cfg.main_clk_rst_vif.start_clk(); + cfg.clkmgr_vif.pwr_i.main_ip_clk_en = main_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.main_status == 1'b1);, + "timeout waiting for main_status to raise", CLK_STATUS_TIMEOUT_NS) + end + `uvm_info(`gfn, "controlling main clock done", UVM_MEDIUM) + endtask + + task control_usb_ip_clock(); + // Do nothing if nothing interesting changed. + if (cfg.clkmgr_vif.pwr_i.usb_ip_clk_en == usb_ip_clk_en) return; + `uvm_info(`gfn, $sformatf( + "controlling usb clk_en from %b to %b with current status %b", + cfg.clkmgr_vif.pwr_i.usb_ip_clk_en, + usb_ip_clk_en, + cfg.clkmgr_vif.pwr_o.usb_status + ), UVM_MEDIUM) + if (!usb_ip_clk_en) begin + cfg.clkmgr_vif.pwr_i.usb_ip_clk_en = usb_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.usb_status == 1'b0);, + "timeout waiting for usb_status to fall", CLK_STATUS_TIMEOUT_NS) + cfg.usb_clk_rst_vif.stop_clk(); + end else begin + cfg.usb_clk_rst_vif.start_clk(); + cfg.clkmgr_vif.pwr_i.usb_ip_clk_en = usb_ip_clk_en; + `DV_SPINWAIT(wait(cfg.clkmgr_vif.pwr_o.usb_status == 1'b1);, + "timeout waiting for usb_status to raise", CLK_STATUS_TIMEOUT_NS) + end + `uvm_info(`gfn, "controlling usb clock done", UVM_MEDIUM) + endtask + + task disable_frequency_measurement(clk_mesr_e which); + `uvm_info(`gfn, $sformatf("Disabling frequency measurement for %0s", which.name), UVM_MEDIUM) + csr_wr(.ptr(meas_ctrl_regs[which].en), .value(MuBi4False)); + endtask + + local function int get_meas_ctrl_value(int min_threshold, int max_threshold, uvm_reg_field lo, + uvm_reg_field hi); + int lo_mask = (1 << lo.get_n_bits()) - 1; + int hi_mask = (1 << hi.get_n_bits()) - 1; + + int value = (((min_threshold & lo_mask) << lo.get_lsb_pos()) | + ((max_threshold & hi_mask) << hi.get_lsb_pos())); + return value; + endfunction + + // Any non-false mubi value in the enable CSR turns measurements on. + task enable_frequency_measurement(clk_mesr_e which, int min_threshold, int max_threshold); + int value = get_meas_ctrl_value(min_threshold, max_threshold, meas_ctrl_regs[which].ctrl_lo, + meas_ctrl_regs[which].ctrl_hi); + mubi4_t en_value = get_rand_mubi4_val(1, 0, 3); + `uvm_info(`gfn, $sformatf( + "Enabling frequency measurement for %0s, min=0x%x, max=0x%x, expected=0x%x", + which.name, + min_threshold, + max_threshold, + ExpectedCounts[which] + ), UVM_MEDIUM) + csr_wr(.ptr(meas_ctrl_regs[which].ctrl_lo.get_dv_base_reg_parent()), .value(value)); + csr_wr(.ptr(meas_ctrl_regs[which].en), .value(en_value)); + endtask + + // This checks that when calibration is lost regwen should be re-enabled and measurements + // disabled. + task calibration_lost_checks(); + void'(ral.measure_ctrl_regwen.predict(1)); + csr_rd_check(.ptr(ral.measure_ctrl_regwen), .compare_value(1)); + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + csr_rd_check(.ptr(meas_ctrl_regs[clk_mesr].en), .compare_value(MuBi4False)); + end + endtask + + local function void control_sync_pulse_assert(clk_mesr_e clk, bit enable); + case (clk) + ClkMesrIo: begin + if (enable) $asserton(0, "tb.dut.u_io_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + else $assertoff(0, "tb.dut.u_io_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + end + ClkMesrIoDiv2: begin + if (enable) $asserton(0, "tb.dut.u_io_div2_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + else $assertoff(0, "tb.dut.u_io_div2_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + end + ClkMesrIoDiv4: begin + if (enable) $asserton(0, "tb.dut.u_io_div4_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + else $assertoff(0, "tb.dut.u_io_div4_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + end + ClkMesrMain: begin + if (enable) $asserton(0, "tb.dut.u_main_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + else $assertoff(0, "tb.dut.u_main_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + end + ClkMesrUsb: begin + if (enable) $asserton(0, "tb.dut.u_usb_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + else $assertoff(0, "tb.dut.u_usb_meas.u_meas.u_sync_ref.SrcPulseCheck_M"); + end + default: `uvm_error(`gfn, $sformatf("unexpected clock index '%0d'", clk)) + endcase + endfunction + + // This turns off/on some clocks being measured to trigger a measurement timeout. + // A side-effect is that some RTL assertions will fire, so they are corresponsdingly controlled. + task disturb_measured_clock(clk_mesr_e clk, bit enable); + case (clk) + ClkMesrIo, ClkMesrIoDiv2, ClkMesrIoDiv4: begin + if (enable) cfg.io_clk_rst_vif.start_clk(); + else cfg.io_clk_rst_vif.stop_clk(); + control_sync_pulse_assert(.clk(ClkMesrIo), .enable(enable)); + control_sync_pulse_assert(.clk(ClkMesrIoDiv2), .enable(enable)); + control_sync_pulse_assert(.clk(ClkMesrIoDiv4), .enable(enable)); + end + ClkMesrMain: begin + if (enable) cfg.main_clk_rst_vif.start_clk(); + else cfg.main_clk_rst_vif.stop_clk(); + control_sync_pulse_assert(.clk(clk), .enable(enable)); + end + ClkMesrUsb: begin + if (enable) cfg.usb_clk_rst_vif.start_clk(); + else cfg.usb_clk_rst_vif.stop_clk(); + control_sync_pulse_assert(.clk(clk), .enable(enable)); + end + default: `uvm_fatal(`gfn, $sformatf("Unexpected clk '%0d'", clk)) + endcase + endtask + + function void report_recov_error_mismatch(string error_type, recov_bits_t expected, + recov_bits_t actual); + recov_bits_t mismatch = actual ^ expected; + foreach (mismatch[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + if (mismatch[clk]) begin + `uvm_info(`gfn, $sformatf( + "Mismatch %0s for %0s, expected %b, actual %b", + error_type, + clk_mesr.name, + expected[clk], + actual[clk] + ), UVM_LOW) + end + end + `uvm_error(`gfn, $sformatf( + "Mismatch for %0s recoverable error, expected 0b%b, got 0b%b", + error_type, + expected, + actual + )) + endfunction + + // Returns the maximum clock period across non-aon clocks. + local function int maximum_clock_period(); + int clk_periods_q[$] = { + cfg.aon_clk_rst_vif.clk_period_ps, + cfg.io_clk_rst_vif.clk_period_ps * 4, + cfg.main_clk_rst_vif.clk_period_ps, + cfg.usb_clk_rst_vif.clk_period_ps + }; + return max(clk_periods_q); + endfunction + + // This is tricky, and we choose to handle it all here, not in "super": + // - there are no multiple clk_rst_vifs, + // - it would be too complicated to coordinate reset durations with super. + // For hard resets we also reset the cfg.root*_clk_rst_vif, and its reset is shorter than + // that of all others. + virtual task apply_resets_concurrently(int reset_duration_ps = 0); + int clk_periods_q[$] = { + reset_duration_ps, + cfg.aon_clk_rst_vif.clk_period_ps, + cfg.io_clk_rst_vif.clk_period_ps * 4, + cfg.main_clk_rst_vif.clk_period_ps, + cfg.usb_clk_rst_vif.clk_period_ps + }; + reset_duration_ps = max(clk_periods_q); + + `uvm_info(`gfn, "In apply_resets_concurrently", UVM_MEDIUM) + cfg.root_io_clk_rst_vif.drive_rst_pin(0); + cfg.root_main_clk_rst_vif.drive_rst_pin(0); + cfg.root_usb_clk_rst_vif.drive_rst_pin(0); + cfg.aon_clk_rst_vif.drive_rst_pin(0); + cfg.clk_rst_vif.drive_rst_pin(0); + cfg.io_clk_rst_vif.drive_rst_pin(0); + cfg.main_clk_rst_vif.drive_rst_pin(0); + cfg.usb_clk_rst_vif.drive_rst_pin(0); + + #(reset_duration_ps * $urandom_range(2, 10) * 1ps); + cfg.root_io_clk_rst_vif.drive_rst_pin(1); + cfg.root_main_clk_rst_vif.drive_rst_pin(1); + cfg.root_usb_clk_rst_vif.drive_rst_pin(1); + `uvm_info(`gfn, "apply_resets_concurrently releases POR", UVM_MEDIUM) + + #(reset_duration_ps * $urandom_range(2, 10) * 1ps); + cfg.aon_clk_rst_vif.drive_rst_pin(1); + cfg.clk_rst_vif.drive_rst_pin(1); + cfg.io_clk_rst_vif.drive_rst_pin(1); + cfg.main_clk_rst_vif.drive_rst_pin(1); + cfg.usb_clk_rst_vif.drive_rst_pin(1); + `uvm_info(`gfn, "apply_resets_concurrently releases other resets", UVM_MEDIUM) + endtask + + virtual task apply_reset(string kind = "HARD"); + if (kind == "HARD") apply_resets_concurrently(); + else begin + fork + cfg.clk_rst_vif.apply_reset(); + cfg.aon_clk_rst_vif.apply_reset(); + cfg.main_clk_rst_vif.apply_reset(); + cfg.io_clk_rst_vif.apply_reset(); + cfg.usb_clk_rst_vif.apply_reset(); + join + end + endtask + + task post_apply_reset(string reset_kind = "HARD"); + super.post_apply_reset(reset_kind); + initialize_on_start(); + cfg.io_clk_rst_vif.wait_clks(POST_APPLY_RESET_CYCLES); + endtask + + // setup basic clkmgr features + virtual task clkmgr_init(); + // Initialize input clock frequencies. + cfg.main_clk_rst_vif.set_freq_mhz((1.0 * MainClkHz) / 1_000_000); + cfg.io_clk_rst_vif.set_freq_mhz((1.0 * IoClkHz) / 1_000_000); + cfg.usb_clk_rst_vif.set_freq_mhz((1.0 * UsbClkHz) / 1_000_000); + // The real clock rate for aon is 200kHz, but that can slow testing down. + // Increasing its frequency improves DV efficiency without compromising quality. + cfg.aon_clk_rst_vif.set_freq_mhz((1.0 * FakeAonClkHz) / 1_000_000); + endtask +endclass : clkmgr_base_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_clk_status_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_clk_status_vseq.sv new file mode 100644 index 0000000000000..f5850366aa9ad --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_clk_status_vseq.sv @@ -0,0 +1,35 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This tests the transitions of the various clock status outputs for random settings of the +// various ip_clk_en inputs. +// +// The checks are done via SVA in clkmgr_pwrmgr_sva_if. +class clkmgr_clk_status_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_clk_status_vseq) + + `uvm_object_new + + function void post_randomize(); + super.post_randomize(); + // Disable scanmode since it is not interesting. + scanmode = prim_mubi_pkg::MuBi4False; + endfunction + + task body(); + for (int i = 0; i < num_trans; ++i) begin + cfg.clk_rst_vif.wait_clks(4); + `DV_CHECK_RANDOMIZE_FATAL(this) + cfg.clkmgr_vif.init(.idle(idle), .scanmode(scanmode)); + control_ip_clocks(); + + // If some units were not idle, make them so. + idle = '1; + // Wait for idle to percolate. + cfg.clk_rst_vif.wait_clks(10); + end + // And set it back to more common values for stress tests. + initialize_on_start(); + endtask : body +endclass : clkmgr_clk_status_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_common_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_common_vseq.sv new file mode 100644 index 0000000000000..21613892f0b76 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_common_vseq.sv @@ -0,0 +1,70 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class clkmgr_common_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_common_vseq) + + constraint num_trans_c {num_trans inside {[1 : 2]};} + `uvm_object_new + + virtual task pre_start(); + csr_excl_item csr_excl = ral.get_excl_item(); + super.pre_start(); + + // Remove rw1c type from same_csr_outstanding + if (common_seq_type == "same_csr_outstanding") begin + csr_excl.add_excl("clkmgr_reg_block.recov_err_code", CsrExclWrite); + end + endtask + + virtual task body(); + run_common_vseq_wrapper(num_trans); + endtask : body + + virtual task check_sec_cm_fi_resp(sec_cm_base_if_proxy if_proxy); + super.check_sec_cm_fi_resp(if_proxy); + + case (if_proxy.sec_cm_type) + SecCmPrimCount: begin + csr_rd_check(.ptr(ral.fatal_err_code.idle_cnt), .compare_value(1)); + end + default: begin + `uvm_error(`gfn, $sformatf("Unexpected sec_cm_type %0s", if_proxy.sec_cm_type.name)) + end + endcase + endtask + + task initialize_on_start(); + super.initialize_on_start(); + // update default idle to false for + // csr test. + cfg.clkmgr_vif.idle_i = {NUM_TRANS{MuBi4False}}; + endtask : initialize_on_start + + // This task is used for non-main clock registers. + // to compensate clock difference, wait longer until + // see get_alert() + task skid_check_fatal_alert_nonblocking(string alert_name); + fork + `DV_SPINWAIT_EXIT( + forever begin + // 1 extra cycle to make sure no race condition + repeat (alert_esc_agent_pkg::ALERT_B2B_DELAY + 20) begin + cfg.clk_rst_vif.wait_n_clks(1); + if (cfg.m_alert_agent_cfgs[alert_name].vif.get_alert() == 1) break; + end + `DV_CHECK_EQ(cfg.m_alert_agent_cfgs[alert_name].vif.get_alert(), 1, + $sformatf("fatal error %0s does not trigger!", alert_name)) + cfg.m_alert_agent_cfgs[alert_name].vif.wait_ack_complete(); + end, + wait(cfg.under_reset);) + join_none + endtask + + // Override shadow_reg_errors task + // to cover shadow regs under clock div2, div4 + task shadow_reg_errors_check_fatal_alert_nonblocking(dv_base_reg shadowed_csr, string alert_name); + skid_check_fatal_alert_nonblocking(alert_name); + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv new file mode 100644 index 0000000000000..5a10f0e49f963 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_extclk_vseq.sv @@ -0,0 +1,241 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// The extclk vseq causes the external clock selection to be triggered. More details +// in the clkmgr_testplan.hjson file. +class clkmgr_extclk_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_extclk_vseq) + + `uvm_object_new + + // When extclk_ctrl_regwen is clear it is not possible to select external clocks. + // This is tested in regular csr_rw, so here this register is simply set to 1. + + // The extclk cannot be manipulated in low power mode. + constraint io_ip_clk_en_on_c {io_ip_clk_en == 1'b1;} + constraint main_ip_clk_en_on_c {main_ip_clk_en == 1'b1;} + constraint usb_ip_clk_en_on_c {usb_ip_clk_en == 1'b1;} + + // This randomizes the time when the extclk_ctrl CSR write and the lc_clk_byp_req + // input is asserted for good measure. Of course, there is a good chance only a single + // one of these trigger a request, so they are also independently tested. + rand int cycles_before_extclk_ctrl_sel; + rand int cycles_before_lc_clk_byp_req; + rand int cycles_before_lc_clk_byp_ack; + rand int cycles_before_all_clk_byp_ack; + rand int cycles_before_div_step_down_req; + rand int cycles_before_io_clk_byp_ack; + rand int cycles_before_next_trans; + + rand int flips_before_io_clk_byp_ack; + rand int flips_before_div_step_down_req; + rand int flips_before_all_clk_byp_ack; + rand int cycles_between_flips; + + constraint cycles_to_stim_c { + cycles_before_extclk_ctrl_sel inside {[4 : 20]}; + cycles_before_lc_clk_byp_req inside {[4 : 20]}; + cycles_before_lc_clk_byp_ack inside {[16 : 30]}; + cycles_before_all_clk_byp_ack inside {[3 : 11]}; + cycles_before_div_step_down_req inside {[3 : 11]}; + cycles_before_io_clk_byp_ack inside {[3 : 11]}; + cycles_before_next_trans inside {[15 : 35]}; + flips_before_io_clk_byp_ack inside {[0 : 3]}; + flips_before_div_step_down_req inside {[0 : 3]}; + flips_before_all_clk_byp_ack inside {[0 : 3]}; + cycles_between_flips inside {[3 : 5]}; + } + + lc_tx_t lc_clk_byp_req; + lc_tx_t lc_debug_en; + mubi4_t io_clk_byp_ack_non_true; + mubi4_t all_clk_byp_ack_non_true; + mubi4_t div_step_down_req_non_true; + + mubi4_t exp_all_clk_byp_ack; + + function void post_randomize(); + if (mubi_mode == ClkmgrMubiLcHand) begin + // increase weight of illegal value only in ClkmgrMubiLcHand + lc_clk_byp_req = get_rand_lc_tx_val(.t_weight(1), .f_weight(1), .other_weight(14)); + end else begin + lc_clk_byp_req = get_rand_lc_tx_val(.t_weight(8), .f_weight(2), .other_weight(2)); + end + if (mubi_mode == ClkmgrMubiLcCtrl) begin + // increase weight of illgal value only in ClkmgrMubiLcHand + lc_debug_en = get_rand_lc_tx_val(.t_weight(1), .f_weight(1), .other_weight(14)); + end else begin + lc_debug_en = get_rand_lc_tx_val(.t_weight(8), .f_weight(2), .other_weight(2)); + end + + io_clk_byp_ack_non_true = get_rand_mubi4_val(.t_weight(0), .f_weight(2), .other_weight(8)); + all_clk_byp_ack_non_true = get_rand_mubi4_val(.t_weight(0), .f_weight(2), .other_weight(8)); + div_step_down_req_non_true = get_rand_mubi4_val(.t_weight(0), .f_weight(2), .other_weight(8)); + + `uvm_info(`gfn, $sformatf( + "randomize gives lc_clk_byp_req=0x%x, lc_debug_en=0x%x", lc_clk_byp_req, lc_debug_en), + UVM_MEDIUM) + super.post_randomize(); + + extclk_ctrl_sel = get_rand_mubi4_val(.t_weight(8), .f_weight(1), .other_weight(1)); + `uvm_info(`gfn, $sformatf("overwrite extclk_ctrl_sel=0x%x", extclk_ctrl_sel), UVM_MEDIUM) + + endfunction + + // Notice only all_clk_byp_req and io_clk_byp_req Mubi4True and Mubi4False cause transitions. + local task delayed_update_all_clk_byp_ack(mubi4_t value, int cycles); + uvm_reg_data_t rd_data; + + if (mubi_mode == ClkmgrMubiHand && value == MuBi4True) begin + repeat (flips_before_all_clk_byp_ack) begin + exp_all_clk_byp_ack = get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(1)); + cfg.clk_rst_vif.wait_clks(cycles_between_flips); + cfg.clkmgr_vif.update_all_clk_byp_ack(exp_all_clk_byp_ack); + cfg.clk_rst_vif.wait_clks(4); + csr_rd(.ptr(ral.extclk_status), .value(rd_data)); + // csr_rd_check didn't work well for status register read check + `DV_CHECK_EQ(exp_all_clk_byp_ack, rd_data, "extclk_status mismatch") + end + end + cfg.clk_rst_vif.wait_clks(cycles_between_flips); + cfg.clkmgr_vif.update_all_clk_byp_ack(value); + endtask + + local task delayed_update_div_step_down_req(mubi4_t value, int cycles); + if (mubi_mode == ClkmgrMubiDiv && value == MuBi4True) begin + repeat (flips_before_div_step_down_req) begin + cfg.clk_rst_vif.wait_clks(cycles_between_flips); + cfg.clkmgr_vif.update_div_step_down_req(get_rand_mubi4_val( + .t_weight(0), .f_weight(1), .other_weight(1))); + end + end + cfg.clk_rst_vif.wait_clks(cycles_between_flips); + `uvm_info(`gfn, $sformatf("Settling div_step_down_req to 0x%x", value), UVM_MEDIUM) + cfg.clkmgr_vif.update_div_step_down_req(value); + endtask + + local task delayed_update_io_clk_byp_ack(mubi4_t value, int cycles); + if (mubi_mode == ClkmgrMubiHand && value == MuBi4True) begin + repeat (flips_before_io_clk_byp_ack) begin + cfg.clk_rst_vif.wait_clks(cycles_between_flips); + cfg.clkmgr_vif.update_io_clk_byp_ack(get_rand_mubi4_val( + .t_weight(0), .f_weight(1), .other_weight(1))); + end + end + cfg.clk_rst_vif.wait_clks(cycles_between_flips); + `uvm_info(`gfn, $sformatf("Settling io_clk_byp_ack to 0x%x", value), UVM_MEDIUM) + cfg.clkmgr_vif.update_io_clk_byp_ack(value); + endtask + + local task all_clk_byp_handshake(); + forever + @cfg.clkmgr_vif.all_clk_byp_req begin : all_clk_byp_ack + if (cfg.clkmgr_vif.all_clk_byp_req == prim_mubi_pkg::MuBi4True) begin + `uvm_info(`gfn, "Got all_clk_byp_req on", UVM_MEDIUM) + fork + delayed_update_all_clk_byp_ack(MuBi4True, cycles_before_all_clk_byp_ack); + delayed_update_div_step_down_req(MuBi4True, cycles_before_div_step_down_req); + join + end else begin + `uvm_info(`gfn, "Got all_clk_byp_req off", UVM_MEDIUM) + // Set inputs to mubi4 non-True. + fork + delayed_update_all_clk_byp_ack(all_clk_byp_ack_non_true, cycles_before_all_clk_byp_ack); + delayed_update_div_step_down_req(div_step_down_req_non_true, + cycles_before_div_step_down_req); + join + end + end + endtask + + local task io_clk_byp_handshake(); + forever + @cfg.clkmgr_vif.io_clk_byp_req begin : io_clk_byp_ack + if (cfg.clkmgr_vif.io_clk_byp_req == MuBi4True) begin + `uvm_info(`gfn, "Got io_clk_byp_req True", UVM_MEDIUM) + fork + delayed_update_io_clk_byp_ack(MuBi4True, cycles_before_io_clk_byp_ack); + delayed_update_div_step_down_req(MuBi4True, cycles_before_div_step_down_req); + join + end else begin + `uvm_info(`gfn, "Got io_clk_byp_req non True", UVM_MEDIUM) + // Set inputs to mubi4 non-True. + fork + delayed_update_io_clk_byp_ack(io_clk_byp_ack_non_true, cycles_before_io_clk_byp_ack); + delayed_update_div_step_down_req(div_step_down_req_non_true, + cycles_before_div_step_down_req); + join + end + end + endtask + + local task lc_clk_byp_handshake(); + forever + @cfg.clkmgr_vif.lc_clk_byp_ack begin : lc_clk_byp_ack + if (cfg.clkmgr_vif.lc_clk_byp_ack == lc_ctrl_pkg::On) begin + `uvm_info(`gfn, "Got lc_clk_byp_ack on", UVM_MEDIUM) + end + end + endtask + + local task run_test(); + for (int i = 0; i < num_trans; ++i) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + // Init needs to be synchronous. + @cfg.clk_rst_vif.cb begin + cfg.clkmgr_vif.init(.idle(idle), .scanmode(scanmode), .lc_debug_en(lc_debug_en)); + control_ip_clocks(); + end + fork + begin + cfg.clk_rst_vif.wait_clks(cycles_before_extclk_ctrl_sel); + csr_wr(.ptr(ral.extclk_ctrl), .value({extclk_ctrl_high_speed_sel, extclk_ctrl_sel})); + end + begin + cfg.clk_rst_vif.wait_clks(cycles_before_lc_clk_byp_req); + cfg.clkmgr_vif.update_lc_clk_byp_req(lc_clk_byp_req); + end + join + `uvm_info(`gfn, $sformatf( + { + "extclk_ctrl_sel=0x%0x, extclk_ctrl_high_speed_sel=0x%0x, lc_clk_byp_req=0x%0x, ", + "lc_debug_en=0x%0x, scanmode=0x%0x" + }, + extclk_ctrl_sel, + extclk_ctrl_high_speed_sel, + lc_clk_byp_req, + lc_debug_en, + scanmode + ), UVM_MEDIUM) + csr_rd_check(.ptr(ral.extclk_ctrl), + .compare_value({extclk_ctrl_high_speed_sel, extclk_ctrl_sel})); + if (lc_clk_byp_req == lc_ctrl_pkg::On) begin + wait(cfg.clkmgr_vif.lc_clk_byp_req == lc_ctrl_pkg::On); + cfg.clk_rst_vif.wait_clks(cycles_before_lc_clk_byp_ack); + cfg.clkmgr_vif.update_lc_clk_byp_req(lc_ctrl_pkg::Off); + end + // Disable extclk software control. + csr_wr(.ptr(ral.extclk_ctrl), .value({Off, Off})); + cfg.clk_rst_vif.wait_clks(cycles_before_next_trans); + end + endtask + + task body(); + set_scanmode_on_low_weight(); + csr_wr(.ptr(ral.extclk_ctrl_regwen), .value(1)); + + fork + begin : isolation_fork + fork + all_clk_byp_handshake(); + io_clk_byp_handshake(); + lc_clk_byp_handshake(); + run_test(); + join_any + disable fork; + end + join + endtask + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_timeout_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_timeout_vseq.sv new file mode 100644 index 0000000000000..c3c6aafed2b57 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_timeout_vseq.sv @@ -0,0 +1,142 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// The frequency timeout vseq exercises the frequency measurement counters. More details +// in the clkmgr_testplan.hjson file. +class clkmgr_frequency_timeout_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_frequency_timeout_vseq) + + `uvm_object_new + + // This is measured in aon clocks. We need to have a few rounds of measurement for timeouts to + // trigger, since they synchronize to the aon clock, and they wait for a few number of AON + // cycles before declaring a timeout. + localparam int CyclesToGetOneMeasurement = 12; + + // If cause_timeout is set, turn off clk_timeout so it gets a timeout. + rand bit cause_timeout; + constraint cause_timeout_c { + cause_timeout dist { + 1 := 4, + 0 := 1 + }; + } + rand int clk_timeout; + constraint clk_timeout_c {clk_timeout inside {[ClkMesrIo : ClkMesrUsb]};} + + constraint all_clk_en_c { + io_ip_clk_en == 1; + main_ip_clk_en == 1; + usb_ip_clk_en == 1; + } + + // The clock that will be disabled. + clk_mesr_e clk_mesr_timeout; + + // This waits a number of AON cycles so that the timeout can get detected. + task wait_before_read_recov_err_code(); + cfg.aon_clk_rst_vif.wait_clks(CyclesToGetOneMeasurement); + endtask + + // Get things back in normal order. + virtual task apply_resets_concurrently(int reset_duration_ps = 0); + super.apply_resets_concurrently(reset_duration_ps); + if (cause_timeout) disturb_measured_clock(.clk(clk_mesr_timeout), .enable(1'b1)); + endtask + + task body(); + logic [TL_DW-1:0] value; + int prior_alert_count; + int current_alert_count; + csr_wr(.ptr(ral.measure_ctrl_regwen), .value(1)); + + // Make sure the aon clock is running as slow as it is meant to. + cfg.aon_clk_rst_vif.set_freq_khz(AonClkHz / 1_000); + control_ip_clocks(); + // Wait so the frequency change takes effect. + cfg.aon_clk_rst_vif.wait_clks(2); + + // Disable cip scoreboard exp_alert checks since they need very fine control, making checks + // really cumbersome. Instead we rely on the alert count to detect if alert were triggered. + cfg.scoreboard.do_alert_check = 0; + + `uvm_info(`gfn, $sformatf("Will run %0d rounds", num_trans), UVM_MEDIUM) + for (int i = 0; i < num_trans; ++i) begin + clkmgr_recov_err_t actual_recov_err = '{default: '0}; + logic [ClkMesrUsb:0] expected_recov_timeout_err = '0; + bit expect_alert = 0; + `DV_CHECK_RANDOMIZE_FATAL(this) + `uvm_info(`gfn, "New round", UVM_MEDIUM) + + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + int min_threshold; + int max_threshold; + int expected = ExpectedCounts[clk]; + min_threshold = expected - 2; + max_threshold = expected + 2; + enable_frequency_measurement(clk_mesr, min_threshold, max_threshold); + end + + prior_alert_count = cfg.scoreboard.get_alert_count("recov_fault"); + // Allow some cycles for measurements to start before turning off the clocks, since the + // measurement control CSRs are controlled by the clocks we intend to stop. + cfg.aon_clk_rst_vif.wait_clks(4); + clk_mesr_timeout = clk_mesr_e'(clk_timeout); + + if (cause_timeout) begin + `uvm_info(`gfn, $sformatf("Will cause a timeout for clk %0s", clk_mesr_timeout.name()), + UVM_MEDIUM) + if (clk_mesr_timeout inside {ClkMesrIo, ClkMesrIoDiv2, ClkMesrIoDiv4}) begin + // All these clocks are derived from io so that gets disabled, and all derived + // clocks will get a timeout. + expected_recov_timeout_err[ClkMesrIo] = 1; + expected_recov_timeout_err[ClkMesrIoDiv2] = 1; + expected_recov_timeout_err[ClkMesrIoDiv4] = 1; + end else begin + expected_recov_timeout_err[clk_mesr_timeout] = 1; + end + disturb_measured_clock(.clk(clk_mesr_timeout), .enable(1'b0)); + end + wait_before_read_recov_err_code(); + if (cause_timeout) begin + disturb_measured_clock(.clk(clk_mesr_e'(clk_timeout)), .enable(1'b1)); + end + csr_rd(.ptr(ral.recov_err_code), .value(actual_recov_err)); + `uvm_info(`gfn, $sformatf("Got recov err register=0x%x", actual_recov_err), UVM_MEDIUM) + if (actual_recov_err.measures) begin + report_recov_error_mismatch("measurement", recov_bits_t'(0), actual_recov_err.measures); + end + if (!cfg.under_reset && actual_recov_err.timeouts != expected_recov_timeout_err) begin + report_recov_error_mismatch("timeout", expected_recov_timeout_err, + actual_recov_err.timeouts); + end + if (actual_recov_err.shadow_update != 0) begin + `uvm_error(`gfn, "Unexpected recoverable shadow update error") + end + // And check that the alert count increased if there was a timeout. + current_alert_count = cfg.scoreboard.get_alert_count("recov_fault"); + if (cause_timeout) begin + if (!cfg.under_reset) begin + `DV_CHECK_NE(current_alert_count, prior_alert_count, "expected some alerts to fire") + end + end else begin + `DV_CHECK_EQ(current_alert_count, prior_alert_count, "expected no alerts to fire") + end + + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + disable_frequency_measurement(clk_mesr); + end + + // Wait enough time for measurements to complete, and for alerts to get processed + // by the alert agents so expected alerts are properly wound down. + cfg.aon_clk_rst_vif.wait_clks(6); + // And clear errors. + csr_wr(.ptr(ral.recov_err_code), .value('1)); + cfg.aon_clk_rst_vif.wait_clks(2); + end + endtask : body + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_vseq.sv new file mode 100644 index 0000000000000..67d93694c19c4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_frequency_vseq.sv @@ -0,0 +1,236 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// The frequency vseq exercises the frequency measurement counters. More details +// in the clkmgr_testplan.hjson file. +class clkmgr_frequency_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_frequency_vseq) + + `uvm_object_new + + // This is measured in aon clocks. This is cannot be too precise because of a synchronizer. + localparam int CyclesToGetMeasurements = 6; + + // The aon cycles between measurements, to make sure the previous measurement settles. + localparam int CyclesBetweenMeasurements = 6; + + // This is measured in clkmgr clk_i clocks. It is set to cover worst case delays. + // The clk_i frequency is randomized for IPs, but the clkmgr is hooked to io_div4, which would + // allow a tighter number of cycles. Leaving the clk_i random probably provides more cases, + // so leaving it as is. + localparam int CyclesForErrUpdate = 16; + + // The min ands max offsets from the expected counts. Notice the count occasionally matches + // expected_counts +- 2 because of CDC synchronizers, so the offsets are set carefully to + // avoid spurious results. + // + // The exp_alert cip feature requires a single alert at a time, so we set at most one of the + // clocks to fail measurement. + rand int clk_tested; + constraint clk_tested_c {clk_tested inside {[ClkMesrIo : ClkMesrUsb]};} + + // If cause_saturation is active, force the initial measurement count of clk_tested to a high + // value so the counter will saturate. + rand bit cause_saturation; + + typedef enum int { + MesrLow, + MesrRight, + MesrHigh + } mesr_e; + rand mesr_e mesr; + rand int min_offset; + rand int max_offset; + + mubi4_t calib_rdy; + + constraint thresholds_c { + solve clk_tested before mesr; + solve mesr before min_offset, max_offset; + if (mesr == MesrLow) { + min_offset inside {[-5 : -3]}; + max_offset inside {[-5 : -3]}; + min_offset <= max_offset; + } else + if (mesr == MesrRight) { + min_offset == -2; + max_offset == 2; + } else + if (mesr == MesrHigh) { + min_offset inside {[3 : 5]}; + max_offset inside {[3 : 5]}; + min_offset <= max_offset; + } + } + + constraint all_clk_en_c { + io_ip_clk_en == 1; + main_ip_clk_en == 1; + usb_ip_clk_en == 1; + } + + function void post_randomize(); + calib_rdy = get_rand_mubi4_val(6, 2, 2); + `uvm_info(`gfn, $sformatf("randomize: calib_rdy=0x%x", calib_rdy), UVM_MEDIUM) + super.post_randomize(); + endfunction + + // Keep saturating the count on aon negedges if needed. + local task maybe_saturate_count(bit saturate, clk_mesr_e clk_tested); + forever begin + @cfg.aon_clk_rst_vif.cbn; + if (saturate) cfg.clkmgr_vif.force_high_starting_count(clk_mesr_e'(clk_tested)); + end + endtask + + // This waits a number of cycles so that: + // - at least one measurement completes, and, + // - the measurement has had time to update the recov_err_code CSR. + task wait_before_read_recov_err_code(bit expect_alert); + // Wait for one measurement (takes an extra cycle to really start). + cfg.aon_clk_rst_vif.wait_clks(CyclesToGetMeasurements); + // Wait for the result to propagate to the recov_err_code CSR. + cfg.clk_rst_vif.wait_clks(CyclesForErrUpdate); + endtask + + // If clocks become uncalibrated measure_ctrl_regwen is re-enabled. + task check_measure_ctrl_regwen_for_calib_rdy(); + logic value; + csr_wr(.ptr(ral.measure_ctrl_regwen), .value(0)); + cfg.clkmgr_vif.update_calib_rdy(MuBi4False); + cfg.clk_rst_vif.wait_clks(20); + calibration_lost_checks(); + endtask + + task body(); + logic [TL_DW-1:0] value; + int prior_alert_count; + int current_alert_count; + + csr_wr(.ptr(ral.measure_ctrl_regwen), .value(1)); + + // Disable alert checks since we cannot make sure a single alert will fire: there is too + // much uncertainty on the cycles for one measurement to complete due to synchronizers. + // This test will instead check whether alerts fire using the alert count. + cfg.scoreboard.do_alert_check = 0; + + // Make sure the aon clock is running as slow as it is meant to. + cfg.aon_clk_rst_vif.set_freq_khz(AonClkHz / 1_000); + control_ip_clocks(); + // Wait so the frequency change takes effect. + cfg.aon_clk_rst_vif.wait_clks(2); + + // Set the thresholds to get no error. + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + enable_frequency_measurement(clk_mesr, ExpectedCounts[clk] - 2, ExpectedCounts[clk] + 2); + end + wait_before_read_recov_err_code('0); + csr_rd_check(.ptr(ral.recov_err_code), .compare_value('0), + .err_msg("Expected no measurement errors")); + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + disable_frequency_measurement(clk_mesr); + end + cfg.aon_clk_rst_vif.wait_clks(CyclesBetweenMeasurements); + // And clear errors. + csr_wr(.ptr(ral.recov_err_code), .value('1)); + + `uvm_info(`gfn, $sformatf("Will run %0d rounds", num_trans), UVM_MEDIUM) + for (int i = 0; i < num_trans; ++i) begin + clkmgr_recov_err_t actual_recov_err = '{default: '0}; + logic [ClkMesrUsb:0] expected_recov_meas_err = '0; + bit expect_alert = 0; + `DV_CHECK_RANDOMIZE_FATAL(this) + // Update calib_rdy input: if calibration is not ready the measurements + // don't happen, so we should not get faults. + cfg.clkmgr_vif.update_calib_rdy(calib_rdy); + `uvm_info(`gfn, $sformatf( + "Updating calib_rdy to 0x%x, predicted regwen 0x%x", + calib_rdy, + ral.measure_ctrl_regwen.get() + ), UVM_MEDIUM) + `uvm_info(`gfn, "New round", UVM_MEDIUM) + // Allow calib_rdy to generate side-effects. + cfg.clk_rst_vif.wait_clks(3); + if (calib_rdy == MuBi4False) calibration_lost_checks(); + prior_alert_count = cfg.scoreboard.get_alert_count("recov_fault"); + if (cause_saturation) `uvm_info(`gfn, "Will cause saturation", UVM_MEDIUM) + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + int min_threshold; + int max_threshold; + int expected = ExpectedCounts[clk]; + if (clk == clk_tested) begin + min_threshold = expected + min_offset; + max_threshold = expected + max_offset; + if (calib_rdy != MuBi4False && + (min_threshold > expected || max_threshold < expected - 1 || cause_saturation)) begin + `uvm_info(`gfn, $sformatf( + "Expect %0s to get a %0s error%0s", + clk_mesr.name, + (cause_saturation ? "fast" : (min_threshold > expected ? "slow" : "fast")), + (cause_saturation ? " due to saturation" : "") + ), UVM_MEDIUM) + expect_alert = 1; + expected_recov_meas_err[clk] = 1; + end + end else begin + min_threshold = expected - 2; + max_threshold = expected + 2; + end + enable_frequency_measurement(clk_mesr, min_threshold, max_threshold); + end + + fork + begin : wait_for_measurements + fork + maybe_saturate_count(cause_saturation, clk_mesr_e'(clk_tested)); + wait_before_read_recov_err_code(expect_alert); + join_any + disable fork; + end + join + + csr_rd(.ptr(ral.recov_err_code), .value(actual_recov_err)); + `uvm_info(`gfn, $sformatf("Expected recov err register=0x%x", expected_recov_meas_err), + UVM_MEDIUM) + if (!cfg.under_reset && actual_recov_err.measures != expected_recov_meas_err) begin + report_recov_error_mismatch("measurement", expected_recov_meas_err, + actual_recov_err.measures); + end + if (actual_recov_err.timeouts != '0) begin + `uvm_error(`gfn, $sformatf( + "Unexpected recoverable timeout error 0b%b", actual_recov_err.timeouts)) + end + if (actual_recov_err.shadow_update != 0) begin + `uvm_error(`gfn, "Unexpected recoverable shadow update error") + end + // Check alerts. + current_alert_count = cfg.scoreboard.get_alert_count("recov_fault"); + if (expect_alert) begin + if (!cfg.under_reset) begin + `DV_CHECK_NE(current_alert_count, prior_alert_count, "expected some alerts to fire") + end + end else begin + `DV_CHECK_EQ(current_alert_count, prior_alert_count, "expected no alerts to fire") + end + + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + disable_frequency_measurement(clk_mesr); + end + + // Wait enough time for measurements to complete, and for alerts to get processed + // by the alert agents so expected alerts are properly wound down. + cfg.aon_clk_rst_vif.wait_clks(CyclesBetweenMeasurements); + // And clear errors. + csr_wr(.ptr(ral.recov_err_code), .value('1)); + cfg.aon_clk_rst_vif.wait_clks(12); + end + // And finally, check that unsetting calib_rdy causes meaesure_ctrl_regwen to be set to 1. + check_measure_ctrl_regwen_for_calib_rdy(); + endtask + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_peri_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_peri_vseq.sv new file mode 100644 index 0000000000000..a389f66d7b8ea --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_peri_vseq.sv @@ -0,0 +1,51 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Tests the control of the peripheral clocks using clk_enables CSR. +// +// This is more general than the corresponding smoke test since it randomizes the initial +// value of clk_enables CSR and the ip_clk_en input. +// +// The expectation is that the peripheral clocks will be sampled at their rate, so this +// sequence needs to wait for the slowest clock to tick before changing enable values. +// The dv environment sets the CSRs clock frequency randomly, so it may run too fast and +// the updates may become a glitch that ends up not sampled in the SVAs. +// To be safe this waits for two cycles of the slowest clock (io_div_4) which is eight +// io_clk cycles. + +class clkmgr_peri_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_peri_vseq) + + `uvm_object_new + + // IO clock cycles to wait before changing clk enable settings. + static int WaitIoCycles = 8; + + rand peri_enables_t initial_enables; + + // The clk_enables CSR cannot be manipulated in low power mode. + constraint io_ip_clk_en_on_c {io_ip_clk_en == 1'b1;} + constraint main_ip_clk_en_on_c {main_ip_clk_en == 1'b1;} + // ICEBOX(#17963) randomize the usb clk enable. + constraint usb_ip_clk_en_on_c {usb_ip_clk_en == 1'b1;} + + task body(); + for (int i = 0; i < num_trans; ++i) begin + peri_enables_t flipped_enables; + `DV_CHECK_RANDOMIZE_FATAL(this) + cfg.clkmgr_vif.init(.idle(idle), .scanmode(scanmode)); + control_ip_clocks(); + csr_wr(.ptr(ral.clk_enables), .value(initial_enables)); + + cfg.io_clk_rst_vif.wait_clks(WaitIoCycles); + // Flip all bits of clk_enables. + flipped_enables = initial_enables ^ ((1 << ral.clk_enables.get_n_bits()) - 1); + csr_wr(.ptr(ral.clk_enables), .value(flipped_enables)); + cfg.io_clk_rst_vif.wait_clks(WaitIoCycles); + end + // And set it back to the reset value for stress tests. + cfg.clk_rst_vif.wait_clks(1); + csr_wr(.ptr(ral.clk_enables), .value(ral.clk_enables.get_reset())); + endtask : body +endclass : clkmgr_peri_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv new file mode 100644 index 0000000000000..ec5d4896a650d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_regwen_vseq.sv @@ -0,0 +1,82 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// The regwen vseq attempts to write to registers whose regwen is randomly on or off to check +// the register contents is not updated when off. More details in the clkmgr_testplan.hjson file. +class clkmgr_regwen_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_regwen_vseq) + + `uvm_object_new + + task check_extclk_regwen(); + bit enable; + int prev_value; + int new_value = {extclk_ctrl_high_speed_sel, extclk_ctrl_sel}; + `DV_CHECK_STD_RANDOMIZE_FATAL(enable) + `uvm_info(`gfn, $sformatf("Check extclk_ctrl regwen set to %b begin", enable), UVM_MEDIUM) + csr_wr(.ptr(ral.extclk_ctrl_regwen), .value(enable)); + csr_rd(.ptr(ral.extclk_ctrl), .value(prev_value)); + csr_wr(.ptr(ral.extclk_ctrl), .value(new_value)); + csr_rd_check(.ptr(ral.extclk_ctrl), .compare_value(enable ? new_value : prev_value)); + `uvm_info(`gfn, "Check extclk_ctrl regwen end", UVM_MEDIUM) + endtask : check_extclk_regwen + + // This must be careful to turn measurements off right after checking the updates + // to avoid measurement errors. We could set the thresholds correctly, but we + // might as well set them randomly for good measure. Carefully masks only the + // real bits for the comparison. + task check_meas_ctrl_regwen(); + bit regwen_enable; + `DV_CHECK_STD_RANDOMIZE_FATAL(regwen_enable) + csr_wr(.ptr(ral.measure_ctrl_regwen), .value(regwen_enable)); + foreach (ExpectedCounts[clk]) begin + clk_mesr_e clk_mesr = clk_mesr_e'(clk); + uvm_reg ctrl_shadowed = meas_ctrl_regs[clk_mesr].ctrl_lo.get_dv_base_reg_parent(); + uvm_reg_data_t prev_en; + mubi4_t new_en = get_rand_mubi4_val(1, 1, 2); + int prev_ctrl; + int new_ctrl = $urandom(); + int actual_ctrl; + int lo_mask = ((1 << meas_ctrl_regs[clk_mesr].ctrl_lo.get_n_bits()) - 1) << + meas_ctrl_regs[clk_mesr].ctrl_lo.get_lsb_pos(); + int hi_mask = ((1 << meas_ctrl_regs[clk_mesr].ctrl_hi.get_n_bits()) - 1) << + meas_ctrl_regs[clk_mesr].ctrl_hi.get_lsb_pos(); + `uvm_info(`gfn, $sformatf( + "Check %0s regwen set to %b begin", meas_ctrl_regs[clk_mesr].name, regwen_enable), + UVM_MEDIUM) + csr_rd(.ptr(meas_ctrl_regs[clk_mesr].en), .value(prev_en)); + csr_rd(.ptr(ctrl_shadowed), .value(prev_ctrl)); + csr_wr(.ptr(ctrl_shadowed), .value(new_ctrl)); + csr_wr(.ptr(meas_ctrl_regs[clk_mesr].en), .value(new_en)); + csr_rd_check(.ptr(meas_ctrl_regs[clk_mesr].en), + .compare_value(mubi4_t'(regwen_enable ? new_en : prev_en))); + csr_rd_check(.ptr(ctrl_shadowed), .compare_value(regwen_enable ? new_ctrl : prev_ctrl), + .compare_mask(lo_mask | hi_mask)); + `uvm_info(`gfn, $sformatf("Check %0s regwen end", meas_ctrl_regs[clk_mesr].name), + UVM_MEDIUM) + csr_wr(.ptr(meas_ctrl_regs[clk_mesr].en), .value(MuBi4False)); + end + endtask : check_meas_ctrl_regwen + + task body(); + // Make sure the aon clock is running as slow as it is meant to, otherwise the aon clock + // runs fast enough that we could end up triggering faults due to the random settings for + // the thresholds. + cfg.aon_clk_rst_vif.set_freq_khz(AonClkHz / 1_000); + + `uvm_info(`gfn, $sformatf("Will run %0d rounds", num_trans), UVM_MEDIUM) + for (int i = 0; i < num_trans; ++i) begin + check_extclk_regwen(); + check_meas_ctrl_regwen(); + apply_reset("HARD"); + // This is to make sure we don't start writes immediately after reset, + // otherwise the tl_agent could mistakenly consider the following read + // happens during reset. + cfg.clk_rst_vif.wait_clks(4); + csr_rd_check(.ptr(ral.extclk_ctrl_regwen), .compare_value(1)); + csr_rd_check(.ptr(ral.measure_ctrl_regwen), .compare_value(1)); + end + endtask : body + +endclass : clkmgr_regwen_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv new file mode 100644 index 0000000000000..6807809aec382 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_smoke_vseq.sv @@ -0,0 +1,108 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// smoke test vseq +class clkmgr_smoke_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_smoke_vseq) + + `uvm_object_new + + constraint io_ip_clk_en_on_c {io_ip_clk_en == 1'b1;} + constraint main_ip_clk_en_on_c {main_ip_clk_en == 1'b1;} + constraint usb_ip_clk_en_on_c {usb_ip_clk_en == 1'b1;} + constraint all_busy_c {idle == IdleAllBusy;} + + task body(); + cfg.clk_rst_vif.wait_clks(10); + test_jitter(); + test_peri_clocks(); + test_trans_clocks(); + endtask : body + + // Simply flip the jitter enable CSR. The side-effects are checked in the scoreboard. + // This needs to be done outside the various CSR tests, since they update the jitter_enable + // CSR, but the scoreboard is disabled for those tests. + task test_jitter(); + prim_mubi_pkg::mubi4_t jitter_value; + for (int i = 0; i < (1 << $bits(prim_mubi_pkg::mubi4_t)); ++i) begin + jitter_value = prim_mubi_pkg::mubi4_t'(i); + csr_wr(.ptr(ral.jitter_enable), .value(jitter_value)); + csr_rd_check(.ptr(ral.jitter_enable), .compare_value(jitter_value)); + // And set it back. + cfg.clk_rst_vif.wait_clks(6); + csr_wr(.ptr(ral.jitter_enable), .value('0)); + csr_rd_check(.ptr(ral.jitter_enable), .compare_value('0)); + end + endtask + + // Flips all clk_enables bits from the reset value with all enabled. All is checked + // via assertions in clkmgr_if.sv and behavioral code in the scoreboard. + task test_peri_clocks(); + // Flip all bits of clk_enables. + peri_enables_t value = ral.clk_enables.get(); + peri_enables_t flipped_value; + csr_rd(.ptr(ral.clk_enables), .value(value)); + flipped_value = value ^ ((1 << ral.clk_enables.get_n_bits()) - 1); + csr_wr(.ptr(ral.clk_enables), .value(flipped_value)); + + // And set it back to the reset value for stress tests. + cfg.clk_rst_vif.wait_clks(1); + csr_wr(.ptr(ral.clk_enables), .value(ral.clk_enables.get_reset())); + endtask : test_peri_clocks + + // Starts with all units busy, and for each one this clears the hint and reads the hint status, + // expecting it to remain at 1 since the unit is busy; then it sets the corresponding idle bit + // and reads status again, expecting it to be low. + // + // We disable the value checks when reset is active since the reads return unpredictable data. + task test_trans_clocks(); + trans_e trans; + logic bit_value; + logic [TL_DW-1:0] value; + mubi_hintables_t idle; + hintables_t bool_idle; + typedef struct { + trans_e unit; + uvm_reg_field hint_bit; + uvm_reg_field value_bit; + } trans_descriptor_t; + trans_descriptor_t trans_descriptors[NUM_TRANS] = '{ + '{TransAes, ral.clk_hints.clk_main_aes_hint, ral.clk_hints_status.clk_main_aes_val}, + '{TransHmac, ral.clk_hints.clk_main_hmac_hint, ral.clk_hints_status.clk_main_hmac_val}, + '{TransKmac, ral.clk_hints.clk_main_kmac_hint, ral.clk_hints_status.clk_main_kmac_val}, + '{TransOtbn, ral.clk_hints.clk_main_otbn_hint, ral.clk_hints_status.clk_main_otbn_val} + }; + idle = 0; + // Changes in idle take at least 10 cycles to stick. + cfg.clkmgr_vif.update_idle(idle); + cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES); + + trans = trans.first; + csr_rd(.ptr(ral.clk_hints), .value(value)); + `uvm_info(`gfn, $sformatf("Starting hints at 0x%0x, idle at 0x%x", value, idle), UVM_MEDIUM) + do begin + trans_descriptor_t descriptor = trans_descriptors[int'(trans)]; + `uvm_info(`gfn, $sformatf("Clearing %s hint bit", descriptor.unit.name), UVM_MEDIUM) + csr_wr(.ptr(descriptor.hint_bit), .value(1'b0)); + csr_rd(.ptr(descriptor.value_bit), .value(bit_value)); + if (!cfg.under_reset) begin + `DV_CHECK_EQ(bit_value, 1'b1, $sformatf( + "%s hint value cannot drop while busy", descriptor.unit.name())) + end + `uvm_info(`gfn, $sformatf("Setting %s idle bit", descriptor.unit.name), UVM_MEDIUM) + cfg.clk_rst_vif.wait_clks(1); + idle[trans] = prim_mubi_pkg::MuBi4True; + cfg.clkmgr_vif.update_idle(idle); + // Some cycles for the logic to settle. + cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES); + csr_rd(.ptr(descriptor.value_bit), .value(bit_value)); + if (!cfg.under_reset) begin + `DV_CHECK_EQ(bit_value, 1'b0, $sformatf( + "%s hint value should drop when idle", descriptor.unit.name())) + end + trans = trans.next(); + end while (trans != trans.first); + csr_wr(.ptr(ral.clk_hints), .value(ral.clk_hints.get_reset())); + endtask : test_trans_clocks +endclass : clkmgr_smoke_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv new file mode 100644 index 0000000000000..c8e0aa5860aa0 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_stress_all_vseq.sv @@ -0,0 +1,44 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// combine all clkmgr seqs (except below seqs) in one seq to run sequentially +// 1. csr seq, which requires scb to be disabled +class clkmgr_stress_all_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_stress_all_vseq) + + `uvm_object_new + + task body(); + string seq_names[] = { + "clkmgr_extclk_vseq", + "clkmgr_frequency_timeout_vseq", + "clkmgr_frequency_vseq", + "clkmgr_peri_vseq", + "clkmgr_smoke_vseq", + "clkmgr_trans_vseq" + }; + for (int i = 1; i <= num_trans; i++) begin + uvm_sequence seq; + clkmgr_base_vseq clkmgr_vseq; + uint seq_idx = $urandom_range(0, seq_names.size - 1); + + seq = create_seq_by_name(seq_names[seq_idx]); + `downcast(clkmgr_vseq, seq) + + // if upper seq disables do_apply_reset for this seq, then can't issue reset + // as upper seq may drive reset + if (do_apply_reset) clkmgr_vseq.do_apply_reset = $urandom_range(0, 1); + else clkmgr_vseq.do_apply_reset = 0; + clkmgr_vseq.set_sequencer(p_sequencer); + `DV_CHECK_RANDOMIZE_FATAL(clkmgr_vseq) + `uvm_info(`gfn, $sformatf("seq_idx = %0d, sequence is %0s", seq_idx, clkmgr_vseq.get_name()), + UVM_MEDIUM) + + clkmgr_vseq.start(p_sequencer); + `uvm_info(`gfn, $sformatf( + "End of sequence %0s with seq_idx = %0d", clkmgr_vseq.get_name(), seq_idx), + UVM_MEDIUM) + end + endtask : body +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv new file mode 100644 index 0000000000000..2474ec2ab394e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_trans_vseq.sv @@ -0,0 +1,96 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// trans test vseq +// This is a more randomized version of the corresponding test in the smoke sequence. +// Starts with random units busy, set the hints at random. The idle units whose hint bit is off +// will be disabled, but the others will remain enabled. Then all units are made idle to check +// that status matches hints. Prior to the next round this raises all hints so all unit clocks are +// running. +// +// Transitions to turn off the clock only go through if idle is asserted for at least 10 main +// cycles, and there is additional synchronizer overhead. +// +// The checks for whether each unit's clock are running are done in SVA. This sequence only +// explicitly checks hints_status. + +class clkmgr_trans_vseq extends clkmgr_base_vseq; + `uvm_object_utils(clkmgr_trans_vseq) + + `uvm_object_new + + rand hintables_t initial_hints; + + // The clk_hints CSR cannot be manipulated in low power mode. + constraint io_ip_clk_en_on_c {io_ip_clk_en == 1'b1;} + constraint main_ip_clk_en_on_c {main_ip_clk_en == 1'b1;} + constraint usb_ip_clk_en_on_c {usb_ip_clk_en == 1'b1;} + + task body(); + for (int i = 0; i < num_trans; ++i) begin + logic bit_value; + hintables_t value; + hintables_t bool_idle; + + `DV_CHECK_RANDOMIZE_FATAL(this) + + csr_rd(.ptr(ral.clk_hints_status), .value(value)); + + `uvm_info(`gfn, $sformatf("Initial clk_hints_status: %b", value), UVM_MEDIUM) + cfg.clkmgr_vif.init(.idle(idle), .scanmode(scanmode)); + + // add random value if mubi idle test + if (mubi_mode == ClkmgrMubiIdle) drive_idle(idle); + print_mubi_hintable(idle); + control_ip_clocks(); + `uvm_info(`gfn, $sformatf("Idle = 0x%x", cfg.clkmgr_vif.idle_i), UVM_MEDIUM) + cfg.clk_rst_vif.wait_clks(10); + `uvm_info(`gfn, $sformatf("Updating hints to 0x%0x", initial_hints), UVM_MEDIUM) + csr_wr(.ptr(ral.clk_hints), .value(initial_hints)); + + // Extra wait because of synchronizers plus counters. + cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES); + // We expect the status to be determined by hints and idle, ignoring scanmode. + bool_idle = mubi_hintables_to_hintables(idle); + value = initial_hints | ~bool_idle; + csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(value), + .err_msg($sformatf( + "Busy units have status high: hints=0x%x, idle=0x%x", + initial_hints, + bool_idle + ))); + + // Setting all idle should make hint_status match hints. + `uvm_info(`gfn, "Setting all units idle", UVM_MEDIUM) + cfg.clkmgr_vif.update_idle({NUM_TRANS{MuBi4True}}); + cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES); + + csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(initial_hints), + .err_msg("All idle: expect status matches hints")); + + // Now set all hints, and the status should also be all ones. + value = '1; + csr_wr(.ptr(ral.clk_hints), .value(value)); + cfg.clk_rst_vif.wait_clks(IDLE_SYNC_CYCLES); + // We expect all units to be on. + csr_rd_check(.ptr(ral.clk_hints_status), .compare_value(value), + .err_msg("All idle and all hints high: units status should be high")); + + // Set hints to the reset value for stress tests. + csr_wr(.ptr(ral.clk_hints), .value(ral.clk_hints.get_reset())); + end + endtask : body + + task drive_idle(ref mubi_hintables_t tbl); + int period; + mubi_hintables_t rand_idle; + foreach (rand_idle[i]) + rand_idle[i] = get_rand_mubi4_val(.t_weight(0), .f_weight(0), .other_weight(1)); + + @cfg.clkmgr_vif.trans_cb; + cfg.clkmgr_vif.idle_i = rand_idle; + + tbl = rand_idle; + endtask : drive_idle +endclass : clkmgr_trans_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_vseq_list.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_vseq_list.sv new file mode 100644 index 0000000000000..c125df499f28a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/env/seq_lib/clkmgr_vseq_list.sv @@ -0,0 +1,15 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "clkmgr_base_vseq.sv" +`include "clkmgr_clk_status_vseq.sv" +`include "clkmgr_common_vseq.sv" +`include "clkmgr_frequency_timeout_vseq.sv" +`include "clkmgr_frequency_vseq.sv" +`include "clkmgr_extclk_vseq.sv" +`include "clkmgr_peri_vseq.sv" +`include "clkmgr_regwen_vseq.sv" +`include "clkmgr_smoke_vseq.sv" +`include "clkmgr_stress_all_vseq.sv" +`include "clkmgr_trans_vseq.sv" diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_aon_cg_en_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_aon_cg_en_sva_if.sv new file mode 100644 index 0000000000000..9e0bcbf7e1e84 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_aon_cg_en_sva_if.sv @@ -0,0 +1,10 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions for clock gating output to alert_handler for +// AON clocks: they are never gated off. +interface clkmgr_aon_cg_en_sva_if (input logic cg_en); + + `ASSERT_INIT_NET(CgEn_A, !cg_en) +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv new file mode 100644 index 0000000000000..101d2ad60d326 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_bind.sv @@ -0,0 +1,323 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module clkmgr_bind; +`ifndef GATE_LEVEL + bind clkmgr 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 clkmgr clkmgr_csr_assert_fpv clkmgr_csr_assert (.clk_i, .rst_ni, .h2d(tl_i), .d2h(tl_o)); +`endif + + bind clkmgr clkmgr_pwrmgr_sva_if #(.IS_USB(0)) clkmgr_pwrmgr_main_sva_if ( + .clk_i, + .rst_ni, + .clk_en(pwr_i.main_ip_clk_en), + .status(pwr_o.main_status) + ); + + bind clkmgr clkmgr_pwrmgr_sva_if #(.IS_USB(0)) clkmgr_pwrmgr_io_sva_if ( + .clk_i, + .rst_ni, + .clk_en(pwr_i.io_ip_clk_en), + .status(pwr_o.io_status) + ); + + bind clkmgr clkmgr_pwrmgr_sva_if #(.IS_USB(1)) clkmgr_pwrmgr_usb_sva_if ( + .clk_i, + .rst_ni, + .clk_en(pwr_i.usb_ip_clk_en), + .status(pwr_o.usb_status) + ); + + bind clkmgr clkmgr_gated_clock_sva_if clkmgr_io_div4_peri_sva_if ( + .clk(clocks_o.clk_io_div4_powerup), + .rst_n(rst_io_div4_ni), + .ip_clk_en(pwr_i.io_ip_clk_en), + .sw_clk_en(clk_io_div4_peri_sw_en), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), + .gated_clk(clocks_o.clk_io_div4_peri) + ); + + bind clkmgr clkmgr_gated_clock_sva_if clkmgr_io_div2_peri_sva_if ( + .clk(clocks_o.clk_io_div2_powerup), + .rst_n(rst_io_div2_ni), + .ip_clk_en(pwr_i.io_ip_clk_en), + .sw_clk_en(clk_io_div2_peri_sw_en), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), + .gated_clk(clocks_o.clk_io_div2_peri) + ); + + bind clkmgr clkmgr_gated_clock_sva_if clkmgr_io_peri_sva_if ( + .clk(clocks_o.clk_io_powerup), + .rst_n(rst_io_ni), + .ip_clk_en(pwr_i.io_ip_clk_en), + .sw_clk_en(clk_io_peri_sw_en), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), + .gated_clk(clocks_o.clk_io_peri) + ); + + bind clkmgr clkmgr_gated_clock_sva_if clkmgr_usb_peri_sva_if ( + .clk(clocks_o.clk_usb_powerup), + .rst_n(rst_usb_ni), + .ip_clk_en(pwr_i.usb_ip_clk_en), + .sw_clk_en(clk_usb_peri_sw_en), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), + .gated_clk(clocks_o.clk_usb_peri) + ); + + // Assertions for transactional clocks. + bind clkmgr clkmgr_trans_sva_if clkmgr_aes_trans_sva_if ( + .clk(clk_main_i), + .rst_n(rst_main_ni), + .hint(reg2hw.clk_hints.clk_main_aes_hint.q), + .idle(idle_i[HintMainAes] == prim_mubi_pkg::MuBi4True), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True), + .status(hw2reg.clk_hints_status.clk_main_aes_val.d), + .trans_clk(clocks_o.clk_main_aes) + ); + + bind clkmgr clkmgr_extclk_sva_if clkmgr_extclk_sva_if ( + .clk_i, + .rst_ni, + .extclk_ctrl_sel, + .extclk_ctrl_hi_speed_sel, + .lc_hw_debug_en_i, + .lc_clk_byp_req_i, + .io_clk_byp_req_o, + .all_clk_byp_req_o, + .hi_speed_sel_o + ); + + bind clkmgr clkmgr_div_sva_if #( + .DIV(2) + ) clkmgr_div2_sva_if ( + .clk(clocks_o.clk_io_powerup), + .rst_n(rst_ni), + .maybe_divided_clk(clocks_o.clk_io_div2_powerup), + .div_step_down_req_i(div_step_down_req_i == prim_mubi_pkg::MuBi4True), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True) + ); + + // The div2 clk also steps, so not a good reference. Instead, check it always tracks io_div2. + bind clkmgr clkmgr_div_sva_if #( + .DIV(4) + ) clkmgr_div4_sva_if ( + .clk(clocks_o.clk_io_div2_powerup), + .rst_n(rst_ni), + .maybe_divided_clk(clocks_o.clk_io_div4_powerup), + .div_step_down_req_i(div_step_down_req_i == prim_mubi_pkg::MuBi4True), + .scanmode(scanmode_i == prim_mubi_pkg::MuBi4True) + ); + + // AON clock gating enables. + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_aon_peri ( + .cg_en(cg_en_o.aon_peri == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_aon_powerup ( + .cg_en(cg_en_o.aon_powerup == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_aon_secure ( + .cg_en(cg_en_o.aon_secure == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_aon_timers ( + .cg_en(cg_en_o.aon_timers == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_io_div2_powerup ( + .cg_en(cg_en_o.io_div2_powerup == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_io_div4_powerup ( + .cg_en(cg_en_o.io_div4_powerup == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_io_powerup ( + .cg_en(cg_en_o.io_powerup == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_main_powerup ( + .cg_en(cg_en_o.main_powerup == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_aon_cg_en_sva_if clkmgr_aon_cg_usb_powerup ( + .cg_en(cg_en_o.usb_powerup == prim_mubi_pkg::MuBi4True) + ); + + // Non-AON clock gating enables with no software control. + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_io_div4_infra ( + .clk(clk_io_div4), + .rst_n(rst_io_div4_ni), + .ip_clk_en(clk_io_div4_en), + .sw_clk_en(1'b1), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.io_div4_infra == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_io_div4_secure ( + .clk(clk_io_div4), + .rst_n(rst_io_div4_ni), + .ip_clk_en(clk_io_div4_en), + .sw_clk_en(1'b1), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.io_div4_secure == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_io_div4_timers ( + .clk(clk_io_div4), + .rst_n(rst_io_div4_ni), + .ip_clk_en(clk_io_div4_en), + .sw_clk_en(1'b1), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.io_div4_timers == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_io_infra ( + .clk(clk_io), + .rst_n(rst_io_ni), + .ip_clk_en(clk_io_en), + .sw_clk_en(1'b1), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.io_infra == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_main_infra ( + .clk(clk_main), + .rst_n(rst_main_ni), + .ip_clk_en(clk_main_en), + .sw_clk_en(1'b1), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.main_infra == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_main_secure ( + .clk(clk_main), + .rst_n(rst_main_ni), + .ip_clk_en(clk_main_en), + .sw_clk_en(1'b1), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.main_secure == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_usb_infra ( + .clk(clk_usb), + .rst_n(rst_usb_ni), + .ip_clk_en(clk_usb_en), + .sw_clk_en(1'b1), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.usb_infra == prim_mubi_pkg::MuBi4True) + ); + + // Software controlled gating enables. + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_io_div4_peri ( + .clk(clk_io_div4), + .rst_n(rst_io_div4_ni), + .ip_clk_en(clk_io_div4_en), + .sw_clk_en(clk_io_div4_peri_sw_en), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.io_div4_peri == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_io_div2_peri ( + .clk(clk_io_div2), + .rst_n(rst_io_div2_ni), + .ip_clk_en(clk_io_div2_en), + .sw_clk_en(clk_io_div2_peri_sw_en), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.io_div2_peri == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_io_peri ( + .clk(clk_io), + .rst_n(rst_io_ni), + .ip_clk_en(clk_io_en), + .sw_clk_en(clk_io_peri_sw_en), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.io_peri == prim_mubi_pkg::MuBi4True) + ); + + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_usb_peri ( + .clk(clk_usb), + .rst_n(rst_usb_ni), + .ip_clk_en(clk_usb_en), + .sw_clk_en(clk_usb_peri_sw_en), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.usb_peri == prim_mubi_pkg::MuBi4True) + ); + + // Hint controlled gating enables. + bind clkmgr clkmgr_cg_en_sva_if clkmgr_cg_main_aes ( + .clk(clk_main_i), + .rst_n(rst_main_ni), + .ip_clk_en(clk_main_en), + .sw_clk_en(u_clk_main_aes_trans.sw_hint_synced || !u_clk_main_aes_trans.idle_valid), + .scanmode(prim_mubi_pkg::MuBi4False), + .cg_en(cg_en_o.main_aes == prim_mubi_pkg::MuBi4True) + ); + + // Calibration assertions. + bind clkmgr clkmgr_lost_calib_regwen_sva_if clkmgr_lost_calib_regwen_sva_if ( + .clk(clk_i), + .rst_n(rst_ni), + .calib_rdy(calib_rdy_i), + .meas_ctrl_regwen(u_reg.measure_ctrl_regwen_qs) + ); + + bind clkmgr clkmgr_lost_calib_ctrl_en_sva_if clkmgr_lost_calib_io_ctrl_en_sva_if ( + .clk(clk_i), + .rst_n(rst_ni), + .calib_rdy(calib_rdy_i), + .meas_ctrl_en(u_reg.io_meas_ctrl_en_qs) + ); + + bind clkmgr clkmgr_lost_calib_ctrl_en_sva_if clkmgr_lost_calib_main_ctrl_en_sva_if ( + .clk(clk_i), + .rst_n(rst_ni), + .calib_rdy(calib_rdy_i), + .meas_ctrl_en(u_reg.main_meas_ctrl_en_qs) + ); + + bind clkmgr clkmgr_lost_calib_ctrl_en_sva_if clkmgr_lost_calib_usb_ctrl_en_sva_if ( + .clk(clk_i), + .rst_n(rst_ni), + .calib_rdy(calib_rdy_i), + .meas_ctrl_en(u_reg.usb_meas_ctrl_en_qs) + ); + + bind clkmgr clkmgr_lost_calib_ctrl_en_sva_if clkmgr_lost_calib_io_div2_ctrl_en_sva_if ( + .clk(clk_i), + .rst_n(rst_ni), + .calib_rdy(calib_rdy_i), + .meas_ctrl_en(u_reg.io_div2_meas_ctrl_en_qs) + ); + + bind clkmgr clkmgr_lost_calib_ctrl_en_sva_if clkmgr_lost_calib_io_div4_ctrl_en_sva_if ( + .clk(clk_i), + .rst_n(rst_ni), + .calib_rdy(calib_rdy_i), + .meas_ctrl_en(u_reg.io_div4_meas_ctrl_en_qs) + ); + + bind clkmgr clkmgr_sec_cm_checker_assert clkmgr_sec_cm_checker_assert ( + .clk_i, + .rst_ni, + .all_clk_byp_req_o, + .lc_hw_debug_en_i, + .lc_clk_byp_req_i, + .lc_clk_byp_ack_o, + .io_clk_byp_req_o, + // internal signal is picked due to inconsistent t->f, f->t delay + .io_clk_byp_ack(u_clkmgr_byp.io_clk_byp_ack), + // internal signal is picked due to inconsistent input to signal delay + .step_down_acks_sync(u_clkmgr_byp.step_down_acks_sync), + .extclk_ctrl_sel + ); +`endif +endmodule : clkmgr_bind diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_cg_en_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_cg_en_sva_if.sv new file mode 100644 index 0000000000000..e995057c8e908 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_cg_en_sva_if.sv @@ -0,0 +1,30 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions for clock gating output to alert_handler. +// - cg_en corresponds to clock gating enabled, which means the clock is gated, +// thus inactive. +// - ip_clk_en and sw_clk_en have the opposite polarity: when they are active +// the clock is enabled. +interface clkmgr_cg_en_sva_if + import prim_mubi_pkg::*; +( + input logic clk, + input logic rst_n, + input logic ip_clk_en, + input logic sw_clk_en, + input prim_mubi_pkg::mubi4_t scanmode, + input logic cg_en +); + + bit disable_sva; + + logic clk_enable; + always_comb clk_enable = ip_clk_en && sw_clk_en; + + `ASSERT(CgEnOn_A, $fell(clk_enable) |=> ##[0:2] clk_enable || cg_en, clk, + !rst_n || scanmode == prim_mubi_pkg::MuBi4True || disable_sva) + `ASSERT(CgEnOff_A, $rose(clk_enable) |=> ##[0:2] !clk_enable || !cg_en, clk, + !rst_n || scanmode == prim_mubi_pkg::MuBi4True || disable_sva) +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_div_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_div_sva_if.sv new file mode 100644 index 0000000000000..acf0408800403 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_div_sva_if.sv @@ -0,0 +1,68 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions for clock dividers. +// - For div2 (DIV == 2) the reference clk is io clock, which is never stepped. +// So when step_down check that the divided clock tracks the reference. This +// means we check at negedge, or we would see nothing interesting. +// - For div4 (DIV == 4) the reference clk is io_div2 clock, which is also stepped. +// So check it is always twice as slow, except during transitions. +// +// All checks at negedges for simplicity. +interface clkmgr_div_sva_if #( + parameter int DIV = 2 +) ( + input logic clk, + input logic rst_n, + input logic maybe_divided_clk, + input logic div_step_down_req_i, + input logic scanmode +); + + localparam int WAIT_CYCLES = 20; + logic step_down; + always_comb step_down = div_step_down_req_i && !scanmode; + + logic step_up; + always_comb step_up = !step_down; + + sequence WholeLeadHigh_S; + step_down || maybe_divided_clk ##1 step_down || !maybe_divided_clk; + endsequence + + sequence WholeLeadLow_S; + step_down || !maybe_divided_clk ##1 step_down || maybe_divided_clk; + endsequence + + if (DIV == 2) begin : g_div2 + + sequence TracksClk_S; step_up || maybe_divided_clk ##1 step_up || maybe_divided_clk; endsequence + + // Notice this fires at negedges, since maybe_divided_clk's value will be on when + // tracking. + `ASSERT(Div2Stepped_A, $rose(step_down) ##1 step_down [* WAIT_CYCLES] |-> TracksClk_S, !clk, + !rst_n) + `ASSERT(Div2Whole_A, + $fell(step_down) ##1 !step_down [* WAIT_CYCLES] |-> WholeLeadLow_S or WholeLeadHigh_S, + !clk, !rst_n) + + end else begin : g_div4 + + sequence StepLeadHigh_S; + step_up || maybe_divided_clk ##1 step_up || !maybe_divided_clk; + endsequence + + sequence StepLeadLow_S; + step_up || !maybe_divided_clk ##1 step_up || maybe_divided_clk; + endsequence + + `ASSERT(Div4Stepped_A, + $rose(step_down) ##1 step_down [* WAIT_CYCLES] |-> StepLeadLow_S or StepLeadHigh_S, + !clk, !rst_n) + `ASSERT(Div4Whole_A, + $fell(step_down) ##1 !step_down [* WAIT_CYCLES] |-> WholeLeadLow_S or WholeLeadHigh_S, + !clk, !rst_n) + + end +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_extclk_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_extclk_sva_if.sv new file mode 100644 index 0000000000000..ab505f527c6a6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_extclk_sva_if.sv @@ -0,0 +1,81 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions to check the external clock bypass control outputs. +// +// Notice when a condition fails we allow the logic to generate non strict mubi values. Ideally it +// would generate mubi False: see https://github.com/lowRISC/opentitan/issues/11400. +interface clkmgr_extclk_sva_if + import prim_mubi_pkg::*, lc_ctrl_pkg::*; +( + input logic clk_i, + input logic rst_ni, + input mubi4_t extclk_ctrl_sel, + input mubi4_t extclk_ctrl_hi_speed_sel, + input lc_tx_t lc_hw_debug_en_i, + input lc_tx_t lc_clk_byp_req_i, + input mubi4_t io_clk_byp_req_o, + input mubi4_t all_clk_byp_req_o, + input mubi4_t hi_speed_sel_o +); + + // The times are to cover the clock domain synchronizers. + localparam int FallCyclesMin = 1; + localparam int FallCyclesMax = 3; + + localparam int RiseCyclesMin = 1; + localparam int RiseCyclesMax = 3; + + bit disable_sva; + + // Check lc_clk_byp_req_i triggers io_clk_byp_req_o. + logic lc_clk_byp_req; + always_comb lc_clk_byp_req = lc_clk_byp_req_i == On; + + `ASSERT(IoClkBypReqRise_A, + $rose( + lc_clk_byp_req + ) |=> ##[RiseCyclesMin:RiseCyclesMax] !lc_clk_byp_req || (io_clk_byp_req_o == MuBi4True), + clk_i, !rst_ni || disable_sva) + `ASSERT(IoClkBypReqFall_A, + $fell( + lc_clk_byp_req + ) |=> ##[FallCyclesMin:FallCyclesMax] lc_clk_byp_req || (io_clk_byp_req_o != MuBi4False), + clk_i, !rst_ni || disable_sva) + + // Check extclk_ctrl triggers all_clk_byp_req_o and hi_speed_sel_o. + logic extclk_sel_enabled; + always_comb extclk_sel_enabled = extclk_ctrl_sel == MuBi4True && lc_hw_debug_en_i == On; + + `ASSERT(AllClkBypReqRise_A, + $rose( + extclk_sel_enabled + ) |=> ##[RiseCyclesMin:RiseCyclesMax] + !extclk_sel_enabled || (all_clk_byp_req_o == MuBi4True), + clk_i, !rst_ni || disable_sva) + `ASSERT(AllClkBypReqFall_A, + $fell( + extclk_sel_enabled + ) |=> ##[FallCyclesMin:FallCyclesMax] + extclk_sel_enabled || (all_clk_byp_req_o != MuBi4True), + clk_i, !rst_ni || disable_sva) + + logic hi_speed_enabled; + always_comb begin + hi_speed_enabled = extclk_ctrl_sel == MuBi4True && extclk_ctrl_hi_speed_sel == MuBi4True && + lc_hw_debug_en_i == On; + end + + `ASSERT(HiSpeedSelRise_A, + $rose( + hi_speed_enabled + ) |=> ##[RiseCyclesMin:RiseCyclesMax] !hi_speed_enabled || (hi_speed_sel_o == MuBi4True), + clk_i, !rst_ni || disable_sva) + `ASSERT(HiSpeedSelFall_A, + $fell( + hi_speed_enabled + ) |=> ##[FallCyclesMin:FallCyclesMax] hi_speed_enabled || (hi_speed_sel_o != MuBi4True), + clk_i, !rst_ni || disable_sva) + +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_gated_clock_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_gated_clock_sva_if.sv new file mode 100644 index 0000000000000..2d532f8613088 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_gated_clock_sva_if.sv @@ -0,0 +1,26 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions for gated clocks. +interface clkmgr_gated_clock_sva_if ( + input logic clk, + input logic rst_n, + input logic ip_clk_en, + input logic sw_clk_en, + input logic scanmode, + input logic gated_clk +); + // This fires at negedges: if the gated clock is inactive its value is expected to be low, + // and viceversa. The assertions pass if clk_enabled is not stable to avoid cycle accuracy, and + // these gated clocks are expected to be changed infrequently. + logic clk_enabled; + always_comb clk_enabled = sw_clk_en && ip_clk_en || scanmode; + + `ASSERT(GateOpen_A, + $rose(clk_enabled) |=> ##[0:3] !clk_enabled || $changed(clk_enabled) || gated_clk, !clk, + !rst_n) + `ASSERT(GateClose_A, + $fell(clk_enabled) |=> ##[0:3] clk_enabled || $changed(clk_enabled) || !gated_clk, !clk, + !rst_n) +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_ctrl_en_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_ctrl_en_sva_if.sv new file mode 100644 index 0000000000000..4b67cd01e628a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_ctrl_en_sva_if.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions to check losing calibration turns off clock measurements. + +interface clkmgr_lost_calib_ctrl_en_sva_if ( + input logic clk, + input logic rst_n, + input logic [$bits(prim_mubi_pkg::mubi4_t)-1:0] calib_rdy, + input logic [$bits(prim_mubi_pkg::mubi4_t)-1:0] meas_ctrl_en +); + // There are two clocks involved, the clock measured and the clkmgr clk_i. + // The latter is io_div4 so it is pretty slow compared to all others. There + // are a number of clock domain crossings, so this needs a large number of + // wait cycles to account for the worst case. + localparam int MAX_CYCLES = 45; + `ASSERT(CtrlEnOn_A, + (calib_rdy == prim_mubi_pkg::MuBi4False && meas_ctrl_en != prim_mubi_pkg::MuBi4False) |=> + ##[0:MAX_CYCLES] (meas_ctrl_en == prim_mubi_pkg::MuBi4False), + clk, !rst_n) +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_regwen_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_regwen_sva_if.sv new file mode 100644 index 0000000000000..47bbf710f60f2 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_lost_calib_regwen_sva_if.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions to check losing calibration enables crtl regwen. + +interface clkmgr_lost_calib_regwen_sva_if ( + input logic clk, + input logic rst_n, + input prim_mubi_pkg::mubi4_t calib_rdy, + input logic meas_ctrl_regwen +); + localparam int MAX_CYCLES = 6; + `ASSERT(RegwenOff_A, + (calib_rdy == prim_mubi_pkg::MuBi4False) |=> ##[0:MAX_CYCLES] meas_ctrl_regwen, clk, + !rst_n) +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sec_cm_checker_assert.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sec_cm_checker_assert.sv new file mode 100644 index 0000000000000..567e26076a850 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sec_cm_checker_assert.sv @@ -0,0 +1,59 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Assertion checker for external clock bypass +// sec cm test +module clkmgr_sec_cm_checker_assert ( + input clk_i, + input rst_ni, + input prim_mubi_pkg::mubi4_t all_clk_byp_req_o, + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + input lc_ctrl_pkg::lc_tx_t lc_clk_byp_req_i, + input lc_ctrl_pkg::lc_tx_t lc_clk_byp_ack_o, + input prim_mubi_pkg::mubi4_t io_clk_byp_req_o, + input prim_mubi_pkg::mubi4_t io_clk_byp_ack, + input logic [1:0] step_down_acks_sync, + input prim_mubi_pkg::mubi4_t extclk_ctrl_sel +); + + bit disable_sva; + bit reset_or_disable; + + always_comb reset_or_disable = !rst_ni || disable_sva; + + // sec_cm_lc_ctrl_intersig_mubi + `ASSERT(AllClkBypReqTrue_A, + lc_hw_debug_en_i == lc_ctrl_pkg::On && extclk_ctrl_sel == prim_mubi_pkg::MuBi4True |=> + all_clk_byp_req_o == prim_mubi_pkg::MuBi4True, + clk_i, reset_or_disable) + `ASSERT(AllClkBypReqFalse_A, + lc_hw_debug_en_i != lc_ctrl_pkg::On || extclk_ctrl_sel != prim_mubi_pkg::MuBi4True |=> + all_clk_byp_req_o != prim_mubi_pkg::MuBi4True, + clk_i, reset_or_disable) + + // sec_cm_lc_ctrl_clk_handshake_intersig_mubi + `ASSERT(IoClkBypReqTrue_A, + lc_clk_byp_req_i == lc_ctrl_pkg::On |=> ##[2:3] + io_clk_byp_req_o == prim_mubi_pkg::MuBi4True, clk_i, reset_or_disable) + `ASSERT(IoClkBypReqFalse_A, + lc_clk_byp_req_i != lc_ctrl_pkg::On |=> ##[2:3] + io_clk_byp_req_o == prim_mubi_pkg::MuBi4False, clk_i, reset_or_disable) + + // sec_cm_clk_handshake_intersig_mubi, sec_cm_div_intersig_mubi + `ASSERT(LcClkBypAckTrue_A, + step_down_acks_sync == 2'b11 && io_clk_byp_ack == prim_mubi_pkg::MuBi4True |=> ($past( + lc_clk_byp_req_i, 3 + ) == lc_clk_byp_ack_o) || ($past( + lc_clk_byp_req_i, 4 + ) != $past( + lc_clk_byp_req_i, 3 + )), + clk_i, reset_or_disable) + `ASSERT(LcClkBypAckFalse_A, + step_down_acks_sync != 2'b11 || + io_clk_byp_ack != prim_mubi_pkg::MuBi4True |=> + lc_clk_byp_ack_o == lc_ctrl_pkg::Off, + clk_i, reset_or_disable) + +endmodule : clkmgr_sec_cm_checker_assert diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva.core new file mode 100644 index 0000000000000..7c744565e7b30 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva.core @@ -0,0 +1,40 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr_sva:0.1 +description: "CLKMGR assertion modules and bind file." +filesets: + files_dv: + depend: + - lowrisc:tlul:headers + - lowrisc:fpv:csr_assert_gen + - lowrisc:opentitan:top_englishbreakfast_clkmgr_sva_ifs:0.1 + files: + - clkmgr_bind.sv + - clkmgr_sec_cm_checker_assert.sv + file_type: systemVerilogSource + + files_formal: + depend: + - lowrisc:opentitan:top_englishbreakfast_clkmgr + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../../data/clkmgr.hjson + +targets: + default: &default_target + filesets: + - files_dv + generate: + - csr_assert_gen + + formal: + <<: *default_target + filesets: + - files_formal + - files_dv + toplevel: clkmgr diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva_ifs.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva_ifs.core new file mode 100644 index 0000000000000..9372bca8ac684 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_sva_ifs.core @@ -0,0 +1,28 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr_sva_ifs:0.1 +description: "CLKMGR SVA interfaces." +filesets: + files_dv: + depend: + - lowrisc:prim:assert + - lowrisc:prim:mubi + - lowrisc:ip:lc_ctrl_pkg + - lowrisc:dv:clkmgr_pwrmgr_sva_if + files: + - clkmgr_aon_cg_en_sva_if.sv + - clkmgr_cg_en_sva_if.sv + - clkmgr_div_sva_if.sv + - clkmgr_extclk_sva_if.sv + - clkmgr_gated_clock_sva_if.sv + - clkmgr_lost_calib_ctrl_en_sva_if.sv + - clkmgr_lost_calib_regwen_sva_if.sv + - clkmgr_trans_sva_if.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_trans_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_trans_sva_if.sv new file mode 100644 index 0000000000000..692e049aac4f6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/sva/clkmgr_trans_sva_if.sv @@ -0,0 +1,35 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This contains SVA assertions for trans clocks. +interface clkmgr_trans_sva_if ( + input logic clk, + input logic rst_n, + input logic hint, + input logic idle, + input logic scanmode, + input logic status, + input logic trans_clk +); + // This fires at negedges: if the trans clock is inactive its value is expected to be low, and + // viceversa. The clock takes some cycles to react to idle and hint. + localparam int MIN_START_CYCLES = 0; + localparam int MAX_START_CYCLES = 3; + + localparam int MIN_STOP_CYCLES = 2; + localparam int MAX_STOP_CYCLES = 15; + + `ASSERT(TransStart_A, + $rose( + hint + ) ##1 hint [* MIN_START_CYCLES] |=> + ##[0:MAX_START_CYCLES-MIN_START_CYCLES] !hint || trans_clk, + !clk, !rst_n) + `ASSERT(TransStop_A, + $fell( + hint || !idle || scanmode + ) ##1 !hint && !scanmode [* MIN_STOP_CYCLES] |=> + ##[0:MAX_STOP_CYCLES-MIN_STOP_CYCLES] hint || scanmode || !trans_clk, + !clk, !rst_n) +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tb.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tb.sv new file mode 100644 index 0000000000000..b7fbf60bf322a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tb.sv @@ -0,0 +1,211 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 clkmgr_env_pkg::*; + import clkmgr_test_pkg::*; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + wire clk, rst_n, rst_shadowed_n; + wire clk_main, rst_main_n; + wire clk_io, rst_io_n; + wire clk_usb, rst_usb_n; + wire clk_aon, rst_aon_n; + + // clock interfaces + clk_rst_if clk_rst_if ( + .clk (clk), + .rst_n(rst_n) + ); + clk_rst_if main_clk_rst_if ( + .clk (clk_main), + .rst_n(rst_main_n) + ); + clk_rst_if io_clk_rst_if ( + .clk (clk_io), + .rst_n(rst_io_n) + ); + clk_rst_if usb_clk_rst_if ( + .clk (clk_usb), + .rst_n(rst_usb_n) + ); + clk_rst_if aon_clk_rst_if ( + .clk (clk_aon), + .rst_n(rst_aon_n) + ); + clk_rst_if root_io_clk_rst_if ( + .clk (), + .rst_n(rst_root_io_n) + ); + clk_rst_if root_main_clk_rst_if ( + .clk (), + .rst_n(rst_root_main_n) + ); + clk_rst_if root_usb_clk_rst_if ( + .clk (), + .rst_n(rst_root_usb_n) + ); + + tl_if tl_if ( + .clk (clk), + .rst_n(rst_n) + ); + + // The clkmgr interface. + clkmgr_if clkmgr_if ( + .clk(clk), + .rst_n(rst_n), + .clk_main(clk_main), + .rst_io_n(rst_io_n), + .rst_main_n(rst_main_n), + .rst_usb_n(rst_usb_n) + ); + + bind clkmgr clkmgr_csrs_if clkmgr_csrs_if ( + .clk(clk_i), + .recov_err_csr({ + u_reg.u_recov_err_code_usb_timeout_err.qs, + u_reg.u_recov_err_code_main_timeout_err.qs, + u_reg.u_recov_err_code_io_div4_timeout_err.qs, + u_reg.u_recov_err_code_io_div2_timeout_err.qs, + u_reg.u_recov_err_code_io_timeout_err.qs, + u_reg.u_recov_err_code_usb_measure_err.qs, + u_reg.u_recov_err_code_main_measure_err.qs, + u_reg.u_recov_err_code_io_div4_measure_err.qs, + u_reg.u_recov_err_code_io_div2_measure_err.qs, + u_reg.u_recov_err_code_io_measure_err.qs, + u_reg.u_recov_err_code_shadow_update_err.qs + }), + .fatal_err_csr({ + u_reg.u_fatal_err_code_shadow_storage_err.qs, + u_reg.u_fatal_err_code_idle_cnt.qs, + u_reg.u_fatal_err_code_reg_intg.qs + }), + .clk_enables({ + reg2hw.clk_enables.clk_usb_peri_en.q, + reg2hw.clk_enables.clk_io_peri_en.q, + reg2hw.clk_enables.clk_io_div2_peri_en.q, + reg2hw.clk_enables.clk_io_div4_peri_en.q}), + .clk_hints({ + reg2hw.clk_hints.clk_main_otbn_hint.q, + reg2hw.clk_hints.clk_main_kmac_hint.q, + reg2hw.clk_hints.clk_main_hmac_hint.q, + reg2hw.clk_hints.clk_main_aes_hint.q}) + ); + + rst_shadowed_if rst_shadowed_if ( + .rst_n(rst_n), + .rst_shadowed_n(rst_shadowed_n) + ); + + initial begin + // Clocks must be set to active at time 0. The rest of the clock configuration happens + // in clkmgr_base_vseq.sv. + clk_rst_if.set_active(); + main_clk_rst_if.set_active(); + io_clk_rst_if.set_active(); + usb_clk_rst_if.set_active(); + aon_clk_rst_if.set_active(); + + root_io_clk_rst_if.set_active(); + root_main_clk_rst_if.set_active(); + root_usb_clk_rst_if.set_active(); + end + + `DV_ALERT_IF_CONNECT() + + // dut + clkmgr dut ( + .clk_i(clk), + .rst_ni(rst_n), + .rst_shadowed_ni(rst_shadowed_n), + + .clk_main_i (clk_main), + .rst_main_ni(rst_main_n), + .clk_io_i (clk_io), + // ICEBOX(#17934): differentiate the io resets to check they generate the + // expected side-effects. Probably doable with a very simple test. + .rst_io_ni (rst_io_n), + .rst_io_div2_ni(rst_io_n), + .rst_io_div4_ni(rst_io_n), + .clk_usb_i (clk_usb), + .rst_usb_ni (rst_usb_n), + .clk_aon_i (clk_aon), + .rst_aon_ni (rst_aon_n), + + // ICEBOX(#17934): differentiate the root resets as mentioned for rst_io_ni above. + .rst_root_ni(rst_root_io_n), + .rst_root_io_ni(rst_root_io_n), + .rst_root_io_div2_ni(rst_root_io_n), + .rst_root_io_div4_ni(rst_root_io_n), + .rst_root_main_ni(rst_root_main_n), + .rst_root_usb_ni(rst_root_usb_n), + + .tl_i(tl_if.h2d), + .tl_o(tl_if.d2h), + + .alert_rx_i(alert_rx), + .alert_tx_o(alert_tx), + + .pwr_i(clkmgr_if.pwr_i), + .pwr_o(clkmgr_if.pwr_o), + + .scanmode_i(clkmgr_if.scanmode_i), + .idle_i (clkmgr_if.idle_i), + + .lc_hw_debug_en_i(clkmgr_if.lc_hw_debug_en_i), + .all_clk_byp_req_o(clkmgr_if.all_clk_byp_req), + .all_clk_byp_ack_i(clkmgr_if.all_clk_byp_ack), + .io_clk_byp_req_o(clkmgr_if.io_clk_byp_req), + .io_clk_byp_ack_i(clkmgr_if.io_clk_byp_ack), + .lc_clk_byp_req_i(clkmgr_if.lc_clk_byp_req), + .lc_clk_byp_ack_o(clkmgr_if.lc_clk_byp_ack), + .div_step_down_req_i(clkmgr_if.div_step_down_req), + + .cg_en_o(), + + .jitter_en_o(clkmgr_if.jitter_en_o), + .clocks_o (clkmgr_if.clocks_o), + + .calib_rdy_i(clkmgr_if.calib_rdy), + .hi_speed_sel_o(clkmgr_if.hi_speed_sel) + ); + + initial begin + // Register interfaces with uvm. + 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", "main_clk_rst_vif", main_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "io_clk_rst_vif", io_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "usb_clk_rst_vif", usb_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "aon_clk_rst_vif", aon_clk_rst_if); + + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "root_io_clk_rst_vif", + root_io_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "root_main_clk_rst_vif", + root_main_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "root_usb_clk_rst_vif", + root_usb_clk_rst_if); + + uvm_config_db#(virtual clkmgr_if)::set(null, "*.env", "clkmgr_vif", clkmgr_if); + + uvm_config_db#(virtual clkmgr_csrs_if)::set(null, "*.env", "clkmgr_csrs_vif", + dut.clkmgr_csrs_if); + + // FIXME Un-comment this once interrupts are created for this ip. + // uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if); + + uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if); + uvm_config_db#(virtual rst_shadowed_if)::set(null, "*.env", "rst_shadowed_vif", + rst_shadowed_if); + $timeformat(-12, 0, " ps", 12); + run_test(); + end + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_base_test.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_base_test.sv new file mode 100644 index 0000000000000..a0ddd45839bd1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_base_test.sv @@ -0,0 +1,20 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class clkmgr_base_test extends cip_base_test #( + .CFG_T(clkmgr_env_cfg), + .ENV_T(clkmgr_env) +); + + `uvm_component_utils(clkmgr_base_test) + `uvm_component_new + + // the base class dv_base_test creates the following instances: + // clkmgr_env_cfg: cfg + // clkmgr_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 : clkmgr_base_test diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test.core b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test.core new file mode 100644 index 0000000000000..10c1f96ef9e8c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_clkmgr_test:0.1 +description: "CLKMGR DV UVM test" +filesets: + files_dv: + depend: + - lowrisc:opentitan:top_englishbreakfast_clkmgr_env:0.1 + files: + - clkmgr_test_pkg.sv + - clkmgr_base_test.sv: {is_include_file: true} + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test_pkg.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test_pkg.sv new file mode 100644 index 0000000000000..0d1e07762f22f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/dv/tests/clkmgr_test_pkg.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package clkmgr_test_pkg; + // dep packages + import uvm_pkg::*; + import cip_base_pkg::*; + import clkmgr_env_pkg::*; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + // local types + + // functions + + // package sources + `include "clkmgr_base_test.sv" + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.vlt b/hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.vlt new file mode 100644 index 0000000000000..f71656fb1304b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.vlt @@ -0,0 +1,5 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// waiver file for clkmgr diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.waiver b/hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.waiver new file mode 100644 index 0000000000000..49663c1a7f696 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/lint/clkmgr.waiver @@ -0,0 +1,21 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# waiver file for clkmgr + +# +# fake errors + +waive -rules INPUT_NOT_READ -location {prim_clock_gating.sv} -regexp {.*} \ + -comment "Generated abstraction files use .*'s which create fake errors" + +waive -rules EMPTY_PARAM_LIST -location {prim_clock_gating.sv} -regexp {.*} \ + -comment "Generated abstraction files may have empty params" + +waive -rules OUTPUT_NOT_DRIVEN -location {prim_clock_gating.sv} -regexp {.*} \ + -comment "Generated abstraction files do not detect drivers" + +# clock mux errors +waive -rules CLOCK_MUX -location {clkmgr.sv} -regexp {.*clk_io_div.* is driven by a multiplexer here} \ + -comment "All divided clocks terminate with a scan mux" diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr.sv new file mode 100644 index 0000000000000..01a3c9002da4b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr.sv @@ -0,0 +1,983 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// The overall clock manager + + +`include "prim_assert.sv" + + module clkmgr + import clkmgr_pkg::*; + import clkmgr_reg_pkg::*; + import lc_ctrl_pkg::lc_tx_t; + import prim_mubi_pkg::mubi4_t; +#( + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}} +) ( + // Primary module control clocks and resets + // This drives the register interface + input clk_i, + input rst_ni, + input rst_shadowed_ni, + + // System clocks and resets + // These are the source clocks for the system + input clk_main_i, + input rst_main_ni, + input clk_io_i, + input rst_io_ni, + input clk_usb_i, + input rst_usb_ni, + input clk_aon_i, + input rst_aon_ni, + + // Resets for derived clocks + // clocks are derived locally + input rst_io_div2_ni, + input rst_io_div4_ni, + + // Resets for derived clock generation, root clock gating and related status + input rst_root_ni, + input rst_root_main_ni, + input rst_root_io_ni, + input rst_root_io_div2_ni, + input rst_root_io_div4_ni, + input rst_root_usb_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, + + // pwrmgr interface + input pwrmgr_pkg::pwr_clk_req_t pwr_i, + output pwrmgr_pkg::pwr_clk_rsp_t pwr_o, + + // dft interface + input prim_mubi_pkg::mubi4_t scanmode_i, + + // idle hints + // SEC_CM: IDLE.INTERSIG.MUBI + input prim_mubi_pkg::mubi4_t [0:0] idle_i, + + // life cycle state output + // SEC_CM: LC_CTRL.INTERSIG.MUBI + input lc_tx_t lc_hw_debug_en_i, + + // clock bypass control with lc_ctrl + // SEC_CM: LC_CTRL_CLK_HANDSHAKE.INTERSIG.MUBI + input lc_tx_t lc_clk_byp_req_i, + output lc_tx_t lc_clk_byp_ack_o, + + // clock bypass control with ast + // SEC_CM: CLK_HANDSHAKE.INTERSIG.MUBI + output mubi4_t io_clk_byp_req_o, + input mubi4_t io_clk_byp_ack_i, + output mubi4_t all_clk_byp_req_o, + input mubi4_t all_clk_byp_ack_i, + output mubi4_t hi_speed_sel_o, + + // clock calibration has been done. + // If this is signal is 0, assume clock frequencies to be + // uncalibrated. + input prim_mubi_pkg::mubi4_t calib_rdy_i, + + // jittery enable to ast + output mubi4_t jitter_en_o, + + // external indication for whether dividers should be stepped down + // SEC_CM: DIV.INTERSIG.MUBI + input mubi4_t div_step_down_req_i, + + // clock gated indications going to alert handlers + output clkmgr_cg_en_t cg_en_o, + + // clock output interface + output clkmgr_out_t clocks_o + +); + + import prim_mubi_pkg::MuBi4False; + import prim_mubi_pkg::MuBi4True; + import prim_mubi_pkg::mubi4_test_true_strict; + import prim_mubi_pkg::mubi4_test_true_loose; + import prim_mubi_pkg::mubi4_test_false_strict; + + // Hookup point for OCC's on root clocks. + logic clk_main; + prim_clock_buf #( + .NoFpgaBuf(1'b1) + ) u_clk_main_buf ( + .clk_i(clk_main_i), + .clk_o(clk_main) + ); + logic clk_io; + prim_clock_buf #( + .NoFpgaBuf(1'b1) + ) u_clk_io_buf ( + .clk_i(clk_io_i), + .clk_o(clk_io) + ); + logic clk_usb; + prim_clock_buf #( + .NoFpgaBuf(1'b1) + ) u_clk_usb_buf ( + .clk_i(clk_usb_i), + .clk_o(clk_usb) + ); + logic clk_aon; + prim_clock_buf #( + .NoFpgaBuf(1'b1) + ) u_clk_aon_buf ( + .clk_i(clk_aon_i), + .clk_o(clk_aon) + ); + + //////////////////////////////////////////////////// + // External step down request + //////////////////////////////////////////////////// + mubi4_t io_step_down_req; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(1), + .StabilityCheck(1), + .ResetValue(MuBi4False) + ) u_io_step_down_req_sync ( + .clk_i(clk_io), + .rst_ni(rst_io_ni), + .mubi_i(div_step_down_req_i), + .mubi_o({io_step_down_req}) + ); + + + //////////////////////////////////////////////////// + // Divided clocks + // Note divided clocks must use the por version of + // its related reset to ensure clock division + // can happen without any dependency + //////////////////////////////////////////////////// + + logic [1:0] step_down_acks; + + logic clk_io_div2; + logic clk_io_div4; + + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] io_div2_div_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_io_div2_div_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o({io_div2_div_scanmode}) + ); + + prim_clock_div #( + .Divisor(2) + ) u_no_scan_io_div2_div ( + // We're using the pre-occ hookup (*_i) version for clock derivation. + .clk_i(clk_io_i), + .rst_ni(rst_root_io_ni), + .step_down_req_i(mubi4_test_true_strict(io_step_down_req)), + .step_down_ack_o(step_down_acks[0]), + .test_en_i(mubi4_test_true_strict(io_div2_div_scanmode[0])), + .clk_o(clk_io_div2) + ); + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] io_div4_div_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_io_div4_div_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o({io_div4_div_scanmode}) + ); + + prim_clock_div #( + .Divisor(4) + ) u_no_scan_io_div4_div ( + // We're using the pre-occ hookup (*_i) version for clock derivation. + .clk_i(clk_io_i), + .rst_ni(rst_root_io_ni), + .step_down_req_i(mubi4_test_true_strict(io_step_down_req)), + .step_down_ack_o(step_down_acks[1]), + .test_en_i(mubi4_test_true_strict(io_div4_div_scanmode[0])), + .clk_o(clk_io_div4) + ); + + //////////////////////////////////////////////////// + // Register Interface + //////////////////////////////////////////////////// + + logic [NumAlerts-1:0] alert_test, alerts; + clkmgr_reg_pkg::clkmgr_reg2hw_t reg2hw; + clkmgr_reg_pkg::clkmgr_hw2reg_t hw2reg; + + // SEC_CM: MEAS.CONFIG.REGWEN + // SEC_CM: MEAS.CONFIG.SHADOW + // SEC_CM: CLK_CTRL.CONFIG.REGWEN + clkmgr_reg_top u_reg ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + .clk_io_i(clk_io), + .rst_io_ni, + .clk_io_div4_i(clk_io_div4), + .rst_io_div4_ni, + .clk_main_i(clk_main), + .rst_main_ni, + .clk_usb_i(clk_usb), + .rst_usb_ni, + .tl_i, + .tl_o, + .reg2hw, + .hw2reg, + .shadowed_storage_err_o(hw2reg.fatal_err_code.shadow_storage_err.de), + .shadowed_update_err_o(hw2reg.recov_err_code.shadow_update_err.de), + // SEC_CM: BUS.INTEGRITY + .intg_err_o(hw2reg.fatal_err_code.reg_intg.de) + ); + assign hw2reg.fatal_err_code.reg_intg.d = 1'b1; + assign hw2reg.recov_err_code.shadow_update_err.d = 1'b1; + assign hw2reg.fatal_err_code.shadow_storage_err.d = 1'b1; + + //////////////////////////////////////////////////// + // Alerts + //////////////////////////////////////////////////// + + assign alert_test = { + reg2hw.alert_test.fatal_fault.q & reg2hw.alert_test.fatal_fault.qe, + reg2hw.alert_test.recov_fault.q & reg2hw.alert_test.recov_fault.qe + }; + + logic recov_alert; + assign recov_alert = + hw2reg.recov_err_code.io_measure_err.de | + hw2reg.recov_err_code.io_timeout_err.de | + hw2reg.recov_err_code.io_div4_measure_err.de | + hw2reg.recov_err_code.io_div4_timeout_err.de | + hw2reg.recov_err_code.main_measure_err.de | + hw2reg.recov_err_code.main_timeout_err.de | + hw2reg.recov_err_code.usb_measure_err.de | + hw2reg.recov_err_code.usb_timeout_err.de | + hw2reg.recov_err_code.shadow_update_err.de; + + assign alerts = { + |reg2hw.fatal_err_code, + recov_alert + }; + + localparam logic [NumAlerts-1:0] AlertFatal = {1'b1, 1'b0}; + + for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx + prim_alert_sender #( + .AsyncOn(AlertAsyncOn[i]), + .IsFatal(AlertFatal[i]) + ) u_prim_alert_sender ( + .clk_i, + .rst_ni, + .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 + + //////////////////////////////////////////////////// + // Clock bypass request + //////////////////////////////////////////////////// + + mubi4_t extclk_ctrl_sel; + mubi4_t extclk_ctrl_hi_speed_sel; + + assign extclk_ctrl_sel = mubi4_t'(reg2hw.extclk_ctrl.sel.q); + assign extclk_ctrl_hi_speed_sel = mubi4_t'(reg2hw.extclk_ctrl.hi_speed_sel.q); + + clkmgr_byp #( + .NumDivClks(2) + ) u_clkmgr_byp ( + .clk_i, + .rst_ni, + .en_i(lc_hw_debug_en_i), + .lc_clk_byp_req_i, + .lc_clk_byp_ack_o, + .byp_req_i(extclk_ctrl_sel), + .byp_ack_o(hw2reg.extclk_status.d), + .hi_speed_sel_i(extclk_ctrl_hi_speed_sel), + .all_clk_byp_req_o, + .all_clk_byp_ack_i, + .io_clk_byp_req_o, + .io_clk_byp_ack_i, + .hi_speed_sel_o, + + // divider step down controls + .step_down_acks_i(step_down_acks) + ); + + //////////////////////////////////////////////////// + // Feed through clocks + // Feed through clocks do not actually need to be in clkmgr, as they are + // completely untouched. The only reason they are here is for easier + // bundling management purposes through clocks_o + //////////////////////////////////////////////////// + prim_clock_buf u_clk_io_div4_powerup_buf ( + .clk_i(clk_io_div4), + .clk_o(clocks_o.clk_io_div4_powerup) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.io_div4_powerup = MuBi4False; + prim_clock_buf u_clk_aon_powerup_buf ( + .clk_i(clk_aon), + .clk_o(clocks_o.clk_aon_powerup) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.aon_powerup = MuBi4False; + prim_clock_buf u_clk_main_powerup_buf ( + .clk_i(clk_main), + .clk_o(clocks_o.clk_main_powerup) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.main_powerup = MuBi4False; + prim_clock_buf u_clk_io_powerup_buf ( + .clk_i(clk_io), + .clk_o(clocks_o.clk_io_powerup) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.io_powerup = MuBi4False; + prim_clock_buf u_clk_usb_powerup_buf ( + .clk_i(clk_usb), + .clk_o(clocks_o.clk_usb_powerup) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.usb_powerup = MuBi4False; + prim_clock_buf u_clk_io_div2_powerup_buf ( + .clk_i(clk_io_div2), + .clk_o(clocks_o.clk_io_div2_powerup) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.io_div2_powerup = MuBi4False; + prim_clock_buf u_clk_aon_secure_buf ( + .clk_i(clk_aon), + .clk_o(clocks_o.clk_aon_secure) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.aon_secure = MuBi4False; + prim_clock_buf u_clk_aon_peri_buf ( + .clk_i(clk_aon), + .clk_o(clocks_o.clk_aon_peri) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.aon_peri = MuBi4False; + prim_clock_buf u_clk_aon_timers_buf ( + .clk_i(clk_aon), + .clk_o(clocks_o.clk_aon_timers) + ); + + // clock gated indication for alert handler: these clocks are never gated. + assign cg_en_o.aon_timers = MuBi4False; + + //////////////////////////////////////////////////// + // Distribute pwrmgr ip_clk_en requests to each family + //////////////////////////////////////////////////// + // clk_main family + logic pwrmgr_main_en; + assign pwrmgr_main_en = pwr_i.main_ip_clk_en; + // clk_io family + logic pwrmgr_io_en; + logic pwrmgr_io_div2_en; + logic pwrmgr_io_div4_en; + assign pwrmgr_io_en = pwr_i.io_ip_clk_en; + assign pwrmgr_io_div2_en = pwr_i.io_ip_clk_en; + assign pwrmgr_io_div4_en = pwr_i.io_ip_clk_en; + // clk_usb family + logic pwrmgr_usb_en; + assign pwrmgr_usb_en = pwr_i.usb_ip_clk_en; + + //////////////////////////////////////////////////// + // Root gating + //////////////////////////////////////////////////// + + // clk_main family + logic [0:0] main_ens; + + logic clk_main_en; + logic clk_main_root; + clkmgr_root_ctrl u_main_root_ctrl ( + .clk_i(clk_main), + .rst_ni(rst_root_main_ni), + .scanmode_i, + .async_en_i(pwrmgr_main_en), + .en_o(clk_main_en), + .clk_o(clk_main_root) + ); + assign main_ens[0] = clk_main_en; + + // create synchronized status + clkmgr_clk_status #( + .NumClocks(1) + ) u_main_status ( + .clk_i, + .rst_ni(rst_root_ni), + .ens_i(main_ens), + .status_o(pwr_o.main_status) + ); + + // clk_io family + logic [2:0] io_ens; + + logic clk_io_en; + logic clk_io_root; + clkmgr_root_ctrl u_io_root_ctrl ( + .clk_i(clk_io), + .rst_ni(rst_root_io_ni), + .scanmode_i, + .async_en_i(pwrmgr_io_en), + .en_o(clk_io_en), + .clk_o(clk_io_root) + ); + assign io_ens[0] = clk_io_en; + + logic clk_io_div2_en; + logic clk_io_div2_root; + clkmgr_root_ctrl u_io_div2_root_ctrl ( + .clk_i(clk_io_div2), + .rst_ni(rst_root_io_div2_ni), + .scanmode_i, + .async_en_i(pwrmgr_io_div2_en), + .en_o(clk_io_div2_en), + .clk_o(clk_io_div2_root) + ); + assign io_ens[1] = clk_io_div2_en; + + logic clk_io_div4_en; + logic clk_io_div4_root; + clkmgr_root_ctrl u_io_div4_root_ctrl ( + .clk_i(clk_io_div4), + .rst_ni(rst_root_io_div4_ni), + .scanmode_i, + .async_en_i(pwrmgr_io_div4_en), + .en_o(clk_io_div4_en), + .clk_o(clk_io_div4_root) + ); + assign io_ens[2] = clk_io_div4_en; + + // create synchronized status + clkmgr_clk_status #( + .NumClocks(3) + ) u_io_status ( + .clk_i, + .rst_ni(rst_root_ni), + .ens_i(io_ens), + .status_o(pwr_o.io_status) + ); + + // clk_usb family + logic [0:0] usb_ens; + + logic clk_usb_en; + logic clk_usb_root; + clkmgr_root_ctrl u_usb_root_ctrl ( + .clk_i(clk_usb), + .rst_ni(rst_root_usb_ni), + .scanmode_i, + .async_en_i(pwrmgr_usb_en), + .en_o(clk_usb_en), + .clk_o(clk_usb_root) + ); + assign usb_ens[0] = clk_usb_en; + + // create synchronized status + clkmgr_clk_status #( + .NumClocks(1) + ) u_usb_status ( + .clk_i, + .rst_ni(rst_root_ni), + .ens_i(usb_ens), + .status_o(pwr_o.usb_status) + ); + + //////////////////////////////////////////////////// + // Clock Measurement for the roots + // SEC_CM: TIMEOUT.CLK.BKGN_CHK, MEAS.CLK.BKGN_CHK + //////////////////////////////////////////////////// + + typedef enum logic [2:0] { + BaseIdx, + ClkIoIdx, + ClkIoDiv4Idx, + ClkMainIdx, + ClkUsbIdx, + CalibRdyLastIdx + } clkmgr_calib_idx_e; + + // if clocks become uncalibrated, allow the measurement control configurations to change + mubi4_t [CalibRdyLastIdx-1:0] calib_rdy; + prim_mubi4_sync #( + .AsyncOn(1), + .NumCopies(int'(CalibRdyLastIdx)), + .ResetValue(MuBi4False) + ) u_calib_rdy_sync ( + .clk_i, + .rst_ni, + .mubi_i(calib_rdy_i), + .mubi_o({calib_rdy}) + ); + + always_comb begin + hw2reg.measure_ctrl_regwen.de = '0; + hw2reg.measure_ctrl_regwen.d = reg2hw.measure_ctrl_regwen; + + if (mubi4_test_false_strict(calib_rdy[BaseIdx])) begin + hw2reg.measure_ctrl_regwen.de = 1'b1; + hw2reg.measure_ctrl_regwen.d = 1'b1; + end + end + + clkmgr_meas_chk #( + .Cnt(960), + .RefCnt(1) + ) u_io_meas ( + .clk_i, + .rst_ni, + .clk_src_i(clk_io), + .rst_src_ni(rst_io_ni), + .clk_ref_i(clk_aon), + .rst_ref_ni(rst_aon_ni), + // signals on source domain + .src_en_i(clk_io_en & mubi4_test_true_loose(mubi4_t'(reg2hw.io_meas_ctrl_en))), + .src_max_cnt_i(reg2hw.io_meas_ctrl_shadowed.hi.q), + .src_min_cnt_i(reg2hw.io_meas_ctrl_shadowed.lo.q), + .src_cfg_meas_en_i(mubi4_t'(reg2hw.io_meas_ctrl_en.q)), + .src_cfg_meas_en_valid_o(hw2reg.io_meas_ctrl_en.de), + .src_cfg_meas_en_o(hw2reg.io_meas_ctrl_en.d), + // signals on local clock domain + .calib_rdy_i(calib_rdy[ClkIoIdx]), + .meas_err_o(hw2reg.recov_err_code.io_measure_err.de), + .timeout_err_o(hw2reg.recov_err_code.io_timeout_err.de) + ); + + assign hw2reg.recov_err_code.io_measure_err.d = 1'b1; + assign hw2reg.recov_err_code.io_timeout_err.d = 1'b1; + + + clkmgr_meas_chk #( + .Cnt(240), + .RefCnt(1) + ) u_io_div4_meas ( + .clk_i, + .rst_ni, + .clk_src_i(clk_io_div4), + .rst_src_ni(rst_io_div4_ni), + .clk_ref_i(clk_aon), + .rst_ref_ni(rst_aon_ni), + // signals on source domain + .src_en_i(clk_io_div4_en & mubi4_test_true_loose(mubi4_t'(reg2hw.io_div4_meas_ctrl_en))), + .src_max_cnt_i(reg2hw.io_div4_meas_ctrl_shadowed.hi.q), + .src_min_cnt_i(reg2hw.io_div4_meas_ctrl_shadowed.lo.q), + .src_cfg_meas_en_i(mubi4_t'(reg2hw.io_div4_meas_ctrl_en.q)), + .src_cfg_meas_en_valid_o(hw2reg.io_div4_meas_ctrl_en.de), + .src_cfg_meas_en_o(hw2reg.io_div4_meas_ctrl_en.d), + // signals on local clock domain + .calib_rdy_i(calib_rdy[ClkIoDiv4Idx]), + .meas_err_o(hw2reg.recov_err_code.io_div4_measure_err.de), + .timeout_err_o(hw2reg.recov_err_code.io_div4_timeout_err.de) + ); + + assign hw2reg.recov_err_code.io_div4_measure_err.d = 1'b1; + assign hw2reg.recov_err_code.io_div4_timeout_err.d = 1'b1; + + + clkmgr_meas_chk #( + .Cnt(1000), + .RefCnt(1) + ) u_main_meas ( + .clk_i, + .rst_ni, + .clk_src_i(clk_main), + .rst_src_ni(rst_main_ni), + .clk_ref_i(clk_aon), + .rst_ref_ni(rst_aon_ni), + // signals on source domain + .src_en_i(clk_main_en & mubi4_test_true_loose(mubi4_t'(reg2hw.main_meas_ctrl_en))), + .src_max_cnt_i(reg2hw.main_meas_ctrl_shadowed.hi.q), + .src_min_cnt_i(reg2hw.main_meas_ctrl_shadowed.lo.q), + .src_cfg_meas_en_i(mubi4_t'(reg2hw.main_meas_ctrl_en.q)), + .src_cfg_meas_en_valid_o(hw2reg.main_meas_ctrl_en.de), + .src_cfg_meas_en_o(hw2reg.main_meas_ctrl_en.d), + // signals on local clock domain + .calib_rdy_i(calib_rdy[ClkMainIdx]), + .meas_err_o(hw2reg.recov_err_code.main_measure_err.de), + .timeout_err_o(hw2reg.recov_err_code.main_timeout_err.de) + ); + + assign hw2reg.recov_err_code.main_measure_err.d = 1'b1; + assign hw2reg.recov_err_code.main_timeout_err.d = 1'b1; + + + clkmgr_meas_chk #( + .Cnt(480), + .RefCnt(1) + ) u_usb_meas ( + .clk_i, + .rst_ni, + .clk_src_i(clk_usb), + .rst_src_ni(rst_usb_ni), + .clk_ref_i(clk_aon), + .rst_ref_ni(rst_aon_ni), + // signals on source domain + .src_en_i(clk_usb_en & mubi4_test_true_loose(mubi4_t'(reg2hw.usb_meas_ctrl_en))), + .src_max_cnt_i(reg2hw.usb_meas_ctrl_shadowed.hi.q), + .src_min_cnt_i(reg2hw.usb_meas_ctrl_shadowed.lo.q), + .src_cfg_meas_en_i(mubi4_t'(reg2hw.usb_meas_ctrl_en.q)), + .src_cfg_meas_en_valid_o(hw2reg.usb_meas_ctrl_en.de), + .src_cfg_meas_en_o(hw2reg.usb_meas_ctrl_en.d), + // signals on local clock domain + .calib_rdy_i(calib_rdy[ClkUsbIdx]), + .meas_err_o(hw2reg.recov_err_code.usb_measure_err.de), + .timeout_err_o(hw2reg.recov_err_code.usb_timeout_err.de) + ); + + assign hw2reg.recov_err_code.usb_measure_err.d = 1'b1; + assign hw2reg.recov_err_code.usb_timeout_err.d = 1'b1; + + + //////////////////////////////////////////////////// + // Clocks with only root gate + //////////////////////////////////////////////////// + assign clocks_o.clk_main_infra = clk_main_root; + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_main_infra ( + .clk_i(clk_main), + .rst_ni(rst_main_ni), + .mubi_i(((clk_main_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.main_infra) + ); + assign clocks_o.clk_io_div4_infra = clk_io_div4_root; + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_io_div4_infra ( + .clk_i(clk_io_div4), + .rst_ni(rst_io_div4_ni), + .mubi_i(((clk_io_div4_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.io_div4_infra) + ); + assign clocks_o.clk_io_infra = clk_io_root; + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_io_infra ( + .clk_i(clk_io), + .rst_ni(rst_io_ni), + .mubi_i(((clk_io_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.io_infra) + ); + assign clocks_o.clk_usb_infra = clk_usb_root; + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_usb_infra ( + .clk_i(clk_usb), + .rst_ni(rst_usb_ni), + .mubi_i(((clk_usb_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.usb_infra) + ); + assign clocks_o.clk_io_div4_secure = clk_io_div4_root; + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_io_div4_secure ( + .clk_i(clk_io_div4), + .rst_ni(rst_io_div4_ni), + .mubi_i(((clk_io_div4_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.io_div4_secure) + ); + assign clocks_o.clk_main_secure = clk_main_root; + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_main_secure ( + .clk_i(clk_main), + .rst_ni(rst_main_ni), + .mubi_i(((clk_main_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.main_secure) + ); + assign clocks_o.clk_io_div4_timers = clk_io_div4_root; + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_io_div4_timers ( + .clk_i(clk_io_div4), + .rst_ni(rst_io_div4_ni), + .mubi_i(((clk_io_div4_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.io_div4_timers) + ); + + //////////////////////////////////////////////////// + // Software direct control group + //////////////////////////////////////////////////// + + logic clk_io_div4_peri_sw_en; + logic clk_io_div2_peri_sw_en; + logic clk_io_peri_sw_en; + logic clk_usb_peri_sw_en; + + prim_flop_2sync #( + .Width(1) + ) u_clk_io_div4_peri_sw_en_sync ( + .clk_i(clk_io_div4), + .rst_ni(rst_io_div4_ni), + .d_i(reg2hw.clk_enables.clk_io_div4_peri_en.q), + .q_o(clk_io_div4_peri_sw_en) + ); + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] clk_io_div4_peri_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_clk_io_div4_peri_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o(clk_io_div4_peri_scanmode) + ); + + logic clk_io_div4_peri_combined_en; + assign clk_io_div4_peri_combined_en = clk_io_div4_peri_sw_en & clk_io_div4_en; + prim_clock_gating #( + .FpgaBufGlobal(1'b1) // This clock spans across multiple clock regions. + ) u_clk_io_div4_peri_cg ( + .clk_i(clk_io_div4), + .en_i(clk_io_div4_peri_combined_en), + .test_en_i(mubi4_test_true_strict(clk_io_div4_peri_scanmode[0])), + .clk_o(clocks_o.clk_io_div4_peri) + ); + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_io_div4_peri ( + .clk_i(clk_io_div4), + .rst_ni(rst_io_div4_ni), + .mubi_i(((clk_io_div4_peri_combined_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.io_div4_peri) + ); + + prim_flop_2sync #( + .Width(1) + ) u_clk_io_div2_peri_sw_en_sync ( + .clk_i(clk_io_div2), + .rst_ni(rst_io_div2_ni), + .d_i(reg2hw.clk_enables.clk_io_div2_peri_en.q), + .q_o(clk_io_div2_peri_sw_en) + ); + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] clk_io_div2_peri_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_clk_io_div2_peri_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o(clk_io_div2_peri_scanmode) + ); + + logic clk_io_div2_peri_combined_en; + assign clk_io_div2_peri_combined_en = clk_io_div2_peri_sw_en & clk_io_div2_en; + prim_clock_gating #( + .FpgaBufGlobal(1'b1) // This clock spans across multiple clock regions. + ) u_clk_io_div2_peri_cg ( + .clk_i(clk_io_div2), + .en_i(clk_io_div2_peri_combined_en), + .test_en_i(mubi4_test_true_strict(clk_io_div2_peri_scanmode[0])), + .clk_o(clocks_o.clk_io_div2_peri) + ); + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_io_div2_peri ( + .clk_i(clk_io_div2), + .rst_ni(rst_io_div2_ni), + .mubi_i(((clk_io_div2_peri_combined_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.io_div2_peri) + ); + + prim_flop_2sync #( + .Width(1) + ) u_clk_io_peri_sw_en_sync ( + .clk_i(clk_io), + .rst_ni(rst_io_ni), + .d_i(reg2hw.clk_enables.clk_io_peri_en.q), + .q_o(clk_io_peri_sw_en) + ); + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] clk_io_peri_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_clk_io_peri_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o(clk_io_peri_scanmode) + ); + + logic clk_io_peri_combined_en; + assign clk_io_peri_combined_en = clk_io_peri_sw_en & clk_io_en; + prim_clock_gating #( + .FpgaBufGlobal(1'b1) // This clock spans across multiple clock regions. + ) u_clk_io_peri_cg ( + .clk_i(clk_io), + .en_i(clk_io_peri_combined_en), + .test_en_i(mubi4_test_true_strict(clk_io_peri_scanmode[0])), + .clk_o(clocks_o.clk_io_peri) + ); + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_io_peri ( + .clk_i(clk_io), + .rst_ni(rst_io_ni), + .mubi_i(((clk_io_peri_combined_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.io_peri) + ); + + prim_flop_2sync #( + .Width(1) + ) u_clk_usb_peri_sw_en_sync ( + .clk_i(clk_usb), + .rst_ni(rst_usb_ni), + .d_i(reg2hw.clk_enables.clk_usb_peri_en.q), + .q_o(clk_usb_peri_sw_en) + ); + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] clk_usb_peri_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_clk_usb_peri_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o(clk_usb_peri_scanmode) + ); + + logic clk_usb_peri_combined_en; + assign clk_usb_peri_combined_en = clk_usb_peri_sw_en & clk_usb_en; + prim_clock_gating #( + .FpgaBufGlobal(1'b1) // This clock spans across multiple clock regions. + ) u_clk_usb_peri_cg ( + .clk_i(clk_usb), + .en_i(clk_usb_peri_combined_en), + .test_en_i(mubi4_test_true_strict(clk_usb_peri_scanmode[0])), + .clk_o(clocks_o.clk_usb_peri) + ); + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender_clk_usb_peri ( + .clk_i(clk_usb), + .rst_ni(rst_usb_ni), + .mubi_i(((clk_usb_peri_combined_en) ? MuBi4False : MuBi4True)), + .mubi_o(cg_en_o.usb_peri) + ); + + + //////////////////////////////////////////////////// + // Software hint group + // The idle hint feedback is assumed to be synchronous to the + // clock target + //////////////////////////////////////////////////// + + logic [0:0] idle_cnt_err; + + clkmgr_trans #( + .FpgaBufGlobal(1'b0) // This clock is used primarily locally. + ) u_clk_main_aes_trans ( + .clk_i(clk_main), + .clk_gated_i(clk_main_root), + .rst_ni(rst_main_ni), + .en_i(clk_main_en), + .idle_i(idle_i[HintMainAes]), + .sw_hint_i(reg2hw.clk_hints.q), + .scanmode_i, + .alert_cg_en_o(cg_en_o.main_aes), + .clk_o(clocks_o.clk_main_aes), + .clk_reg_i(clk_i), + .rst_reg_ni(rst_ni), + .reg_en_o(hw2reg.clk_hints_status.d), + .reg_cnt_err_o(idle_cnt_err[HintMainAes]) + ); + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT( + ClkMainAesCountCheck_A, + u_clk_main_aes_trans.u_idle_cnt, + alert_tx_o[1]) + assign hw2reg.fatal_err_code.idle_cnt.d = 1'b1; + assign hw2reg.fatal_err_code.idle_cnt.de = |idle_cnt_err; + + // state readback + assign hw2reg.clk_hints_status.de = 1'b1; + + // SEC_CM: JITTER.CONFIG.MUBI + assign jitter_en_o = mubi4_t'(reg2hw.jitter_enable.q); + + //////////////////////////////////////////////////// + // Exported clocks + //////////////////////////////////////////////////// + + + //////////////////////////////////////////////////// + // 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(PwrMgrKnownO_A, pwr_o) + `ASSERT_KNOWN(AllClkBypReqKnownO_A, all_clk_byp_req_o) + `ASSERT_KNOWN(IoClkBypReqKnownO_A, io_clk_byp_req_o) + `ASSERT_KNOWN(LcCtrlClkBypAckKnownO_A, lc_clk_byp_ack_o) + `ASSERT_KNOWN(JitterEnableKnownO_A, jitter_en_o) + `ASSERT_KNOWN(ClocksKownO_A, clocks_o) + `ASSERT_KNOWN(CgEnKnownO_A, cg_en_o) + + // Alert assertions for reg_we onehot check + `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[1]) +endmodule // clkmgr diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_byp.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_byp.sv new file mode 100644 index 0000000000000..28bb82baa6087 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_byp.sv @@ -0,0 +1,163 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Handle clock manager bypass requests + +module clkmgr_byp + import clkmgr_pkg::*; + import lc_ctrl_pkg::lc_tx_t; + import prim_mubi_pkg::mubi4_t; +# ( + parameter int NumDivClks = 1 +) ( + input clk_i, + input rst_ni, + // interaction with lc_ctrl + input lc_tx_t en_i, + input lc_tx_t lc_clk_byp_req_i, + output lc_tx_t lc_clk_byp_ack_o, + // interaction with software + input mubi4_t byp_req_i, + output mubi4_t byp_ack_o, + input mubi4_t hi_speed_sel_i, + // interaction with ast + output mubi4_t all_clk_byp_req_o, + input mubi4_t all_clk_byp_ack_i, + output mubi4_t io_clk_byp_req_o, + input mubi4_t io_clk_byp_ack_i, + output mubi4_t hi_speed_sel_o, + // interaction with dividers + input [NumDivClks-1:0] step_down_acks_i +); + + import prim_mubi_pkg::MuBi4Width; + import prim_mubi_pkg::MuBi4True; + import prim_mubi_pkg::MuBi4False; + import prim_mubi_pkg::mubi4_and_hi; + import prim_mubi_pkg::mubi4_test_true_strict; + + // synchornize incoming lc signals + lc_tx_t en; + prim_lc_sync #( + .NumCopies(1), + .AsyncOn(1), + .ResetValueIsOn(0) + ) u_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(en_i), + .lc_en_o({en}) + ); + + typedef enum logic [1:0] { + LcClkBypReqIoReq, + LcClkBypReqLcAck, + LcClkBypReqLast + } lc_clk_byp_req_e; + + lc_tx_t [LcClkBypReqLast-1:0] lc_clk_byp_req; + prim_lc_sync #( + .NumCopies(int'(LcClkBypReqLast)), + .AsyncOn(1), + .ResetValueIsOn(0) + ) u_lc_byp_req ( + .clk_i, + .rst_ni, + .lc_en_i(lc_clk_byp_req_i), + .lc_en_o(lc_clk_byp_req) + ); + + // synchronize step down acks + logic [NumDivClks-1:0] step_down_acks_sync; + prim_flop #( + .Width(NumDivClks), + .ResetValue(0) + ) u_step_down_acks_sync ( + .clk_i, + .rst_ni, + .d_i(step_down_acks_i), + .q_o(step_down_acks_sync) + ); + + // life cycle handling + mubi4_t io_clk_byp_req_d; + assign io_clk_byp_req_d = lc_ctrl_pkg::lc_tx_test_true_strict(lc_clk_byp_req[LcClkBypReqIoReq]) ? + MuBi4True : + MuBi4False; + + prim_mubi4_sender #( + .ResetValue(MuBi4False), + .EnSecBuf(1) + ) u_io_byp_req ( + .clk_i, + .rst_ni, + .mubi_i(io_clk_byp_req_d), + .mubi_o(io_clk_byp_req_o) + ); + + // only ack the lc_ctrl if it made a request. + mubi4_t io_clk_byp_ack; + prim_lc_sender u_send ( + .clk_i, + .rst_ni, + .lc_en_i(&step_down_acks_sync & mubi4_test_true_strict(io_clk_byp_ack) ? + lc_clk_byp_req[LcClkBypReqLcAck] : lc_ctrl_pkg::Off), + .lc_en_o(lc_clk_byp_ack_o) + ); + + // software switch request handling + mubi4_t debug_en; + assign debug_en = lc_ctrl_pkg::lc_to_mubi4(en); + + mubi4_t all_clk_byp_req_d; + assign all_clk_byp_req_d = mubi4_and_hi(byp_req_i, debug_en); + + prim_mubi4_sender #( + .AsyncOn(1), + .ResetValue(MuBi4False), + .EnSecBuf(1) + ) u_all_byp_req ( + .clk_i, + .rst_ni, + .mubi_i(all_clk_byp_req_d), + .mubi_o(all_clk_byp_req_o) + ); + + prim_mubi4_sync #( + .AsyncOn(1), + .StabilityCheck(1), + .ResetValue(MuBi4False) + ) u_io_ack_sync ( + .clk_i, + .rst_ni, + .mubi_i(io_clk_byp_ack_i), + .mubi_o({io_clk_byp_ack}) + ); + + // since div_step_down_req is now directly fed externally, there is no longer + // a use for the related 'ack' signals + prim_mubi4_sync #( + .AsyncOn(1), + .StabilityCheck(1), + .ResetValue(MuBi4False) + ) u_all_ack_sync ( + .clk_i, + .rst_ni, + .mubi_i(all_clk_byp_ack_i), + .mubi_o({byp_ack_o}) + ); + + // the software high speed select is valid only when software requests clock + // bypass + prim_mubi4_sender #( + .AsyncOn(1), + .ResetValue(MuBi4True) + ) u_hi_speed_sel ( + .clk_i, + .rst_ni, + .mubi_i(mubi4_and_hi(all_clk_byp_req_d, hi_speed_sel_i)), + .mubi_o(hi_speed_sel_o) + ); + +endmodule // clkmgr_byp diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_clk_status.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_clk_status.sv new file mode 100644 index 0000000000000..3c6b38b1025c1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_clk_status.sv @@ -0,0 +1,58 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Wrapper module for computing enable / disable status on family of clocks + +module clkmgr_clk_status #( + parameter int NumClocks = 1, + parameter int FilterStages = 2 +) ( + input clk_i, + input rst_ni, + input [NumClocks-1:0] ens_i, + output logic status_o +); + + // The enables are coming from different clock domains, + // therefore after synchronization we must de-bounce the + // signal to ensure it is stable + logic [NumClocks-1:0] ens_sync; + prim_flop_2sync #( + .Width(NumClocks) + ) u_en_sync ( + .clk_i, + .rst_ni, + .d_i(ens_i), + .q_o(ens_sync) + ); + + logic [FilterStages-1:0] en_q, dis_q, en_d, dis_d; + + // enable is true when all inputs are 1 + assign en_d = {en_q[FilterStages-2:0], &ens_sync}; + + // disable is true all all inputs are 0 + assign dis_d = {dis_q[FilterStages-2:0], ~|ens_sync}; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + en_q <= '0; + dis_q <= '0; + end else begin + en_q <= en_d; + dis_q <= dis_d; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + status_o <= '0; + end else if (&en_q) begin + status_o <= 1'b1; + end else if (&dis_q) begin + status_o <= 1'b0; + end + end + +endmodule // clkmgr_clk_status diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_meas_chk.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_meas_chk.sv new file mode 100644 index 0000000000000..ea0bc8e92be6f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_meas_chk.sv @@ -0,0 +1,127 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Clock manager measurement and timeout checks + +module clkmgr_meas_chk + import prim_mubi_pkg::mubi4_t; +#( + // Maximum value of input clock counts over measurement period + parameter int Cnt = 16, + // Maximum value of reference clock counts over measurement period + parameter int RefCnt = 1, + localparam int CntWidth = prim_util_pkg::vbits(Cnt) +) ( + // the local operating clock + input clk_i, + input rst_ni, + // the clock we are measuring + input clk_src_i, + input rst_src_ni, + // the reference clock we are measuring against + input clk_ref_i, + input rst_ref_ni, + // controls all provided on src clock + input src_en_i, + input [CntWidth-1:0] src_max_cnt_i, + input [CntWidth-1:0] src_min_cnt_i, + input mubi4_t src_cfg_meas_en_i, + output logic src_cfg_meas_en_valid_o, + output mubi4_t src_cfg_meas_en_o, + // calibration ready input provided on local operating clock + input mubi4_t calib_rdy_i, + // error output are provided on local operating clock + output logic meas_err_o, + output logic timeout_err_o +); + + logic src_fast_err; + logic src_slow_err; + logic ref_timeout_err; + + prim_clock_meas #( + .Cnt(Cnt), + .RefCnt(RefCnt), + .ClkTimeOutChkEn(1'b1), + .RefTimeOutChkEn(1'b0) + ) u_meas ( + .clk_i(clk_src_i), + .rst_ni(rst_src_ni), + .clk_ref_i, + .rst_ref_ni, + .en_i(src_en_i), + .max_cnt(src_max_cnt_i), + .min_cnt(src_min_cnt_i), + .valid_o(), + .fast_o(src_fast_err), + .slow_o(src_slow_err), + .timeout_clk_ref_o(), + .ref_timeout_clk_o(ref_timeout_err) + ); + + mubi4_t src_calib_rdy; + prim_mubi4_sync #( + .AsyncOn(1), + .ResetValue(prim_mubi_pkg::MuBi4False) + ) u_calib_rdy_sync ( + .clk_i, + .rst_ni, + .mubi_i(calib_rdy_i), + .mubi_o({src_calib_rdy}) + ); + + // if clocks become uncalibrated, switch off measurement controls + always_comb begin + src_cfg_meas_en_valid_o = '0; + src_cfg_meas_en_o = src_cfg_meas_en_i; + + // if calibration is lost when measurement is currently enabled, + // disable measurement enable. + if (prim_mubi_pkg::mubi4_test_false_strict(src_calib_rdy) && + prim_mubi_pkg::mubi4_test_true_loose(src_cfg_meas_en_o)) begin + src_cfg_meas_en_valid_o = 1'b1; + src_cfg_meas_en_o = prim_mubi_pkg::MuBi4False; + end + end + + // A reqack module is used here instead of a pulse_saync + // because the source pulses may toggle too fast for the + // the destination to receive. + logic src_err_req, src_err_ack; + always_ff @(posedge clk_src_i or negedge rst_src_ni) begin + if (!rst_src_ni) begin + src_err_req <= '0; + end else if (src_fast_err || src_slow_err) begin + src_err_req <= 1'b1; + end else if (src_err_req && src_err_ack) begin + src_err_req <= '0; + end + end + + prim_sync_reqack u_err_sync ( + .clk_src_i, + .rst_src_ni, + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .req_chk_i(1'b1), + .src_req_i(src_err_req), + .src_ack_o(src_err_ack), + .dst_req_o(meas_err_o), + .dst_ack_i(meas_err_o) + ); + + prim_edge_detector #( + .Width(1), + .ResetValue('0), + .EnSync(1'b1) + ) u_timeout_err_sync ( + .clk_i, + .rst_ni, + .d_i(ref_timeout_err), + .q_sync_o(), + .q_posedge_pulse_o(timeout_err_o), + .q_negedge_pulse_o() + ); + +endmodule // clkmgr_meas_chk diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_pkg.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_pkg.sv new file mode 100644 index 0000000000000..5c1a9e9f4d5a5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_pkg.sv @@ -0,0 +1,74 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + + + +package clkmgr_pkg; + + typedef enum int { + HintMainAes = 0 + } hint_names_e; + + // clocks generated and broadcast + typedef struct packed { + logic clk_io_div4_powerup; + logic clk_aon_powerup; + logic clk_main_powerup; + logic clk_io_powerup; + logic clk_usb_powerup; + logic clk_io_div2_powerup; + logic clk_aon_secure; + logic clk_aon_peri; + logic clk_aon_timers; + logic clk_main_aes; + logic clk_main_infra; + logic clk_io_div4_infra; + logic clk_io_infra; + logic clk_usb_infra; + logic clk_io_div4_secure; + logic clk_main_secure; + logic clk_io_div4_timers; + logic clk_io_div4_peri; + logic clk_io_div2_peri; + logic clk_io_peri; + logic clk_usb_peri; + } clkmgr_out_t; + + // clock gating indication for alert handler + typedef struct packed { + prim_mubi_pkg::mubi4_t io_div4_powerup; + prim_mubi_pkg::mubi4_t aon_powerup; + prim_mubi_pkg::mubi4_t main_powerup; + prim_mubi_pkg::mubi4_t io_powerup; + prim_mubi_pkg::mubi4_t usb_powerup; + prim_mubi_pkg::mubi4_t io_div2_powerup; + prim_mubi_pkg::mubi4_t aon_secure; + prim_mubi_pkg::mubi4_t aon_peri; + prim_mubi_pkg::mubi4_t aon_timers; + prim_mubi_pkg::mubi4_t main_aes; + prim_mubi_pkg::mubi4_t main_infra; + prim_mubi_pkg::mubi4_t io_div4_infra; + prim_mubi_pkg::mubi4_t io_infra; + prim_mubi_pkg::mubi4_t usb_infra; + prim_mubi_pkg::mubi4_t io_div4_secure; + prim_mubi_pkg::mubi4_t main_secure; + prim_mubi_pkg::mubi4_t io_div4_timers; + prim_mubi_pkg::mubi4_t io_div4_peri; + prim_mubi_pkg::mubi4_t io_div2_peri; + prim_mubi_pkg::mubi4_t io_peri; + prim_mubi_pkg::mubi4_t usb_peri; + } clkmgr_cg_en_t; + + parameter int NumOutputClk = 21; + + + typedef struct packed { + logic [1-1:0] idle; + } clk_hint_status_t; + + parameter clk_hint_status_t CLK_HINT_STATUS_DEFAULT = '{ + idle: {1{1'b1}} + }; + +endpackage // clkmgr_pkg diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_pkg.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_pkg.sv new file mode 100644 index 0000000000000..2a80db664638e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_pkg.sv @@ -0,0 +1,330 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 clkmgr_reg_pkg; + + // Param list + parameter int NumGroups = 8; + parameter int NumSwGateableClocks = 4; + parameter int NumHintableClocks = 1; + parameter int NumAlerts = 2; + + // Address widths within the block + parameter int BlockAw = 7; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + struct packed { + logic q; + logic qe; + } fatal_fault; + struct packed { + logic q; + logic qe; + } recov_fault; + } clkmgr_reg2hw_alert_test_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } hi_speed_sel; + struct packed { + logic [3:0] q; + } sel; + } clkmgr_reg2hw_extclk_ctrl_reg_t; + + typedef struct packed { + logic [3:0] q; + } clkmgr_reg2hw_jitter_enable_reg_t; + + typedef struct packed { + struct packed { + logic q; + } clk_usb_peri_en; + struct packed { + logic q; + } clk_io_peri_en; + struct packed { + logic q; + } clk_io_div2_peri_en; + struct packed { + logic q; + } clk_io_div4_peri_en; + } clkmgr_reg2hw_clk_enables_reg_t; + + typedef struct packed { + logic q; + } clkmgr_reg2hw_clk_hints_reg_t; + + typedef struct packed { + logic q; + } clkmgr_reg2hw_measure_ctrl_regwen_reg_t; + + typedef struct packed { + logic [3:0] q; + } clkmgr_reg2hw_io_meas_ctrl_en_reg_t; + + typedef struct packed { + struct packed { + logic [9:0] q; + } lo; + struct packed { + logic [9:0] q; + } hi; + } clkmgr_reg2hw_io_meas_ctrl_shadowed_reg_t; + + typedef struct packed { + logic [3:0] q; + } clkmgr_reg2hw_io_div4_meas_ctrl_en_reg_t; + + typedef struct packed { + struct packed { + logic [7:0] q; + } lo; + struct packed { + logic [7:0] q; + } hi; + } clkmgr_reg2hw_io_div4_meas_ctrl_shadowed_reg_t; + + typedef struct packed { + logic [3:0] q; + } clkmgr_reg2hw_main_meas_ctrl_en_reg_t; + + typedef struct packed { + struct packed { + logic [9:0] q; + } lo; + struct packed { + logic [9:0] q; + } hi; + } clkmgr_reg2hw_main_meas_ctrl_shadowed_reg_t; + + typedef struct packed { + logic [3:0] q; + } clkmgr_reg2hw_usb_meas_ctrl_en_reg_t; + + typedef struct packed { + struct packed { + logic [8:0] q; + } lo; + struct packed { + logic [8:0] q; + } hi; + } clkmgr_reg2hw_usb_meas_ctrl_shadowed_reg_t; + + typedef struct packed { + struct packed { + logic q; + } shadow_storage_err; + struct packed { + logic q; + } idle_cnt; + struct packed { + logic q; + } reg_intg; + } clkmgr_reg2hw_fatal_err_code_reg_t; + + typedef struct packed { + logic [3:0] d; + } clkmgr_hw2reg_extclk_status_reg_t; + + typedef struct packed { + logic d; + logic de; + } clkmgr_hw2reg_clk_hints_status_reg_t; + + typedef struct packed { + logic d; + logic de; + } clkmgr_hw2reg_measure_ctrl_regwen_reg_t; + + typedef struct packed { + logic [3:0] d; + logic de; + } clkmgr_hw2reg_io_meas_ctrl_en_reg_t; + + typedef struct packed { + logic [3:0] d; + logic de; + } clkmgr_hw2reg_io_div4_meas_ctrl_en_reg_t; + + typedef struct packed { + logic [3:0] d; + logic de; + } clkmgr_hw2reg_main_meas_ctrl_en_reg_t; + + typedef struct packed { + logic [3:0] d; + logic de; + } clkmgr_hw2reg_usb_meas_ctrl_en_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } shadow_update_err; + struct packed { + logic d; + logic de; + } io_measure_err; + struct packed { + logic d; + logic de; + } io_div4_measure_err; + struct packed { + logic d; + logic de; + } main_measure_err; + struct packed { + logic d; + logic de; + } usb_measure_err; + struct packed { + logic d; + logic de; + } io_timeout_err; + struct packed { + logic d; + logic de; + } io_div4_timeout_err; + struct packed { + logic d; + logic de; + } main_timeout_err; + struct packed { + logic d; + logic de; + } usb_timeout_err; + } clkmgr_hw2reg_recov_err_code_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } reg_intg; + struct packed { + logic d; + logic de; + } idle_cnt; + struct packed { + logic d; + logic de; + } shadow_storage_err; + } clkmgr_hw2reg_fatal_err_code_reg_t; + + // Register -> HW type + typedef struct packed { + clkmgr_reg2hw_alert_test_reg_t alert_test; // [114:111] + clkmgr_reg2hw_extclk_ctrl_reg_t extclk_ctrl; // [110:103] + clkmgr_reg2hw_jitter_enable_reg_t jitter_enable; // [102:99] + clkmgr_reg2hw_clk_enables_reg_t clk_enables; // [98:95] + clkmgr_reg2hw_clk_hints_reg_t clk_hints; // [94:94] + clkmgr_reg2hw_measure_ctrl_regwen_reg_t measure_ctrl_regwen; // [93:93] + clkmgr_reg2hw_io_meas_ctrl_en_reg_t io_meas_ctrl_en; // [92:89] + clkmgr_reg2hw_io_meas_ctrl_shadowed_reg_t io_meas_ctrl_shadowed; // [88:69] + clkmgr_reg2hw_io_div4_meas_ctrl_en_reg_t io_div4_meas_ctrl_en; // [68:65] + clkmgr_reg2hw_io_div4_meas_ctrl_shadowed_reg_t io_div4_meas_ctrl_shadowed; // [64:49] + clkmgr_reg2hw_main_meas_ctrl_en_reg_t main_meas_ctrl_en; // [48:45] + clkmgr_reg2hw_main_meas_ctrl_shadowed_reg_t main_meas_ctrl_shadowed; // [44:25] + clkmgr_reg2hw_usb_meas_ctrl_en_reg_t usb_meas_ctrl_en; // [24:21] + clkmgr_reg2hw_usb_meas_ctrl_shadowed_reg_t usb_meas_ctrl_shadowed; // [20:3] + clkmgr_reg2hw_fatal_err_code_reg_t fatal_err_code; // [2:0] + } clkmgr_reg2hw_t; + + // HW -> register type + typedef struct packed { + clkmgr_hw2reg_extclk_status_reg_t extclk_status; // [51:48] + clkmgr_hw2reg_clk_hints_status_reg_t clk_hints_status; // [47:46] + clkmgr_hw2reg_measure_ctrl_regwen_reg_t measure_ctrl_regwen; // [45:44] + clkmgr_hw2reg_io_meas_ctrl_en_reg_t io_meas_ctrl_en; // [43:39] + clkmgr_hw2reg_io_div4_meas_ctrl_en_reg_t io_div4_meas_ctrl_en; // [38:34] + clkmgr_hw2reg_main_meas_ctrl_en_reg_t main_meas_ctrl_en; // [33:29] + clkmgr_hw2reg_usb_meas_ctrl_en_reg_t usb_meas_ctrl_en; // [28:24] + clkmgr_hw2reg_recov_err_code_reg_t recov_err_code; // [23:6] + clkmgr_hw2reg_fatal_err_code_reg_t fatal_err_code; // [5:0] + } clkmgr_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] CLKMGR_ALERT_TEST_OFFSET = 7'h 0; + parameter logic [BlockAw-1:0] CLKMGR_EXTCLK_CTRL_REGWEN_OFFSET = 7'h 4; + parameter logic [BlockAw-1:0] CLKMGR_EXTCLK_CTRL_OFFSET = 7'h 8; + parameter logic [BlockAw-1:0] CLKMGR_EXTCLK_STATUS_OFFSET = 7'h c; + parameter logic [BlockAw-1:0] CLKMGR_JITTER_REGWEN_OFFSET = 7'h 10; + parameter logic [BlockAw-1:0] CLKMGR_JITTER_ENABLE_OFFSET = 7'h 14; + parameter logic [BlockAw-1:0] CLKMGR_CLK_ENABLES_OFFSET = 7'h 18; + parameter logic [BlockAw-1:0] CLKMGR_CLK_HINTS_OFFSET = 7'h 1c; + parameter logic [BlockAw-1:0] CLKMGR_CLK_HINTS_STATUS_OFFSET = 7'h 20; + parameter logic [BlockAw-1:0] CLKMGR_MEASURE_CTRL_REGWEN_OFFSET = 7'h 24; + parameter logic [BlockAw-1:0] CLKMGR_IO_MEAS_CTRL_EN_OFFSET = 7'h 28; + parameter logic [BlockAw-1:0] CLKMGR_IO_MEAS_CTRL_SHADOWED_OFFSET = 7'h 2c; + parameter logic [BlockAw-1:0] CLKMGR_IO_DIV4_MEAS_CTRL_EN_OFFSET = 7'h 30; + parameter logic [BlockAw-1:0] CLKMGR_IO_DIV4_MEAS_CTRL_SHADOWED_OFFSET = 7'h 34; + parameter logic [BlockAw-1:0] CLKMGR_MAIN_MEAS_CTRL_EN_OFFSET = 7'h 38; + parameter logic [BlockAw-1:0] CLKMGR_MAIN_MEAS_CTRL_SHADOWED_OFFSET = 7'h 3c; + parameter logic [BlockAw-1:0] CLKMGR_USB_MEAS_CTRL_EN_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] CLKMGR_USB_MEAS_CTRL_SHADOWED_OFFSET = 7'h 44; + parameter logic [BlockAw-1:0] CLKMGR_RECOV_ERR_CODE_OFFSET = 7'h 48; + parameter logic [BlockAw-1:0] CLKMGR_FATAL_ERR_CODE_OFFSET = 7'h 4c; + + // Reset values for hwext registers and their fields + parameter logic [1:0] CLKMGR_ALERT_TEST_RESVAL = 2'h 0; + parameter logic [0:0] CLKMGR_ALERT_TEST_RECOV_FAULT_RESVAL = 1'h 0; + parameter logic [0:0] CLKMGR_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0; + parameter logic [3:0] CLKMGR_EXTCLK_STATUS_RESVAL = 4'h 9; + parameter logic [3:0] CLKMGR_EXTCLK_STATUS_ACK_RESVAL = 4'h 9; + + // Register index + typedef enum int { + CLKMGR_ALERT_TEST, + CLKMGR_EXTCLK_CTRL_REGWEN, + CLKMGR_EXTCLK_CTRL, + CLKMGR_EXTCLK_STATUS, + CLKMGR_JITTER_REGWEN, + CLKMGR_JITTER_ENABLE, + CLKMGR_CLK_ENABLES, + CLKMGR_CLK_HINTS, + CLKMGR_CLK_HINTS_STATUS, + CLKMGR_MEASURE_CTRL_REGWEN, + CLKMGR_IO_MEAS_CTRL_EN, + CLKMGR_IO_MEAS_CTRL_SHADOWED, + CLKMGR_IO_DIV4_MEAS_CTRL_EN, + CLKMGR_IO_DIV4_MEAS_CTRL_SHADOWED, + CLKMGR_MAIN_MEAS_CTRL_EN, + CLKMGR_MAIN_MEAS_CTRL_SHADOWED, + CLKMGR_USB_MEAS_CTRL_EN, + CLKMGR_USB_MEAS_CTRL_SHADOWED, + CLKMGR_RECOV_ERR_CODE, + CLKMGR_FATAL_ERR_CODE + } clkmgr_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] CLKMGR_PERMIT [20] = '{ + 4'b 0001, // index[ 0] CLKMGR_ALERT_TEST + 4'b 0001, // index[ 1] CLKMGR_EXTCLK_CTRL_REGWEN + 4'b 0001, // index[ 2] CLKMGR_EXTCLK_CTRL + 4'b 0001, // index[ 3] CLKMGR_EXTCLK_STATUS + 4'b 0001, // index[ 4] CLKMGR_JITTER_REGWEN + 4'b 0001, // index[ 5] CLKMGR_JITTER_ENABLE + 4'b 0001, // index[ 6] CLKMGR_CLK_ENABLES + 4'b 0001, // index[ 7] CLKMGR_CLK_HINTS + 4'b 0001, // index[ 8] CLKMGR_CLK_HINTS_STATUS + 4'b 0001, // index[ 9] CLKMGR_MEASURE_CTRL_REGWEN + 4'b 0001, // index[10] CLKMGR_IO_MEAS_CTRL_EN + 4'b 0111, // index[11] CLKMGR_IO_MEAS_CTRL_SHADOWED + 4'b 0001, // index[12] CLKMGR_IO_DIV4_MEAS_CTRL_EN + 4'b 0011, // index[13] CLKMGR_IO_DIV4_MEAS_CTRL_SHADOWED + 4'b 0001, // index[14] CLKMGR_MAIN_MEAS_CTRL_EN + 4'b 0111, // index[15] CLKMGR_MAIN_MEAS_CTRL_SHADOWED + 4'b 0001, // index[16] CLKMGR_USB_MEAS_CTRL_EN + 4'b 0111, // index[17] CLKMGR_USB_MEAS_CTRL_SHADOWED + 4'b 0011, // index[18] CLKMGR_RECOV_ERR_CODE + 4'b 0001 // index[19] CLKMGR_FATAL_ERR_CODE + }; + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_top.sv new file mode 100644 index 0000000000000..6bfd601dbc27a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_reg_top.sv @@ -0,0 +1,2291 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 clkmgr_reg_top ( + input clk_i, + input rst_ni, + input rst_shadowed_ni, + input clk_io_i, + input rst_io_ni, + input clk_io_div4_i, + input rst_io_div4_ni, + input clk_main_i, + input rst_main_ni, + input clk_usb_i, + input rst_usb_ni, + input tlul_pkg::tl_h2d_t tl_i, + output tlul_pkg::tl_d2h_t tl_o, + // To HW + output clkmgr_reg_pkg::clkmgr_reg2hw_t reg2hw, // Write + input clkmgr_reg_pkg::clkmgr_hw2reg_t hw2reg, // Read + + output logic shadowed_storage_err_o, + output logic shadowed_update_err_o, + + // Integrity check errors + output logic intg_err_o +); + + import clkmgr_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 [19:0] reg_we_check; + prim_reg_we_check #( + .OneHotWidth(20) + ) 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 = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic alert_test_we; + logic alert_test_recov_fault_wd; + logic alert_test_fatal_fault_wd; + logic extclk_ctrl_regwen_we; + logic extclk_ctrl_regwen_qs; + logic extclk_ctrl_regwen_wd; + logic extclk_ctrl_we; + logic [3:0] extclk_ctrl_sel_qs; + logic [3:0] extclk_ctrl_sel_wd; + logic [3:0] extclk_ctrl_hi_speed_sel_qs; + logic [3:0] extclk_ctrl_hi_speed_sel_wd; + logic extclk_status_re; + logic [3:0] extclk_status_qs; + logic jitter_regwen_we; + logic jitter_regwen_qs; + logic jitter_regwen_wd; + logic jitter_enable_we; + logic [3:0] jitter_enable_qs; + logic [3:0] jitter_enable_wd; + logic clk_enables_we; + logic clk_enables_clk_io_div4_peri_en_qs; + logic clk_enables_clk_io_div4_peri_en_wd; + logic clk_enables_clk_io_div2_peri_en_qs; + logic clk_enables_clk_io_div2_peri_en_wd; + logic clk_enables_clk_io_peri_en_qs; + logic clk_enables_clk_io_peri_en_wd; + logic clk_enables_clk_usb_peri_en_qs; + logic clk_enables_clk_usb_peri_en_wd; + logic clk_hints_we; + logic clk_hints_qs; + logic clk_hints_wd; + logic clk_hints_status_qs; + logic measure_ctrl_regwen_we; + logic measure_ctrl_regwen_qs; + logic measure_ctrl_regwen_wd; + logic io_meas_ctrl_en_we; + logic [3:0] io_meas_ctrl_en_qs; + logic io_meas_ctrl_en_busy; + logic io_meas_ctrl_shadowed_re; + logic io_meas_ctrl_shadowed_we; + logic [19:0] io_meas_ctrl_shadowed_qs; + logic io_meas_ctrl_shadowed_busy; + logic io_meas_ctrl_shadowed_hi_storage_err; + logic io_meas_ctrl_shadowed_hi_update_err; + logic io_meas_ctrl_shadowed_lo_storage_err; + logic io_meas_ctrl_shadowed_lo_update_err; + logic io_div4_meas_ctrl_en_we; + logic [3:0] io_div4_meas_ctrl_en_qs; + logic io_div4_meas_ctrl_en_busy; + logic io_div4_meas_ctrl_shadowed_re; + logic io_div4_meas_ctrl_shadowed_we; + logic [15:0] io_div4_meas_ctrl_shadowed_qs; + logic io_div4_meas_ctrl_shadowed_busy; + logic io_div4_meas_ctrl_shadowed_hi_storage_err; + logic io_div4_meas_ctrl_shadowed_hi_update_err; + logic io_div4_meas_ctrl_shadowed_lo_storage_err; + logic io_div4_meas_ctrl_shadowed_lo_update_err; + logic main_meas_ctrl_en_we; + logic [3:0] main_meas_ctrl_en_qs; + logic main_meas_ctrl_en_busy; + logic main_meas_ctrl_shadowed_re; + logic main_meas_ctrl_shadowed_we; + logic [19:0] main_meas_ctrl_shadowed_qs; + logic main_meas_ctrl_shadowed_busy; + logic main_meas_ctrl_shadowed_hi_storage_err; + logic main_meas_ctrl_shadowed_hi_update_err; + logic main_meas_ctrl_shadowed_lo_storage_err; + logic main_meas_ctrl_shadowed_lo_update_err; + logic usb_meas_ctrl_en_we; + logic [3:0] usb_meas_ctrl_en_qs; + logic usb_meas_ctrl_en_busy; + logic usb_meas_ctrl_shadowed_re; + logic usb_meas_ctrl_shadowed_we; + logic [17:0] usb_meas_ctrl_shadowed_qs; + logic usb_meas_ctrl_shadowed_busy; + logic usb_meas_ctrl_shadowed_hi_storage_err; + logic usb_meas_ctrl_shadowed_hi_update_err; + logic usb_meas_ctrl_shadowed_lo_storage_err; + logic usb_meas_ctrl_shadowed_lo_update_err; + logic recov_err_code_we; + logic recov_err_code_shadow_update_err_qs; + logic recov_err_code_shadow_update_err_wd; + logic recov_err_code_io_measure_err_qs; + logic recov_err_code_io_measure_err_wd; + logic recov_err_code_io_div4_measure_err_qs; + logic recov_err_code_io_div4_measure_err_wd; + logic recov_err_code_main_measure_err_qs; + logic recov_err_code_main_measure_err_wd; + logic recov_err_code_usb_measure_err_qs; + logic recov_err_code_usb_measure_err_wd; + logic recov_err_code_io_timeout_err_qs; + logic recov_err_code_io_timeout_err_wd; + logic recov_err_code_io_div4_timeout_err_qs; + logic recov_err_code_io_div4_timeout_err_wd; + logic recov_err_code_main_timeout_err_qs; + logic recov_err_code_main_timeout_err_wd; + logic recov_err_code_usb_timeout_err_qs; + logic recov_err_code_usb_timeout_err_wd; + logic fatal_err_code_reg_intg_qs; + logic fatal_err_code_idle_cnt_qs; + logic fatal_err_code_shadow_storage_err_qs; + // Define register CDC handling. + // CDC handling is done on a per-reg instead of per-field boundary. + + logic [3:0] io_io_meas_ctrl_en_ds_int; + logic [3:0] io_io_meas_ctrl_en_qs_int; + logic [3:0] io_io_meas_ctrl_en_ds; + logic io_io_meas_ctrl_en_qe; + logic [3:0] io_io_meas_ctrl_en_qs; + logic [3:0] io_io_meas_ctrl_en_wdata; + logic io_io_meas_ctrl_en_we; + logic unused_io_io_meas_ctrl_en_wdata; + logic io_io_meas_ctrl_en_regwen; + + always_comb begin + io_io_meas_ctrl_en_qs = 4'h9; + io_io_meas_ctrl_en_ds = 4'h9; + io_io_meas_ctrl_en_ds = io_io_meas_ctrl_en_ds_int; + io_io_meas_ctrl_en_qs = io_io_meas_ctrl_en_qs_int; + end + + prim_reg_cdc #( + .DataWidth(4), + .ResetVal(4'h9), + .BitMask(4'hf), + .DstWrReq(1) + ) u_io_meas_ctrl_en_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_io_i), + .rst_dst_ni (rst_io_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (io_meas_ctrl_en_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[3:0]), + .src_busy_o (io_meas_ctrl_en_busy), + .src_qs_o (io_meas_ctrl_en_qs), // for software read back + .dst_update_i (io_io_meas_ctrl_en_qe), + .dst_ds_i (io_io_meas_ctrl_en_ds), + .dst_qs_i (io_io_meas_ctrl_en_qs), + .dst_we_o (io_io_meas_ctrl_en_we), + .dst_re_o (), + .dst_regwen_o (io_io_meas_ctrl_en_regwen), + .dst_wd_o (io_io_meas_ctrl_en_wdata) + ); + assign unused_io_io_meas_ctrl_en_wdata = + ^io_io_meas_ctrl_en_wdata; + + logic [9:0] io_io_meas_ctrl_shadowed_hi_qs_int; + logic [9:0] io_io_meas_ctrl_shadowed_lo_qs_int; + logic [19:0] io_io_meas_ctrl_shadowed_qs; + logic [19:0] io_io_meas_ctrl_shadowed_wdata; + logic io_io_meas_ctrl_shadowed_we; + logic unused_io_io_meas_ctrl_shadowed_wdata; + logic io_io_meas_ctrl_shadowed_re; + logic io_io_meas_ctrl_shadowed_regwen; + + always_comb begin + io_io_meas_ctrl_shadowed_qs = 20'h759ea; + io_io_meas_ctrl_shadowed_qs[9:0] = io_io_meas_ctrl_shadowed_hi_qs_int; + io_io_meas_ctrl_shadowed_qs[19:10] = io_io_meas_ctrl_shadowed_lo_qs_int; + end + + prim_reg_cdc #( + .DataWidth(20), + .ResetVal(20'h759ea), + .BitMask(20'hfffff), + .DstWrReq(0) + ) u_io_meas_ctrl_shadowed_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_io_i), + .rst_dst_ni (rst_io_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (io_meas_ctrl_shadowed_we), + .src_re_i (io_meas_ctrl_shadowed_re), + .src_wd_i (reg_wdata[19:0]), + .src_busy_o (io_meas_ctrl_shadowed_busy), + .src_qs_o (io_meas_ctrl_shadowed_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (io_io_meas_ctrl_shadowed_qs), + .dst_we_o (io_io_meas_ctrl_shadowed_we), + .dst_re_o (io_io_meas_ctrl_shadowed_re), + .dst_regwen_o (io_io_meas_ctrl_shadowed_regwen), + .dst_wd_o (io_io_meas_ctrl_shadowed_wdata) + ); + assign unused_io_io_meas_ctrl_shadowed_wdata = + ^io_io_meas_ctrl_shadowed_wdata; + + logic [3:0] io_div4_io_div4_meas_ctrl_en_ds_int; + logic [3:0] io_div4_io_div4_meas_ctrl_en_qs_int; + logic [3:0] io_div4_io_div4_meas_ctrl_en_ds; + logic io_div4_io_div4_meas_ctrl_en_qe; + logic [3:0] io_div4_io_div4_meas_ctrl_en_qs; + logic [3:0] io_div4_io_div4_meas_ctrl_en_wdata; + logic io_div4_io_div4_meas_ctrl_en_we; + logic unused_io_div4_io_div4_meas_ctrl_en_wdata; + logic io_div4_io_div4_meas_ctrl_en_regwen; + + always_comb begin + io_div4_io_div4_meas_ctrl_en_qs = 4'h9; + io_div4_io_div4_meas_ctrl_en_ds = 4'h9; + io_div4_io_div4_meas_ctrl_en_ds = io_div4_io_div4_meas_ctrl_en_ds_int; + io_div4_io_div4_meas_ctrl_en_qs = io_div4_io_div4_meas_ctrl_en_qs_int; + end + + prim_reg_cdc #( + .DataWidth(4), + .ResetVal(4'h9), + .BitMask(4'hf), + .DstWrReq(1) + ) u_io_div4_meas_ctrl_en_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_io_div4_i), + .rst_dst_ni (rst_io_div4_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (io_div4_meas_ctrl_en_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[3:0]), + .src_busy_o (io_div4_meas_ctrl_en_busy), + .src_qs_o (io_div4_meas_ctrl_en_qs), // for software read back + .dst_update_i (io_div4_io_div4_meas_ctrl_en_qe), + .dst_ds_i (io_div4_io_div4_meas_ctrl_en_ds), + .dst_qs_i (io_div4_io_div4_meas_ctrl_en_qs), + .dst_we_o (io_div4_io_div4_meas_ctrl_en_we), + .dst_re_o (), + .dst_regwen_o (io_div4_io_div4_meas_ctrl_en_regwen), + .dst_wd_o (io_div4_io_div4_meas_ctrl_en_wdata) + ); + assign unused_io_div4_io_div4_meas_ctrl_en_wdata = + ^io_div4_io_div4_meas_ctrl_en_wdata; + + logic [7:0] io_div4_io_div4_meas_ctrl_shadowed_hi_qs_int; + logic [7:0] io_div4_io_div4_meas_ctrl_shadowed_lo_qs_int; + logic [15:0] io_div4_io_div4_meas_ctrl_shadowed_qs; + logic [15:0] io_div4_io_div4_meas_ctrl_shadowed_wdata; + logic io_div4_io_div4_meas_ctrl_shadowed_we; + logic unused_io_div4_io_div4_meas_ctrl_shadowed_wdata; + logic io_div4_io_div4_meas_ctrl_shadowed_re; + logic io_div4_io_div4_meas_ctrl_shadowed_regwen; + + always_comb begin + io_div4_io_div4_meas_ctrl_shadowed_qs = 16'h6e82; + io_div4_io_div4_meas_ctrl_shadowed_qs[7:0] = io_div4_io_div4_meas_ctrl_shadowed_hi_qs_int; + io_div4_io_div4_meas_ctrl_shadowed_qs[15:8] = io_div4_io_div4_meas_ctrl_shadowed_lo_qs_int; + end + + prim_reg_cdc #( + .DataWidth(16), + .ResetVal(16'h6e82), + .BitMask(16'hffff), + .DstWrReq(0) + ) u_io_div4_meas_ctrl_shadowed_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_io_div4_i), + .rst_dst_ni (rst_io_div4_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (io_div4_meas_ctrl_shadowed_we), + .src_re_i (io_div4_meas_ctrl_shadowed_re), + .src_wd_i (reg_wdata[15:0]), + .src_busy_o (io_div4_meas_ctrl_shadowed_busy), + .src_qs_o (io_div4_meas_ctrl_shadowed_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (io_div4_io_div4_meas_ctrl_shadowed_qs), + .dst_we_o (io_div4_io_div4_meas_ctrl_shadowed_we), + .dst_re_o (io_div4_io_div4_meas_ctrl_shadowed_re), + .dst_regwen_o (io_div4_io_div4_meas_ctrl_shadowed_regwen), + .dst_wd_o (io_div4_io_div4_meas_ctrl_shadowed_wdata) + ); + assign unused_io_div4_io_div4_meas_ctrl_shadowed_wdata = + ^io_div4_io_div4_meas_ctrl_shadowed_wdata; + + logic [3:0] main_main_meas_ctrl_en_ds_int; + logic [3:0] main_main_meas_ctrl_en_qs_int; + logic [3:0] main_main_meas_ctrl_en_ds; + logic main_main_meas_ctrl_en_qe; + logic [3:0] main_main_meas_ctrl_en_qs; + logic [3:0] main_main_meas_ctrl_en_wdata; + logic main_main_meas_ctrl_en_we; + logic unused_main_main_meas_ctrl_en_wdata; + logic main_main_meas_ctrl_en_regwen; + + always_comb begin + main_main_meas_ctrl_en_qs = 4'h9; + main_main_meas_ctrl_en_ds = 4'h9; + main_main_meas_ctrl_en_ds = main_main_meas_ctrl_en_ds_int; + main_main_meas_ctrl_en_qs = main_main_meas_ctrl_en_qs_int; + end + + prim_reg_cdc #( + .DataWidth(4), + .ResetVal(4'h9), + .BitMask(4'hf), + .DstWrReq(1) + ) u_main_meas_ctrl_en_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_main_i), + .rst_dst_ni (rst_main_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (main_meas_ctrl_en_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[3:0]), + .src_busy_o (main_meas_ctrl_en_busy), + .src_qs_o (main_meas_ctrl_en_qs), // for software read back + .dst_update_i (main_main_meas_ctrl_en_qe), + .dst_ds_i (main_main_meas_ctrl_en_ds), + .dst_qs_i (main_main_meas_ctrl_en_qs), + .dst_we_o (main_main_meas_ctrl_en_we), + .dst_re_o (), + .dst_regwen_o (main_main_meas_ctrl_en_regwen), + .dst_wd_o (main_main_meas_ctrl_en_wdata) + ); + assign unused_main_main_meas_ctrl_en_wdata = + ^main_main_meas_ctrl_en_wdata; + + logic [9:0] main_main_meas_ctrl_shadowed_hi_qs_int; + logic [9:0] main_main_meas_ctrl_shadowed_lo_qs_int; + logic [19:0] main_main_meas_ctrl_shadowed_qs; + logic [19:0] main_main_meas_ctrl_shadowed_wdata; + logic main_main_meas_ctrl_shadowed_we; + logic unused_main_main_meas_ctrl_shadowed_wdata; + logic main_main_meas_ctrl_shadowed_re; + logic main_main_meas_ctrl_shadowed_regwen; + + always_comb begin + main_main_meas_ctrl_shadowed_qs = 20'h7a9fe; + main_main_meas_ctrl_shadowed_qs[9:0] = main_main_meas_ctrl_shadowed_hi_qs_int; + main_main_meas_ctrl_shadowed_qs[19:10] = main_main_meas_ctrl_shadowed_lo_qs_int; + end + + prim_reg_cdc #( + .DataWidth(20), + .ResetVal(20'h7a9fe), + .BitMask(20'hfffff), + .DstWrReq(0) + ) u_main_meas_ctrl_shadowed_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_main_i), + .rst_dst_ni (rst_main_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (main_meas_ctrl_shadowed_we), + .src_re_i (main_meas_ctrl_shadowed_re), + .src_wd_i (reg_wdata[19:0]), + .src_busy_o (main_meas_ctrl_shadowed_busy), + .src_qs_o (main_meas_ctrl_shadowed_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (main_main_meas_ctrl_shadowed_qs), + .dst_we_o (main_main_meas_ctrl_shadowed_we), + .dst_re_o (main_main_meas_ctrl_shadowed_re), + .dst_regwen_o (main_main_meas_ctrl_shadowed_regwen), + .dst_wd_o (main_main_meas_ctrl_shadowed_wdata) + ); + assign unused_main_main_meas_ctrl_shadowed_wdata = + ^main_main_meas_ctrl_shadowed_wdata; + + logic [3:0] usb_usb_meas_ctrl_en_ds_int; + logic [3:0] usb_usb_meas_ctrl_en_qs_int; + logic [3:0] usb_usb_meas_ctrl_en_ds; + logic usb_usb_meas_ctrl_en_qe; + logic [3:0] usb_usb_meas_ctrl_en_qs; + logic [3:0] usb_usb_meas_ctrl_en_wdata; + logic usb_usb_meas_ctrl_en_we; + logic unused_usb_usb_meas_ctrl_en_wdata; + logic usb_usb_meas_ctrl_en_regwen; + + always_comb begin + usb_usb_meas_ctrl_en_qs = 4'h9; + usb_usb_meas_ctrl_en_ds = 4'h9; + usb_usb_meas_ctrl_en_ds = usb_usb_meas_ctrl_en_ds_int; + usb_usb_meas_ctrl_en_qs = usb_usb_meas_ctrl_en_qs_int; + end + + prim_reg_cdc #( + .DataWidth(4), + .ResetVal(4'h9), + .BitMask(4'hf), + .DstWrReq(1) + ) u_usb_meas_ctrl_en_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_usb_i), + .rst_dst_ni (rst_usb_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (usb_meas_ctrl_en_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[3:0]), + .src_busy_o (usb_meas_ctrl_en_busy), + .src_qs_o (usb_meas_ctrl_en_qs), // for software read back + .dst_update_i (usb_usb_meas_ctrl_en_qe), + .dst_ds_i (usb_usb_meas_ctrl_en_ds), + .dst_qs_i (usb_usb_meas_ctrl_en_qs), + .dst_we_o (usb_usb_meas_ctrl_en_we), + .dst_re_o (), + .dst_regwen_o (usb_usb_meas_ctrl_en_regwen), + .dst_wd_o (usb_usb_meas_ctrl_en_wdata) + ); + assign unused_usb_usb_meas_ctrl_en_wdata = + ^usb_usb_meas_ctrl_en_wdata; + + logic [8:0] usb_usb_meas_ctrl_shadowed_hi_qs_int; + logic [8:0] usb_usb_meas_ctrl_shadowed_lo_qs_int; + logic [17:0] usb_usb_meas_ctrl_shadowed_qs; + logic [17:0] usb_usb_meas_ctrl_shadowed_wdata; + logic usb_usb_meas_ctrl_shadowed_we; + logic unused_usb_usb_meas_ctrl_shadowed_wdata; + logic usb_usb_meas_ctrl_shadowed_re; + logic usb_usb_meas_ctrl_shadowed_regwen; + + always_comb begin + usb_usb_meas_ctrl_shadowed_qs = 18'h1ccfa; + usb_usb_meas_ctrl_shadowed_qs[8:0] = usb_usb_meas_ctrl_shadowed_hi_qs_int; + usb_usb_meas_ctrl_shadowed_qs[17:9] = usb_usb_meas_ctrl_shadowed_lo_qs_int; + end + + prim_reg_cdc #( + .DataWidth(18), + .ResetVal(18'h1ccfa), + .BitMask(18'h3ffff), + .DstWrReq(0) + ) u_usb_meas_ctrl_shadowed_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_usb_i), + .rst_dst_ni (rst_usb_ni), + .src_regwen_i (measure_ctrl_regwen_qs), + .src_we_i (usb_meas_ctrl_shadowed_we), + .src_re_i (usb_meas_ctrl_shadowed_re), + .src_wd_i (reg_wdata[17:0]), + .src_busy_o (usb_meas_ctrl_shadowed_busy), + .src_qs_o (usb_meas_ctrl_shadowed_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (usb_usb_meas_ctrl_shadowed_qs), + .dst_we_o (usb_usb_meas_ctrl_shadowed_we), + .dst_re_o (usb_usb_meas_ctrl_shadowed_re), + .dst_regwen_o (usb_usb_meas_ctrl_shadowed_regwen), + .dst_wd_o (usb_usb_meas_ctrl_shadowed_wdata) + ); + assign unused_usb_usb_meas_ctrl_shadowed_wdata = + ^usb_usb_meas_ctrl_shadowed_wdata; + + // Register instances + // R[alert_test]: V(True) + logic alert_test_qe; + logic [1:0] alert_test_flds_we; + assign alert_test_qe = &alert_test_flds_we; + // F[recov_fault]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_recov_fault ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_recov_fault_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[0]), + .q (reg2hw.alert_test.recov_fault.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.recov_fault.qe = alert_test_qe; + + // F[fatal_fault]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_fault ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_fault_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[1]), + .q (reg2hw.alert_test.fatal_fault.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_fault.qe = alert_test_qe; + + + // R[extclk_ctrl_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_extclk_ctrl_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (extclk_ctrl_regwen_we), + .wd (extclk_ctrl_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (extclk_ctrl_regwen_qs) + ); + + + // R[extclk_ctrl]: V(False) + // Create REGWEN-gated WE signal + logic extclk_ctrl_gated_we; + assign extclk_ctrl_gated_we = extclk_ctrl_we & extclk_ctrl_regwen_qs; + // F[sel]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_extclk_ctrl_sel ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (extclk_ctrl_gated_we), + .wd (extclk_ctrl_sel_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.extclk_ctrl.sel.q), + .ds (), + + // to register interface (read) + .qs (extclk_ctrl_sel_qs) + ); + + // F[hi_speed_sel]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_extclk_ctrl_hi_speed_sel ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (extclk_ctrl_gated_we), + .wd (extclk_ctrl_hi_speed_sel_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.extclk_ctrl.hi_speed_sel.q), + .ds (), + + // to register interface (read) + .qs (extclk_ctrl_hi_speed_sel_qs) + ); + + + // R[extclk_status]: V(True) + prim_subreg_ext #( + .DW (4) + ) u_extclk_status ( + .re (extclk_status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.extclk_status.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (extclk_status_qs) + ); + + + // R[jitter_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_jitter_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (jitter_regwen_we), + .wd (jitter_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (jitter_regwen_qs) + ); + + + // R[jitter_enable]: V(False) + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_jitter_enable ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (jitter_enable_we), + .wd (jitter_enable_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.jitter_enable.q), + .ds (), + + // to register interface (read) + .qs (jitter_enable_qs) + ); + + + // R[clk_enables]: V(False) + // F[clk_io_div4_peri_en]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_clk_enables_clk_io_div4_peri_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (clk_enables_we), + .wd (clk_enables_clk_io_div4_peri_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.clk_enables.clk_io_div4_peri_en.q), + .ds (), + + // to register interface (read) + .qs (clk_enables_clk_io_div4_peri_en_qs) + ); + + // F[clk_io_div2_peri_en]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_clk_enables_clk_io_div2_peri_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (clk_enables_we), + .wd (clk_enables_clk_io_div2_peri_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.clk_enables.clk_io_div2_peri_en.q), + .ds (), + + // to register interface (read) + .qs (clk_enables_clk_io_div2_peri_en_qs) + ); + + // F[clk_io_peri_en]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_clk_enables_clk_io_peri_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (clk_enables_we), + .wd (clk_enables_clk_io_peri_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.clk_enables.clk_io_peri_en.q), + .ds (), + + // to register interface (read) + .qs (clk_enables_clk_io_peri_en_qs) + ); + + // F[clk_usb_peri_en]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_clk_enables_clk_usb_peri_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (clk_enables_we), + .wd (clk_enables_clk_usb_peri_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.clk_enables.clk_usb_peri_en.q), + .ds (), + + // to register interface (read) + .qs (clk_enables_clk_usb_peri_en_qs) + ); + + + // R[clk_hints]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_clk_hints ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (clk_hints_we), + .wd (clk_hints_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.clk_hints.q), + .ds (), + + // to register interface (read) + .qs (clk_hints_qs) + ); + + + // R[clk_hints_status]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_clk_hints_status ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.clk_hints_status.de), + .d (hw2reg.clk_hints_status.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (clk_hints_status_qs) + ); + + + // R[measure_ctrl_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_measure_ctrl_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (measure_ctrl_regwen_we), + .wd (measure_ctrl_regwen_wd), + + // from internal hardware + .de (hw2reg.measure_ctrl_regwen.de), + .d (hw2reg.measure_ctrl_regwen.d), + + // to internal hardware + .qe (), + .q (reg2hw.measure_ctrl_regwen.q), + .ds (), + + // to register interface (read) + .qs (measure_ctrl_regwen_qs) + ); + + + // R[io_meas_ctrl_en]: V(False) + logic [0:0] io_meas_ctrl_en_flds_we; + assign io_io_meas_ctrl_en_qe = |io_meas_ctrl_en_flds_we; + // Create REGWEN-gated WE signal + logic io_io_meas_ctrl_en_gated_we; + assign io_io_meas_ctrl_en_gated_we = io_io_meas_ctrl_en_we & io_io_meas_ctrl_en_regwen; + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_io_meas_ctrl_en ( + .clk_i (clk_io_i), + .rst_ni (rst_io_ni), + + // from register interface + .we (io_io_meas_ctrl_en_gated_we), + .wd (io_io_meas_ctrl_en_wdata[3:0]), + + // from internal hardware + .de (hw2reg.io_meas_ctrl_en.de), + .d (hw2reg.io_meas_ctrl_en.d), + + // to internal hardware + .qe (io_meas_ctrl_en_flds_we[0]), + .q (reg2hw.io_meas_ctrl_en.q), + .ds (io_io_meas_ctrl_en_ds_int), + + // to register interface (read) + .qs (io_io_meas_ctrl_en_qs_int) + ); + + + // R[io_meas_ctrl_shadowed]: V(False) + // Create REGWEN-gated WE signal + logic io_io_meas_ctrl_shadowed_gated_we; + assign io_io_meas_ctrl_shadowed_gated_we = + io_io_meas_ctrl_shadowed_we & io_io_meas_ctrl_shadowed_regwen; + // F[hi]: 9:0 + logic async_io_meas_ctrl_shadowed_hi_err_update; + logic async_io_meas_ctrl_shadowed_hi_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_io_meas_ctrl_shadowed_hi_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_io_meas_ctrl_shadowed_hi_err_storage), + .q_o(io_meas_ctrl_shadowed_hi_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_io_meas_ctrl_shadowed_hi_err_update_sync ( + .clk_src_i(clk_io_i), + .rst_src_ni(rst_io_ni), + .src_pulse_i(async_io_meas_ctrl_shadowed_hi_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(io_meas_ctrl_shadowed_hi_update_err) + ); + prim_subreg_shadow #( + .DW (10), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (10'h1ea), + .Mubi (1'b0) + ) u_io_meas_ctrl_shadowed_hi ( + .clk_i (clk_io_i), + .rst_ni (rst_io_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (io_io_meas_ctrl_shadowed_re), + .we (io_io_meas_ctrl_shadowed_gated_we), + .wd (io_io_meas_ctrl_shadowed_wdata[9:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.io_meas_ctrl_shadowed.hi.q), + .ds (), + + // to register interface (read) + .qs (io_io_meas_ctrl_shadowed_hi_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_io_meas_ctrl_shadowed_hi_err_update), + .err_storage (async_io_meas_ctrl_shadowed_hi_err_storage) + ); + + // F[lo]: 19:10 + logic async_io_meas_ctrl_shadowed_lo_err_update; + logic async_io_meas_ctrl_shadowed_lo_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_io_meas_ctrl_shadowed_lo_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_io_meas_ctrl_shadowed_lo_err_storage), + .q_o(io_meas_ctrl_shadowed_lo_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_io_meas_ctrl_shadowed_lo_err_update_sync ( + .clk_src_i(clk_io_i), + .rst_src_ni(rst_io_ni), + .src_pulse_i(async_io_meas_ctrl_shadowed_lo_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(io_meas_ctrl_shadowed_lo_update_err) + ); + prim_subreg_shadow #( + .DW (10), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (10'h1d6), + .Mubi (1'b0) + ) u_io_meas_ctrl_shadowed_lo ( + .clk_i (clk_io_i), + .rst_ni (rst_io_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (io_io_meas_ctrl_shadowed_re), + .we (io_io_meas_ctrl_shadowed_gated_we), + .wd (io_io_meas_ctrl_shadowed_wdata[19:10]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.io_meas_ctrl_shadowed.lo.q), + .ds (), + + // to register interface (read) + .qs (io_io_meas_ctrl_shadowed_lo_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_io_meas_ctrl_shadowed_lo_err_update), + .err_storage (async_io_meas_ctrl_shadowed_lo_err_storage) + ); + + + // R[io_div4_meas_ctrl_en]: V(False) + logic [0:0] io_div4_meas_ctrl_en_flds_we; + assign io_div4_io_div4_meas_ctrl_en_qe = |io_div4_meas_ctrl_en_flds_we; + // Create REGWEN-gated WE signal + logic io_div4_io_div4_meas_ctrl_en_gated_we; + assign io_div4_io_div4_meas_ctrl_en_gated_we = + io_div4_io_div4_meas_ctrl_en_we & io_div4_io_div4_meas_ctrl_en_regwen; + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_io_div4_meas_ctrl_en ( + .clk_i (clk_io_div4_i), + .rst_ni (rst_io_div4_ni), + + // from register interface + .we (io_div4_io_div4_meas_ctrl_en_gated_we), + .wd (io_div4_io_div4_meas_ctrl_en_wdata[3:0]), + + // from internal hardware + .de (hw2reg.io_div4_meas_ctrl_en.de), + .d (hw2reg.io_div4_meas_ctrl_en.d), + + // to internal hardware + .qe (io_div4_meas_ctrl_en_flds_we[0]), + .q (reg2hw.io_div4_meas_ctrl_en.q), + .ds (io_div4_io_div4_meas_ctrl_en_ds_int), + + // to register interface (read) + .qs (io_div4_io_div4_meas_ctrl_en_qs_int) + ); + + + // R[io_div4_meas_ctrl_shadowed]: V(False) + // Create REGWEN-gated WE signal + logic io_div4_io_div4_meas_ctrl_shadowed_gated_we; + assign io_div4_io_div4_meas_ctrl_shadowed_gated_we = + io_div4_io_div4_meas_ctrl_shadowed_we & io_div4_io_div4_meas_ctrl_shadowed_regwen; + // F[hi]: 7:0 + logic async_io_div4_meas_ctrl_shadowed_hi_err_update; + logic async_io_div4_meas_ctrl_shadowed_hi_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_io_div4_meas_ctrl_shadowed_hi_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_io_div4_meas_ctrl_shadowed_hi_err_storage), + .q_o(io_div4_meas_ctrl_shadowed_hi_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_io_div4_meas_ctrl_shadowed_hi_err_update_sync ( + .clk_src_i(clk_io_div4_i), + .rst_src_ni(rst_io_div4_ni), + .src_pulse_i(async_io_div4_meas_ctrl_shadowed_hi_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(io_div4_meas_ctrl_shadowed_hi_update_err) + ); + prim_subreg_shadow #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h82), + .Mubi (1'b0) + ) u_io_div4_meas_ctrl_shadowed_hi ( + .clk_i (clk_io_div4_i), + .rst_ni (rst_io_div4_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (io_div4_io_div4_meas_ctrl_shadowed_re), + .we (io_div4_io_div4_meas_ctrl_shadowed_gated_we), + .wd (io_div4_io_div4_meas_ctrl_shadowed_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.io_div4_meas_ctrl_shadowed.hi.q), + .ds (), + + // to register interface (read) + .qs (io_div4_io_div4_meas_ctrl_shadowed_hi_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_io_div4_meas_ctrl_shadowed_hi_err_update), + .err_storage (async_io_div4_meas_ctrl_shadowed_hi_err_storage) + ); + + // F[lo]: 15:8 + logic async_io_div4_meas_ctrl_shadowed_lo_err_update; + logic async_io_div4_meas_ctrl_shadowed_lo_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_io_div4_meas_ctrl_shadowed_lo_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_io_div4_meas_ctrl_shadowed_lo_err_storage), + .q_o(io_div4_meas_ctrl_shadowed_lo_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_io_div4_meas_ctrl_shadowed_lo_err_update_sync ( + .clk_src_i(clk_io_div4_i), + .rst_src_ni(rst_io_div4_ni), + .src_pulse_i(async_io_div4_meas_ctrl_shadowed_lo_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(io_div4_meas_ctrl_shadowed_lo_update_err) + ); + prim_subreg_shadow #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h6e), + .Mubi (1'b0) + ) u_io_div4_meas_ctrl_shadowed_lo ( + .clk_i (clk_io_div4_i), + .rst_ni (rst_io_div4_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (io_div4_io_div4_meas_ctrl_shadowed_re), + .we (io_div4_io_div4_meas_ctrl_shadowed_gated_we), + .wd (io_div4_io_div4_meas_ctrl_shadowed_wdata[15:8]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.io_div4_meas_ctrl_shadowed.lo.q), + .ds (), + + // to register interface (read) + .qs (io_div4_io_div4_meas_ctrl_shadowed_lo_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_io_div4_meas_ctrl_shadowed_lo_err_update), + .err_storage (async_io_div4_meas_ctrl_shadowed_lo_err_storage) + ); + + + // R[main_meas_ctrl_en]: V(False) + logic [0:0] main_meas_ctrl_en_flds_we; + assign main_main_meas_ctrl_en_qe = |main_meas_ctrl_en_flds_we; + // Create REGWEN-gated WE signal + logic main_main_meas_ctrl_en_gated_we; + assign main_main_meas_ctrl_en_gated_we = + main_main_meas_ctrl_en_we & main_main_meas_ctrl_en_regwen; + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_main_meas_ctrl_en ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + + // from register interface + .we (main_main_meas_ctrl_en_gated_we), + .wd (main_main_meas_ctrl_en_wdata[3:0]), + + // from internal hardware + .de (hw2reg.main_meas_ctrl_en.de), + .d (hw2reg.main_meas_ctrl_en.d), + + // to internal hardware + .qe (main_meas_ctrl_en_flds_we[0]), + .q (reg2hw.main_meas_ctrl_en.q), + .ds (main_main_meas_ctrl_en_ds_int), + + // to register interface (read) + .qs (main_main_meas_ctrl_en_qs_int) + ); + + + // R[main_meas_ctrl_shadowed]: V(False) + // Create REGWEN-gated WE signal + logic main_main_meas_ctrl_shadowed_gated_we; + assign main_main_meas_ctrl_shadowed_gated_we = + main_main_meas_ctrl_shadowed_we & main_main_meas_ctrl_shadowed_regwen; + // F[hi]: 9:0 + logic async_main_meas_ctrl_shadowed_hi_err_update; + logic async_main_meas_ctrl_shadowed_hi_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_main_meas_ctrl_shadowed_hi_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_main_meas_ctrl_shadowed_hi_err_storage), + .q_o(main_meas_ctrl_shadowed_hi_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_main_meas_ctrl_shadowed_hi_err_update_sync ( + .clk_src_i(clk_main_i), + .rst_src_ni(rst_main_ni), + .src_pulse_i(async_main_meas_ctrl_shadowed_hi_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(main_meas_ctrl_shadowed_hi_update_err) + ); + prim_subreg_shadow #( + .DW (10), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (10'h1fe), + .Mubi (1'b0) + ) u_main_meas_ctrl_shadowed_hi ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (main_main_meas_ctrl_shadowed_re), + .we (main_main_meas_ctrl_shadowed_gated_we), + .wd (main_main_meas_ctrl_shadowed_wdata[9:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.main_meas_ctrl_shadowed.hi.q), + .ds (), + + // to register interface (read) + .qs (main_main_meas_ctrl_shadowed_hi_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_main_meas_ctrl_shadowed_hi_err_update), + .err_storage (async_main_meas_ctrl_shadowed_hi_err_storage) + ); + + // F[lo]: 19:10 + logic async_main_meas_ctrl_shadowed_lo_err_update; + logic async_main_meas_ctrl_shadowed_lo_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_main_meas_ctrl_shadowed_lo_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_main_meas_ctrl_shadowed_lo_err_storage), + .q_o(main_meas_ctrl_shadowed_lo_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_main_meas_ctrl_shadowed_lo_err_update_sync ( + .clk_src_i(clk_main_i), + .rst_src_ni(rst_main_ni), + .src_pulse_i(async_main_meas_ctrl_shadowed_lo_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(main_meas_ctrl_shadowed_lo_update_err) + ); + prim_subreg_shadow #( + .DW (10), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (10'h1ea), + .Mubi (1'b0) + ) u_main_meas_ctrl_shadowed_lo ( + .clk_i (clk_main_i), + .rst_ni (rst_main_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (main_main_meas_ctrl_shadowed_re), + .we (main_main_meas_ctrl_shadowed_gated_we), + .wd (main_main_meas_ctrl_shadowed_wdata[19:10]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.main_meas_ctrl_shadowed.lo.q), + .ds (), + + // to register interface (read) + .qs (main_main_meas_ctrl_shadowed_lo_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_main_meas_ctrl_shadowed_lo_err_update), + .err_storage (async_main_meas_ctrl_shadowed_lo_err_storage) + ); + + + // R[usb_meas_ctrl_en]: V(False) + logic [0:0] usb_meas_ctrl_en_flds_we; + assign usb_usb_meas_ctrl_en_qe = |usb_meas_ctrl_en_flds_we; + // Create REGWEN-gated WE signal + logic usb_usb_meas_ctrl_en_gated_we; + assign usb_usb_meas_ctrl_en_gated_we = usb_usb_meas_ctrl_en_we & usb_usb_meas_ctrl_en_regwen; + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_usb_meas_ctrl_en ( + .clk_i (clk_usb_i), + .rst_ni (rst_usb_ni), + + // from register interface + .we (usb_usb_meas_ctrl_en_gated_we), + .wd (usb_usb_meas_ctrl_en_wdata[3:0]), + + // from internal hardware + .de (hw2reg.usb_meas_ctrl_en.de), + .d (hw2reg.usb_meas_ctrl_en.d), + + // to internal hardware + .qe (usb_meas_ctrl_en_flds_we[0]), + .q (reg2hw.usb_meas_ctrl_en.q), + .ds (usb_usb_meas_ctrl_en_ds_int), + + // to register interface (read) + .qs (usb_usb_meas_ctrl_en_qs_int) + ); + + + // R[usb_meas_ctrl_shadowed]: V(False) + // Create REGWEN-gated WE signal + logic usb_usb_meas_ctrl_shadowed_gated_we; + assign usb_usb_meas_ctrl_shadowed_gated_we = + usb_usb_meas_ctrl_shadowed_we & usb_usb_meas_ctrl_shadowed_regwen; + // F[hi]: 8:0 + logic async_usb_meas_ctrl_shadowed_hi_err_update; + logic async_usb_meas_ctrl_shadowed_hi_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_usb_meas_ctrl_shadowed_hi_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_usb_meas_ctrl_shadowed_hi_err_storage), + .q_o(usb_meas_ctrl_shadowed_hi_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_usb_meas_ctrl_shadowed_hi_err_update_sync ( + .clk_src_i(clk_usb_i), + .rst_src_ni(rst_usb_ni), + .src_pulse_i(async_usb_meas_ctrl_shadowed_hi_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(usb_meas_ctrl_shadowed_hi_update_err) + ); + prim_subreg_shadow #( + .DW (9), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (9'hfa), + .Mubi (1'b0) + ) u_usb_meas_ctrl_shadowed_hi ( + .clk_i (clk_usb_i), + .rst_ni (rst_usb_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (usb_usb_meas_ctrl_shadowed_re), + .we (usb_usb_meas_ctrl_shadowed_gated_we), + .wd (usb_usb_meas_ctrl_shadowed_wdata[8:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.usb_meas_ctrl_shadowed.hi.q), + .ds (), + + // to register interface (read) + .qs (usb_usb_meas_ctrl_shadowed_hi_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_usb_meas_ctrl_shadowed_hi_err_update), + .err_storage (async_usb_meas_ctrl_shadowed_hi_err_storage) + ); + + // F[lo]: 17:9 + logic async_usb_meas_ctrl_shadowed_lo_err_update; + logic async_usb_meas_ctrl_shadowed_lo_err_storage; + + // storage error is persistent and can be sampled at any time + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_usb_meas_ctrl_shadowed_lo_err_storage_sync ( + .clk_i, + .rst_ni, + .d_i(async_usb_meas_ctrl_shadowed_lo_err_storage), + .q_o(usb_meas_ctrl_shadowed_lo_storage_err) + ); + + // update error is transient and must be immediately captured + prim_pulse_sync u_usb_meas_ctrl_shadowed_lo_err_update_sync ( + .clk_src_i(clk_usb_i), + .rst_src_ni(rst_usb_ni), + .src_pulse_i(async_usb_meas_ctrl_shadowed_lo_err_update), + .clk_dst_i(clk_i), + .rst_dst_ni(rst_ni), + .dst_pulse_o(usb_meas_ctrl_shadowed_lo_update_err) + ); + prim_subreg_shadow #( + .DW (9), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (9'he6), + .Mubi (1'b0) + ) u_usb_meas_ctrl_shadowed_lo ( + .clk_i (clk_usb_i), + .rst_ni (rst_usb_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (usb_usb_meas_ctrl_shadowed_re), + .we (usb_usb_meas_ctrl_shadowed_gated_we), + .wd (usb_usb_meas_ctrl_shadowed_wdata[17:9]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.usb_meas_ctrl_shadowed.lo.q), + .ds (), + + // to register interface (read) + .qs (usb_usb_meas_ctrl_shadowed_lo_qs_int), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (async_usb_meas_ctrl_shadowed_lo_err_update), + .err_storage (async_usb_meas_ctrl_shadowed_lo_err_storage) + ); + + + // R[recov_err_code]: V(False) + // F[shadow_update_err]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_shadow_update_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_shadow_update_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.shadow_update_err.de), + .d (hw2reg.recov_err_code.shadow_update_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_shadow_update_err_qs) + ); + + // F[io_measure_err]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_io_measure_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_io_measure_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.io_measure_err.de), + .d (hw2reg.recov_err_code.io_measure_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_io_measure_err_qs) + ); + + // F[io_div4_measure_err]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_io_div4_measure_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_io_div4_measure_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.io_div4_measure_err.de), + .d (hw2reg.recov_err_code.io_div4_measure_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_io_div4_measure_err_qs) + ); + + // F[main_measure_err]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_main_measure_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_main_measure_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.main_measure_err.de), + .d (hw2reg.recov_err_code.main_measure_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_main_measure_err_qs) + ); + + // F[usb_measure_err]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_usb_measure_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_usb_measure_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.usb_measure_err.de), + .d (hw2reg.recov_err_code.usb_measure_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_usb_measure_err_qs) + ); + + // F[io_timeout_err]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_io_timeout_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_io_timeout_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.io_timeout_err.de), + .d (hw2reg.recov_err_code.io_timeout_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_io_timeout_err_qs) + ); + + // F[io_div4_timeout_err]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_io_div4_timeout_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_io_div4_timeout_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.io_div4_timeout_err.de), + .d (hw2reg.recov_err_code.io_div4_timeout_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_io_div4_timeout_err_qs) + ); + + // F[main_timeout_err]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_main_timeout_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_main_timeout_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.main_timeout_err.de), + .d (hw2reg.recov_err_code.main_timeout_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_main_timeout_err_qs) + ); + + // F[usb_timeout_err]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_recov_err_code_usb_timeout_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (recov_err_code_we), + .wd (recov_err_code_usb_timeout_err_wd), + + // from internal hardware + .de (hw2reg.recov_err_code.usb_timeout_err.de), + .d (hw2reg.recov_err_code.usb_timeout_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (recov_err_code_usb_timeout_err_qs) + ); + + + // R[fatal_err_code]: V(False) + // F[reg_intg]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fatal_err_code_reg_intg ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fatal_err_code.reg_intg.de), + .d (hw2reg.fatal_err_code.reg_intg.d), + + // to internal hardware + .qe (), + .q (reg2hw.fatal_err_code.reg_intg.q), + .ds (), + + // to register interface (read) + .qs (fatal_err_code_reg_intg_qs) + ); + + // F[idle_cnt]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fatal_err_code_idle_cnt ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fatal_err_code.idle_cnt.de), + .d (hw2reg.fatal_err_code.idle_cnt.d), + + // to internal hardware + .qe (), + .q (reg2hw.fatal_err_code.idle_cnt.q), + .ds (), + + // to register interface (read) + .qs (fatal_err_code_idle_cnt_qs) + ); + + // F[shadow_storage_err]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fatal_err_code_shadow_storage_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fatal_err_code.shadow_storage_err.de), + .d (hw2reg.fatal_err_code.shadow_storage_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fatal_err_code.shadow_storage_err.q), + .ds (), + + // to register interface (read) + .qs (fatal_err_code_shadow_storage_err_qs) + ); + + + + logic [19:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == CLKMGR_ALERT_TEST_OFFSET); + addr_hit[ 1] = (reg_addr == CLKMGR_EXTCLK_CTRL_REGWEN_OFFSET); + addr_hit[ 2] = (reg_addr == CLKMGR_EXTCLK_CTRL_OFFSET); + addr_hit[ 3] = (reg_addr == CLKMGR_EXTCLK_STATUS_OFFSET); + addr_hit[ 4] = (reg_addr == CLKMGR_JITTER_REGWEN_OFFSET); + addr_hit[ 5] = (reg_addr == CLKMGR_JITTER_ENABLE_OFFSET); + addr_hit[ 6] = (reg_addr == CLKMGR_CLK_ENABLES_OFFSET); + addr_hit[ 7] = (reg_addr == CLKMGR_CLK_HINTS_OFFSET); + addr_hit[ 8] = (reg_addr == CLKMGR_CLK_HINTS_STATUS_OFFSET); + addr_hit[ 9] = (reg_addr == CLKMGR_MEASURE_CTRL_REGWEN_OFFSET); + addr_hit[10] = (reg_addr == CLKMGR_IO_MEAS_CTRL_EN_OFFSET); + addr_hit[11] = (reg_addr == CLKMGR_IO_MEAS_CTRL_SHADOWED_OFFSET); + addr_hit[12] = (reg_addr == CLKMGR_IO_DIV4_MEAS_CTRL_EN_OFFSET); + addr_hit[13] = (reg_addr == CLKMGR_IO_DIV4_MEAS_CTRL_SHADOWED_OFFSET); + addr_hit[14] = (reg_addr == CLKMGR_MAIN_MEAS_CTRL_EN_OFFSET); + addr_hit[15] = (reg_addr == CLKMGR_MAIN_MEAS_CTRL_SHADOWED_OFFSET); + addr_hit[16] = (reg_addr == CLKMGR_USB_MEAS_CTRL_EN_OFFSET); + addr_hit[17] = (reg_addr == CLKMGR_USB_MEAS_CTRL_SHADOWED_OFFSET); + addr_hit[18] = (reg_addr == CLKMGR_RECOV_ERR_CODE_OFFSET); + addr_hit[19] = (reg_addr == CLKMGR_FATAL_ERR_CODE_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] & (|(CLKMGR_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(CLKMGR_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(CLKMGR_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(CLKMGR_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(CLKMGR_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(CLKMGR_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(CLKMGR_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(CLKMGR_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(CLKMGR_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(CLKMGR_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(CLKMGR_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(CLKMGR_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(CLKMGR_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(CLKMGR_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(CLKMGR_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(CLKMGR_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(CLKMGR_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(CLKMGR_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(CLKMGR_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(CLKMGR_PERMIT[19] & ~reg_be))))); + end + + // Generate write-enables + assign alert_test_we = addr_hit[0] & reg_we & !reg_error; + + assign alert_test_recov_fault_wd = reg_wdata[0]; + + assign alert_test_fatal_fault_wd = reg_wdata[1]; + assign extclk_ctrl_regwen_we = addr_hit[1] & reg_we & !reg_error; + + assign extclk_ctrl_regwen_wd = reg_wdata[0]; + assign extclk_ctrl_we = addr_hit[2] & reg_we & !reg_error; + + assign extclk_ctrl_sel_wd = reg_wdata[3:0]; + + assign extclk_ctrl_hi_speed_sel_wd = reg_wdata[7:4]; + assign extclk_status_re = addr_hit[3] & reg_re & !reg_error; + assign jitter_regwen_we = addr_hit[4] & reg_we & !reg_error; + + assign jitter_regwen_wd = reg_wdata[0]; + assign jitter_enable_we = addr_hit[5] & reg_we & !reg_error; + + assign jitter_enable_wd = reg_wdata[3:0]; + assign clk_enables_we = addr_hit[6] & reg_we & !reg_error; + + assign clk_enables_clk_io_div4_peri_en_wd = reg_wdata[0]; + + assign clk_enables_clk_io_div2_peri_en_wd = reg_wdata[1]; + + assign clk_enables_clk_io_peri_en_wd = reg_wdata[2]; + + assign clk_enables_clk_usb_peri_en_wd = reg_wdata[3]; + assign clk_hints_we = addr_hit[7] & reg_we & !reg_error; + + assign clk_hints_wd = reg_wdata[0]; + assign measure_ctrl_regwen_we = addr_hit[9] & reg_we & !reg_error; + + assign measure_ctrl_regwen_wd = reg_wdata[0]; + assign io_meas_ctrl_en_we = addr_hit[10] & reg_we & !reg_error; + + assign io_meas_ctrl_shadowed_re = addr_hit[11] & reg_re & !reg_error; + assign io_meas_ctrl_shadowed_we = addr_hit[11] & reg_we & !reg_error; + + + assign io_div4_meas_ctrl_en_we = addr_hit[12] & reg_we & !reg_error; + + assign io_div4_meas_ctrl_shadowed_re = addr_hit[13] & reg_re & !reg_error; + assign io_div4_meas_ctrl_shadowed_we = addr_hit[13] & reg_we & !reg_error; + + + assign main_meas_ctrl_en_we = addr_hit[14] & reg_we & !reg_error; + + assign main_meas_ctrl_shadowed_re = addr_hit[15] & reg_re & !reg_error; + assign main_meas_ctrl_shadowed_we = addr_hit[15] & reg_we & !reg_error; + + + assign usb_meas_ctrl_en_we = addr_hit[16] & reg_we & !reg_error; + + assign usb_meas_ctrl_shadowed_re = addr_hit[17] & reg_re & !reg_error; + assign usb_meas_ctrl_shadowed_we = addr_hit[17] & reg_we & !reg_error; + + + assign recov_err_code_we = addr_hit[18] & reg_we & !reg_error; + + assign recov_err_code_shadow_update_err_wd = reg_wdata[0]; + + assign recov_err_code_io_measure_err_wd = reg_wdata[1]; + + assign recov_err_code_io_div4_measure_err_wd = reg_wdata[2]; + + assign recov_err_code_main_measure_err_wd = reg_wdata[3]; + + assign recov_err_code_usb_measure_err_wd = reg_wdata[4]; + + assign recov_err_code_io_timeout_err_wd = reg_wdata[5]; + + assign recov_err_code_io_div4_timeout_err_wd = reg_wdata[6]; + + assign recov_err_code_main_timeout_err_wd = reg_wdata[7]; + + assign recov_err_code_usb_timeout_err_wd = reg_wdata[8]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = alert_test_we; + reg_we_check[1] = extclk_ctrl_regwen_we; + reg_we_check[2] = extclk_ctrl_gated_we; + reg_we_check[3] = 1'b0; + reg_we_check[4] = jitter_regwen_we; + reg_we_check[5] = jitter_enable_we; + reg_we_check[6] = clk_enables_we; + reg_we_check[7] = clk_hints_we; + reg_we_check[8] = 1'b0; + reg_we_check[9] = measure_ctrl_regwen_we; + reg_we_check[10] = io_meas_ctrl_en_we; + reg_we_check[11] = io_meas_ctrl_shadowed_we; + reg_we_check[12] = io_div4_meas_ctrl_en_we; + reg_we_check[13] = io_div4_meas_ctrl_shadowed_we; + reg_we_check[14] = main_meas_ctrl_en_we; + reg_we_check[15] = main_meas_ctrl_shadowed_we; + reg_we_check[16] = usb_meas_ctrl_en_we; + reg_we_check[17] = usb_meas_ctrl_shadowed_we; + reg_we_check[18] = recov_err_code_we; + reg_we_check[19] = 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] = '0; + reg_rdata_next[1] = '0; + end + + addr_hit[1]: begin + reg_rdata_next[0] = extclk_ctrl_regwen_qs; + end + + addr_hit[2]: begin + reg_rdata_next[3:0] = extclk_ctrl_sel_qs; + reg_rdata_next[7:4] = extclk_ctrl_hi_speed_sel_qs; + end + + addr_hit[3]: begin + reg_rdata_next[3:0] = extclk_status_qs; + end + + addr_hit[4]: begin + reg_rdata_next[0] = jitter_regwen_qs; + end + + addr_hit[5]: begin + reg_rdata_next[3:0] = jitter_enable_qs; + end + + addr_hit[6]: begin + reg_rdata_next[0] = clk_enables_clk_io_div4_peri_en_qs; + reg_rdata_next[1] = clk_enables_clk_io_div2_peri_en_qs; + reg_rdata_next[2] = clk_enables_clk_io_peri_en_qs; + reg_rdata_next[3] = clk_enables_clk_usb_peri_en_qs; + end + + addr_hit[7]: begin + reg_rdata_next[0] = clk_hints_qs; + end + + addr_hit[8]: begin + reg_rdata_next[0] = clk_hints_status_qs; + end + + addr_hit[9]: begin + reg_rdata_next[0] = measure_ctrl_regwen_qs; + end + + addr_hit[10]: begin + reg_rdata_next = DW'(io_meas_ctrl_en_qs); + end + addr_hit[11]: begin + reg_rdata_next = DW'(io_meas_ctrl_shadowed_qs); + end + addr_hit[12]: begin + reg_rdata_next = DW'(io_div4_meas_ctrl_en_qs); + end + addr_hit[13]: begin + reg_rdata_next = DW'(io_div4_meas_ctrl_shadowed_qs); + end + addr_hit[14]: begin + reg_rdata_next = DW'(main_meas_ctrl_en_qs); + end + addr_hit[15]: begin + reg_rdata_next = DW'(main_meas_ctrl_shadowed_qs); + end + addr_hit[16]: begin + reg_rdata_next = DW'(usb_meas_ctrl_en_qs); + end + addr_hit[17]: begin + reg_rdata_next = DW'(usb_meas_ctrl_shadowed_qs); + end + addr_hit[18]: begin + reg_rdata_next[0] = recov_err_code_shadow_update_err_qs; + reg_rdata_next[1] = recov_err_code_io_measure_err_qs; + reg_rdata_next[2] = recov_err_code_io_div4_measure_err_qs; + reg_rdata_next[3] = recov_err_code_main_measure_err_qs; + reg_rdata_next[4] = recov_err_code_usb_measure_err_qs; + reg_rdata_next[5] = recov_err_code_io_timeout_err_qs; + reg_rdata_next[6] = recov_err_code_io_div4_timeout_err_qs; + reg_rdata_next[7] = recov_err_code_main_timeout_err_qs; + reg_rdata_next[8] = recov_err_code_usb_timeout_err_qs; + end + + addr_hit[19]: begin + reg_rdata_next[0] = fatal_err_code_reg_intg_qs; + reg_rdata_next[1] = fatal_err_code_idle_cnt_qs; + reg_rdata_next[2] = fatal_err_code_shadow_storage_err_qs; + end + + default: begin + reg_rdata_next = '1; + end + endcase + end + + // shadow busy + logic shadow_busy; + logic rst_done; + logic shadow_rst_done; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rst_done <= '0; + end else begin + rst_done <= 1'b1; + end + end + + always_ff @(posedge clk_i or negedge rst_shadowed_ni) begin + if (!rst_shadowed_ni) begin + shadow_rst_done <= '0; + end else begin + shadow_rst_done <= 1'b1; + end + end + + // both shadow and normal resets have been released + assign shadow_busy = ~(rst_done & shadow_rst_done); + + // Collect up storage and update errors + assign shadowed_storage_err_o = |{ + io_meas_ctrl_shadowed_hi_storage_err, + io_meas_ctrl_shadowed_lo_storage_err, + io_div4_meas_ctrl_shadowed_hi_storage_err, + io_div4_meas_ctrl_shadowed_lo_storage_err, + main_meas_ctrl_shadowed_hi_storage_err, + main_meas_ctrl_shadowed_lo_storage_err, + usb_meas_ctrl_shadowed_hi_storage_err, + usb_meas_ctrl_shadowed_lo_storage_err + }; + assign shadowed_update_err_o = |{ + io_meas_ctrl_shadowed_hi_update_err, + io_meas_ctrl_shadowed_lo_update_err, + io_div4_meas_ctrl_shadowed_hi_update_err, + io_div4_meas_ctrl_shadowed_lo_update_err, + main_meas_ctrl_shadowed_hi_update_err, + main_meas_ctrl_shadowed_lo_update_err, + usb_meas_ctrl_shadowed_hi_update_err, + usb_meas_ctrl_shadowed_lo_update_err + }; + + // register busy + logic reg_busy_sel; + assign reg_busy = reg_busy_sel | shadow_busy; + always_comb begin + reg_busy_sel = '0; + unique case (1'b1) + addr_hit[10]: begin + reg_busy_sel = io_meas_ctrl_en_busy; + end + addr_hit[11]: begin + reg_busy_sel = io_meas_ctrl_shadowed_busy; + end + addr_hit[12]: begin + reg_busy_sel = io_div4_meas_ctrl_en_busy; + end + addr_hit[13]: begin + reg_busy_sel = io_div4_meas_ctrl_shadowed_busy; + end + addr_hit[14]: begin + reg_busy_sel = main_meas_ctrl_en_busy; + end + addr_hit[15]: begin + reg_busy_sel = main_meas_ctrl_shadowed_busy; + end + addr_hit[16]: begin + reg_busy_sel = usb_meas_ctrl_en_busy; + end + addr_hit[17]: begin + reg_busy_sel = usb_meas_ctrl_shadowed_busy; + end + default: begin + reg_busy_sel = '0; + end + endcase + end + + + // 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_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_root_ctrl.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_root_ctrl.sv new file mode 100644 index 0000000000000..3008d2b24aa9e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_root_ctrl.sv @@ -0,0 +1,41 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Wrapper for scan sync and clock gating cell + +module clkmgr_root_ctrl + import clkmgr_pkg::*; + import prim_mubi_pkg::mubi4_t; +( + input clk_i, + input rst_ni, + + input mubi4_t scanmode_i, + input async_en_i, + + output logic en_o, + output logic clk_o +); + + mubi4_t scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) // clock/reset below is only used for SVAs. + ) u_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o({scanmode}) + ); + + prim_clock_gating_sync u_cg ( + .clk_i, + .rst_ni, + .test_en_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode)), + .async_en_i, + .en_o, + .clk_o + ); + +endmodule // clkmgr_root_ctrl diff --git a/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_trans.sv b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_trans.sv new file mode 100644 index 0000000000000..80c6aa2164256 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/clkmgr/rtl/clkmgr_trans.sv @@ -0,0 +1,175 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Handle clock manager transactional clocks + +module clkmgr_trans + import clkmgr_pkg::*; + import prim_mubi_pkg::mubi4_t; +# ( + parameter bit FpgaBufGlobal = 1 +) ( + input clk_i, + input clk_gated_i, + input rst_ni, + input en_i, + input mubi4_t idle_i, + input sw_hint_i, + input mubi4_t scanmode_i, + output mubi4_t alert_cg_en_o, + output logic clk_o, + + // interface to regfile + input clk_reg_i, + input rst_reg_ni, + output logic reg_en_o, + output logic reg_cnt_err_o +); + + import prim_mubi_pkg::MuBi4False; + import prim_mubi_pkg::MuBi4True; + import prim_mubi_pkg::mubi4_test_true_strict; + import prim_mubi_pkg::mubi4_test_false_loose; + + // Note this value is specifically chosen. + // The binary value is 1010, which is a balanced 4-bit value + // that should in theory be resistant to all 0 or all 1 attacks. + localparam int unsigned TransIdleCnt = 10; + localparam int IdleCntWidth = $clog2(TransIdleCnt + 1); + + logic [IdleCntWidth-1:0] idle_cnt; + logic idle_valid; + logic sw_hint_synced; + logic local_en; + assign idle_valid = (idle_cnt == IdleCntWidth'(TransIdleCnt)); + assign local_en = sw_hint_synced | ~idle_valid; + + prim_flop_2sync #( + .Width(1) + ) u_hint_sync ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(sw_hint_i), + .q_o(sw_hint_synced) + ); + + // Idle sync: Idle signal comes from IP module. The reset of the Idle signal + // may differ from the reset here. Adding mubi sync to synchronize. + prim_mubi_pkg::mubi4_t [0:0] idle; + prim_mubi4_sync #( + .NumCopies ( 1 ), + .AsyncOn ( 1'b 1 ), + .StabilityCheck ( 1'b 1 ) + ) u_idle_sync ( + .clk_i, + .rst_ni, + .mubi_i (idle_i), + .mubi_o (idle) + ); + + // SEC_CM: IDLE.CTR.REDUN + logic cnt_err; + prim_count #( + .Width(IdleCntWidth) + ) u_idle_cnt ( + .clk_i(clk_i), + .rst_ni(rst_ni), + // the default condition is to keep the clock enabled + .clr_i(mubi4_test_false_loose(idle[0])), + .set_i('0), + .set_cnt_i('0), + .incr_en_i(mubi4_test_true_strict(idle[0]) & ~idle_valid), + .decr_en_i(1'b0), + .step_i(IdleCntWidth'(1'b1)), + .commit_i(1'b1), + .cnt_o(idle_cnt), + .cnt_after_commit_o(), + .err_o(cnt_err) + ); + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o(scanmode) + ); + + // Add a prim buf here to make sure the CG and the lc sender inputs + // are derived from the same physical signal. + logic combined_en_d, combined_en_q; + prim_buf u_prim_buf_en ( + .in_i(local_en & en_i), + .out_o(combined_en_d) + ); + + // clk_gated_i is already controlled by en_i, so there is no need + // to use it in the below gating function + prim_clock_gating #( + .FpgaBufGlobal(FpgaBufGlobal) + ) u_cg ( + .clk_i(clk_gated_i), + .en_i(local_en), + .test_en_i(mubi4_test_true_strict(scanmode[0])), + .clk_o(clk_o) + ); + + // clock gated indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .mubi_i(combined_en_d ? MuBi4False : MuBi4True), + .mubi_o(alert_cg_en_o) + ); + + // we hold the error because there is no guarantee on + // what the timing of cnt_err looks like, it may be a + // pulse or it may be level. If it's for former, + // prim_sync_reqack may miss it, if it's the latter, + // prim_pulse_sync may miss it. As a result, just + // latch forever and sync it over. + logic hold_err; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + hold_err <= '0; + end else if (cnt_err) begin + hold_err <= 1'b1; + end + end + + // register facing domain + prim_flop_2sync #( + .Width(1) + ) u_err_sync ( + .clk_i(clk_reg_i), + .rst_ni(rst_reg_ni), + .d_i(hold_err), + .q_o(reg_cnt_err_o) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + combined_en_q <= '0; + end else begin + combined_en_q <= combined_en_d; + end + end + + prim_flop_2sync #( + .Width(1) + ) u_en_sync ( + .clk_i(clk_reg_i), + .rst_ni(rst_reg_ni), + .d_i(combined_en_q), + .q_o(reg_en_o) + ); + + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/BUILD b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/BUILD new file mode 100644 index 0000000000000..dda56de039e27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/flash_ctrl/README.md b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/README.md new file mode 100644 index 0000000000000..79259c4455172 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/README.md @@ -0,0 +1,195 @@ +# Flash Controller HWIP Technical Specification + +[`flash_ctrl`](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/latest/report.html): +![](https://dashboards.lowrisc.org/badges/dv/flash_ctrl/test.svg) +![](https://dashboards.lowrisc.org/badges/dv/flash_ctrl/passing.svg) +![](https://dashboards.lowrisc.org/badges/dv/flash_ctrl/functional.svg) +![](https://dashboards.lowrisc.org/badges/dv/flash_ctrl/code.svg) + +# Overview + +This document describes the flash controller functionality. +The flash controller is broken down into 3 major components +* Open source flash controller +* Closed source vendor flash wrapper +* Closed source vendor flash module + +A breakdown of the 3 can be seen below +![Flash High Level Boundaries](./doc/flash_boundaries.svg) + + +This open source flash controller is divided into two partitions. + +* Flash protocol controller +* Flash physical controller + +The remaining document focuses primarily on the function of these blocks. + +This module conforms to the [Comportable guideline for peripheral functionality](https://opentitan.org/book/doc/contributing/hw/comportability). +See that document for integration overview within the broader top level system. + +## Features + +### Flash Protocol Controller Features +The flash protocol controller interfaces with software and other hardware components in the system (such as life cycle, key manager and OTP). +Regardless of the flash size underneath, the flash controller maintains the same data resolution as the bus and processor (default 4B). +The flash physical controller (see section below) is then responsible for bridging that size gap between the default data resolution and the actual flash memory. + +The protocol controller currently supports the following features: + +* Controller initiated read, program and erase of flash. + * Erase can be either of a page, or an entire bank. +* Support for differentiation between informational and data flash partitions. +* Support for accessing multiple types of information partition. + * Some flash storage support multiple types of information storage for each information partition. +* Parameterized support for burst program / read, up to 64B. + * Longer programs / reads are supported, however the protocol controller will directly back-pressure the bus if software supplies more data than can be consumed, or if software reads more than there is data available. + * Software can also choose to operate by polling the current state of the FIFO or through FIFO interrupts (empty / full / level). +* Flash memory protection at page boundaries. +* Life cycle RMA entry. +* Key manager secret seeds that are inaccessible to software. +* Support vendor flash module [erase suspend](./doc/theory_of_operation.md#erase-suspend). +* Provisioning of flash specific attributes: + * High endurance. +* Idle indication to external power managers. +* Software control of flash code fetch. + +### Flash Physical Controller Features + +The flash physical controller wraps the actual flash memory and translates both host and controller initiated requests into low level flash transactions. + +The physical controller supports the following features +* Multiple banks of flash memory. +* For each flash bank, parameterized support for number of flash pages (default to 256). +* For each flash page, parameterized support for number of words and word size (default to 256 words of 8-bytes each). +* Data and informational partitions within each bank of flash memory. +* Arbitration between host requests and controller requests at the bank level. + * Host requests are always favored, however the controller priority can escalate if it repeatedly loses arbitration. + * Since banks are arbitrated independently and transactions may take different amounts of times to complete, the physical controller is also responsible for ensuring in-order response to both the controller and host. +* Flash read stage. + * Each bank maintains a parameterizable number of read buffers in front of the flash memory (default to 4). + * The read buffers behave as miniature read-only-caches to store flash data when flash words are greater than bus words. + * When a program or erase collides with an entry already stored in the read buffer, the buffer contents are invalidated. + * This situation may arise if a read is followed by a program or erase. +* Flash program stage + * Flash data word packing when flash word size is an integer multiple of bus word size. +* Flash scrambling + * Flash supports XEX scrambling using the PRINCE cipher. + * Scrambling is optional based on page boundaries and is configurable by software. +* Two types of Flash ECC support. + * A pre-scramble ICV (integrity check value) used for integrity verification implemented as ECC. + * A post-scramble ECC used for reliability detection, this is configurable on a page boundary. +* Life cycle modulated JTAG connection to the vendor flash module. + + +### Flash Memory Overview + +Unlike sram, flash memory is not typically organized as a contiguous block of generic storage. +Instead it is organized into data partitions and information partitions. + +The data partition holds generic data like a generic memory would. +The information partition holds metadata about the data partition as well as design specific secret data. +This includes but is not limited to: +* Redundancy information. +* Manufacturer specific information. +* Manufacturer flash timing information. +* Design specific unique seeds. +* The redundancy pages themselves, which are not accessible directly as data partitions. + +Note, there **can** be more than one information partition, and none of them are required to be the same size as the data partition. +See the diagram below for an illustrative example. +![Flash Example Partition](./doc/flash_partitions.svg) + +Which type of partition is accessed is controlled through the [`CONTROL.PARTITION_SEL`](data/flash_ctrl.hjson#control) field. +The current flash controller implements one type of information partition and thus is controlled by 1 bit only. +This may change in the future. + +Lastly, while the different partitions may be identical in some attributes, they are different in others. +* All types of partitions must have the same page size and word size; however they are not required to have the same number of pages, thus some partitions may be larger and others smaller. +* All types of partitions obey the same program and erase rules : + * A bit cannot be programmed back to 1 once it has been programmed to 0. + * Only erase can restore a bit to 1 under normal circumstances. +* All partitions (data and information) can be read, programmed and erased by the flash protocol controller, subject to [memory protection](./doc/theory_of_operation.md#memory-protection) and [life cycle qualification](./doc/theory_of_operation.md#memory-protection-for-key-manager-and-life-cycle) . +* System hosts (processor and other entities) can only directly read the data partition, they do not have any kind of access to information partitions. + * System hosts are also not subject to memory protection rules, as those apply to the flash protocol controller only. + +For default assumptions of the design, see the [default configuration](./doc/theory_of_operation.md#flash-default-configuration). + +#### Addresses Map + +##### Bank Address +The flash address map is built upon the bank base address. +The bank size is based upon the number of pages in the data partition. +The first bank's address is always `0x0`. +The second bank's address is `0x0 + size_of_bank_in_bytes`. + +For example: +Assume each bank is 512KB in size. +The address of bank 0 is `0x0`. +The address of bank 1 is `0x80000` + +##### Page Address +The address of a particular page is calculated based on the page size and the index number of the page. + +For example: +Assume each page is 2KB in size. + +To access page 0 in bank 1, the address would be the base address of bank 1 plus the base address of page 0. +This would still be `0x80000` in this case. + +To access page 4 in bank 1, the address would then be `0x80000 + 2KB * 4 = 0x82000`. + +##### Partition Access +All partitions share the same addressing scheme. +For example, the page 0 address of any kind of partition is always the same. + +To distinguish which partition is accessed, use the configuration in [`CONTROL.PARTITION_SEL`](data/flash_ctrl.hjson#control) and [`CONTROL.INFO_SEL`](data/flash_ctrl.hjson#control) +Note however, the system host is only able to access the [data partitions](./doc/theory_of_operation.md#host-and-protocol-controller-handling). + +##### Default Address Map +Based on the [default configuration](./doc/theory_of_operation.md#flash-default-configuration), the following would be the default address map for each partition / page. + +Location | Address | +----------------|------------- | +Bank 0 Page 0 | 0x0 | +Bank 0 Page 1 | 0x800 | +Bank 0 Page 2 | 0x1000 | +... | ... | +Bank 0 Page 255 | 0x7F800 | +Bank 1 Page 0 | 0x80000 | +Bank 1 Page 1 | 0x80800 | +Bank 1 Page 2 | 0x81000 | +... | ... | +Bank 1 Page 255 | 0xFF800 | + +Note when accessing from host, the system memory address for flash should be added to this offset. + + +#### Secret Information Partitions + +Two information partition pages (one for creator and one for owner) in the design hold secret seeds for the key manager. +These pages, when enabled by life cycle and OTP, are read upon flash controller initialization (no software configuration is required). +The read values are then fed to the key manager for later processing. +There is a page for creator and a page for the owner. + +The seed pages can be programmed/erased/read by software when the following are set: +* `lc_creator_seed_sw_rw_en` - allows software access to creator seed partition. +* `lc_owner_seed_sw_rw_en` - allows software access to owner seed partition. + +The seed pages are read under the following initialization conditions: +* life cycle sets provision enable - `lc_seed_hw_rd_en` is set. + +See [life cycle](../../../ip/lc_ctrl/README.md#creator_seed_sw_rw_en-and-owner_seed_sw_rw_en) for more details on when this partition is allowed to be populated. + +#### Isolated Information Partitions + +One information partition page in the design is used for manufacturing time authentication. +The accessibility of this page is controlled by life cycle and OTP. + +During TEST states, the isolated page is only programmable. +* `lc_iso_part_sw_wr_en` is set, but `lc_iso_part_sw_rd_en` is not. + +During production and RMA states, the isolated page is also readable. +* Both `lc_iso_part_sw_wr_en` and `lc_iso_part_sw_rd_en` are set. + +See [life cycle](../../../ip/lc_ctrl/README.md#iso_part_sw_rd_en-and-iso_part_sw_wr_en) for more details diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl.hjson new file mode 100644 index 0000000000000..b862b5f303dba --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl.hjson @@ -0,0 +1,3223 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + + + +{ + name: "flash_ctrl", + human_name: "Flash Controller", + one_line_desc: "Interfaces and manages integrated non-volatile flash memory; supports scrambling, integrity, and secure wipe", + one_paragraph_desc: ''' + Flash Controller interfaces the integrated, non-volatile flash memory with software and other hardware components in the system, such as Life Cycle Controller, Key Manager, and OTP Controller. + It consists of the open source flash controller that interfaces with a third party flash module. + The protocol controller handles read, program, and erase requests, as well as life cycle RMA entry. + It supports differentiation between informational and data flash partitions, flash memory protection at page boundaries, and the handling of key manager secrets inaccessible to software. + The actual physical controller is highly parameterized (number of banks, number of pages for each bank, number of words and word size for each page, and number of read buffers) and supports XEX scrambling configurable by software, as well as two types of ECC support configurable on a page boundary. + ''' + // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. + cip_id: "8", + design_spec: "../doc", + dv_doc: "../doc/dv" + hw_checklist: "../doc/checklist", + sw_checklist: "/sw/device/lib/dif/dif_flash_ctrl", + revisions: [ + { + version: "0.1.0", + life_stage: "L1", + design_stage: "D1", + verification_stage: "V1", + commit_id: "7049fd0d5d48e20772f8ebf32b240faa0dad5528", + }, + { + version: "2.0.0", + life_stage: "L1", + design_stage: "D2S", + verification_stage: "V2S", + dif_stage: "S2", + }, + ] + clocking: [ + {clock: "clk_i", reset: "rst_ni", primary: true}, + {clock: "clk_otp_i", reset: "rst_otp_ni"} + ] + bus_interfaces: [ + { protocol: "tlul", direction: "device", name: "core" } + { protocol: "tlul", direction: "device", name: "prim" , hier_path: "u_eflash.u_flash.gen_generic.u_impl_generic.u_reg_top"} + { protocol: "tlul", direction: "device", name: "mem" } + ], + available_input_list: [ + { name: "tck", desc: "jtag clock" }, + { name: "tms", desc: "jtag tms" }, + { name: "tdi", desc: "jtag input" }, + ], + available_output_list: [ + { name: "tdo", desc: "jtag output" }, + ], + interrupt_list: [ + // The first two status interrupts assert by default, since the FIFO is empty. + // This is captured in the Hjson via the `default` key so that automatically generated tests can incorporate this information. + { name: "prog_empty", type: "status", desc: "Program FIFO empty", default: "1"}, + { name: "prog_lvl", type: "status", desc: "Program FIFO drained to level", default: "1"}, + { name: "rd_full", type: "status", desc: "Read FIFO full", }, + { name: "rd_lvl", type: "status", desc: "Read FIFO filled to level", }, + { name: "op_done", type: "event", desc: "Operation complete", }, + { name: "corr_err", type: "event", desc: "Correctable error encountered", }, + ], + + alert_list: [ + { name: "recov_err", + desc: "flash recoverable errors", + }, + { name: "fatal_std_err", + desc: "flash standard fatal errors" + }, + { name: "fatal_err", + desc: ''' + Flash fatal errors including uncorrectable ECC errors. + + Note that this alert is not always fatal. + The underlying error bits in the !!FAULT_STATUS register remain set until reset, meaning the alert keeps firing. + This doesn't hold for !!FAULT_STATUS.PHY_RELBL_ERR and !!FAULT_STATUS.PHY_STORAGE_ERR. + To enable firmware dealing with multi-bit ECC and ICV errors during firmware selection and verification, these error bits can be cleared. + After passing this stage, it is recommended that firmware classifies the corresponding alert as fatal on the receiver end, i.e, inside the alert handler. + ''' + }, + { name: "fatal_prim_flash_alert", + desc: "Fatal alert triggered inside the flash primitive, including fatal TL-UL bus integrity faults of the test interface." + }, + { name: "recov_prim_flash_alert", + desc: "Recoverable alert triggered inside the flash primitive." + } + ], + + // Define flash_ctrl <-> flash_phy struct package + inter_signal_list: [ + { struct: "flash_otp_key", + type: "req_rsp", + name: "otp", + act: "req", + package: "otp_ctrl_pkg" + }, + + { struct: "lc_tx", + package: "lc_ctrl_pkg", + type: "uni" + act: "rcv" + name: "lc_nvm_debug_en" + }, + + { struct: "mubi4" + package: "prim_mubi_pkg" + type: "uni" + act: "rcv" + name: "flash_bist_enable" + }, + + { struct: "logic" + package: "" + type: "uni" + act: "rcv" + name: "flash_power_down_h" + }, + { struct: "logic" + package: "" + type: "uni" + act: "rcv" + name: "flash_power_ready_h" + }, + { struct: "", + package: "", + width: "2", + type: "io" + act: "none" + name: "flash_test_mode_a" + }, + { struct: "", + package: "", + type: "io" + act: "none" + name: "flash_test_voltage_h" + }, + + { struct: "lc_tx" + type: "uni" + name: "lc_creator_seed_sw_rw_en" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_tx" + type: "uni" + name: "lc_owner_seed_sw_rw_en" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_tx" + type: "uni" + name: "lc_iso_part_sw_rd_en" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_tx" + type: "uni" + name: "lc_iso_part_sw_wr_en" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_tx" + type: "uni" + name: "lc_seed_hw_rd_en" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_tx" + type: "uni" + name: "lc_escalate_en" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_tx" + type: "uni" + name: "rma_req" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_tx" + type: "uni" + name: "rma_ack" + act: "req" + package: "lc_ctrl_pkg" + }, + + { struct: "lc_flash_rma_seed" + type: "uni" + name: "rma_seed" + act: "rcv" + package: "lc_ctrl_pkg" + }, + + { struct: "pwr_flash", + type: "uni", + name: "pwrmgr", + act: "req", + package: "pwrmgr_pkg" + }, + + { struct: "keymgr_flash", + type: "uni", + name: "keymgr", + act: "req", + package: "flash_ctrl_pkg" + } + + { struct: "ast_obs_ctrl", + type: "uni", + name: "obs_ctrl", + act: "rcv", + package: "ast_pkg" + } + + { struct: "logic", + type: "uni", + name: "fla_obs", + act: "req", + width: "8", + package: "" + } + + ], + countermeasures: [ + { name: "REG.BUS.INTEGRITY", + desc: ''' + End-to-end bus integrity scheme. + Since there are multiple access points for flash, please see + Transmission Integrity Faults in the documentation for more details. + + The bus integrity scheme for flash is different from other comportable modules. + ''' + } + { name: "HOST.BUS.INTEGRITY", + desc: ''' + End-to-end bus integrity scheme. + Since there are multiple access points for flash, please see + Transmission Integrity Faults in the documentation for more details. + + The bus integrity scheme for flash is different from other comportable modules. + ''' + } + { name: "MEM.BUS.INTEGRITY", + desc: ''' + End-to-end bus integrity scheme. + Since there are multiple access points for flash, please see + Transmission Integrity Faults in the documentation for more details. + + The bus integrity scheme for flash is different from other comportable modules. + ''' + } + { name: "MEM.ADDR_INFECTION", + desc: ''' + On host reads, the address of the request is XORed with the data inside the read pipeline. + The request address is removed from the data before returning the data over TL-UL. + A mismatch triggers a data integrity error. + ''' + } + { name: "SCRAMBLE.KEY.SIDELOAD", + desc: "The scrambling key is sideloaded from OTP and thus unreadable by SW." + } + { name: "LC_CTRL.INTERSIG.MUBI", + desc: ''' + Life cycle control signals are used control information partition access + and flash debug access. See secret information partition, isolated information partitions + and jtag connection in documentation for more details. + ''' + } + { name: "CTRL.CONFIG.REGWEN", + desc: "Configurations cannot be changed when an operation is ongoing." + } + { name: "DATA_REGIONS.CONFIG.REGWEN", + desc: "Each data region has a configurable regwen." + } + { name: "DATA_REGIONS.CONFIG.SHADOW", + desc: "Data region configuration is shadowed." + } + { name: "INFO_REGIONS.CONFIG.REGWEN", + desc: "Each info page of each type in each bank has separate regwen." + } + { name: "INFO_REGIONS.CONFIG.SHADOW", + desc: "Each info page is shadowed." + } + { name: "BANK.CONFIG.REGWEN", + desc: "Each bank has separate regwen for bank erase." + } + { name: "BANK.CONFIG.SHADOW", + desc: "Each bank has separate regwen for bank erase." + } + { name: "MEM.CTRL.GLOBAL_ESC", + desc: "Global escalation causes memory to no longer be accessible." + } + { name: "MEM.CTRL.LOCAL_ESC", + desc: ''' + A subset of fatal errors cause memory to no longer be accessible. + This subset is defined in !!STD_FAULT_STATUS. + ''' + } + { name: "MEM_DISABLE.CONFIG.MUBI", + desc: ''' + Software control for flash disable is multibit. + The register is !!DIS. + ''' + } + { name: "EXEC.CONFIG.REDUN", + desc: ''' + Software control for flash enable is 32-bit constant. + The register is !!EXEC. + ''' + } + { name: "MEM.SCRAMBLE", + desc: ''' + The flash supports XEX scrambling. + The cipher used is PRINCE. + The scrambling scheme is enabled by software, please see flash scrambling in documentation for more details. + ''' + } + { name: "MEM.INTEGRITY", + desc: ''' + The flash supports two layers of ECC integrity: one layer is for integrity, + and the other layer is for reliability. + These ECCs are enabled and disabled together by software. + Please see Flash ECC in the documentation for more details. + ''' + } + { name: "RMA_ENTRY.MEM.SEC_WIPE", + desc: "RMA entry entry wipes flash memory with random data." + } + { name: "CTRL.FSM.SPARSE", + desc: ''' + RMA handling FSMs in flash_ctrl_lcmgr are sparsely encoded. + FSM in flash_ctrl_arb is sparsely encoded. + ''' + } + { name: "PHY.FSM.SPARSE", + desc: "PHY FSMs are sparsely encoded." + } + { name: "PHY_PROG.FSM.SPARSE", + desc: "PHY program FSMs are sparsely encoded." + } + { name: "CTR.REDUN", + desc: ''' + flash_ctrl_lcmgr handling counters are redundantly encoded. + This includes seed count and address count used during seed reading phase, + as well as word count, page count and wipe index in RMA entry phase. + ''' + } + { name: "PHY_ARBITER.CTRL.REDUN", + desc: ''' + The phy arbiters for controller/host arbitration and in the shared scrambling module are redundant. + The arbiters have two instances underneath that are constantly compared to each other. + ''' + } + { name: "PHY_HOST_GRANT.CTRL.CONSISTENCY", + desc: ''' + The host grant is consistency checked. + If the host is ever granted with info partition access, it is an error. + If the host is ever granted at the same time as a program/erase operation, it is an error. + ''' + } + { name: "PHY_ACK.CTRL.CONSISTENCY", + desc: ''' + If the host or controller ever receive an unexpeced transaction acknowledge, it is an error. + ''' + } + { name: "FIFO.CTR.REDUN", + desc: "The FIFO pointers of several FIFOs are implemented with duplicate counters." + } + { name: "MEM_TL_LC_GATE.FSM.SPARSE", + desc: "The control FSM inside the TL-UL gating primitive is sparsely encoded." + } + { name: "PROG_TL_LC_GATE.FSM.SPARSE", + desc: "The control FSM inside the TL-UL gating primitive is sparsely encoded." + } + ] + + scan: "true", // Enable `scanmode_i` port + scan_en: "true", // Enable `scan_en_i` port + scan_reset: "true", // Enable `scan_rst_ni` port + param_list: [ + // The reg parameters can be modified directly through top_*.hjson. + // The template will automatically propagate the appropriate values. + + // Random netlist constants + { name: "RndCnstAddrKey", + desc: "Compile-time random bits for default address key", + type: "flash_ctrl_pkg::flash_key_t" + randcount: "128", + randtype: "data", // randomize randcount databits + }, + { name: "RndCnstDataKey", + desc: "Compile-time random bits for default data key", + type: "flash_ctrl_pkg::flash_key_t" + randcount: "128", + randtype: "data", // randomize randcount databits + }, + { name: "RndCnstAllSeeds", + desc: "Compile-time random bits for default seeds", + type: "flash_ctrl_pkg::all_seeds_t" + randcount: "512", + randtype: "data", // randomize randcount databits + }, + { name: "RndCnstLfsrSeed", + desc: "Compile-time random bits for initial LFSR seed", + type: "flash_ctrl_pkg::lfsr_seed_t" + randcount: "32", + randtype: "data", + }, + { name: "RndCnstLfsrPerm", + desc: "Compile-time random permutation for LFSR output", + type: "flash_ctrl_pkg::lfsr_perm_t" + randcount: "32", + randtype: "perm", + }, + + { name: "RegNumBanks", + desc: "Number of flash banks", + type: "int", + default: "2", + local: "true" + }, + + { name: "RegPagesPerBank", + desc: "Number of pages per bank", + type: "int", + default: "16", + local: "true" + }, + + { name: "RegBusPgmResBytes", + desc: "Program resolution window in bytes", + type: "int", + default: "64", + local: "true" + }, + + { name: "RegPageWidth", + desc: "Number of bits needed to represent the pages within a bank", + type: "int", + default: "4", + local: "true" + }, + + { name: "RegBankWidth", + desc: "Number of bits needed to represent the number of banks", + type: "int", + default: "1", + local: "true" + }, + + { name: "NumRegions", + desc: "Number of configurable flash regions", + type: "int", + default: "8", + local: "true" + }, + + // The following parameters are derived from topgen and should not be + // directly modified. + { name: "NumInfoTypes", + desc: "Number of info partition types", + type: "int", + default: "3", + local: "true" + }, + { name: "NumInfos0", + desc: "Number of configurable flash info pages for info type 0", + type: "int", + default: "10", + local: "true" + }, + { name: "NumInfos1", + desc: "Number of configurable flash info pages for info type 1", + type: "int", + default: "1", + local: "true" + }, + { name: "NumInfos2", + desc: "Number of configurable flash info pages for info type 2", + type: "int", + default: "2", + local: "true" + }, + + { name: "WordsPerPage", + desc: "Number of words per page", + type: "int", + default: "256", + local: "true" + }, + + { name: "BytesPerWord", + desc: "Number of bytes per word", + type: "int", + default: "8", + local: "true" + }, + + { name: "BytesPerPage", + desc: "Number of bytes per page", + type: "int", + default: "2048", + local: "true" + }, + + { name: "BytesPerBank", + desc: "Number of bytes per bank", + type: "int", + default: "32768", + local: "true" + }, + + // hex value of 0xa26a38f7 + { name: "ExecEn", + desc: "Constant value that enables flash execution", + type: "int unsigned" + default: "2724870391", + local: "true" + }, + + { name: "SecScrambleEn", + desc: "Compile-time option to enable flash scrambling", + type: "bit", + default: "1", + local: "false", + expose: "true", + }, + + // Program FIFO depth + { name: "ProgFifoDepth", + desc: "Depth of program fifo", + type: "int" + default: "16", + local: "false", + expose: "true" + }, + + { name: "RdFifoDepth", + desc: "Depth of read fifo", + type: "int" + default: "16", + local: "false", + expose: "true" + }, + + // Maximum FIFO depth allowed + { name: "MaxFifoDepth", + desc: "Maximum depth for read / program fifos", + type: "int" + default: "16", + }, + + { name: "MaxFifoWidth", + desc: "Maximum depth for read / program fifos", + type: "int" + default: "5", + }, + ], + + features: [ + { + name: "FLASH_CTRL.ESCALATION" + desc:'''Flash controller has two sources of escalation. + 1. Global escalation : This is initiated by the Lifecycle Controller through lc_escalate_en. + 2. Local escalation : This is activated in response to standard faults detected within the flash. + These faults are monitored through flash_ctrl.STD_FAULT_STATUS. + ''' + } + { + name: "FLASH_CTRL.FETCH_CODE" + desc: '''If SW programs flash_ctrl.EXEC to 0xA26A38F7, code fetch from flash device is allowed. + All top-level tests that make use of the tests uses this features. No dedicated test is required. + ''' + } + { + name: "FLASH_CTRL.INFO.CREATOR_PARTITION" + desc: '''This partition stores creator root seed. + It is accessed by the flash controller after scramble key is received. + SW can read or program the contents when both of the following conditions are satisfied: + 1. Life cycle state is one of DEV, PROD, PROD_END, or RMA. + 2. OTP SECRET2_DIGEST partition has not been written and locked. + ''' + } + { + name: "FLASH_CTRL.INFO.ISOLATED_PARTITION" + desc: '''This partition can hold extra manufacturing details (e.g., the wafer authentication secret). + SW can read or program the contents when life cycle state is one of PROD, PROD_END, or RMA. + SW can only program the contents when life cycle state is TEST_UNLOCKED* or DEV. + ''' + } + { + name: "FLASH_CTRL.INFO.OWNER_PARTITION" + desc: '''This partition stores owner root seed. + It is accessed by the flash controller after scramble key is received. + SW can read or program the contents when life cycle state is one of DEV, PROD, PROD_END, or RMA. + ''' + } + { + name: "FLASH_CTRL.INIT.ROOT_SEEDS" + desc: "After the scrambling keys are requested, the flash controller reads root seeds from secret partitions and provides them to the key manager." + } + { + name: "FLASH_CTRL.INIT.SCRAMBLING_KEYS" + desc: "When flash_ctrl.INIT is set, flash controller requests scrambling keys from otp contoller." + } + { + name: "FLASH_CTRL.MEM_PROTECTION" + desc: '''For data partitions, SW can designate a memory region of up to 8 regions. + Each of these regions can contain more than one page, up to a maximum limit (which is 512 in earlgrey). + For each region, SW can establish the access policy by programming flash_ctrl.MP_REGION_CFG. + In the case of information partitions, the access policy can be configured on a per page basis. + To achieve this, SW must configure flash_ctrl.BANK*_INFO*_PAGE_CFG. + ''' + } + { + name: "FLASH_CTRL.OP.HOST_READ" + desc: "Host can read any data partition by providing a valid physical address." + } + { + name: "FLASH_CTRL.OP.PROTOCOL_CTRL" + desc: '''As opposed to the host, the protocol controller can read, write and erase both data and info partitions. + It has lower priority than host requests. + While an operation is in progress, other hw initiated request i.e. RMA, will be held until the operation is finished. + ''' + } + { + name: "FLASH_CTRL.RMA" + desc: '''Upon receiving an RMA request from the LC (Lifecycle Controller), the flash controller ensures the completion of all ongoing processes. + Subsequently, it proceeds to perform the following actions: + 1. Erase the following partitions: + - Creator partition + - Owner partition + - Isolated partition + - Data partition + 2. After erasing each page within these partitions, the flash controller systematically writes random data to them. + This procedure is implemented to guarantee that any sensitive information previously stored in these partitions remains unrecoverable. + ''' + } + ], + + regwidth: "32", + registers: { + core: [ + { name: "DIS", + desc: "Disable flash functionality", + swaccess: "rw1s", + hwaccess: "hro", + fields: [ + { bits: "3:0", + name: "VAL", + mubi: true, + desc: ''' + Disables flash functionality completely. + This is a shortcut mechanism used by the software to completely + kill flash in case of emergency. + + Since this register is rw1s instead of rw, to disable, write the value kMuBi4True + to the register to disable the flash. + ''' + resval: false, + }, + ] + tags: [// Dont touch disable, it has several side effects on the system + "excl:CsrAllTests:CsrExclWrite"], + }, + + { name: "EXEC", + desc: "Controls whether flash can be used for code execution fetches", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "31:0", + name: "EN", + desc: ''' + A value of 0xa26a38f7 allows flash to be used for code execution. + Any other value prevents code execution. + ''' + resval: 0 + }, + ] + }, + + { name: "INIT", + desc: "Controller init register", + swaccess: "rw1s", + hwaccess: "hro", + fields: [ + { bits: "0", + name: "VAL", + desc: ''' + Initializes the flash controller. + + During the initialization process, the flash controller requests the address and data + scramble keys and reads out the root seeds stored in flash before allowing other usage + of the flash controller. + + When the initialization sequence is complete, the flash read buffers are enabled + and turned on. + ''' + resval: "0" + tags: [// Dont init flash, it has several side effects on the status bits + "excl:CsrAllTests:CsrExclWrite"], + }, + ] + }, + + { name: "CTRL_REGWEN", + swaccess: "ro", + hwaccess: "hwo", + hwext: "true", + desc: ''' + Controls the configurability of the !!CONTROL register. + + This register ensures the contents of !!CONTROL cannot be changed by software once a flash + operation has begun. + + It unlocks whenever the existing flash operation completes, regardless of success or error. + ''', + + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Configuration enable. + + This bit defaults to 1 and is set to 0 by hardware when flash operation is initiated. + When the controller completes the flash operation, 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", + regwen: "CTRL_REGWEN", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "0", + hwaccess: "hrw", + name: "START", + desc: ''' + Start flash transaction. This bit shall only be set at the same time or after the other + fields of the !!CONTROL register and !!ADDR have been programmed. + ''' + resval: "0" + tags: [// Dont enable flash - it causes several side-effects. + "excl:CsrAllTests:CsrExclWrite"], + }, + { bits: "5:4", + name: "OP", + desc: "Flash operation selection", + resval: "0" + enum: [ + { value: "0", + name: "Read", + desc: ''' + Flash Read. + + Read desired number of flash words + ''' + }, + { value: "1", + name: "Prog", + desc: ''' + Flash Program. + + Program desired number of flash words + ''' + }, + { value: "2", + name: "Erase", + desc: ''' + Flash Erase Operation. + + See ERASE_SEL for details on erase operation + ''' + }, + ] + }, + + { bits: "6", + name: "PROG_SEL", + desc: "Flash program operation type selection", + resval: "0" + enum: [ + { value: "0", + name: "Normal program", + desc: ''' + Normal program operation to the flash + ''' + }, + { value: "1", + name: "Program repair", + desc: ''' + Repair program operation to the flash. Whether this is actually + supported depends on the underlying flash memory. + ''' + }, + ] + }, + + { bits: "7", + name: "ERASE_SEL", + desc: "Flash erase operation type selection", + resval: "0" + enum: [ + { value: "0", + name: "Page Erase", + desc: ''' + Erase 1 page of flash + ''' + }, + { value: "1", + name: "Bank Erase", + desc: ''' + Erase 1 bank of flash + ''' + }, + ] + }, + { bits: "8", + name: "PARTITION_SEL", + desc: ''' + When doing a read, program or page erase operation, selects either info or data partition for operation. + When 0, select data partition - this is the portion of flash that is accessible both by the host and by the controller. + When 1, select info partition - this is the portion of flash that is only accessible by the controller. + + When doing a bank erase operation, selects info partition also for erase. + When 0, bank erase only erases data partition. + When 1, bank erase erases data partition and info partition. + ''' + resval: "0" + }, + { bits: "10:9", + name: "INFO_SEL", + desc: ''' + Informational partions can have multiple types. + + This field selects the info type to be accessed. + ''' + resval: "0" + }, + { bits: "27:16", + name: "NUM", + desc: ''' + One fewer than the number of bus words the flash operation should read or program. + For example, to read 10 words, software should program this field with the value 9. + ''' + resval: "0" + }, + ] + }, + { name: "ADDR", + desc: "Address for flash operation", + swaccess: "rw", + hwaccess: "hro", + regwen: "CTRL_REGWEN", + resval: "0", + fields: [ + { bits: "15:0", + name: "START", + desc: ''' + Start address of a flash transaction. This is a byte address relative to the flash + only. Ie, an address of 0 will access address 0 of the requested partition. + + For read operations, the flash controller will truncate to the closest, lower word + aligned address. For example, if 0x13 is supplied, the controller will perform a + read at address 0x10. + + Program operations behave similarly, the controller does not have read modified write + support. + + For page erases, the controller will truncate to the closest lower page aligned + address. Similarly for bank erases, the controller will truncate to the closest + lower bank aligned address. + ''' + resval: "0" + }, + ] + }, + + // Program type + { name: "PROG_TYPE_EN", + desc: "Enable different program types", + regwen: "CTRL_REGWEN", + swaccess: "rw0c", + hwaccess: "hro", + fields: [ + { bits: "0", + resval: "1", + name: "NORMAL", + desc: ''' + Normal prog type available + ''' + }, + { bits: "1", + resval: "1", + name: "REPAIR", + desc: ''' + Repair prog type available + ''' + }, + ] + }, + + // erase suspend support + { name: "ERASE_SUSPEND", + desc: "Suspend erase", + swaccess: "rw", + hwaccess: "hrw", + fields: [ + { bits: "0", + resval: "0", + name: "REQ", + desc: ''' + When 1, request erase suspend. + If no erase ongoing, the request is immediately cleared by hardware + If erase ongoing, the request is fed to the flash_phy and cleared when the suspend is handled. + ''' + }, + ], + tags: [// Erase suspend must be directly tested + "excl:CsrAllTests:CsrExclWrite"], + }, + + // Data partition memory properties region setup + { multireg: { + cname: "FLASH_CTRL", + name: "REGION_CFG_REGWEN" + desc: "Memory region registers configuration enable.", + count: "NumRegions", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { bits: "0", + name: "REGION", + resval: "1" + desc: "Region register write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Region locked", + desc: ''' + Region can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Region enabled", + desc: ''' + Region can be configured + ''' + }, + ] + }, + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "MP_REGION_CFG", + desc: "Memory property configuration for data partition", + count: "NumRegions", + swaccess: "rw", + hwaccess: "hro", + regwen: "REGION_CFG_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "EN", + mubi: true, + desc: ''' + Region enabled, following fields apply. + If region is disabled, it is not matched against any incoming transaction. + ''', + resval: false + }, + { bits: "7:4", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "11:8", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "15:12", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "19:16", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "23:20", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is integrity checked and reliability ECC enabled. + ''', + resval: false + } + { bits: "27:24", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "MP_REGION", + desc: "Memory base and size configuration for data partition", + count: "NumRegions", + swaccess: "rw", + hwaccess: "hro", + regwen: "REGION_CFG_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "4:0", + name: "BASE", + desc: ''' + Region base page. Note the granularity is page, not byte or word + ''', + resval: "0" + }, + { bits: "10:5", + name: "SIZE", + desc: ''' + Region size in number of pages. + For example, if base is 0 and size is 1, then the region is defined by page 0. + If base is 0 and size is 2, then the region is defined by pages 0 and 1. + ''', + resval: "0" + }, + ], + }, + }, + + // Default region properties for data partition + { name: "DEFAULT_REGION", + desc: "Default region properties", + swaccess: "rw", + hwaccess: "hro", + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "7:4", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "11:8", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "15:12", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "19:16", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is ECC enabled (both integrity and reliability ECC). + ''', + resval: false + } + { bits: "23:20", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ] + }, + + // Info partition memory properties setup + { multireg: { + cname: "FLASH_CTRL", + name: "BANK0_INFO0_REGWEN" + desc: "Memory region registers configuration enable.", + count: "NumInfos0", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { bits: "0", + name: "REGION", + resval: "1" + desc: "Info0 page write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Page locked", + desc: ''' + Region can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Page enabled", + desc: ''' + Region can be configured + ''' + }, + ] + }, + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "BANK0_INFO0_PAGE_CFG", + desc: ''' + Memory property configuration for info partition in bank0, + Unlike data partition, each page is individually configured. + ''' + count: "NumInfos0", + swaccess: "rw", + hwaccess: "hro", + regwen: "BANK0_INFO0_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "EN", + mubi: true, + desc: ''' + Region enabled, following fields apply + ''', + resval: false + }, + { bits: "7:4", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "11:8", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "15:12", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "19:16", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "23:20", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is ECC enabled (both integrity and reliability ECC). + ''', + resval: false + } + { bits: "27:24", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ], + }, + }, + { multireg: { + cname: "FLASH_CTRL", + name: "BANK0_INFO1_REGWEN" + desc: "Memory region registers configuration enable.", + count: "NumInfos1", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { bits: "0", + name: "REGION", + resval: "1" + desc: "Info1 page write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Page locked", + desc: ''' + Region can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Page enabled", + desc: ''' + Region can be configured + ''' + }, + ] + }, + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "BANK0_INFO1_PAGE_CFG", + desc: ''' + Memory property configuration for info partition in bank0, + Unlike data partition, each page is individually configured. + ''' + count: "NumInfos1", + swaccess: "rw", + hwaccess: "hro", + regwen: "BANK0_INFO1_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "EN", + mubi: true, + desc: ''' + Region enabled, following fields apply + ''', + resval: false + }, + { bits: "7:4", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "11:8", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "15:12", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "19:16", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "23:20", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is ECC enabled (both integrity and reliability ECC). + ''', + resval: false + } + { bits: "27:24", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ], + }, + }, + { multireg: { + cname: "FLASH_CTRL", + name: "BANK0_INFO2_REGWEN" + desc: "Memory region registers configuration enable.", + count: "NumInfos2", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { bits: "0", + name: "REGION", + resval: "1" + desc: "Info2 page write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Page locked", + desc: ''' + Region can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Page enabled", + desc: ''' + Region can be configured + ''' + }, + ] + }, + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "BANK0_INFO2_PAGE_CFG", + desc: ''' + Memory property configuration for info partition in bank0, + Unlike data partition, each page is individually configured. + ''' + count: "NumInfos2", + swaccess: "rw", + hwaccess: "hro", + regwen: "BANK0_INFO2_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "EN", + mubi: true, + desc: ''' + Region enabled, following fields apply + ''', + resval: false + }, + { bits: "7:4", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "11:8", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "15:12", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "19:16", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "23:20", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is ECC enabled (both integrity and reliability ECC). + ''', + resval: false + } + { bits: "27:24", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ], + }, + }, + { multireg: { + cname: "FLASH_CTRL", + name: "BANK1_INFO0_REGWEN" + desc: "Memory region registers configuration enable.", + count: "NumInfos0", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { bits: "0", + name: "REGION", + resval: "1" + desc: "Info0 page write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Page locked", + desc: ''' + Region can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Page enabled", + desc: ''' + Region can be configured + ''' + }, + ] + }, + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "BANK1_INFO0_PAGE_CFG", + desc: ''' + Memory property configuration for info partition in bank1, + Unlike data partition, each page is individually configured. + ''' + count: "NumInfos0", + swaccess: "rw", + hwaccess: "hro", + regwen: "BANK1_INFO0_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "EN", + mubi: true, + desc: ''' + Region enabled, following fields apply + ''', + resval: false + }, + { bits: "7:4", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "11:8", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "15:12", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "19:16", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "23:20", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is ECC enabled (both integrity and reliability ECC). + ''', + resval: false + } + { bits: "27:24", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ], + }, + }, + { multireg: { + cname: "FLASH_CTRL", + name: "BANK1_INFO1_REGWEN" + desc: "Memory region registers configuration enable.", + count: "NumInfos1", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { bits: "0", + name: "REGION", + resval: "1" + desc: "Info1 page write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Page locked", + desc: ''' + Region can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Page enabled", + desc: ''' + Region can be configured + ''' + }, + ] + }, + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "BANK1_INFO1_PAGE_CFG", + desc: ''' + Memory property configuration for info partition in bank1, + Unlike data partition, each page is individually configured. + ''' + count: "NumInfos1", + swaccess: "rw", + hwaccess: "hro", + regwen: "BANK1_INFO1_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "EN", + mubi: true, + desc: ''' + Region enabled, following fields apply + ''', + resval: false + }, + { bits: "7:4", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "11:8", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "15:12", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "19:16", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "23:20", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is ECC enabled (both integrity and reliability ECC). + ''', + resval: false + } + { bits: "27:24", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ], + }, + }, + { multireg: { + cname: "FLASH_CTRL", + name: "BANK1_INFO2_REGWEN" + desc: "Memory region registers configuration enable.", + count: "NumInfos2", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { bits: "0", + name: "REGION", + resval: "1" + desc: "Info2 page write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Page locked", + desc: ''' + Region can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Page enabled", + desc: ''' + Region can be configured + ''' + }, + ] + }, + ], + }, + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "BANK1_INFO2_PAGE_CFG", + desc: ''' + Memory property configuration for info partition in bank1, + Unlike data partition, each page is individually configured. + ''' + count: "NumInfos2", + swaccess: "rw", + hwaccess: "hro", + regwen: "BANK1_INFO2_REGWEN", + regwen_multi: true, + update_err_alert: "recov_err", + storage_err_alert: "fatal_err", + fields: [ + { bits: "3:0", + name: "EN", + mubi: true, + desc: ''' + Region enabled, following fields apply + ''', + resval: false + }, + { bits: "7:4", + name: "RD_EN", + mubi: true, + desc: ''' + Region can be read + ''', + resval: false + }, + { bits: "11:8", + name: "PROG_EN", + mubi: true, + desc: ''' + Region can be programmed + ''', + resval: false + } + { bits: "15:12", + name: "ERASE_EN", + mubi: true, + desc: ''' + Region can be erased + ''', + resval: false + } + { bits: "19:16", + name: "SCRAMBLE_EN", + mubi: true, + desc: ''' + Region is scramble enabled. + ''', + resval: false + } + { bits: "23:20", + name: "ECC_EN", + mubi: true, + desc: ''' + Region is ECC enabled (both integrity and reliability ECC). + ''', + resval: false + } + { bits: "27:24", + name: "HE_EN", + mubi: true, + desc: ''' + Region is high endurance enabled. + ''', + resval: false + } + ], + }, + }, + + { name: "HW_INFO_CFG_OVERRIDE", + desc: "HW interface info configuration rule overrides", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "3:0", + name: "SCRAMBLE_DIS", + mubi: true, + desc: ''' + The hardwired hardware info configuration rules for scramble enable are logically AND'd with + this field. + If the hardware rules hardwires scramble to enable, we can disable via software if needed. + + By default this field is false. + ''', + resval: false + } + { bits: "7:4", + name: "ECC_DIS", + mubi: true, + desc: ''' + The hardwired hardware info configuration rules for ECC enable are logically AND'd with + this field. + If the hardware rules hardwires ECC to enable, we can disable via software if needed. + + By default this field is false. + ''', + resval: false + } + ] + }, + + { name: "BANK_CFG_REGWEN" + desc: "Bank configuration registers configuration enable.", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "BANK", + resval: "1" + desc: "Bank register write enable. Once set to 0, it can longer be configured to 1", + enum: [ + { value: "0", + name: "Bank locked", + desc: ''' + Bank can no longer be configured until next reset + ''' + }, + { value: "1", + name: "Bank enabled", + desc: ''' + Bank can be configured + ''' + }, + ] + }, + ], + }, + + { multireg: { + cname: "FLASH_CTRL", + name: "MP_BANK_CFG_SHADOWED", + desc: "Memory properties bank configuration", + count: "RegNumBanks", + swaccess: "rw", + hwaccess: "hro", + regwen: "BANK_CFG_REGWEN", + shadowed: "true", + update_err_alert: "recov_err", + storage_err_alert: "fatal_std_err", + fields: [ + { bits: "0", + name: "ERASE_EN", + desc: ''' + Bank wide erase enable + ''', + resval: "0" + }, + ], + }, + }, + + { name: "OP_STATUS", + desc: "Flash Operation Status", + swaccess: "rw", + hwaccess: "hwo", + fields: [ + { bits: "0", name: "done", + desc: "Flash operation done. Set by HW, cleared by SW" }, + { bits: "1", name: "err", + desc: "Flash operation error. Set by HW, cleared by SW. See !!ERR_CODE for more details."}, + ] + }, + + { name: "STATUS", + desc: "Flash Controller Status", + swaccess: "ro", + hwaccess: "hwo", + fields: [ + { bits: "0", name: "rd_full", desc: "Flash read FIFO full, software must consume data"}, + { bits: "1", name: "rd_empty", desc: "Flash read FIFO empty", resval: "1"}, + { bits: "2", name: "prog_full", desc: "Flash program FIFO full"}, + { bits: "3", name: "prog_empty", desc: "Flash program FIFO empty, software must provide data", resval: "1"}, + { bits: "4", name: "init_wip", desc: "Flash controller undergoing init, inclusive of phy init" + tags: [ // Bit changes immediately after start from reset value to 1b1 due to initialization + "excl:CsrAllTests:CsrExclAll"] + } + { bits: "5", name: "initialized",desc: "Flash controller initialized" + tags: [ // Bit changes immediately after start from reset value to 1b1 due to initialization + "excl:CsrAllTests:CsrExclAll"] + }, + ] + }, + + { name: "DEBUG_STATE", + desc: "Current flash fsm state", + swaccess: "ro", + hwaccess: "hwo", + hwext: "true" + fields: [ + { bits: "10:0", + name: "lcmgr_state", + desc: "Current lcmgr interface staet ", + tags: [ // Bit changes immediately after start from reset value to 1b1 due to initialization + "excl:CsrAllTests:CsrExclAll"] + } + ] + }, + + { name: "ERR_CODE", + desc: ''' + Flash error code register. + This register tabulates detailed error status of the flash. + This is separate from !!OP_STATUS, which is used to indicate the current state of the software initiated + flash operation. + + Note, all errors in this register are considered recoverable errors, ie, errors that could have been + generated by software. + ''' + swaccess: "rw1c", + hwaccess: "hwo", + fields: [ + { bits: "0", + name: "op_err", + desc: ''' + Software has supplied an undefined operation. + See !!CONTROL.OP for list of valid operations. + ''' + }, + { bits: "1", + name: "mp_err", + desc: ''' + Flash access has encountered an access permission error. + Please see !!ERR_ADDR for exact address. + This is a synchronous error. + ''' + }, + { bits: "2", + name: "rd_err", + desc: ''' + Flash read has an error. + This could be a reliability ECC error or an storage integrity error + encountered during a software issued controller read, see !!STD_FAULT_STATUS. + See !!ERR_ADDR for exact address. + This is a synchronous error. + ''' + }, + { bits: "3", + name: "prog_err", + desc: ''' + Flash program has an error. + This could be a program integrity error, see !!STD_FAULT_STATUS. + This is a synchronous error. + ''' + }, + { bits: "4", + name: "prog_win_err", + desc: ''' + Flash program has a window resolution error. Ie, the start of program + and end of program are in different windows. Please check !!ERR_ADDR. + This is a synchronous error. + ''' + }, + { bits: "5", + name: "prog_type_err", + desc: ''' + Flash program selected unavailable type, see !!PROG_TYPE_EN. + This is a synchronous error. + ''' + }, + { bits: "6", + name: "update_err", + desc: ''' + A shadow register encountered an update error. + This is an asynchronous error. + ''' + }, + { bits: "7", + name: "macro_err", + desc: ''' + A recoverable error has been encountered in the flash macro. + Please read the flash macro status registers for more details. + ''' + }, + ] + }, + + { name: "STD_FAULT_STATUS", + desc: ''' + This register tabulates standard fault status of the flash. + + These represent errors that occur in the standard structures of the design. + For example fsm integrity, counter integrity and tlul integrity. + ''' + swaccess: "ro", + hwaccess: "hrw", + fields: [ + { bits: "0", + name: "reg_intg_err", + desc: ''' + The flash controller encountered a register integrity error. + ''' + }, + { bits: "1", + name: "prog_intg_err", + desc: ''' + The flash controller encountered a program data transmission integrity error. + ''' + }, + { bits: "2", + name: "lcmgr_err", + desc: ''' + The life cycle management interface has encountered a fatal error. + The error is either an FSM sparse encoding error or a count error. + ''' + }, + { bits: "3", + name: "lcmgr_intg_err", + desc: ''' + The life cycle management interface has encountered a transmission + integrity error. This is an integrity error on the generated integrity + during a life cycle management interface read. + ''' + }, + { bits: "4", + name: "arb_fsm_err", + desc: ''' + The arbiter fsm has encountered a sparse encoding error. + ''' + }, + { bits: "5", + name: "storage_err", + desc: ''' + A shadow register encountered a storage error. + ''' + }, + { bits: "6", + name: "phy_fsm_err", + desc: ''' + A flash phy fsm has encountered a sparse encoding error. + ''' + }, + { bits: "7", + name: "ctrl_cnt_err", + desc: ''' + Flash ctrl read/prog has encountered a count error. + ''' + }, + { bits: "8", + name: "fifo_err", + desc: ''' + Flash primitive fifo's have encountered a count error. + ''' + }, + ] + }, + + { name: "FAULT_STATUS", + desc: ''' + This register tabulates customized fault status of the flash. + + These are errors that are impossible to have been caused by software or unrecoverable in nature. + + All errors except for multi-bit ECC errors (!!FAULT_STATUS.PHY_RELBL_ERR) and ICV (!!FAULT_STATUS.PHY_STORAGE_ERR) trigger a fatal alert. + Once set, they remain set until reset. + ''' + hwaccess: "hrw", + fields: [ + { bits: "0", + name: "op_err", + swaccess: "ro", + desc: ''' + The flash life cycle management interface has supplied an undefined operation. + See !!CONTROL.OP for list of valid operations. + ''' + }, + { bits: "1", + name: "mp_err", + swaccess: "ro", + desc: ''' + The flash life cycle management interface encountered a memory permission error. + ''' + }, + { bits: "2", + name: "rd_err", + swaccess: "ro", + desc: ''' + The flash life cycle management interface encountered a read error. + This could be a reliability ECC error or an integrity ECC error + encountered during a read, see !!STD_FAULT_STATUS for more details. + ''' + }, + { bits: "3", + name: "prog_err", + swaccess: "ro", + desc: ''' + The flash life cycle management interface encountered a program error. + This could be a program integirty eror, see !!STD_FAULT_STATUS for more details. + ''' + }, + { bits: "4", + name: "prog_win_err", + swaccess: "ro", + desc: ''' + The flash life cycle management interface encountered a program resolution error. + ''' + }, + { bits: "5", + name: "prog_type_err", + swaccess: "ro", + desc: ''' + The flash life cycle management interface encountered a program type error. + A program type not supported by the flash macro was issued. + ''' + }, + { bits: "6", + name: "seed_err", + swaccess: "ro", + desc: ''' + The seed reading process encountered an unexpected error. + ''' + }, + { bits: "7", + name: "phy_relbl_err", + swaccess: "rw0c", + desc: ''' + The flash macro encountered a storage reliability ECC error. + + Note that this error bit can be cleared to allow firmware dealing with multi-bit ECC errors during firmware selection and verification. + After passing this stage, it is recommended that firmware classifies the corresponding alert as fatal on the receiver end, i.e, inside the alert handler. + ''' + }, + { bits: "8", + name: "phy_storage_err", + swaccess: "rw0c", + desc: ''' + The flash macro encountered a storage integrity ECC error. + + Note that this error bit can be cleared to allow firmware dealing with ICV errors during firmware selection and verification. + After passing this stage, it is recommended that firmware classifies the corresponding alert as fatal on the receiver end, i.e, inside the alert handler. + ''' + }, + { bits: "9", + name: "spurious_ack", + swaccess: "ro", + desc: ''' + The flash emitted an unexpected acknowledgement. + ''' + }, + { bits: "10", + name: "arb_err", + swaccess: "ro", + desc: ''' + The phy arbiter encountered inconsistent results. + ''' + }, + { bits: "11", + name: "host_gnt_err", + swaccess: "ro", + desc: ''' + A host transaction was granted with illegal properties. + ''' + }, + ] + }, + + { name: "ERR_ADDR", + desc: "Synchronous error address", + swaccess: "ro", + hwaccess: "hwo", + fields: [ + { bits: "15:0", + resval: 0, + }, + ] + }, + + { multireg: { + cname: "ECC_SINGLE_ERR", + name: "ECC_SINGLE_ERR_CNT", + desc: "Total number of single bit ECC error count", + count: "RegNumBanks", + swaccess: "rw", + hwaccess: "hrw", + fields: [ + { bits: "7:0", + desc: "This count will not wrap when saturated", + resval: 0, + }, + ] + } + }, + + { multireg: { + cname: "ECC_SINGLE_ERR", + name: "ECC_SINGLE_ERR_ADDR", + desc: "Latest address of ECC single err", + count: "RegNumBanks", + swaccess: "ro", + hwaccess: "hwo", + compact: false, + fields: [ + { bits: "15:0", + desc: "Latest single error address for this bank", + resval: 0, + }, + ] + } + } + + { name: "PHY_ALERT_CFG", + desc: "Phy alert configuration", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "0", + name: "alert_ack", + desc: "Acknowledge flash phy alert" + }, + { bits: "1", + name: "alert_trig", + desc: "Trigger flash phy alert" + } + ] + tags: [ // alert triggers should be tested by directed tests + "excl:CsrAllTests:CsrExclWrite"] + }, + + { name: "PHY_STATUS", + desc: "Flash Phy Status", + swaccess: "ro", + hwaccess: "hwo", + fields: [ + { bits: "0", + name: "init_wip", + desc: "Flash phy controller initializing" + tags: [ // Bit changes immediately after start from reset value to 1b1 due to initialization + "excl:CsrAllTests:CsrExclAll"] + }, + { bits: "1", + name: "prog_normal_avail", + resval: "0x1", + desc: "Normal program supported" + }, + { bits: "2", + name: "prog_repair_avail", + resval: "0x1", + desc: "Program repair supported" + }, + ] + }, + + { name: "Scratch", + desc: "Flash Controller Scratch", + swaccess: "rw", + fields: [ + { bits: "31:0", name: "data", desc: "Flash ctrl scratch register" }, + ] + }, + + { name: "FIFO_LVL", + desc: "Programmable depth where FIFOs should generate interrupts", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "4:0", + name: "PROG", + desc: ''' + When the program FIFO drains to this level, trigger an interrupt. + Default value is set such that interrupt does not trigger at reset. + ''' + resval: "0xF" + }, + { bits: "12:8", + name: "RD", + desc: ''' + When the read FIFO fills to this level, trigger an interrupt. + Default value is set such that interrupt does not trigger at reset. + ''' + resval: "0xF" + }, + ] + } + + { name: "FIFO_RST", + desc: "Reset for flash controller FIFOs", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Active high resets for both program and read FIFOs. This is especially useful after the controller + encounters an error of some kind. + This bit will hold the FIFO in reset as long as it is set. + ''' + resval: "0" + }, + ] + }, + + { name: "CURR_FIFO_LVL", + desc: "Current program and read fifo depth", + swaccess: "ro", + hwaccess: "hwo", + hwext: "true", + fields: [ + { bits: "4:0", + name: "PROG", + desc: ''' + Current program fifo depth + ''' + resval: "0x0" + }, + { bits: "12:8", + name: "RD", + desc: ''' + Current read fifo depth + ''' + resval: "0x0" + }, + ] + } + + { window: { + name: "prog_fifo", + items: "1", + validbits: "32", + data-intg-passthru: "true", + byte-write: "false", + unusual: "false" + swaccess: "wo", + desc: ''' + Flash program FIFO. + + The FIFO is 16 entries of 4B flash words. This FIFO can only be programmed + by software after a program operation has been initiated via the !!CONTROL register. + This ensures accidental programming of the program FIFO cannot lock up the system. + ''' + }, + }, + + { window: { + name: "rd_fifo", + items: "1", + validbits: "32", + data-intg-passthru: "true", + byte-write: "false", + unusual: "false" + swaccess: "ro", + desc: ''' + Flash read FIFO. + + The FIFO is 16 entries of 4B flash words + ''' + }, + }, + ], + + prim: [ + { + name: "CSR0_REGWEN", + desc: "", + fields: [ + { + bits: "0", + name: "field0", + swaccess: "rw0c", + hwaccess: "none", + resval: "1", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False" + }, + { + name: "CSR1", + desc: "", + fields: [ + { + bits: "7:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "12:8", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR2", + desc: "", + fields: [ + { + bits: "0", + name: "field0", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "1", + name: "field1", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "2", + name: "field2", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "3", + name: "field3", + swaccess: "rw", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "4", + name: "field4", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "5", + name: "field5", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "6", + name: "field6", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "7", + name: "field7", + swaccess: "rw", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False" + }, + { + name: "CSR3", + desc: "", + fields: [ + { + bits: "3:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "7:4", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "10:8", + name: "field2", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "13:11", + name: "field3", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "16:14", + name: "field4", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "19:17", + name: "field5", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "20", + name: "field6", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "23:21", + name: "field7", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "25:24", + name: "field8", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "27:26", + name: "field9", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR4", + desc: "", + fields: [ + { + bits: "2:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "5:3", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "8:6", + name: "field2", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "11:9", + name: "field3", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR5", + desc: "", + fields: [ + { + bits: "2:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "4:3", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "13:5", + name: "field2", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "18:14", + name: "field3", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "22:19", + name: "field4", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR6", + desc: "", + fields: [ + { + bits: "2:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "5:3", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "13:6", + name: "field2", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "16:14", + name: "field3", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "18:17", + name: "field4", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "20:19", + name: "field5", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "22:21", + name: "field6", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "23", + name: "field7", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "24", + name: "field8", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR7", + desc: "", + fields: [ + { + bits: "7:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "16:8", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR8", + desc: "", + fields: [ + { + bits: "31:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR9", + desc: "", + fields: [ + { + bits: "31:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR10", + desc: "", + fields: [ + { + bits: "31:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR11", + desc: "", + fields: [ + { + bits: "31:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR12", + desc: "", + fields: [ + { + bits: "9:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR13", + desc: "", + fields: [ + { + bits: "19:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "20", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR14", + desc: "", + fields: [ + { + bits: "7:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "8", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR15", + desc: "", + fields: [ + { + bits: "7:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "8", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR16", + desc: "", + fields: [ + { + bits: "7:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "8", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR17", + desc: "", + fields: [ + { + bits: "7:0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "8", + name: "field1", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR18", + desc: "", + fields: [ + { + bits: "0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR19", + desc: "", + fields: [ + { + bits: "0", + name: "field0", + swaccess: "rw", + hwaccess: "hro", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False", + regwen: "CSR0_REGWEN" + }, + { + name: "CSR20", + desc: "", + fields: [ + { + bits: "0", + name: "field0", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "1", + name: "field1", + swaccess: "rw1c", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + }, + { + bits: "2", + name: "field2", + swaccess: "ro", + hwaccess: "hrw", + resval: "0", + tags: [], + desc: "", + enum: [] + } + ], + hwext: "False", + hwqe: "False", + hwre: "False", + tags: [], + shadowed: "False" + } + ], + mem: [] + } +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_sec_cm_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_sec_cm_testplan.hjson new file mode 100644 index 0000000000000..d433474be5984 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_sec_cm_testplan.hjson @@ -0,0 +1,319 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// .../flash_ctrl/data/flash_ctrl.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: +// .../flash_ctrl/data/flash_ctrl_testplan.hjson +{ + testpoints: [ + { + name: sec_cm_reg_bus_integrity + desc: '''Verify the countermeasure(s) REG.BUS.INTEGRITY. + This entry is covered by tl_access_test + (hw/dv/tools/dvsim/tests/tl_access_tests.hjson) + ''' + stage: V2S + tests: ["flash_ctrl_tl_intg_err"] + } + { + name: sec_cm_host_bus_integrity + desc: '''Verify the countermeasure(s) HOST.BUS.INTEGRITY. + This entry is covered by tl_access_test + (hw/dv/tools/dvsim/tests/tl_access_tests.hjson) + ''' + stage: V2S + tests: ["flash_ctrl_tl_intg_err"] + } + { + name: sec_cm_mem_bus_integrity + desc: '''Verify the countermeasure(s) MEM.BUS.INTEGRITY. + For read path, inject error to + tb.dut.u_eflash.gen_flash_cores[*].u_core.u_rd.gen_bufs[0]. + u_rd_buf.data_i + read data error will trigger fault_status.phy_storage_err + and err_code.rd_err. + For write path, inject error to tb.dut.u_prog_fifo.wdata_i + This will trigger fatal_std_err.prog_intg_err and + err_code.prog_err + ''' + stage: V2S + tests: ["flash_ctrl_rd_intg", "flash_ctrl_wr_intg"] + } + { + name: sec_cm_scramble_key_sideload + desc: '''Verify the countermeasure(s) SCRAMBLE.KEY.SIDELOAD. + The scrambling key is sideloaded from OTP and thus unreadable by SW. + TBD + ''' + stage: V2S + tests: ["flash_ctrl_smoke"] + } + { + name: sec_cm_lc_ctrl_intersig_mubi + desc: '''Verify the countermeasure(s) LC_CTRL.INTERSIG.MUBI. + - Creator info partition can be read, written, erased when lc_creator_seed_sw_rw_en is true. + Owner info partition can be read, written, erased when lc_owner_seed_sw_rw_en is true. + Isolated info partition can be written whwen lc_iso_part_sw_wr_en is true, + and can be read when lc_iso_part_sw_rd_en is true. + Run test for each partition and check whether each partition can be accessed + only when each lc_ctrl input is valid. + If lc_ctrl inputs are invalid, the access to the secret info region will trigger + recoverable fatal alert. + - lc_seed_hw_rd_en is covered by flash_ctrl_otp_reset test. + - lc_escalate_en_i is covered by flash_ctrl_disable test. See 'flash_ctrl_disable` + from the flash_ctrl_testpan.hjson + - lc_nvm_debug_en_i is covered by flash_ctrl_connect. See 'flash_ctrl_connect' + from the flash_ctrl_testplan.hjson + ''' + stage: V2S + tests: ["flash_ctrl_sec_info_access", "flash_ctrl_disable", + "flash_ctrl_connect", "flash_ctrl_otp_reset"] + } + { + name: sec_cm_ctrl_config_regwen + desc: "Verify the countermeasure(s) CTRL.CONFIG.REGWEN." + stage: V2S + tests: ["flash_ctrl_config_regwen"] + } + { + name: sec_cm_data_regions_config_regwen + desc: "Verify the countermeasure(s) DATA_REGIONS.CONFIG.REGWEN." + stage: V2S + tests: ["flash_ctrl_csr_rw"] + } + { + name: sec_cm_data_regions_config_shadow + desc: "Verify the countermeasure(s) DATA_REGIONS.CONFIG.SHADOW." + stage: V2S + tests: ["flash_ctrl_shadow_reg_errors"] + } + { + name: sec_cm_info_regions_config_regwen + desc: "Verify the countermeasure(s) INFO_REGIONS.CONFIG.REGWEN." + stage: V2S + tests: ["flash_ctrl_csr_rw"] + } + { + name: sec_cm_info_regions_config_shadow + desc: "Verify the countermeasure(s) INFO_REGIONS.CONFIG.SHADOW." + stage: V2S + tests: ["flash_ctrl_shadow_reg_errors"] + } + { + name: sec_cm_bank_config_regwen + desc: "Verify the countermeasure(s) BANK.CONFIG.REGWEN." + stage: V2S + tests: ["flash_ctrl_csr_rw"] + } + { + name: sec_cm_bank_config_shadow + desc: "Verify the countermeasure(s) BANK.CONFIG.SHADOW." + stage: V2S + tests: ["flash_ctrl_shadow_reg_errors"] + } + { + name: sec_cm_mem_ctrl_global_esc + desc: '''Verify the countermeasure(s) MEM.CTRL.GLOBAL_ESC. + Send a few flash access commands and + disable flash access by setting lc_escalate_en to lc_ctrl_pkg::On. + Check + - Ctrl initiated traffic : mp error + - Host initiated traffic : tlul errors + - Outstanding traffic: + Program or erase will be completed. + Read will be dropped. + - Debug state is changed to 'flash_ctrl_env_pkg::FlashLcDisabled' state + ''' + stage: V2S + tests: ["flash_ctrl_disable"] + } + { + name: sec_cm_mem_ctrl_local_esc + desc: '''Verify the countermeasure(s) MEM.CTRL.LOCAL_ESC. + Send a few flash access commands and + disable flash access by triggering std_fault. + Check + - Ctrl initiated traffic : mp error + - Host initiated traffic : tlul errors + - Outstanding traffic: + Program or erase will be completed. + Read will be dropped. + - Debug state is changed to 'flash_ctrl_env_pkg::FlashLcDisabled' state + ''' + stage: V2S + tests: ["flash_ctrl_rd_intg", "flash_ctrl_access_after_disable"] + } + { + name: sec_cm_mem_addr_infection + desc: '''Verify the countermeasure(s) MEM.ADDR_INFECTION. + Send a flash request from the host, inject a fault into the address inside + the flash_phy_rd module, and check that we receive the expected TL-UL + integrity error. + ''' + stage: V2S + tests: ["flash_ctrl_host_addr_infection"] + } + { + name: sec_cm_mem_disable_config_mubi + desc: "Verify the countermeasure(s) MEM_DISABLE.CONFIG.MUBI." + stage: V2S + tests: ["flash_ctrl_disable"] + } + { + name: sec_cm_exec_config_redun + desc: "Verify the countermeasure(s) EXEC.CONFIG.REDUN." + stage: V2S + tests: ["flash_ctrl_fetch_code"] + } + { + name: sec_cm_mem_scramble + desc: "Verify the countermeasure(s) MEM.SCRAMBLE." + stage: V2S + tests: ["flash_ctrl_rw"] + } + { + name: sec_cm_mem_integrity + desc: "Verify the countermeasure(s) MEM.INTEGRITY." + stage: V2S + tests: ["flash_ctrl_rw_serr", "flash_ctrl_rw_derr", "flash_ctrl_integrity"] + } + { + name: sec_cm_rma_entry_mem_sec_wipe + desc: '''Verify the countermeasure(s) RMA_ENTRY.MEM.SEC_WIPE. + RMA entry wipes flash memory with random data. + ''' + stage: V2S + tests: ["flash_ctrl_hw_rma"] + } + { + name: sec_cm_ctrl_fsm_sparse + desc: '''Verify the countermeasure(s) CTRL.FSM.SPARSE. + Error is injected by global test. + Follwing state machines are in this category. + - tb.dut.u_ctrl_arb.state_q : + Error from this state machine will trigger std_fault_status.arb_fsm_err. + - tb.dut.u_flash_hw_if.state_q, tb.dut.u_flash_hw_if.rma_state_q + Error from these state machines will trigger std_fault_status.lcmgr_err. + ''' + stage: V2S + tests: ["flash_ctrl_sec_cm"] + } + { + name: sec_cm_phy_fsm_sparse + desc: '''Verify the countermeasure(s) PHY.FSM.SPARSE. + Error is injected by global test on + tb.dut.u_eflash.gen_flash_cores[*].u_core.state_q. + Error from this state machine will trigger std_fault_status.phy_fsm_err. + ''' + stage: V2S + tests: ["flash_ctrl_sec_cm"] + } + { + name: sec_cm_phy_prog_fsm_sparse + desc: '''Verify the countermeasure(s) PHY_PROG.FSM.SPARSE. + Error is injected by global test on + tb.dut.u_eflash.gen_flash_cores[*].u_core.gen_prog_data.u_prog.state_q. + Error from this state machine will trigger std_fault_status.phy_fsm_err. + ''' + stage: V2S + tests: ["flash_ctrl_sec_cm"] + } + { + name: sec_cm_ctr_redun + desc: '''Verify the countermeasure(s) CTR.REDUN. + Error is injected by global test. + Follwing counters are in this category. + - tb.dut.u_flash_hw_if.seed_cnt_q + - tb.dut.u_flash_hw_if.addr_cnt_q + - tb.dut.u_flash_hw_if.page_cnt + - tb.dut.u_flash_hw_if.word_cnt + - tb.dut.u_flash_hw_if.rma_wipe_idx + Error from these counters will trigger std_fault_status.lcmgr_err. + ''' + stage: V2S + tests: ["flash_ctrl_sec_cm"] + } + { + name: sec_cm_phy_arbiter_ctrl_redun + desc: '''Verify the countermeasure(s) PHY_ARBITER.CTRL.REDUN. + + The phy arbiters for controller and host are redundant. There are four + of these. Each arbiter has two instance underneath that are constantly + compared to each other. This test injects arbitration faults randomly + choosing any of the four redundant arbiters, and randomly grounding any + of the two copies. The fault is caused by having the request to both + copies mismatch, and the test checks fault_status.arb_err is triggered. + ''' + stage: V2S + tests: ["flash_ctrl_phy_arb_redun"] + } + { + name: sec_cm_phy_host_grant_ctrl_consistency + desc: '''Verify the countermeasure(s) PHY_HOST_GRANT.CTRL.CONSISTENCY. + + A host transaction was granted to the muxed partition, this is illegal. + @ tb.dut.u_eflash.gen_flash_cores[0].u_core.host_gnt, + force tb.dut.u_eflash.gen_flash_cores[0].u_core.muxed_part = 1 and check + fault_status.host_gnt_err. + ''' + stage: V2S + tests: ["flash_ctrl_phy_host_grant_err"] + } + { + name: sec_cm_phy_ack_ctrl_consistency + desc: '''Verify the countermeasure(s) PHY_ACK.CTRL.CONSISTENCY. + + Trigger tb.dut.u_eflash.gen_flash_cores[0].u_core.spurious_ack_o as follows: + @ tb.dut.u_eflash.gen_flash_cores[0].u_core.ctrl_fsm_idle + force tb.dut.u_eflash.gen_flash_cores[0].u_core.ctrl_rsp_vld = 1 or + @ tb.dut.u_eflash.gen_flash_cores[0].u_core.host_outstanding[1:0] == 0 + force tb.dut.u_eflash.gen_flash_cores[0].u_core.host_req_done_o = 1 + Check fault_status.spurious_ack + ''' + stage: V2S + tests: ["flash_ctrl_phy_ack_consistency"] + } + { + name: sec_cm_fifo_ctr_redun + desc: '''Verify the countermeasure(s) FIFO.CTR.REDUN. + Error is injected by global test. + Follwing fifos are in this category. + - dut.u_to_rd_fifo, + - dut.u_eflash.gen_flash_cores[*].u_core.u_rd.u_rsp_order_fifo, + - dut.u_eflash.gen_flash_cores[*].u_core.u_rd.u_rd_storage + Error from these fifos will trigger std_fault_status.fifo_err. + ''' + stage: V2S + tests: ["flash_ctrl_sec_cm"] + } + { + name: sec_cm_mem_tl_lc_gate_fsm_sparse + desc: "Verify the countermeasure(s) MEM_TL_LC_GATE.FSM.SPARSE." + stage: V2S + tests: ["flash_ctrl_sec_cm"] + } + { + name: sec_cm_prog_tl_lc_gate_fsm_sparse + desc: "Verify the countermeasure(s) PROG_TL_LC_GATE.FSM.SPARSE." + stage: V2S + tests: ["flash_ctrl_sec_cm"] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_testplan.hjson new file mode 100644 index 0000000000000..604383e0d4c45 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/flash_ctrl_testplan.hjson @@ -0,0 +1,499 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "flash_ctrl" + import_testplans: ["hw/dv/tools/dvsim/testplans/csr_testplan.hjson", + "hw/dv/tools/dvsim/testplans/mem_testplan.hjson", + "hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", + "hw/dv/tools/dvsim/testplans/intr_test_testplan.hjson", + "hw/dv/tools/dvsim/testplans/shadow_reg_errors_testplan.hjson", + "hw/dv/tools/dvsim/testplans/tl_device_access_types_testplan.hjson", + "hw/dv/tools/dvsim/testplans/stress_all_with_reset_testplan.hjson", + "flash_ctrl_sec_cm_testplan.hjson"] + testpoints: [ + { + name: smoke + desc: ''' + Randomly read, program or erase (page or a bank) a randomized chunk of flash memory. + Only the data partition is accessed. No extra features enabled. Flash memory is + invalidated and the targeted chunk is initialized with random data for reads and all 1s + for writes. Interrupts are not enabled, Completion is ascertained through polling. The + success of each operation is verified via backdoor. + ''' + stage: V1 + tests: ["flash_ctrl_smoke"] + } + { + name: smoke_hw + desc: ''' + Perform host direct read on the single page of Data partition. First Flash memory is + initialized with random values and then it is being read directly by Host interface. + Finally, backdoor read is used for checking read data. + ''' + stage: V1 + tests: ["flash_ctrl_smoke_hw"] + } + { + name: sw_op + desc: ''' + Perform flash protocol controller read, program and erase on the single page of one + bank within Data partition. Finally perform read on same location in order to test + if previous operation was done successfully. + ''' + stage: V2 + tests: ["flash_ctrl_sw_op"] + } + { + name: host_read_direct + desc: ''' + Perform back-to-back direct reads via Host in order to test bandwidth of hardware host + interface. In addition, perform stalls to test pipeline structure. Enable scramble to + test pipeline structure. + ''' + stage: V2 + tests: ["flash_ctrl_host_dir_rd"] + } + { + name: rma_hw_if + desc: ''' + Perform RMA entry requests and check afterwards that the software has no access to + the Flash. After RMA entry, verify that the content of the flash is wiped out. + ''' + stage: V2 + tests: ["flash_ctrl_hw_rma", "flash_ctrl_hw_rma_reset", "flash_ctrl_lcmgr_intg"] + } + { + name: host_controller_arb + desc: ''' + Perform operations via the Flash Software Interface, and at the same time invoke a + Hardware RMA operation. This verifies the arbitration within the Flash Protocol + Controller. The arbiter should allow any outstanding Software operations to complete + before the RMA starts. When the RMA completes the RMA FSM remains in its final state + until Reset and software access is blocked. + ''' + stage: V2 + tests: ["flash_ctrl_host_ctrl_arb"] + } + { + name: erase_suspend + desc: ''' + Perform erase suspend when erase is ongoing and also when erase is not ongoing. + Check if request is immediately cleared in case when no erase is ongoing. + Check if request is cleared in case when suspend is handled. + Read affected bank in order to verify erase suspension feature. + ''' + stage: V2 + tests: ["flash_ctrl_erase_suspend"] + } + { + name: program_reset + desc: ''' + Reset controller at every state of programming operation and check + if controller doesn't have any residue for the next operation. + ''' + stage: V2 + tests: ["flash_ctrl_prog_reset"] + } + { + name: full_memory_access + desc: ''' + Entire memory is accessed by Controller and directly by Host. In addition, Data + partitions can be directly read by Software(Flash controller) and hardware hosts, + while Info partitions can be read only by the Flash controller. + ''' + stage: V2 + tests: ["flash_ctrl_full_mem_access"] + } + { + name: rd_buff_eviction + desc: ''' + Perform following sequences of operations: read/program/read and read/erase/read in + order to test read buffer eviction properly. Read should be executed by both Software + and Host interface. All combinations should be tested. Covergroup for this hazardous + behavior is eviction_cg. + ''' + stage: V2 + tests: ["flash_ctrl_rd_buff_evict"] + } + { + name: rd_buff_eviction_w_ecc + desc: ''' + Run read eviction test with multiple memory protection configs. + Each config should enable read but randomize all other fields + including scramble and ecc enable. + ''' + stage: V2 + tests: ["flash_ctrl_rw_evict", "flash_ctrl_re_evict", "flash_ctrl_rw_evict_all_en"] + } + { + name: host_arb + desc: ''' + Test arbitration within Flash Physical Controller by reading from both interfaces at + the same time. Perform continuously direct read data from host interface and at the + same time, perform all operations READ/PROGRAM/ERASE from the flash controller is in + progress. Perform parallel operations at addresses of different banks and also on same + bank. Expect that operations are successfully executed. + ''' + stage: V2 + tests: ["flash_ctrl_phy_arb"] + } + { + name: host_interleave + desc: ''' + At same time, perform two read operations and the same time via host and via + controller. At same time, perform read operation via host and program + operation via controller. Perform mentioned parallel operations at different addresses + and on the same address. Expect that operations are successfully + executed. + ''' + stage: V2 + tests: ["flash_ctrl_phy_arb"] + } + { + name: memory_protection + desc: ''' + Perform READ/ PROGRAM/ ERASE operations over protected regions and pages of data and + info partitions. Use set and reset values of corresponding read, program and erase + enable bits. Test boundary values of regions. Test overlap of regions in which lower + region wins arbitration. + ''' + stage: V2 + tests: ["flash_ctrl_mp_regions"] + } + { + name: fetch_code + desc: ''' + Verify the Code Fetch Feature. + Reads for instructions via the Hardware Interface are allowed if a specific value + is written to the EXEC csr. + ''' + stage: V2 + tests: ["flash_ctrl_fetch_code"] + } + { + name: all_partitions + desc: ''' + Sanity + both, legal data and info partitions are accessed. In future, support for + multiple info partitions may be added - those will be covered as well. + ''' + stage: V2 + tests: ["flash_ctrl_rand_ops"] + } + { + name: error_mp + desc: ''' + Perform accesses in order to provoke memory permission errors. Test the Software + interface (Erase, Program, Read). Related covergroup is sw_error_cg. + ''' + stage: V2 + tests: ["flash_ctrl_error_mp"] + } + { + name: error_prog_win + desc: ''' + Perform accesses in order to provoke the 'program resolution' error. + Test via the Software interface. Related covergroup is sw_error_cg. + ''' + stage: V2 + tests: ["flash_ctrl_error_prog_win"] + } + { + name: error_prog_type + desc: ''' + Perform accesses in order to provoke the 'program type' error. + Test via the Software interface. Related covergroup is sw_error_cg. + ''' + stage: V2 + tests: ["flash_ctrl_error_prog_type"] + } + { + name: error_read_seed + desc: ''' + Create sw read error during hw seed read process. + Check all errors are properly detected. + ''' + stage: V2 + tests: ["flash_ctrl_hw_read_seed_err"] + } + { + name: read_write_overflow + desc: ''' + Send following error transactions with normal traffic and see + any catastrophic event happens. + - Program flash size longer than 64 bytes. + This wil cause prog_win_err. + - Read flash from controller without settting start op. + - Issue rd_fifo read more thatn CONTROL.NUM field value. + Both will cause d_error in tlul response. + Each transaction is terminated gracefully and should not cause + data path lock up. Also error status should be check per each + transaction. + ''' + stage: V2 + tests: ["flash_ctrl_oversize_error"] + } + { + name: flash_ctrl_disable + desc: ''' + Set flash ctrl disable by hw (lc_escalate_en = On) or + sw (flash_ctrl.dis = MuBi4True). And try to access flash ctrl + and check the access attempt to be failed. + ''' + stage: V2 + tests: ["flash_ctrl_disable"] + } + { + name: flash_ctrl_connect + desc: ''' + Check jtag input / output ports connectivity with lc_nvm_debug_en. + Connections are set only when lc_nvm_debug_en = On. + ''' + stage: V2 + tests: ["flash_ctrl_connect"] + } + { + name: stress_all + desc: ''' + - combine above sequences in one test to run sequentially, except csr sequence + - randomly add reset between each sequence + ''' + stage: V2 + tests: ["flash_ctrl_stress_all"] + } + { + name: secret_partition + desc: ''' + Verify the secret information partitions. Accessibility is controlled by the Life Cycle Controller + Seeds are read upon flash controller initialization and sent to the Key Manager, additionally verify + that scramble Keys are Read from the OTP and sent into the Flash Ctlr. Also erify that programmed + Secret Partitions retain their values through a Reset Cycle. + ''' + stage: V2 + tests: ["flash_ctrl_hw_sec_otp", "flash_ctrl_otp_reset"] + } + { + name: isolation_partition + desc: ''' + Verify the isolated information partitions. Accessablity is controlled by Life + Cycle Controller. Verify Partition can be erase, written and programmed, with + HW control, and wipes after an RMA. + ''' + stage: V2 + tests: ["flash_ctrl_hw_rma"] + } + { + name: interrupts + desc: ''' + Perform accesses in order to raise all interrupts given in register map. + Check behaviour of Interrupt Enable and Status Registers. + ''' + stage: V2 + tests: ["flash_ctrl_intr_rd", "flash_ctrl_intr_wr", + "flash_ctrl_intr_rd_slow_flash", "flash_ctrl_intr_wr_slow_flash"] + } + { + name: invalid_op + desc: ''' + Send invalid command in order to check that it does not affect memory content. + Check that recovery alert is triggered. + ''' + stage: V2 + tests: ["flash_ctrl_invalid_op"] + } + { + name: mid_op_rst + desc: ''' + Flash middle operation reset test. Send reset via power ready signal + in the middle of operation program, read, erase and erase suspend. + ''' + stage: V2 + tests: ["flash_ctrl_mid_op_rst"] + } + { + name: double_bit_err + desc: ''' + Run read / write test and inject double bit error randomly for read transactions -- + both direct and controller read. + Check op_status.err and err_code.rd_err are asserted for ctrl read and + tlul response error for host read. + Check fatal alert is asserted for reliability ecc errors (double bits) and + integrity ECC errors. + ''' + stage: V2 + tests: ["flash_ctrl_read_word_sweep_derr", "flash_ctrl_ro_derr", + "flash_ctrl_rw_derr", "flash_ctrl_derr_detect", "flash_ctrl_integrity"] + } + { + name: single_bit_err + desc: ''' + Run read only or read write test with randomly injected single bit error. + All single bit error should be corrected and all read data should be + matched with expected written value. + ''' + stage: V2 + tests: ["flash_ctrl_read_word_sweep_serr", + "flash_ctrl_ro_serr", "flash_ctrl_rw_serr"] + } + { + name: singlebit_err_counter + desc: ''' + Run read / write test and inject single bit error randomly for read transactions. - + both direct and controller read - Adjust error injection ratio s.t. counter is not + saturated. + Compare counter values for both bank with expected counter values. + ''' + stage: V2 + tests: ["flash_ctrl_serr_counter"] + } + { + name: singlebit_err_address + desc: ''' + Run read / write test and inject a single bit error randomly either direct + or controller read. Once error is injected a certain transaction, wait for the + transaction to be completed and compare ecc_single_err_addr register with the + expected value. Do this for multiple rounds for both banks. + ''' + stage: V2 + tests: ["flash_ctrl_serr_address"] + } + { + name: scramble + desc: ''' + Enable scrambling, along with randomized scramble keys. Program a fresh chunk of + memory and read back (both, via controller and host) to ensure data integrity. On + program, verify via backdoor scrambling was done on the raw data correctly. When + reading via host, read the same memory via host multiple times back-to-back and ensure + the timing is correct (subsequent reads should be faster). When scrambling is not + enabled, ensure that the raw data is written and read back. + ''' + stage: V2 + tests: ["flash_ctrl_wo", "flash_ctrl_ro", "flash_ctrl_rw", + "flash_ctrl_write_word_sweep", "flash_ctrl_read_word_sweep"] + } + { + name: filesystem_support + desc: ''' + Enable ECC and disable scrambling for all regions. + Initialize flash with erased state (FlashMemInitSet). + Execute random number of writes without writing the same location twice. + Record all write locations(Minimum resolution of location is 8bytes). + After that, execute write and read back test for random page and check + - If the locations are in the written record, write data should be all 0 and + readback data should match with the written data. + - If the locations are not in the written record, write data should be random and + readback data should match with the written data. + ''' + stage: V2 + tests: ["flash_ctrl_fs_sup"] + } + { + name: rma_write_process_error + desc: ''' + Verify error handling process duing the rma wipe process. + In normal rma process, inject bit error at the write path + (tb.dut.u_eflash.gen_flash_cores[0].u_core.gen_prog_data.u_prog.pack_data). + This should make debug_state to flash_ctrl_env_pkg::FlashLcIvalid and + fatal error (std_fault_status.lcmgr_err) should be triggered. + ''' + stage: V2 + tests: ["flash_ctrl_rma_err", "flash_ctrl_hw_prog_rma_wipe_err"] + } + { + name: asymmetric_read_path + desc: ''' + Create 'fast' and 'slow' read path using scramble enable. + Send flash read requst over slow path followed by fast path. + While return data comes from fast path first but they are expected + to be returned in request order. + ''' + stage: V3 + tests: ["flash_ctrl_rd_ooo"] + } + ] + + covergroups: [ + { + name: control_cg + desc: ''' + Covers that all operations READ/PROGRAM/ERASE/UNKNOWN have been tested. + Covers that ERASE operation is performed on a page and on entire bank. + Covers data and info partitions selection. + All valid combinations of the above will also be crossed. + ''' + } + { + name: erase_susp_cg + desc: ''' + Covers if request of erase suspension occured. + ''' + } + { + name: msgfifo_level_cg + desc: ''' + Covers that all possible fifo statuses generate interrupts for operations READ/PROGRAM. + Covers both boundary values 0 and 31. Also covers acceptable distributions within + ranges. + ''' + } + { + name: sw_error_cg + desc: ''' + Covers following error scenarios given in Flash error code register: + - op_err: Undefined operation. + - mp_err: Flash access has encountered an access permission error. + - rd_err: Flash read has an uncorrectable data error. + - prog_err: Flash program has an error. + - prog_win_err: Flash program has a window resolution error. + - prog_type_err: Flash program selected unavailable type. + - update_err: A shadow register encountered an update error. + ''' + } + { + name: eviction_cg + desc: ''' + Covers eviction with mp_region_cfgs for data and info regions. + Sample all 4 rd_buf status. + When each buffer hazard is set, capture the address stored in the buffer. + Then search from tb data base to see which region the address belong to. + After that record the config value (scrambe_en and ecc_en) of the region. + Use cross over buffer index, the operation to cause the eviction and + the region config values. + ''' + } + { + name: fetch_code_cg + desc: ''' + Covers whether dut received valid or invalid key value from ral.exec register. + Cross with tlul.instr_types. + ''' + } + { + name: rma_init_cg + desc: ''' + Cover rma operation is executed regardless of when flash_init started. + flash_ctrl_hw_rma runs rma operation and flash init in parallel thread. + In this test, sample rma state when flash init starts. + If rma state is StRmaIdle, which means rma is not started. So it confirms + rma start after flash init start. + If rma state is [StRmaPageSel:StRmaInvalid], which mean rma is on going. + So it confirms rma start before flash init start. + ''' + } + { + name: phy_rd_cg + desc: ''' + Cover various read sequences on the physical interfaces of each bank. + Create bins such as read after read, read after program and read after + erase. + ''' + } + { + name: b2b_read_interval_cg + desc: ''' + Cover interval profile of back to back read operation. + Minimum interval of the back to back read is 1 cycle. + ''' + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/top_englishbreakfast_flash_ctrl.ipconfig.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/top_englishbreakfast_flash_ctrl.ipconfig.hjson new file mode 100644 index 0000000000000..3a9526df87ec4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/data/top_englishbreakfast_flash_ctrl.ipconfig.hjson @@ -0,0 +1,30 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + instance_name: top_englishbreakfast_flash_ctrl + param_values: + { + banks: 2 + pages_per_bank: 16 + program_resolution: 8 + words_per_page: 256 + data_width: 64 + metadata_width: 12 + info_types: 3 + infos_per_bank: + [ + 10 + 1 + 2 + ] + word_bytes: 8 + pgm_resolution_bytes: 64 + bytes_per_page: 2048 + bytes_per_bank: 32768 + size: 65536 + pwrmgr_vlnv_prefix: top_englishbreakfast_ + top_pkg_vlnv: lowrisc:constants:top_englishbreakfast_top_pkg + topname: englishbreakfast + } +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/defs.bzl b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/defs.bzl new file mode 100644 index 0000000000000..25072f48547c8 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +load("//rules/opentitan:hw.bzl", "opentitan_ip") + +FLASH_CTRL = opentitan_ip( + name = "flash_ctrl", + hjson = "//hw/top_englishbreakfast/ip_autogen/flash_ctrl:data/flash_ctrl.hjson", +) diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/checklist.md b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/checklist.md new file mode 100644 index 0000000000000..0cf571de0c398 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/checklist.md @@ -0,0 +1,267 @@ +# FLASH_CTRL Checklist + +This checklist is for [Hardware Stage](../../../../../doc/project_governance/development_stages.md) transitions for the [FLASH_CTRL 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 | [FLASH_CTRL Spec][] +Documentation | [CSR_DEFINED][] | Done | +RTL | [CLKRST_CONNECTED][] | Done | +RTL | [IP_TOP][] | Done | +RTL | [IP_INSTANTIABLE][] | Done | +RTL | [PHYSICAL_MACROS_DEFINED_80][] | Done | +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][] | Done | +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][] | Done | +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 | [flash_ctrl_dv_doc](../dv/README.md) +Documentation | [TESTPLAN_COMPLETED][] | Done | +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][] | Waived | Automation setup is a WIP +Testbench | [TB_GEN_AUTOMATED][] | N/A | +Tests | [SIM_SMOKE_TEST_PASSING][] | Done | +Tests | [SIM_CSR_MEM_TEST_SUITE_PASSING][] | Done | +Tests | [FPV_MAIN_ASSERTIONS_PROVEN][] | N/A | +Tool Setup | [SIM_ALT_TOOL_SETUP][] | Done | Primary: VCS, Alt: 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][] | N/A | +Review | [DESIGN_SPEC_REVIEWED][] | Done | +Review | [TESTPLAN_REVIEWED][] | Done | +Review | [STD_TEST_CATEGORIES_PLANNED][] | Done | +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][] | N/A | +Tests | [FPV_ALL_ASSUMPTIONS_REVIEWED][] | N/A | +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][] | N/A | +Coverage | [FPV_COI_COVERAGE_V2][] | N/A | +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 | +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/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_abstraction.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_abstraction.svg new file mode 100644 index 0000000000000..61e7d931ec3b1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_abstraction.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_block_diagram.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_block_diagram.svg new file mode 100644 index 0000000000000..2cfb1aff61232 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_block_diagram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_boundaries.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_boundaries.svg new file mode 100644 index 0000000000000..88f2ad1970709 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_boundaries.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_integrity.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_integrity.svg new file mode 100644 index 0000000000000..4773b6f6b792a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_integrity.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_partitions.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_partitions.svg new file mode 100644 index 0000000000000..c209f5bc098f5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_partitions.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_protocol_controller.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_protocol_controller.svg new file mode 100644 index 0000000000000..1ccb9cd610adc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_protocol_controller.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_read_pipeline.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_read_pipeline.svg new file mode 100644 index 0000000000000..1d0629c893002 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/flash_read_pipeline.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/interfaces.md b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/interfaces.md new file mode 100644 index 0000000000000..d00ebb54d29c6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/interfaces.md @@ -0,0 +1,141 @@ +# Interfaces + + +Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`flash_ctrl`** has the following hardware interfaces defined +- Primary Clock: **`clk_i`** +- Other Clocks: **`clk_otp_i`** +- Bus Device Interfaces (TL-UL): **`core_tl`**, **`prim_tl`**, **`mem_tl`** +- Bus Host Interfaces (TL-UL): *none* + +## Peripheral Pins for Chip IO + +| Pin name | Direction | Description | +|:-----------|:------------|:--------------| +| tck | input | jtag clock | +| tms | input | jtag tms | +| tdi | input | jtag input | +| tdo | output | jtag output | + +## [Inter-Module Signals](https://opentitan.org/book/doc/contributing/hw/comportability/index.html#inter-signal-handling) + +| Port Name | Package::Struct | Type | Act | Width | Description | +|:-------------------------|:-------------------------------|:--------|:------|--------:|:--------------| +| otp | otp_ctrl_pkg::flash_otp_key | req_rsp | req | 1 | | +| lc_nvm_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| flash_bist_enable | prim_mubi_pkg::mubi4 | uni | rcv | 1 | | +| flash_power_down_h | logic | uni | rcv | 1 | | +| flash_power_ready_h | logic | uni | rcv | 1 | | +| flash_test_mode_a | | io | none | 2 | | +| flash_test_voltage_h | | io | none | 1 | | +| lc_creator_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| lc_owner_seed_sw_rw_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| lc_iso_part_sw_rd_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| lc_iso_part_sw_wr_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| lc_seed_hw_rd_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| lc_escalate_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| rma_req | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | | +| rma_ack | lc_ctrl_pkg::lc_tx | uni | req | 1 | | +| rma_seed | lc_ctrl_pkg::lc_flash_rma_seed | uni | rcv | 1 | | +| pwrmgr | pwrmgr_pkg::pwr_flash | uni | req | 1 | | +| keymgr | flash_ctrl_pkg::keymgr_flash | uni | req | 1 | | +| obs_ctrl | ast_pkg::ast_obs_ctrl | uni | rcv | 1 | | +| fla_obs | logic | uni | req | 8 | | +| core_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | +| prim_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | +| mem_tl | tlul_pkg::tl | req_rsp | rsp | 1 | | + +## Interrupts + +| Interrupt Name | Type | Description | +|:-----------------|:-------|:------------------------------| +| prog_empty | Status | Program FIFO empty | +| prog_lvl | Status | Program FIFO drained to level | +| rd_full | Status | Read FIFO full | +| rd_lvl | Status | Read FIFO filled to level | +| op_done | Event | Operation complete | +| corr_err | Event | Correctable error encountered | + +## Security Alerts + +| Alert Name | Description | +|:-----------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| recov_err | flash recoverable errors | +| fatal_std_err | flash standard fatal errors | +| fatal_err | Flash fatal errors including uncorrectable ECC errors. Note that this alert is not always fatal. The underlying error bits in the [`FAULT_STATUS`](registers.md#fault_status) register remain set until reset, meaning the alert keeps firing. This doesn't hold for [`FAULT_STATUS.PHY_RELBL_ERR`](registers.md#fault_status) and [`FAULT_STATUS.PHY_STORAGE_ERR.`](registers.md#fault_status) To enable firmware dealing with multi-bit ECC and ICV errors during firmware selection and verification, these error bits can be cleared. After passing this stage, it is recommended that firmware classifies the corresponding alert as fatal on the receiver end, i.e, inside the alert handler. | +| fatal_prim_flash_alert | Fatal alert triggered inside the flash primitive, including fatal TL-UL bus integrity faults of the test interface. | +| recov_prim_flash_alert | Recoverable alert triggered inside the flash primitive. | + +## Security Countermeasures + +| Countermeasure ID | Description | +|:-------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| FLASH_CTRL.REG.BUS.INTEGRITY | End-to-end bus integrity scheme. Since there are multiple access points for flash, please see Transmission Integrity Faults in the documentation for more details. The bus integrity scheme for flash is different from other comportable modules. | +| FLASH_CTRL.HOST.BUS.INTEGRITY | End-to-end bus integrity scheme. Since there are multiple access points for flash, please see Transmission Integrity Faults in the documentation for more details. The bus integrity scheme for flash is different from other comportable modules. | +| FLASH_CTRL.MEM.BUS.INTEGRITY | End-to-end bus integrity scheme. Since there are multiple access points for flash, please see Transmission Integrity Faults in the documentation for more details. The bus integrity scheme for flash is different from other comportable modules. | +| FLASH_CTRL.MEM.ADDR_INFECTION | On host reads, the address of the request is XORed with the data inside the read pipeline. The request address is removed from the data before returning the data over TL-UL. A mismatch triggers a data integrity error. | +| FLASH_CTRL.SCRAMBLE.KEY.SIDELOAD | The scrambling key is sideloaded from OTP and thus unreadable by SW. | +| FLASH_CTRL.LC_CTRL.INTERSIG.MUBI | Life cycle control signals are used control information partition access and flash debug access. See secret information partition, isolated information partitions and jtag connection in documentation for more details. | +| FLASH_CTRL.CTRL.CONFIG.REGWEN | Configurations cannot be changed when an operation is ongoing. | +| FLASH_CTRL.DATA_REGIONS.CONFIG.REGWEN | Each data region has a configurable regwen. | +| FLASH_CTRL.DATA_REGIONS.CONFIG.SHADOW | Data region configuration is shadowed. | +| FLASH_CTRL.INFO_REGIONS.CONFIG.REGWEN | Each info page of each type in each bank has separate regwen. | +| FLASH_CTRL.INFO_REGIONS.CONFIG.SHADOW | Each info page is shadowed. | +| FLASH_CTRL.BANK.CONFIG.REGWEN | Each bank has separate regwen for bank erase. | +| FLASH_CTRL.BANK.CONFIG.SHADOW | Each bank has separate regwen for bank erase. | +| FLASH_CTRL.MEM.CTRL.GLOBAL_ESC | Global escalation causes memory to no longer be accessible. | +| FLASH_CTRL.MEM.CTRL.LOCAL_ESC | A subset of fatal errors cause memory to no longer be accessible. This subset is defined in [`STD_FAULT_STATUS.`](registers.md#std_fault_status) | +| FLASH_CTRL.MEM_DISABLE.CONFIG.MUBI | Software control for flash disable is multibit. The register is [`DIS.`](registers.md#dis) | +| FLASH_CTRL.EXEC.CONFIG.REDUN | Software control for flash enable is 32-bit constant. The register is [`EXEC.`](registers.md#exec) | +| FLASH_CTRL.MEM.SCRAMBLE | The flash supports XEX scrambling. The cipher used is PRINCE. The scrambling scheme is enabled by software, please see flash scrambling in documentation for more details. | +| FLASH_CTRL.MEM.INTEGRITY | The flash supports two layers of ECC integrity: one layer is for integrity, and the other layer is for reliability. These ECCs are enabled and disabled together by software. Please see Flash ECC in the documentation for more details. | +| FLASH_CTRL.RMA_ENTRY.MEM.SEC_WIPE | RMA entry entry wipes flash memory with random data. | +| FLASH_CTRL.CTRL.FSM.SPARSE | RMA handling FSMs in flash_ctrl_lcmgr are sparsely encoded. FSM in flash_ctrl_arb is sparsely encoded. | +| FLASH_CTRL.PHY.FSM.SPARSE | PHY FSMs are sparsely encoded. | +| FLASH_CTRL.PHY_PROG.FSM.SPARSE | PHY program FSMs are sparsely encoded. | +| FLASH_CTRL.CTR.REDUN | flash_ctrl_lcmgr handling counters are redundantly encoded. This includes seed count and address count used during seed reading phase, as well as word count, page count and wipe index in RMA entry phase. | +| FLASH_CTRL.PHY_ARBITER.CTRL.REDUN | The phy arbiters for controller/host arbitration and in the shared scrambling module are redundant. The arbiters have two instances underneath that are constantly compared to each other. | +| FLASH_CTRL.PHY_HOST_GRANT.CTRL.CONSISTENCY | The host grant is consistency checked. If the host is ever granted with info partition access, it is an error. If the host is ever granted at the same time as a program/erase operation, it is an error. | +| FLASH_CTRL.PHY_ACK.CTRL.CONSISTENCY | If the host or controller ever receive an unexpeced transaction acknowledge, it is an error. | +| FLASH_CTRL.FIFO.CTR.REDUN | The FIFO pointers of several FIFOs are implemented with duplicate counters. | +| FLASH_CTRL.MEM_TL_LC_GATE.FSM.SPARSE | The control FSM inside the TL-UL gating primitive is sparsely encoded. | +| FLASH_CTRL.PROG_TL_LC_GATE.FSM.SPARSE | The control FSM inside the TL-UL gating primitive is sparsely encoded. | + + + + +## Signals + +In addition to the interrupts and bus signals, the tables below lists the flash controller functional I/Os. + +Signal | Direction | Description +------------------------ |----------- |--------------- +`lc_creator_seed_sw_rw_en` | `input` | Indication from `lc_ctrl` that software is allowed to read/write creator seed. +`lc_owner_seed_sw_rw_en` | `input` | Indication from `lc_ctrl` that software is allowed to read/write owner seed. +`lc_seed_hw_rd_en` | `input` | Indication from `lc_ctrl` that hardware is allowed to read creator / owner seeds. +`lc_iso_part_sw_rd_en` | `input` | Indication from `lc_ctrl` that software is allowed to read the isolated partition. +`lc_iso_part_sw_wr_en` | `input` | Indication from `lc_ctrl` that software is allowed to write the isolated partition. +`lc_escalate_en` | `input` | Escalation indication from `lc_ctrl`. +`lc_nvm_debug_en` | `input` | Indication from lc_ctrl that non-volatile memory debug is allowed. +`core_tl` | `input/output` | TL-UL interface used to access `flash_ctrl` registers for activating program / erase and reads to information partitions/ +`prim_tl` | `input/output` | TL-UL interface used to access the vendor flash memory proprietary registers. +`mem_tl` | `input/output` | TL-UL interface used by host to access the vendor flash memory directly. +`OTP` | `input/output` | Interface used to request scrambling keys from `otp_ctrl`. +`rma_req` | `input` | rma entry request from `lc_ctrl`. +`rma_ack` | `output` | rma entry acknowlegement to `lc_ctrl`. +`rma_seed` | `input` | rma entry seed. +`pwrmgr` | `output` | Idle indication to `pwrmgr`. +`keymgr` | `output` | Secret seed bus to `keymgr`. + +In addition to the functional IOs, there are a set of signals that are directly connected to vendor flash module. + +Signal | Direction | Description +------------------------ |----------- |--------------- +`scan_en` | `input` | scan enable +`scanmode` | `input` | scan mode +`scan_rst_n` | `input` | scan reset +`flash_bist_enable` | `input` | enable flash built-in-self-test +`flash_power_down_h` | `input` | flash power down indication, note this is NOT a core level signal +`flash_power_ready_h` | `input` | flash power ready indication, note this is NOT a core level signal +`flash_test_mode_a` | `input/output` | flash test mode io, note this is NOT a core level signal +`flash_test_voltage_h` | `input/output` | flash test voltage, note this is NOT a core level signal +`flash_alert` | `output` | flash alert outputs directly to AST diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/programmers_guide.md b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/programmers_guide.md new file mode 100644 index 0000000000000..8f57609cf3864 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/programmers_guide.md @@ -0,0 +1,75 @@ +# Programmer's Guide + +## Issuing a Controller Read + +To issue a flash read, the programmer must +* Specify the address of the first flash word to read +* Specify the number of total flash words to read, beginning at the supplied address +* Specify the operation to be 'READ' type +* Set the 'START' bit for the operation to begin + +The above fields can be set in the [`CONTROL`](registers.md#control) and [`ADDR`](registers.md#addr) registers. +See [library code](https://github.com/lowRISC/opentitan/blob/master/sw/device/lib/dif/dif_flash_ctrl.c) for implementation. + +It is acceptable for total number of flash words to be significantly greater than the depth of the read FIFO. +In this situation, the read FIFO will fill up (or hit programmable fill value), pause the flash read and trigger an interrupt to software. +Once there is space inside the FIFO, the controller will resume reading until the appropriate number of words have been read. +Once the total count has been reached, the flash controller will post OP_DONE in the [`OP_STATUS`](registers.md#op_status) register. + +## Issuing a Controller Program + +To program flash, the same procedure as read is followed. +However, instead of setting the [`CONTROL`](registers.md#control) register for read operation, a program operation is selected instead. +Software will then fill the program FIFO and wait for the controller to consume this data. +Similar to the read case, the controller will automatically stall when there is insufficient data in the FIFO. +When all desired words have been programmed, the controller will post OP_DONE in the [`OP_STATUS`](registers.md#op_status) register. + +## Debugging a Read Error +Since flash has multiple access modes, debugging read errors can be complicated. +The following lays out the expected cases. + +### Error Encountered by Software Direct Read +If software reads the flash directly, it may encounter a variety of errors (read data integrity / ECC failures, both reliability and integrity). +ECC failures create in-band error responses and should be recognized as a bus exception. +Read data integrity failures also create exceptions directly inside the processor as part of end-to-end transmission integrity. + +From these exceptions, software should be able to determine the error address through processor specific means. +Once the address is discovered, further steps can be taken to triage the issue. + +### Error Encountered by Software Initiated Controller Operations +A controller operation can encounter a much greater variety of errors, see [`ERR_CODE`](registers.md#err_code). +When such an error is encountered, as reflected by [`OP_STATUS`](registers.md#op_status) when the operation is complete, software can examine the [`ERR_ADDR`](registers.md#err_addr) to determine the error location. +Once the address is discovered, further steps can be taken to triage the issue. + +### Hardware Initiated Reads + +If the root secrets have been provisioned in OTP and the life cycle state is in either DEV, PROD* or RMA, the special info pages holding the creator and owner seeds will be read out automatically by the flash controller and sent to the keymanager upon flash initialization (see [life cycle controller documentation](../../../../ip/lc_ctrl/doc/theory_of_operation.md#life-cycle-access-control-signals) and [OTP controller documentation](../../../../ip/otp_ctrl/doc/theory_of_operation.md#life-cycle-interfaces) for more details). +Hence, it is important that these pages are initialized with valid data, since otherwise the hardware will likely encounter ECC errors during the automatic readout. + +Note that by default, hardware assumes that scrambling and ECC is enabled on these special info pages. +If software decides to not use scrambling or ECC on these partitions at the time of provisioning, software should disable these features in the [`HW_INFO_CFG_OVERRIDE`](registers.md#hw_info_cfg_override) register accordingly when initializing the flash controller. +Otherwise, a configuration mismatch between hardware interface and the software side will lead to corrupted seed values and ECC errors upon automatic readout. + +### Correctable ECC Errors +Correctable ECC errors are by nature not fatal errors and do not stop operation. +Instead, if the error is correctable, the flash controller fixes the issue and registers the last address where a single bit error was seen. +See [`ECC_SINGLE_ERR_CNT`](registers.md#ecc_single_err_cnt) and [`ECC_SINGLE_ERR_ADDR`](registers.md#ecc_single_err_addr) + +### Errors during Multi-Word Controller Reads + +Note that upon experiencing the first error during any multi-word read operation, the flash controller aborts the internal read operation but still returns the requested amount of data. +For the word where the read error has been observed, the actual flash data is returned. +For subsequent words, the flash controller may return: +- An all-one word in case of an access permission error. +- An all-zero word in case of a flash read error (e.g. reliability ECC and ICV errors) and if the flash read pipeline remains idle. +- The data belonging to other read operations in case of a flash read error and if the flash read pipeline continues doing, e.g., host initiated read operations. + In this case, the data returned for the subsequent words may contain further ECC and ICV errors. + +## Granularity of Scrambling and Reliability ECC + +While the minimum granularity for host and controller interface accesses is 32 bits, the scrambling as well as reliability ECC operate on full Flash words (64 bits). +Whenever reliability ECC and/or scrambling are enabled, read, program and erase operations should thus be based on 64-bit aligned addresses. + +## Device Interface Functions (DIFs) + +- [Device Interface Functions](../../../../../sw/device/lib/dif/dif_flash_ctrl.h) diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/registers.md b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/registers.md new file mode 100644 index 0000000000000..7c99c85a80046 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/registers.md @@ -0,0 +1,2122 @@ +# Registers + +The flash protocol controller maintains two separate access windows for the FIFO. +It is implemented this way because the access window supports transaction back-pressure should the FIFO become full (in case of write) or empty (in case of read). + + +## Summary of the **`core`** interface's registers + +| Name | Offset | Length | Description | +|:-------------------------------------------------------------|:---------|---------:|:--------------------------------------------------------------| +| flash_ctrl.[`INTR_STATE`](#intr_state) | 0x0 | 4 | Interrupt State Register | +| flash_ctrl.[`INTR_ENABLE`](#intr_enable) | 0x4 | 4 | Interrupt Enable Register | +| flash_ctrl.[`INTR_TEST`](#intr_test) | 0x8 | 4 | Interrupt Test Register | +| flash_ctrl.[`ALERT_TEST`](#alert_test) | 0xc | 4 | Alert Test Register | +| flash_ctrl.[`DIS`](#dis) | 0x10 | 4 | Disable flash functionality | +| flash_ctrl.[`EXEC`](#exec) | 0x14 | 4 | Controls whether flash can be used for code execution fetches | +| flash_ctrl.[`INIT`](#init) | 0x18 | 4 | Controller init register | +| flash_ctrl.[`CTRL_REGWEN`](#ctrl_regwen) | 0x1c | 4 | Controls the configurability of the !!CONTROL register. | +| flash_ctrl.[`CONTROL`](#control) | 0x20 | 4 | Control register | +| flash_ctrl.[`ADDR`](#addr) | 0x24 | 4 | Address for flash operation | +| flash_ctrl.[`PROG_TYPE_EN`](#prog_type_en) | 0x28 | 4 | Enable different program types | +| flash_ctrl.[`ERASE_SUSPEND`](#erase_suspend) | 0x2c | 4 | Suspend erase | +| flash_ctrl.[`REGION_CFG_REGWEN_0`](#region_cfg_regwen) | 0x30 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`REGION_CFG_REGWEN_1`](#region_cfg_regwen) | 0x34 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`REGION_CFG_REGWEN_2`](#region_cfg_regwen) | 0x38 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`REGION_CFG_REGWEN_3`](#region_cfg_regwen) | 0x3c | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`REGION_CFG_REGWEN_4`](#region_cfg_regwen) | 0x40 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`REGION_CFG_REGWEN_5`](#region_cfg_regwen) | 0x44 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`REGION_CFG_REGWEN_6`](#region_cfg_regwen) | 0x48 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`REGION_CFG_REGWEN_7`](#region_cfg_regwen) | 0x4c | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`MP_REGION_CFG_0`](#mp_region_cfg) | 0x50 | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_CFG_1`](#mp_region_cfg) | 0x54 | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_CFG_2`](#mp_region_cfg) | 0x58 | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_CFG_3`](#mp_region_cfg) | 0x5c | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_CFG_4`](#mp_region_cfg) | 0x60 | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_CFG_5`](#mp_region_cfg) | 0x64 | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_CFG_6`](#mp_region_cfg) | 0x68 | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_CFG_7`](#mp_region_cfg) | 0x6c | 4 | Memory property configuration for data partition | +| flash_ctrl.[`MP_REGION_0`](#mp_region) | 0x70 | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`MP_REGION_1`](#mp_region) | 0x74 | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`MP_REGION_2`](#mp_region) | 0x78 | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`MP_REGION_3`](#mp_region) | 0x7c | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`MP_REGION_4`](#mp_region) | 0x80 | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`MP_REGION_5`](#mp_region) | 0x84 | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`MP_REGION_6`](#mp_region) | 0x88 | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`MP_REGION_7`](#mp_region) | 0x8c | 4 | Memory base and size configuration for data partition | +| flash_ctrl.[`DEFAULT_REGION`](#default_region) | 0x90 | 4 | Default region properties | +| flash_ctrl.[`BANK0_INFO0_REGWEN_0`](#bank0_info0_regwen) | 0x94 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_1`](#bank0_info0_regwen) | 0x98 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_2`](#bank0_info0_regwen) | 0x9c | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_3`](#bank0_info0_regwen) | 0xa0 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_4`](#bank0_info0_regwen) | 0xa4 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_5`](#bank0_info0_regwen) | 0xa8 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_6`](#bank0_info0_regwen) | 0xac | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_7`](#bank0_info0_regwen) | 0xb0 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_8`](#bank0_info0_regwen) | 0xb4 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_REGWEN_9`](#bank0_info0_regwen) | 0xb8 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_0`](#bank0_info0_page_cfg) | 0xbc | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_1`](#bank0_info0_page_cfg) | 0xc0 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_2`](#bank0_info0_page_cfg) | 0xc4 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_3`](#bank0_info0_page_cfg) | 0xc8 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_4`](#bank0_info0_page_cfg) | 0xcc | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_5`](#bank0_info0_page_cfg) | 0xd0 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_6`](#bank0_info0_page_cfg) | 0xd4 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_7`](#bank0_info0_page_cfg) | 0xd8 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_8`](#bank0_info0_page_cfg) | 0xdc | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO0_PAGE_CFG_9`](#bank0_info0_page_cfg) | 0xe0 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO1_REGWEN`](#bank0_info1_regwen) | 0xe4 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO1_PAGE_CFG`](#bank0_info1_page_cfg) | 0xe8 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO2_REGWEN_0`](#bank0_info2_regwen) | 0xec | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO2_REGWEN_1`](#bank0_info2_regwen) | 0xf0 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK0_INFO2_PAGE_CFG_0`](#bank0_info2_page_cfg) | 0xf4 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK0_INFO2_PAGE_CFG_1`](#bank0_info2_page_cfg) | 0xf8 | 4 | Memory property configuration for info partition in bank0, | +| flash_ctrl.[`BANK1_INFO0_REGWEN_0`](#bank1_info0_regwen) | 0xfc | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_1`](#bank1_info0_regwen) | 0x100 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_2`](#bank1_info0_regwen) | 0x104 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_3`](#bank1_info0_regwen) | 0x108 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_4`](#bank1_info0_regwen) | 0x10c | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_5`](#bank1_info0_regwen) | 0x110 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_6`](#bank1_info0_regwen) | 0x114 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_7`](#bank1_info0_regwen) | 0x118 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_8`](#bank1_info0_regwen) | 0x11c | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_REGWEN_9`](#bank1_info0_regwen) | 0x120 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_0`](#bank1_info0_page_cfg) | 0x124 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_1`](#bank1_info0_page_cfg) | 0x128 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_2`](#bank1_info0_page_cfg) | 0x12c | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_3`](#bank1_info0_page_cfg) | 0x130 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_4`](#bank1_info0_page_cfg) | 0x134 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_5`](#bank1_info0_page_cfg) | 0x138 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_6`](#bank1_info0_page_cfg) | 0x13c | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_7`](#bank1_info0_page_cfg) | 0x140 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_8`](#bank1_info0_page_cfg) | 0x144 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO0_PAGE_CFG_9`](#bank1_info0_page_cfg) | 0x148 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO1_REGWEN`](#bank1_info1_regwen) | 0x14c | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO1_PAGE_CFG`](#bank1_info1_page_cfg) | 0x150 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO2_REGWEN_0`](#bank1_info2_regwen) | 0x154 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO2_REGWEN_1`](#bank1_info2_regwen) | 0x158 | 4 | Memory region registers configuration enable. | +| flash_ctrl.[`BANK1_INFO2_PAGE_CFG_0`](#bank1_info2_page_cfg) | 0x15c | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`BANK1_INFO2_PAGE_CFG_1`](#bank1_info2_page_cfg) | 0x160 | 4 | Memory property configuration for info partition in bank1, | +| flash_ctrl.[`HW_INFO_CFG_OVERRIDE`](#hw_info_cfg_override) | 0x164 | 4 | HW interface info configuration rule overrides | +| flash_ctrl.[`BANK_CFG_REGWEN`](#bank_cfg_regwen) | 0x168 | 4 | Bank configuration registers configuration enable. | +| flash_ctrl.[`MP_BANK_CFG_SHADOWED`](#MP_BANK_CFG_SHADOWED) | 0x16c | 4 | Memory properties bank configuration | +| flash_ctrl.[`OP_STATUS`](#op_status) | 0x170 | 4 | Flash Operation Status | +| flash_ctrl.[`STATUS`](#status) | 0x174 | 4 | Flash Controller Status | +| flash_ctrl.[`DEBUG_STATE`](#debug_state) | 0x178 | 4 | Current flash fsm state | +| flash_ctrl.[`ERR_CODE`](#err_code) | 0x17c | 4 | Flash error code register. | +| flash_ctrl.[`STD_FAULT_STATUS`](#std_fault_status) | 0x180 | 4 | This register tabulates standard fault status of the flash. | +| flash_ctrl.[`FAULT_STATUS`](#fault_status) | 0x184 | 4 | This register tabulates customized fault status of the flash. | +| flash_ctrl.[`ERR_ADDR`](#err_addr) | 0x188 | 4 | Synchronous error address | +| flash_ctrl.[`ECC_SINGLE_ERR_CNT`](#ECC_SINGLE_ERR_CNT) | 0x18c | 4 | Total number of single bit ECC error count | +| flash_ctrl.[`ECC_SINGLE_ERR_ADDR_0`](#ecc_single_err_addr) | 0x190 | 4 | Latest address of ECC single err | +| flash_ctrl.[`ECC_SINGLE_ERR_ADDR_1`](#ecc_single_err_addr) | 0x194 | 4 | Latest address of ECC single err | +| flash_ctrl.[`PHY_ALERT_CFG`](#phy_alert_cfg) | 0x198 | 4 | Phy alert configuration | +| flash_ctrl.[`PHY_STATUS`](#phy_status) | 0x19c | 4 | Flash Phy Status | +| flash_ctrl.[`Scratch`](#scratch) | 0x1a0 | 4 | Flash Controller Scratch | +| flash_ctrl.[`FIFO_LVL`](#fifo_lvl) | 0x1a4 | 4 | Programmable depth where FIFOs should generate interrupts | +| flash_ctrl.[`FIFO_RST`](#fifo_rst) | 0x1a8 | 4 | Reset for flash controller FIFOs | +| flash_ctrl.[`CURR_FIFO_LVL`](#curr_fifo_lvl) | 0x1ac | 4 | Current program and read fifo depth | +| flash_ctrl.[`prog_fifo`](#prog_fifo) | 0x1b0 | 4 | Flash program FIFO. | +| flash_ctrl.[`rd_fifo`](#rd_fifo) | 0x1b4 | 4 | Flash read FIFO. | + +## INTR_STATE +Interrupt State Register +- Offset: `0x0` +- Reset default: `0x3` +- Reset mask: `0x3f` + +### Fields + +```wavejson +{"reg": [{"name": "prog_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_lvl", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "rd_full", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "rd_lvl", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "op_done", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "corr_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-----------|:------------------------------| +| 31:6 | | | | Reserved | +| 5 | rw1c | 0x0 | corr_err | Correctable error encountered | +| 4 | rw1c | 0x0 | op_done | Operation complete | +| 3 | ro | 0x0 | rd_lvl | Read FIFO filled to level | +| 2 | ro | 0x0 | rd_full | Read FIFO full | +| 1 | ro | 0x1 | prog_lvl | Program FIFO drained to level | +| 0 | ro | 0x1 | prog_empty | Program FIFO empty | + +## INTR_ENABLE +Interrupt Enable Register +- Offset: `0x4` +- Reset default: `0x0` +- Reset mask: `0x3f` + +### Fields + +```wavejson +{"reg": [{"name": "prog_empty", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "prog_lvl", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "rd_full", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "rd_lvl", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "op_done", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "corr_err", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-----------|:---------------------------------------------------------------------| +| 31:6 | | | | Reserved | +| 5 | rw | 0x0 | corr_err | Enable interrupt when [`INTR_STATE.corr_err`](#intr_state) is set. | +| 4 | rw | 0x0 | op_done | Enable interrupt when [`INTR_STATE.op_done`](#intr_state) is set. | +| 3 | rw | 0x0 | rd_lvl | Enable interrupt when [`INTR_STATE.rd_lvl`](#intr_state) is set. | +| 2 | rw | 0x0 | rd_full | Enable interrupt when [`INTR_STATE.rd_full`](#intr_state) is set. | +| 1 | rw | 0x0 | prog_lvl | Enable interrupt when [`INTR_STATE.prog_lvl`](#intr_state) is set. | +| 0 | rw | 0x0 | prog_empty | Enable interrupt when [`INTR_STATE.prog_empty`](#intr_state) is set. | + +## INTR_TEST +Interrupt Test Register +- Offset: `0x8` +- Reset default: `0x0` +- Reset mask: `0x3f` + +### Fields + +```wavejson +{"reg": [{"name": "prog_empty", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "prog_lvl", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "rd_full", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "rd_lvl", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "op_done", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "corr_err", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-----------|:--------------------------------------------------------------| +| 31:6 | | | | Reserved | +| 5 | wo | 0x0 | corr_err | Write 1 to force [`INTR_STATE.corr_err`](#intr_state) to 1. | +| 4 | wo | 0x0 | op_done | Write 1 to force [`INTR_STATE.op_done`](#intr_state) to 1. | +| 3 | wo | 0x0 | rd_lvl | Write 1 to force [`INTR_STATE.rd_lvl`](#intr_state) to 1. | +| 2 | wo | 0x0 | rd_full | Write 1 to force [`INTR_STATE.rd_full`](#intr_state) to 1. | +| 1 | wo | 0x0 | prog_lvl | Write 1 to force [`INTR_STATE.prog_lvl`](#intr_state) to 1. | +| 0 | wo | 0x0 | prog_empty | Write 1 to force [`INTR_STATE.prog_empty`](#intr_state) to 1. | + +## ALERT_TEST +Alert Test Register +- Offset: `0xc` +- Reset default: `0x0` +- Reset mask: `0x1f` + +### Fields + +```wavejson +{"reg": [{"name": "recov_err", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_std_err", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_err", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_prim_flash_alert", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "recov_prim_flash_alert", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 27}], "config": {"lanes": 1, "fontsize": 10, "vspace": 240}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-----------------------|:-------------------------------------------------| +| 31:5 | | | | Reserved | +| 4 | wo | 0x0 | recov_prim_flash_alert | Write 1 to trigger one alert event of this kind. | +| 3 | wo | 0x0 | fatal_prim_flash_alert | Write 1 to trigger one alert event of this kind. | +| 2 | wo | 0x0 | fatal_err | Write 1 to trigger one alert event of this kind. | +| 1 | wo | 0x0 | fatal_std_err | Write 1 to trigger one alert event of this kind. | +| 0 | wo | 0x0 | recov_err | Write 1 to trigger one alert event of this kind. | + +## DIS +Disable flash functionality +- Offset: `0x10` +- Reset default: `0x9` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["rw1s"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-----------------| +| 31:4 | | | Reserved | +| 3:0 | rw1s | 0x9 | [VAL](#dis--val) | + +### DIS . VAL +Disables flash functionality completely. +This is a shortcut mechanism used by the software to completely +kill flash in case of emergency. + +Since this register is rw1s instead of rw, to disable, write the value kMuBi4True +to the register to disable the flash. + +## EXEC +Controls whether flash can be used for code execution fetches +- Offset: `0x14` +- Reset default: `0x0` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:-----------------------------------------------------------------------------------------------------------| +| 31:0 | rw | 0x0 | EN | A value of 0xa26a38f7 allows flash to be used for code execution. Any other value prevents code execution. | + +## INIT +Controller init register +- Offset: `0x18` +- Reset default: `0x0` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 1, "attr": ["rw1s"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------| +| 31:1 | | | Reserved | +| 0 | rw1s | 0x0 | [VAL](#init--val) | + +### INIT . VAL +Initializes the flash controller. + +During the initialization process, the flash controller requests the address and data +scramble keys and reads out the root seeds stored in flash before allowing other usage +of the flash controller. + +When the initialization sequence is complete, the flash read buffers are enabled +and turned on. + +## CTRL_REGWEN +Controls the configurability of the [`CONTROL`](#control) register. + +This register ensures the contents of [`CONTROL`](#control) cannot be changed by software once a flash +operation has begun. + +It unlocks whenever the existing flash operation completes, regardless of success or error. +- Offset: `0x1c` +- 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 flash operation is initiated. When the controller completes the flash operation, this bit is set back to 1 to allow software configuration of [`CONTROL`](#control) | + +## CONTROL +Control register +- Offset: `0x20` +- Reset default: `0x0` +- Reset mask: `0xfff07f1` +- Register enable: [`CTRL_REGWEN`](#ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "START", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 3}, {"name": "OP", "bits": 2, "attr": ["rw"], "rotate": 0}, {"name": "PROG_SEL", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_SEL", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "PARTITION_SEL", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "INFO_SEL", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 5}, {"name": "NUM", "bits": 12, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 150}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-----------------------------------------| +| 31:28 | | | Reserved | +| 27:16 | rw | 0x0 | [NUM](#control--num) | +| 15:11 | | | Reserved | +| 10:9 | rw | 0x0 | [INFO_SEL](#control--info_sel) | +| 8 | rw | 0x0 | [PARTITION_SEL](#control--partition_sel) | +| 7 | rw | 0x0 | [ERASE_SEL](#control--erase_sel) | +| 6 | rw | 0x0 | [PROG_SEL](#control--prog_sel) | +| 5:4 | rw | 0x0 | [OP](#control--op) | +| 3:1 | | | Reserved | +| 0 | rw | 0x0 | [START](#control--start) | + +### CONTROL . NUM +One fewer than the number of bus words the flash operation should read or program. +For example, to read 10 words, software should program this field with the value 9. + +### CONTROL . INFO_SEL +Informational partions can have multiple types. + +This field selects the info type to be accessed. + +### CONTROL . PARTITION_SEL +When doing a read, program or page erase operation, selects either info or data partition for operation. +When 0, select data partition - this is the portion of flash that is accessible both by the host and by the controller. +When 1, select info partition - this is the portion of flash that is only accessible by the controller. + +When doing a bank erase operation, selects info partition also for erase. +When 0, bank erase only erases data partition. +When 1, bank erase erases data partition and info partition. + +### CONTROL . ERASE_SEL +Flash erase operation type selection + +| Value | Name | Description | +|:--------|:-----------|:----------------------| +| 0x0 | Page Erase | Erase 1 page of flash | +| 0x1 | Bank Erase | Erase 1 bank of flash | + + +### CONTROL . PROG_SEL +Flash program operation type selection + +| Value | Name | Description | +|:--------|:---------------|:-------------------------------------------------------------------------------------------------------------------| +| 0x0 | Normal program | Normal program operation to the flash | +| 0x1 | Program repair | Repair program operation to the flash. Whether this is actually supported depends on the underlying flash memory. | + + +### CONTROL . OP +Flash operation selection + +| Value | Name | Description | +|:--------|:-------|:--------------------------------------------------------------------| +| 0x0 | Read | Flash Read. Read desired number of flash words | +| 0x1 | Prog | Flash Program. Program desired number of flash words | +| 0x2 | Erase | Flash Erase Operation. See ERASE_SEL for details on erase operation | + +Other values are reserved. + +### CONTROL . START +Start flash transaction. This bit shall only be set at the same time or after the other +fields of the [`CONTROL`](#control) register and [`ADDR`](#addr) have been programmed. + +## ADDR +Address for flash operation +- Offset: `0x24` +- Reset default: `0x0` +- Reset mask: `0xffff` +- Register enable: [`CTRL_REGWEN`](#ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "START", "bits": 16, "attr": ["rw"], "rotate": 0}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:----------------------| +| 31:16 | | | Reserved | +| 15:0 | rw | 0x0 | [START](#addr--start) | + +### ADDR . START +Start address of a flash transaction. This is a byte address relative to the flash +only. Ie, an address of 0 will access address 0 of the requested partition. + +For read operations, the flash controller will truncate to the closest, lower word +aligned address. For example, if 0x13 is supplied, the controller will perform a +read at address 0x10. + +Program operations behave similarly, the controller does not have read modified write +support. + +For page erases, the controller will truncate to the closest lower page aligned +address. Similarly for bank erases, the controller will truncate to the closest +lower bank aligned address. + +## PROG_TYPE_EN +Enable different program types +- Offset: `0x28` +- Reset default: `0x3` +- Reset mask: `0x3` +- Register enable: [`CTRL_REGWEN`](#ctrl_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "NORMAL", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "REPAIR", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:---------------------------| +| 31:2 | | | | Reserved | +| 1 | rw0c | 0x1 | REPAIR | Repair prog type available | +| 0 | rw0c | 0x1 | NORMAL | Normal prog type available | + +## ERASE_SUSPEND +Suspend erase +- Offset: `0x2c` +- Reset default: `0x0` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "REQ", "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 | REQ | When 1, request erase suspend. If no erase ongoing, the request is immediately cleared by hardware If erase ongoing, the request is fed to the flash_phy and cleared when the suspend is handled. | + +## REGION_CFG_REGWEN +Memory region registers configuration enable. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:--------------------|:---------| +| REGION_CFG_REGWEN_0 | 0x30 | +| REGION_CFG_REGWEN_1 | 0x34 | +| REGION_CFG_REGWEN_2 | 0x38 | +| REGION_CFG_REGWEN_3 | 0x3c | +| REGION_CFG_REGWEN_4 | 0x40 | +| REGION_CFG_REGWEN_5 | 0x44 | +| REGION_CFG_REGWEN_6 | 0x48 | +| REGION_CFG_REGWEN_7 | 0x4c | + + +### Fields + +```wavejson +{"reg": [{"name": "REGION", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [REGION](#region_cfg_regwen--region) | + +### REGION_CFG_REGWEN . REGION +Region register write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:---------------|:----------------------------------------------------| +| 0x0 | Region locked | Region can no longer be configured until next reset | +| 0x1 | Region enabled | Region can be configured | + + +## MP_REGION_CFG +Memory property configuration for data partition +- Reset default: `0x9999999` +- Reset mask: `0xfffffff` +- Register enable: [`REGION_CFG_REGWEN`](#region_cfg_regwen) + +### Instances + +| Name | Offset | +|:----------------|:---------| +| MP_REGION_CFG_0 | 0x50 | +| MP_REGION_CFG_1 | 0x54 | +| MP_REGION_CFG_2 | 0x58 | +| MP_REGION_CFG_3 | 0x5c | +| MP_REGION_CFG_4 | 0x60 | +| MP_REGION_CFG_5 | 0x64 | +| MP_REGION_CFG_6 | 0x68 | +| MP_REGION_CFG_7 | 0x6c | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:-------------------------------------------------------------------------------------------------------------------| +| 31:28 | | | | Reserved | +| 27:24 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 23:20 | rw | 0x9 | ECC_EN | Region is integrity checked and reliability ECC enabled. | +| 19:16 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 15:12 | rw | 0x9 | ERASE_EN | Region can be erased | +| 11:8 | rw | 0x9 | PROG_EN | Region can be programmed | +| 7:4 | rw | 0x9 | RD_EN | Region can be read | +| 3:0 | rw | 0x9 | EN | Region enabled, following fields apply. If region is disabled, it is not matched against any incoming transaction. | + +## MP_REGION +Memory base and size configuration for data partition +- Reset default: `0x0` +- Reset mask: `0x7ff` +- Register enable: [`REGION_CFG_REGWEN`](#region_cfg_regwen) + +### Instances + +| Name | Offset | +|:------------|:---------| +| MP_REGION_0 | 0x70 | +| MP_REGION_1 | 0x74 | +| MP_REGION_2 | 0x78 | +| MP_REGION_3 | 0x7c | +| MP_REGION_4 | 0x80 | +| MP_REGION_5 | 0x84 | +| MP_REGION_6 | 0x88 | +| MP_REGION_7 | 0x8c | + + +### Fields + +```wavejson +{"reg": [{"name": "BASE", "bits": 5, "attr": ["rw"], "rotate": 0}, {"name": "SIZE", "bits": 6, "attr": ["rw"], "rotate": 0}, {"bits": 21}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:11 | | | | Reserved | +| 10:5 | rw | 0x0 | SIZE | Region size in number of pages. For example, if base is 0 and size is 1, then the region is defined by page 0. If base is 0 and size is 2, then the region is defined by pages 0 and 1. | +| 4:0 | rw | 0x0 | BASE | Region base page. Note the granularity is page, not byte or word | + +## DEFAULT_REGION +Default region properties +- Offset: `0x90` +- Reset default: `0x999999` +- Reset mask: `0xffffff` + +### Fields + +```wavejson +{"reg": [{"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 8}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------------------------------------| +| 31:24 | | | | Reserved | +| 23:20 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 19:16 | rw | 0x9 | ECC_EN | Region is ECC enabled (both integrity and reliability ECC). | +| 15:12 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 11:8 | rw | 0x9 | ERASE_EN | Region can be erased | +| 7:4 | rw | 0x9 | PROG_EN | Region can be programmed | +| 3:0 | rw | 0x9 | RD_EN | Region can be read | + +## BANK0_INFO0_REGWEN +Memory region registers configuration enable. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:---------------------|:---------| +| BANK0_INFO0_REGWEN_0 | 0x94 | +| BANK0_INFO0_REGWEN_1 | 0x98 | +| BANK0_INFO0_REGWEN_2 | 0x9c | +| BANK0_INFO0_REGWEN_3 | 0xa0 | +| BANK0_INFO0_REGWEN_4 | 0xa4 | +| BANK0_INFO0_REGWEN_5 | 0xa8 | +| BANK0_INFO0_REGWEN_6 | 0xac | +| BANK0_INFO0_REGWEN_7 | 0xb0 | +| BANK0_INFO0_REGWEN_8 | 0xb4 | +| BANK0_INFO0_REGWEN_9 | 0xb8 | + + +### Fields + +```wavejson +{"reg": [{"name": "REGION", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [REGION](#bank0_info0_regwen--region) | + +### BANK0_INFO0_REGWEN . REGION +Info0 page write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:-------------|:----------------------------------------------------| +| 0x0 | Page locked | Region can no longer be configured until next reset | +| 0x1 | Page enabled | Region can be configured | + + +## BANK0_INFO0_PAGE_CFG + Memory property configuration for info partition in bank0, + Unlike data partition, each page is individually configured. +- Reset default: `0x9999999` +- Reset mask: `0xfffffff` +- Register enable: [`BANK0_INFO0_REGWEN`](#bank0_info0_regwen) + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| BANK0_INFO0_PAGE_CFG_0 | 0xbc | +| BANK0_INFO0_PAGE_CFG_1 | 0xc0 | +| BANK0_INFO0_PAGE_CFG_2 | 0xc4 | +| BANK0_INFO0_PAGE_CFG_3 | 0xc8 | +| BANK0_INFO0_PAGE_CFG_4 | 0xcc | +| BANK0_INFO0_PAGE_CFG_5 | 0xd0 | +| BANK0_INFO0_PAGE_CFG_6 | 0xd4 | +| BANK0_INFO0_PAGE_CFG_7 | 0xd8 | +| BANK0_INFO0_PAGE_CFG_8 | 0xdc | +| BANK0_INFO0_PAGE_CFG_9 | 0xe0 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------------------------------------| +| 31:28 | | | | Reserved | +| 27:24 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 23:20 | rw | 0x9 | ECC_EN | Region is ECC enabled (both integrity and reliability ECC). | +| 19:16 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 15:12 | rw | 0x9 | ERASE_EN | Region can be erased | +| 11:8 | rw | 0x9 | PROG_EN | Region can be programmed | +| 7:4 | rw | 0x9 | RD_EN | Region can be read | +| 3:0 | rw | 0x9 | EN | Region enabled, following fields apply | + +## BANK0_INFO1_REGWEN +Memory region registers configuration enable. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:-------------------|:---------| +| BANK0_INFO1_REGWEN | 0xe4 | + + +### Fields + +```wavejson +{"reg": [{"name": "REGION", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [REGION](#bank0_info1_regwen--region) | + +### BANK0_INFO1_REGWEN . REGION +Info1 page write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:-------------|:----------------------------------------------------| +| 0x0 | Page locked | Region can no longer be configured until next reset | +| 0x1 | Page enabled | Region can be configured | + + +## BANK0_INFO1_PAGE_CFG + Memory property configuration for info partition in bank0, + Unlike data partition, each page is individually configured. +- Reset default: `0x9999999` +- Reset mask: `0xfffffff` +- Register enable: [`BANK0_INFO1_REGWEN`](#bank0_info1_regwen) + +### Instances + +| Name | Offset | +|:---------------------|:---------| +| BANK0_INFO1_PAGE_CFG | 0xe8 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------------------------------------| +| 31:28 | | | | Reserved | +| 27:24 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 23:20 | rw | 0x9 | ECC_EN | Region is ECC enabled (both integrity and reliability ECC). | +| 19:16 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 15:12 | rw | 0x9 | ERASE_EN | Region can be erased | +| 11:8 | rw | 0x9 | PROG_EN | Region can be programmed | +| 7:4 | rw | 0x9 | RD_EN | Region can be read | +| 3:0 | rw | 0x9 | EN | Region enabled, following fields apply | + +## BANK0_INFO2_REGWEN +Memory region registers configuration enable. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:---------------------|:---------| +| BANK0_INFO2_REGWEN_0 | 0xec | +| BANK0_INFO2_REGWEN_1 | 0xf0 | + + +### Fields + +```wavejson +{"reg": [{"name": "REGION", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [REGION](#bank0_info2_regwen--region) | + +### BANK0_INFO2_REGWEN . REGION +Info2 page write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:-------------|:----------------------------------------------------| +| 0x0 | Page locked | Region can no longer be configured until next reset | +| 0x1 | Page enabled | Region can be configured | + + +## BANK0_INFO2_PAGE_CFG + Memory property configuration for info partition in bank0, + Unlike data partition, each page is individually configured. +- Reset default: `0x9999999` +- Reset mask: `0xfffffff` +- Register enable: [`BANK0_INFO2_REGWEN`](#bank0_info2_regwen) + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| BANK0_INFO2_PAGE_CFG_0 | 0xf4 | +| BANK0_INFO2_PAGE_CFG_1 | 0xf8 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------------------------------------| +| 31:28 | | | | Reserved | +| 27:24 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 23:20 | rw | 0x9 | ECC_EN | Region is ECC enabled (both integrity and reliability ECC). | +| 19:16 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 15:12 | rw | 0x9 | ERASE_EN | Region can be erased | +| 11:8 | rw | 0x9 | PROG_EN | Region can be programmed | +| 7:4 | rw | 0x9 | RD_EN | Region can be read | +| 3:0 | rw | 0x9 | EN | Region enabled, following fields apply | + +## BANK1_INFO0_REGWEN +Memory region registers configuration enable. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:---------------------|:---------| +| BANK1_INFO0_REGWEN_0 | 0xfc | +| BANK1_INFO0_REGWEN_1 | 0x100 | +| BANK1_INFO0_REGWEN_2 | 0x104 | +| BANK1_INFO0_REGWEN_3 | 0x108 | +| BANK1_INFO0_REGWEN_4 | 0x10c | +| BANK1_INFO0_REGWEN_5 | 0x110 | +| BANK1_INFO0_REGWEN_6 | 0x114 | +| BANK1_INFO0_REGWEN_7 | 0x118 | +| BANK1_INFO0_REGWEN_8 | 0x11c | +| BANK1_INFO0_REGWEN_9 | 0x120 | + + +### Fields + +```wavejson +{"reg": [{"name": "REGION", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [REGION](#bank1_info0_regwen--region) | + +### BANK1_INFO0_REGWEN . REGION +Info0 page write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:-------------|:----------------------------------------------------| +| 0x0 | Page locked | Region can no longer be configured until next reset | +| 0x1 | Page enabled | Region can be configured | + + +## BANK1_INFO0_PAGE_CFG + Memory property configuration for info partition in bank1, + Unlike data partition, each page is individually configured. +- Reset default: `0x9999999` +- Reset mask: `0xfffffff` +- Register enable: [`BANK1_INFO0_REGWEN`](#bank1_info0_regwen) + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| BANK1_INFO0_PAGE_CFG_0 | 0x124 | +| BANK1_INFO0_PAGE_CFG_1 | 0x128 | +| BANK1_INFO0_PAGE_CFG_2 | 0x12c | +| BANK1_INFO0_PAGE_CFG_3 | 0x130 | +| BANK1_INFO0_PAGE_CFG_4 | 0x134 | +| BANK1_INFO0_PAGE_CFG_5 | 0x138 | +| BANK1_INFO0_PAGE_CFG_6 | 0x13c | +| BANK1_INFO0_PAGE_CFG_7 | 0x140 | +| BANK1_INFO0_PAGE_CFG_8 | 0x144 | +| BANK1_INFO0_PAGE_CFG_9 | 0x148 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------------------------------------| +| 31:28 | | | | Reserved | +| 27:24 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 23:20 | rw | 0x9 | ECC_EN | Region is ECC enabled (both integrity and reliability ECC). | +| 19:16 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 15:12 | rw | 0x9 | ERASE_EN | Region can be erased | +| 11:8 | rw | 0x9 | PROG_EN | Region can be programmed | +| 7:4 | rw | 0x9 | RD_EN | Region can be read | +| 3:0 | rw | 0x9 | EN | Region enabled, following fields apply | + +## BANK1_INFO1_REGWEN +Memory region registers configuration enable. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:-------------------|:---------| +| BANK1_INFO1_REGWEN | 0x14c | + + +### Fields + +```wavejson +{"reg": [{"name": "REGION", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [REGION](#bank1_info1_regwen--region) | + +### BANK1_INFO1_REGWEN . REGION +Info1 page write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:-------------|:----------------------------------------------------| +| 0x0 | Page locked | Region can no longer be configured until next reset | +| 0x1 | Page enabled | Region can be configured | + + +## BANK1_INFO1_PAGE_CFG + Memory property configuration for info partition in bank1, + Unlike data partition, each page is individually configured. +- Reset default: `0x9999999` +- Reset mask: `0xfffffff` +- Register enable: [`BANK1_INFO1_REGWEN`](#bank1_info1_regwen) + +### Instances + +| Name | Offset | +|:---------------------|:---------| +| BANK1_INFO1_PAGE_CFG | 0x150 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------------------------------------| +| 31:28 | | | | Reserved | +| 27:24 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 23:20 | rw | 0x9 | ECC_EN | Region is ECC enabled (both integrity and reliability ECC). | +| 19:16 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 15:12 | rw | 0x9 | ERASE_EN | Region can be erased | +| 11:8 | rw | 0x9 | PROG_EN | Region can be programmed | +| 7:4 | rw | 0x9 | RD_EN | Region can be read | +| 3:0 | rw | 0x9 | EN | Region enabled, following fields apply | + +## BANK1_INFO2_REGWEN +Memory region registers configuration enable. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:---------------------|:---------| +| BANK1_INFO2_REGWEN_0 | 0x154 | +| BANK1_INFO2_REGWEN_1 | 0x158 | + + +### Fields + +```wavejson +{"reg": [{"name": "REGION", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [REGION](#bank1_info2_regwen--region) | + +### BANK1_INFO2_REGWEN . REGION +Info2 page write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:-------------|:----------------------------------------------------| +| 0x0 | Page locked | Region can no longer be configured until next reset | +| 0x1 | Page enabled | Region can be configured | + + +## BANK1_INFO2_PAGE_CFG + Memory property configuration for info partition in bank1, + Unlike data partition, each page is individually configured. +- Reset default: `0x9999999` +- Reset mask: `0xfffffff` +- Register enable: [`BANK1_INFO2_REGWEN`](#bank1_info2_regwen) + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| BANK1_INFO2_PAGE_CFG_0 | 0x15c | +| BANK1_INFO2_PAGE_CFG_1 | 0x160 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "RD_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "PROG_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "SCRAMBLE_EN", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "HE_EN", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------------------------------------| +| 31:28 | | | | Reserved | +| 27:24 | rw | 0x9 | HE_EN | Region is high endurance enabled. | +| 23:20 | rw | 0x9 | ECC_EN | Region is ECC enabled (both integrity and reliability ECC). | +| 19:16 | rw | 0x9 | SCRAMBLE_EN | Region is scramble enabled. | +| 15:12 | rw | 0x9 | ERASE_EN | Region can be erased | +| 11:8 | rw | 0x9 | PROG_EN | Region can be programmed | +| 7:4 | rw | 0x9 | RD_EN | Region can be read | +| 3:0 | rw | 0x9 | EN | Region enabled, following fields apply | + +## HW_INFO_CFG_OVERRIDE +HW interface info configuration rule overrides +- Offset: `0x164` +- Reset default: `0x99` +- Reset mask: `0xff` + +### Fields + +```wavejson +{"reg": [{"name": "SCRAMBLE_DIS", "bits": 4, "attr": ["rw"], "rotate": -90}, {"name": "ECC_DIS", "bits": 4, "attr": ["rw"], "rotate": -90}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 140}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:8 | | | | Reserved | +| 7:4 | rw | 0x9 | ECC_DIS | The hardwired hardware info configuration rules for ECC enable are logically AND'd with this field. If the hardware rules hardwires ECC to enable, we can disable via software if needed. By default this field is false. | +| 3:0 | rw | 0x9 | SCRAMBLE_DIS | The hardwired hardware info configuration rules for scramble enable are logically AND'd with this field. If the hardware rules hardwires scramble to enable, we can disable via software if needed. By default this field is false. | + +## BANK_CFG_REGWEN +Bank configuration registers configuration enable. +- Offset: `0x168` +- Reset default: `0x1` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "BANK", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [BANK](#bank_cfg_regwen--bank) | + +### BANK_CFG_REGWEN . BANK +Bank register write enable. Once set to 0, it can longer be configured to 1 + +| Value | Name | Description | +|:--------|:-------------|:--------------------------------------------------| +| 0x0 | Bank locked | Bank can no longer be configured until next reset | +| 0x1 | Bank enabled | Bank can be configured | + + +## MP_BANK_CFG_SHADOWED +Memory properties bank configuration +- Offset: `0x16c` +- Reset default: `0x0` +- Reset mask: `0x3` +- Register enable: [`BANK_CFG_REGWEN`](#bank_cfg_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "ERASE_EN_0", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "ERASE_EN_1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-----------|:-----------------------| +| 31:2 | | | | Reserved | +| 1 | rw | 0x0 | ERASE_EN_1 | Bank wide erase enable | +| 0 | rw | 0x0 | ERASE_EN_0 | Bank wide erase enable | + +## OP_STATUS +Flash Operation Status +- Offset: `0x170` +- Reset default: `0x0` +- Reset mask: `0x3` + +### Fields + +```wavejson +{"reg": [{"name": "done", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "err", "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 | err | Flash operation error. Set by HW, cleared by SW. See [`ERR_CODE`](#err_code) for more details. | +| 0 | rw | 0x0 | done | Flash operation done. Set by HW, cleared by SW | + +## STATUS +Flash Controller Status +- Offset: `0x174` +- Reset default: `0xa` +- Reset mask: `0x3f` + +### Fields + +```wavejson +{"reg": [{"name": "rd_full", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "rd_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_full", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_empty", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "init_wip", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "initialized", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 130}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:--------------------------------------------------------| +| 31:6 | | | | Reserved | +| 5 | ro | 0x0 | initialized | Flash controller initialized | +| 4 | ro | 0x0 | init_wip | Flash controller undergoing init, inclusive of phy init | +| 3 | ro | 0x1 | prog_empty | Flash program FIFO empty, software must provide data | +| 2 | ro | 0x0 | prog_full | Flash program FIFO full | +| 1 | ro | 0x1 | rd_empty | Flash read FIFO empty | +| 0 | ro | 0x0 | rd_full | Flash read FIFO full, software must consume data | + +## DEBUG_STATE +Current flash fsm state +- Offset: `0x178` +- Reset default: `0x0` +- Reset mask: `0x7ff` + +### Fields + +```wavejson +{"reg": [{"name": "lcmgr_state", "bits": 11, "attr": ["ro"], "rotate": 0}, {"bits": 21}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------|:------------------------------| +| 31:11 | | | | Reserved | +| 10:0 | ro | x | lcmgr_state | Current lcmgr interface staet | + +## ERR_CODE +Flash error code register. +This register tabulates detailed error status of the flash. +This is separate from [`OP_STATUS`](#op_status), which is used to indicate the current state of the software initiated +flash operation. + +Note, all errors in this register are considered recoverable errors, ie, errors that could have been +generated by software. +- Offset: `0x17c` +- Reset default: `0x0` +- Reset mask: `0xff` + +### Fields + +```wavejson +{"reg": [{"name": "op_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "mp_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "rd_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "prog_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "prog_win_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "prog_type_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "update_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "macro_err", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 150}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:--------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:8 | | | | Reserved | +| 7 | rw1c | 0x0 | macro_err | A recoverable error has been encountered in the flash macro. Please read the flash macro status registers for more details. | +| 6 | rw1c | 0x0 | update_err | A shadow register encountered an update error. This is an asynchronous error. | +| 5 | rw1c | 0x0 | prog_type_err | Flash program selected unavailable type, see [`PROG_TYPE_EN.`](#prog_type_en) This is a synchronous error. | +| 4 | rw1c | 0x0 | prog_win_err | Flash program has a window resolution error. Ie, the start of program and end of program are in different windows. Please check [`ERR_ADDR.`](#err_addr) This is a synchronous error. | +| 3 | rw1c | 0x0 | prog_err | Flash program has an error. This could be a program integrity error, see [`STD_FAULT_STATUS.`](#std_fault_status) This is a synchronous error. | +| 2 | rw1c | 0x0 | rd_err | Flash read has an error. This could be a reliability ECC error or an storage integrity error encountered during a software issued controller read, see [`STD_FAULT_STATUS.`](#std_fault_status) See [`ERR_ADDR`](#err_addr) for exact address. This is a synchronous error. | +| 1 | rw1c | 0x0 | mp_err | Flash access has encountered an access permission error. Please see [`ERR_ADDR`](#err_addr) for exact address. This is a synchronous error. | +| 0 | rw1c | 0x0 | op_err | Software has supplied an undefined operation. See [`CONTROL.OP`](#control) for list of valid operations. | + +## STD_FAULT_STATUS +This register tabulates standard fault status of the flash. + +These represent errors that occur in the standard structures of the design. +For example fsm integrity, counter integrity and tlul integrity. +- Offset: `0x180` +- Reset default: `0x0` +- Reset mask: `0x1ff` + +### Fields + +```wavejson +{"reg": [{"name": "reg_intg_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_intg_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "lcmgr_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "lcmgr_intg_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "arb_fsm_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "storage_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "phy_fsm_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "ctrl_cnt_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "fifo_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 160}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:---------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:9 | | | | Reserved | +| 8 | ro | 0x0 | fifo_err | Flash primitive fifo's have encountered a count error. | +| 7 | ro | 0x0 | ctrl_cnt_err | Flash ctrl read/prog has encountered a count error. | +| 6 | ro | 0x0 | phy_fsm_err | A flash phy fsm has encountered a sparse encoding error. | +| 5 | ro | 0x0 | storage_err | A shadow register encountered a storage error. | +| 4 | ro | 0x0 | arb_fsm_err | The arbiter fsm has encountered a sparse encoding error. | +| 3 | ro | 0x0 | lcmgr_intg_err | The life cycle management interface has encountered a transmission integrity error. This is an integrity error on the generated integrity during a life cycle management interface read. | +| 2 | ro | 0x0 | lcmgr_err | The life cycle management interface has encountered a fatal error. The error is either an FSM sparse encoding error or a count error. | +| 1 | ro | 0x0 | prog_intg_err | The flash controller encountered a program data transmission integrity error. | +| 0 | ro | 0x0 | reg_intg_err | The flash controller encountered a register integrity error. | + +## FAULT_STATUS +This register tabulates customized fault status of the flash. + +These are errors that are impossible to have been caused by software or unrecoverable in nature. + +All errors except for multi-bit ECC errors ([`FAULT_STATUS.PHY_RELBL_ERR`](#fault_status)) and ICV ([`FAULT_STATUS.PHY_STORAGE_ERR`](#fault_status)) trigger a fatal alert. +Once set, they remain set until reset. +- Offset: `0x184` +- Reset default: `0x0` +- Reset mask: `0xfff` + +### Fields + +```wavejson +{"reg": [{"name": "op_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "mp_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "rd_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_win_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_type_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "seed_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "phy_relbl_err", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "phy_storage_err", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "spurious_ack", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "arb_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "host_gnt_err", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 20}], "config": {"lanes": 1, "fontsize": 10, "vspace": 170}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------------------------| +| 31:12 | | | Reserved | +| 11 | ro | 0x0 | [host_gnt_err](#fault_status--host_gnt_err) | +| 10 | ro | 0x0 | [arb_err](#fault_status--arb_err) | +| 9 | ro | 0x0 | [spurious_ack](#fault_status--spurious_ack) | +| 8 | rw0c | 0x0 | [phy_storage_err](#fault_status--phy_storage_err) | +| 7 | rw0c | 0x0 | [phy_relbl_err](#fault_status--phy_relbl_err) | +| 6 | ro | 0x0 | [seed_err](#fault_status--seed_err) | +| 5 | ro | 0x0 | [prog_type_err](#fault_status--prog_type_err) | +| 4 | ro | 0x0 | [prog_win_err](#fault_status--prog_win_err) | +| 3 | ro | 0x0 | [prog_err](#fault_status--prog_err) | +| 2 | ro | 0x0 | [rd_err](#fault_status--rd_err) | +| 1 | ro | 0x0 | [mp_err](#fault_status--mp_err) | +| 0 | ro | 0x0 | [op_err](#fault_status--op_err) | + +### FAULT_STATUS . host_gnt_err +A host transaction was granted with illegal properties. + +### FAULT_STATUS . arb_err +The phy arbiter encountered inconsistent results. + +### FAULT_STATUS . spurious_ack +The flash emitted an unexpected acknowledgement. + +### FAULT_STATUS . phy_storage_err +The flash macro encountered a storage integrity ECC error. + +Note that this error bit can be cleared to allow firmware dealing with ICV errors during firmware selection and verification. +After passing this stage, it is recommended that firmware classifies the corresponding alert as fatal on the receiver end, i.e, inside the alert handler. + +### FAULT_STATUS . phy_relbl_err +The flash macro encountered a storage reliability ECC error. + +Note that this error bit can be cleared to allow firmware dealing with multi-bit ECC errors during firmware selection and verification. +After passing this stage, it is recommended that firmware classifies the corresponding alert as fatal on the receiver end, i.e, inside the alert handler. + +### FAULT_STATUS . seed_err +The seed reading process encountered an unexpected error. + +### FAULT_STATUS . prog_type_err +The flash life cycle management interface encountered a program type error. +A program type not supported by the flash macro was issued. + +### FAULT_STATUS . prog_win_err +The flash life cycle management interface encountered a program resolution error. + +### FAULT_STATUS . prog_err +The flash life cycle management interface encountered a program error. +This could be a program integirty eror, see [`STD_FAULT_STATUS`](#std_fault_status) for more details. + +### FAULT_STATUS . rd_err +The flash life cycle management interface encountered a read error. +This could be a reliability ECC error or an integrity ECC error +encountered during a read, see [`STD_FAULT_STATUS`](#std_fault_status) for more details. + +### FAULT_STATUS . mp_err +The flash life cycle management interface encountered a memory permission error. + +### FAULT_STATUS . op_err +The flash life cycle management interface has supplied an undefined operation. +See [`CONTROL.OP`](#control) for list of valid operations. + +## ERR_ADDR +Synchronous error address +- Offset: `0x188` +- Reset default: `0x0` +- Reset mask: `0xffff` + +### Fields + +```wavejson +{"reg": [{"name": "ERR_ADDR", "bits": 16, "attr": ["ro"], "rotate": 0}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:---------|:--------------| +| 31:16 | | | | Reserved | +| 15:0 | ro | 0x0 | ERR_ADDR | | + +## ECC_SINGLE_ERR_CNT +Total number of single bit ECC error count +- Offset: `0x18c` +- Reset default: `0x0` +- Reset mask: `0xffff` + +### Fields + +```wavejson +{"reg": [{"name": "ECC_SINGLE_ERR_CNT_0", "bits": 8, "attr": ["rw"], "rotate": -90}, {"name": "ECC_SINGLE_ERR_CNT_1", "bits": 8, "attr": ["rw"], "rotate": -90}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 220}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:---------------------|:----------------------------------------| +| 31:16 | | | | Reserved | +| 15:8 | rw | 0x0 | ECC_SINGLE_ERR_CNT_1 | This count will not wrap when saturated | +| 7:0 | rw | 0x0 | ECC_SINGLE_ERR_CNT_0 | This count will not wrap when saturated | + +## ECC_SINGLE_ERR_ADDR +Latest address of ECC single err +- Reset default: `0x0` +- Reset mask: `0xffff` + +### Instances + +| Name | Offset | +|:----------------------|:---------| +| ECC_SINGLE_ERR_ADDR_0 | 0x190 | +| ECC_SINGLE_ERR_ADDR_1 | 0x194 | + + +### Fields + +```wavejson +{"reg": [{"name": "ECC_SINGLE_ERR_ADDR", "bits": 16, "attr": ["ro"], "rotate": 0}, {"bits": 16}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:--------------------|:------------------------------------------| +| 31:16 | | | | Reserved | +| 15:0 | ro | 0x0 | ECC_SINGLE_ERR_ADDR | Latest single error address for this bank | + +## PHY_ALERT_CFG +Phy alert configuration +- Offset: `0x198` +- Reset default: `0x0` +- Reset mask: `0x3` + +### Fields + +```wavejson +{"reg": [{"name": "alert_ack", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "alert_trig", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 120}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-----------|:----------------------------| +| 31:2 | | | | Reserved | +| 1 | rw | 0x0 | alert_trig | Trigger flash phy alert | +| 0 | rw | 0x0 | alert_ack | Acknowledge flash phy alert | + +## PHY_STATUS +Flash Phy Status +- Offset: `0x19c` +- Reset default: `0x6` +- Reset mask: `0x7` + +### Fields + +```wavejson +{"reg": [{"name": "init_wip", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_normal_avail", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "prog_repair_avail", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 190}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------------|:----------------------------------| +| 31:3 | | | | Reserved | +| 2 | ro | 0x1 | prog_repair_avail | Program repair supported | +| 1 | ro | 0x1 | prog_normal_avail | Normal program supported | +| 0 | ro | 0x0 | init_wip | Flash phy controller initializing | + +## Scratch +Flash Controller Scratch +- Offset: `0x1a0` +- Reset default: `0x0` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "data", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------| +| 31:0 | rw | 0x0 | data | Flash ctrl scratch register | + +## FIFO_LVL +Programmable depth where FIFOs should generate interrupts +- Offset: `0x1a4` +- Reset default: `0xf0f` +- Reset mask: `0x1f1f` + +### Fields + +```wavejson +{"reg": [{"name": "PROG", "bits": 5, "attr": ["rw"], "rotate": 0}, {"bits": 3}, {"name": "RD", "bits": 5, "attr": ["rw"], "rotate": 0}, {"bits": 19}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------------------------------------------------------------------------------------------------------------------------------| +| 31:13 | | | | Reserved | +| 12:8 | rw | 0xf | RD | When the read FIFO fills to this level, trigger an interrupt. Default value is set such that interrupt does not trigger at reset. | +| 7:5 | | | | Reserved | +| 4:0 | rw | 0xf | PROG | When the program FIFO drains to this level, trigger an interrupt. Default value is set such that interrupt does not trigger at reset. | + +## FIFO_RST +Reset for flash controller FIFOs +- Offset: `0x1a8` +- Reset default: `0x0` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "EN", "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 | EN | Active high resets for both program and read FIFOs. This is especially useful after the controller encounters an error of some kind. This bit will hold the FIFO in reset as long as it is set. | + +## CURR_FIFO_LVL +Current program and read fifo depth +- Offset: `0x1ac` +- Reset default: `0x0` +- Reset mask: `0x1f1f` + +### Fields + +```wavejson +{"reg": [{"name": "PROG", "bits": 5, "attr": ["ro"], "rotate": 0}, {"bits": 3}, {"name": "RD", "bits": 5, "attr": ["ro"], "rotate": 0}, {"bits": 19}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:---------------------------| +| 31:13 | | | | Reserved | +| 12:8 | ro | 0x0 | RD | Current read fifo depth | +| 7:5 | | | | Reserved | +| 4:0 | ro | 0x0 | PROG | Current program fifo depth | + +## prog_fifo +Flash program FIFO. + +The FIFO is 16 entries of 4B flash words. This FIFO can only be programmed +by software after a program operation has been initiated via the !!CONTROL register. +This ensures accidental programming of the program FIFO cannot lock up the system. + +- Word Aligned Offset Range: `0x1b0`to`0x1b0` +- Size (words): `1` +- Access: `wo` +- Byte writes are *not* supported. + +## rd_fifo +Flash read FIFO. + +The FIFO is 16 entries of 4B flash words + +- Word Aligned Offset Range: `0x1b4`to`0x1b4` +- Size (words): `1` +- Access: `ro` +- Byte writes are *not* supported. + +## Summary of the **`prim`** interface's registers + +| Name | Offset | Length | Description | +|:-----------------------------------------|:---------|---------:|:--------------| +| flash_ctrl.[`CSR0_REGWEN`](#csr0_regwen) | 0x0 | 4 | | +| flash_ctrl.[`CSR1`](#csr1) | 0x4 | 4 | | +| flash_ctrl.[`CSR2`](#csr2) | 0x8 | 4 | | +| flash_ctrl.[`CSR3`](#csr3) | 0xc | 4 | | +| flash_ctrl.[`CSR4`](#csr4) | 0x10 | 4 | | +| flash_ctrl.[`CSR5`](#csr5) | 0x14 | 4 | | +| flash_ctrl.[`CSR6`](#csr6) | 0x18 | 4 | | +| flash_ctrl.[`CSR7`](#csr7) | 0x1c | 4 | | +| flash_ctrl.[`CSR8`](#csr8) | 0x20 | 4 | | +| flash_ctrl.[`CSR9`](#csr9) | 0x24 | 4 | | +| flash_ctrl.[`CSR10`](#csr10) | 0x28 | 4 | | +| flash_ctrl.[`CSR11`](#csr11) | 0x2c | 4 | | +| flash_ctrl.[`CSR12`](#csr12) | 0x30 | 4 | | +| flash_ctrl.[`CSR13`](#csr13) | 0x34 | 4 | | +| flash_ctrl.[`CSR14`](#csr14) | 0x38 | 4 | | +| flash_ctrl.[`CSR15`](#csr15) | 0x3c | 4 | | +| flash_ctrl.[`CSR16`](#csr16) | 0x40 | 4 | | +| flash_ctrl.[`CSR17`](#csr17) | 0x44 | 4 | | +| flash_ctrl.[`CSR18`](#csr18) | 0x48 | 4 | | +| flash_ctrl.[`CSR19`](#csr19) | 0x4c | 4 | | +| flash_ctrl.[`CSR20`](#csr20) | 0x50 | 4 | | + +## CSR0_REGWEN + +- Offset: `0x0` +- Reset default: `0x1` +- Reset mask: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 31}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------------| +| 31:1 | | | Reserved | +| 0 | rw0c | 0x1 | [field0](#csr0_regwen--field0) | + +### CSR0_REGWEN . field0 + +All values are reserved. + +## CSR1 + +- Offset: `0x4` +- Reset default: `0x0` +- Reset mask: `0x1fff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 5, "attr": ["rw"], "rotate": 0}, {"bits": 19}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:13 | | | Reserved | +| 12:8 | rw | 0x0 | [field1](#csr1--field1) | +| 7:0 | rw | 0x0 | [field0](#csr1--field0) | + +### CSR1 . field1 + +All values are reserved. + +### CSR1 . field0 + +All values are reserved. + +## CSR2 + +- Offset: `0x8` +- Reset default: `0x0` +- Reset mask: `0xff` + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field1", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field2", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field3", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field4", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field5", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field6", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field7", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:8 | | | Reserved | +| 7 | rw | 0x0 | [field7](#csr2--field7) | +| 6 | rw1c | 0x0 | [field6](#csr2--field6) | +| 5 | rw1c | 0x0 | [field5](#csr2--field5) | +| 4 | rw1c | 0x0 | [field4](#csr2--field4) | +| 3 | rw | 0x0 | [field3](#csr2--field3) | +| 2 | rw1c | 0x0 | [field2](#csr2--field2) | +| 1 | rw1c | 0x0 | [field1](#csr2--field1) | +| 0 | rw1c | 0x0 | [field0](#csr2--field0) | + +### CSR2 . field7 + +All values are reserved. + +### CSR2 . field6 + +All values are reserved. + +### CSR2 . field5 + +All values are reserved. + +### CSR2 . field4 + +All values are reserved. + +### CSR2 . field3 + +All values are reserved. + +### CSR2 . field2 + +All values are reserved. + +### CSR2 . field1 + +All values are reserved. + +### CSR2 . field0 + +All values are reserved. + +## CSR3 + +- Offset: `0xc` +- Reset default: `0x0` +- Reset mask: `0xfffffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 4, "attr": ["rw"], "rotate": 0}, {"name": "field2", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field3", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field4", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field5", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field6", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field7", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field8", "bits": 2, "attr": ["rw"], "rotate": -90}, {"name": "field9", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 4}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:28 | | | Reserved | +| 27:26 | rw | 0x0 | [field9](#csr3--field9) | +| 25:24 | rw | 0x0 | [field8](#csr3--field8) | +| 23:21 | rw | 0x0 | [field7](#csr3--field7) | +| 20 | rw | 0x0 | [field6](#csr3--field6) | +| 19:17 | rw | 0x0 | [field5](#csr3--field5) | +| 16:14 | rw | 0x0 | [field4](#csr3--field4) | +| 13:11 | rw | 0x0 | [field3](#csr3--field3) | +| 10:8 | rw | 0x0 | [field2](#csr3--field2) | +| 7:4 | rw | 0x0 | [field1](#csr3--field1) | +| 3:0 | rw | 0x0 | [field0](#csr3--field0) | + +### CSR3 . field9 + +All values are reserved. + +### CSR3 . field8 + +All values are reserved. + +### CSR3 . field7 + +All values are reserved. + +### CSR3 . field6 + +All values are reserved. + +### CSR3 . field5 + +All values are reserved. + +### CSR3 . field4 + +All values are reserved. + +### CSR3 . field3 + +All values are reserved. + +### CSR3 . field2 + +All values are reserved. + +### CSR3 . field1 + +All values are reserved. + +### CSR3 . field0 + +All values are reserved. + +## CSR4 + +- Offset: `0x10` +- Reset default: `0x0` +- Reset mask: `0xfff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field1", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field3", "bits": 3, "attr": ["rw"], "rotate": -90}, {"bits": 20}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:12 | | | Reserved | +| 11:9 | rw | 0x0 | [field3](#csr4--field3) | +| 8:6 | rw | 0x0 | [field2](#csr4--field2) | +| 5:3 | rw | 0x0 | [field1](#csr4--field1) | +| 2:0 | rw | 0x0 | [field0](#csr4--field0) | + +### CSR4 . field3 + +All values are reserved. + +### CSR4 . field2 + +All values are reserved. + +### CSR4 . field1 + +All values are reserved. + +### CSR4 . field0 + +All values are reserved. + +## CSR5 + +- Offset: `0x14` +- Reset default: `0x0` +- Reset mask: `0x7fffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field1", "bits": 2, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 9, "attr": ["rw"], "rotate": 0}, {"name": "field3", "bits": 5, "attr": ["rw"], "rotate": 0}, {"name": "field4", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 9}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:23 | | | Reserved | +| 22:19 | rw | 0x0 | [field4](#csr5--field4) | +| 18:14 | rw | 0x0 | [field3](#csr5--field3) | +| 13:5 | rw | 0x0 | [field2](#csr5--field2) | +| 4:3 | rw | 0x0 | [field1](#csr5--field1) | +| 2:0 | rw | 0x0 | [field0](#csr5--field0) | + +### CSR5 . field4 + +All values are reserved. + +### CSR5 . field3 + +All values are reserved. + +### CSR5 . field2 + +All values are reserved. + +### CSR5 . field1 + +All values are reserved. + +### CSR5 . field0 + +All values are reserved. + +## CSR6 + +- Offset: `0x18` +- Reset default: `0x0` +- Reset mask: `0x1ffffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field1", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field2", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "field3", "bits": 3, "attr": ["rw"], "rotate": -90}, {"name": "field4", "bits": 2, "attr": ["rw"], "rotate": -90}, {"name": "field5", "bits": 2, "attr": ["rw"], "rotate": -90}, {"name": "field6", "bits": 2, "attr": ["rw"], "rotate": -90}, {"name": "field7", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "field8", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 7}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:25 | | | Reserved | +| 24 | rw | 0x0 | [field8](#csr6--field8) | +| 23 | rw | 0x0 | [field7](#csr6--field7) | +| 22:21 | rw | 0x0 | [field6](#csr6--field6) | +| 20:19 | rw | 0x0 | [field5](#csr6--field5) | +| 18:17 | rw | 0x0 | [field4](#csr6--field4) | +| 16:14 | rw | 0x0 | [field3](#csr6--field3) | +| 13:6 | rw | 0x0 | [field2](#csr6--field2) | +| 5:3 | rw | 0x0 | [field1](#csr6--field1) | +| 2:0 | rw | 0x0 | [field0](#csr6--field0) | + +### CSR6 . field8 + +All values are reserved. + +### CSR6 . field7 + +All values are reserved. + +### CSR6 . field6 + +All values are reserved. + +### CSR6 . field5 + +All values are reserved. + +### CSR6 . field4 + +All values are reserved. + +### CSR6 . field3 + +All values are reserved. + +### CSR6 . field2 + +All values are reserved. + +### CSR6 . field1 + +All values are reserved. + +### CSR6 . field0 + +All values are reserved. + +## CSR7 + +- Offset: `0x1c` +- Reset default: `0x0` +- Reset mask: `0x1ffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 9, "attr": ["rw"], "rotate": 0}, {"bits": 15}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:17 | | | Reserved | +| 16:8 | rw | 0x0 | [field1](#csr7--field1) | +| 7:0 | rw | 0x0 | [field0](#csr7--field0) | + +### CSR7 . field1 + +All values are reserved. + +### CSR7 . field0 + +All values are reserved. + +## CSR8 + +- Offset: `0x20` +- Reset default: `0x0` +- Reset mask: `0xffffffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:0 | rw | 0x0 | [field0](#csr8--field0) | + +### CSR8 . field0 + +All values are reserved. + +## CSR9 + +- Offset: `0x24` +- Reset default: `0x0` +- Reset mask: `0xffffffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------| +| 31:0 | rw | 0x0 | [field0](#csr9--field0) | + +### CSR9 . field0 + +All values are reserved. + +## CSR10 + +- Offset: `0x28` +- Reset default: `0x0` +- Reset mask: `0xffffffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:0 | rw | 0x0 | [field0](#csr10--field0) | + +### CSR10 . field0 + +All values are reserved. + +## CSR11 + +- Offset: `0x2c` +- Reset default: `0x0` +- Reset mask: `0xffffffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 32, "attr": ["rw"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:0 | rw | 0x0 | [field0](#csr11--field0) | + +### CSR11 . field0 + +All values are reserved. + +## CSR12 + +- Offset: `0x30` +- Reset default: `0x0` +- Reset mask: `0x3ff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 10, "attr": ["rw"], "rotate": 0}, {"bits": 22}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:10 | | | Reserved | +| 9:0 | rw | 0x0 | [field0](#csr12--field0) | + +### CSR12 . field0 + +All values are reserved. + +## CSR13 + +- Offset: `0x34` +- Reset default: `0x0` +- Reset mask: `0x1fffff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 20, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 11}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:21 | | | Reserved | +| 20 | rw | 0x0 | [field1](#csr13--field1) | +| 19:0 | rw | 0x0 | [field0](#csr13--field0) | + +### CSR13 . field1 + +All values are reserved. + +### CSR13 . field0 + +All values are reserved. + +## CSR14 + +- Offset: `0x38` +- Reset default: `0x0` +- Reset mask: `0x1ff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:9 | | | Reserved | +| 8 | rw | 0x0 | [field1](#csr14--field1) | +| 7:0 | rw | 0x0 | [field0](#csr14--field0) | + +### CSR14 . field1 + +All values are reserved. + +### CSR14 . field0 + +All values are reserved. + +## CSR15 + +- Offset: `0x3c` +- Reset default: `0x0` +- Reset mask: `0x1ff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:9 | | | Reserved | +| 8 | rw | 0x0 | [field1](#csr15--field1) | +| 7:0 | rw | 0x0 | [field0](#csr15--field0) | + +### CSR15 . field1 + +All values are reserved. + +### CSR15 . field0 + +All values are reserved. + +## CSR16 + +- Offset: `0x40` +- Reset default: `0x0` +- Reset mask: `0x1ff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:9 | | | Reserved | +| 8 | rw | 0x0 | [field1](#csr16--field1) | +| 7:0 | rw | 0x0 | [field0](#csr16--field0) | + +### CSR16 . field1 + +All values are reserved. + +### CSR16 . field0 + +All values are reserved. + +## CSR17 + +- Offset: `0x44` +- Reset default: `0x0` +- Reset mask: `0x1ff` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 8, "attr": ["rw"], "rotate": 0}, {"name": "field1", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 23}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:9 | | | Reserved | +| 8 | rw | 0x0 | [field1](#csr17--field1) | +| 7:0 | rw | 0x0 | [field0](#csr17--field0) | + +### CSR17 . field1 + +All values are reserved. + +### CSR17 . field0 + +All values are reserved. + +## CSR18 + +- Offset: `0x48` +- Reset default: `0x0` +- Reset mask: `0x1` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "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 | [field0](#csr18--field0) | + +### CSR18 . field0 + +All values are reserved. + +## CSR19 + +- Offset: `0x4c` +- Reset default: `0x0` +- Reset mask: `0x1` +- Register enable: [`CSR0_REGWEN`](#csr0_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "field0", "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 | [field0](#csr19--field0) | + +### CSR19 . field0 + +All values are reserved. + +## CSR20 + +- Offset: `0x50` +- Reset default: `0x0` +- Reset mask: `0x7` + +### Fields + +```wavejson +{"reg": [{"name": "field0", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field1", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "field2", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-------------------------| +| 31:3 | | | Reserved | +| 2 | ro | 0x0 | [field2](#csr20--field2) | +| 1 | rw1c | 0x0 | [field1](#csr20--field1) | +| 0 | rw1c | 0x0 | [field0](#csr20--field0) | + +### CSR20 . field2 + +All values are reserved. + +### CSR20 . field1 + +All values are reserved. + +### CSR20 . field0 + +All values are reserved. + +This interface does not expose any registers. + diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/theory_of_operation.md b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/theory_of_operation.md new file mode 100644 index 0000000000000..be6f32e03c0b5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/doc/theory_of_operation.md @@ -0,0 +1,528 @@ +# Theory of Operation + +## Block Diagram + +![Flash Block Diagram](../doc/flash_block_diagram.svg) + +### Flash Protocol Controller + +The Flash Protocol Controller sits between the host software interface, other hardware components and the flash physical controller. +Its primary functions are two fold +* Translate software program, erase and read requests into a high level protocol for the actual flash physical controller +* Act as communication interface between flash and other components in the system, such as life cycle and key manager. + +The flash protocol controller is not responsible for the detailed timing and waveform control of the flash, nor is it responsible for data scrambling and reliability metadata such as ICV and ECC. +Instead, it maintains FIFOs / interrupts for the software to process data, as well as high level abstraction of region protection controls and error handling. + +The flash controller selects requests between the software and hardware interfaces. +By default, the hardware interfaces have precedence and are used to read out seed materials from flash. +The seed material is read twice to confirm the values are consistent. +They are then forwarded to the key manager for processing. +During this seed phase, software initiated activities are back-pressured until the seed reading is complete. +It is recommended that instead of blindly issuing transactions to the flash controller, the software polls [`STATUS.INIT_WIP`](registers.md#status) until it is 0. + +Once the seed phase is complete, the flash controller switches to the software interface. +Software can then read / program / erase the flash as needed. + +#### RMA Entry Handling + +When an RMA entry request is received from the life cycle manager, the flash controller waits for any pending flash transaction to complete, then switches priority to the hardware interface. +The flash controller then initiates RMA entry process and notifies the life cycle controller when it is complete. +The RMA entry process wipes out all data, creator, owner and isolated partitions. + +After RMA completes, the flash controller is [disabled](#flash-access-disable). +When disabled the flash protocol controller registers can still be accessed. +However, flash memory access are not allowed, either directly by the host or indirectly through flash protocol controller initiated transactions. +It is expected that after an RMA transition, the entire system will be rebooted. + + +#### Initialization + +The flash protocol controller is initialized through [`INIT`](registers.md#init). +When initialization is invoked, the flash controller requests the address and data scrambling keys from an external entity, [otp_ctrl](../../../../ip/otp_ctrl/README.md#interface-to-flash-scrambler) in this case. + +After the scrambling keys are requested, the flash protocol controller reads the root seeds out of the [secret partitions](#secret-information-partitions) and sends them to the key manager. +Once the above steps are completed, the read buffers in the flash physical controller are enabled for operation. + +#### RMA Entry +During RMA entry, the flash controller "wipes" the contents of the following: +- Creator partition +- Owner partition +- Isolated partition +- All data partitions + +This process ensures that after RMA there is no sensitive information left that can be made use on the tester. +As stated previously, once RMA entry completes, the flash memory can no longer be accessed, either directly or indirectly. +The flash controller registers however, remain accessible for status reads and so forth, although new operations cannot be issued. + +#### Memory Protection + +Flash memory protection is handled differently depending on what type of partition is accessed. + +For data partitions, software can configure a number of memory protection regions such as [`MP_REGION_CFG_0`](registers.md#mp_region_cfg). +For each region, software specifies both the beginning page and the number of pages that belong to that region. +Software then configures the access privileges for that region. +Finally, each region can be activated or de-activated from matching through [`MP_REGION_CFG_0.EN`](registers.md#mp_region_cfg). + +Subsequent accesses are then allowed or denied based on the defined rule set. +Similar to RISCV pmp, if two region overlaps, the lower region index has higher priority. + +For information partitions, the protection is done per individual page. +Each page can be configured with access privileges. +As a result, software does not need to define a start and end page for information partitions. +See [`BANK0_INFO0_PAGE_CFG_0`](registers.md#bank0_info0_page_cfg) as an example. + +#### Bank Erase Protection + +Unlike read, program and page erase operations, the bank erase command is the only one that can be issued at a bank level. +Because of this, bank erase commands are not guarded by the typical [memory protection mechanisms](#memory-protection). + +Instead, whether bank erase is allowed is controlled by [`MP_BANK_CFG_SHADOWED`](registers.md#mp_bank_cfg_shadowed), where there is a separate configuration bit per bank. +When the corresponding bit is set, that particular bank is permitted to have bank level operations. + +The specific behavior of what is erased when bank erase is issued is flash memory dependent and thus can vary by vendor and technology. +[This section](#flash-bank-erase-behavior) describes the general behavior and how open source modeling is done. + +#### Memory Protection for Key Manager and Life Cycle + +While memory protection is largely under software control, certain behavior is hardwired to support key manager secret partitions and life cycle functions. + +Software can only control the accessibility of the creator secret seed page under the following condition(s): +* life cycle sets provision enable. +* OTP indicates the seeds are not locked. + +Software can only control the accessibility of the owner secret seed page under the following condition(s): +* life cycle sets provision enable. + +During life cycle RMA transition, the software configured memory protection for both data and information partitions is ignored. +Instead, the flash controller assumes a default accessibility setting that allows it to secure the chip and transition to RMA. + +#### Program Resolution + +Certain flash memories place restrictions on the program window. +This means the flash accepts program beats only if all beats belong to the same address window. +Typically, this boundary is nicely aligned (for example, 16 words, 32 words) and is related to how the flash memory amortizes the program operation over nearby words. + +To support this function, the flash controller errors back anytime the start of the program beat is in a different window from the end of the program beat. +The valid program range is thus the valid program resolution for a particular memory. + +This information is not configurable but instead decided at design time and is exposed as a readable status. + +#### Erase Suspend + +The flash controller supports erase suspend through [`ERASE_SUSPEND`](registers.md#erase_suspend). +This allows the software to interrupt an ongoing erase operation. + +The behavior of what happens to flash contents when erase is suspended is vendor defined; however, generally it can be assumed that the erase would be incomplete. +It is then up to the controlling software to take appropriate steps to erase again at a later time. + +#### Additional Flash Attributes + +There are certain attributes provisioned in [`MP_REGION_CFG_0`](registers.md#mp_region_cfg) that are not directly used by the open source protocol or physical controllers. + +Instead, these attributes are fed to the vendor flash module on a per-page or defined boundary basis. +Currently there is only one such attribute [`MP_REGION_CFG_0.HE`](registers.md#mp_region_cfg). + +#### Idle Indication to External Power Manager + +The flash controller provides an idle indication to an external power manager. +This idle indication does not mean the controller is doing "nothing", but rather the controller is not doing anything "stateful", e.g. program or erase. + +This is because an external power manager event (such as shutting off power) while a flash stateful transaction is ongoing may be damaging to the vendor flash module. + +#### Flash Code Execution Handling + +Flash can be used to store both data and code. +To support separate access privileges between data and code, the flash protocol controller provides [`EXEC`](registers.md#exec) for software control. + +If software programs [`EXEC`](registers.md#exec) to `0xa26a38f7`, code fetch from flash is allowed. +If software programs [`EXEC`](registers.md#exec) to any other value, code fetch from flash results in an error. + +The flash protocol controller distinguishes code / data transactions through the [instruction type attribute](../../../../ip/lc_ctrl/README.md#usage-of-user-bits) of the TL-UL interface. + +#### Flash Errors and Faults + +The flash protocol controller maintains 3 different categories of observed errors and faults. +In general, errors are considered recoverable and primarily geared towards problems that could have been caused by software or that occurred during a software initiated operation. +Errors can be found in [`ERR_CODE`](registers.md#err_code). + +Faults, on the other hand, represent error events that are unlikely to have been caused by software and represent a major malfunction of the system. + +Faults are further divided into two categories: +- Standard faults +- Custom faults + +Standard faults represent errors that occur in the standard structures of the design, for example sparsely encoded FSMs, duplicated counters and the bus transmission integrity scheme. + +Custom faults represent custom errors, primarily errors generated by the life cycle management interface, the flash storage integrity interface and the flash macro itself. + +See (#flash-escalation) for further differentiation between standard and custom faults. + +#### Transmission Integrity Faults + +Since the flash controller has multiple interfaces for access, transmission integrity failures can manifest in different ways. + +There are 4 interfaces: +- host direct access to flash controller [register files](#host-direct-access-to-flash-controller-register-files). +- host direct access to [flash macro](#host-direct-access-to-flash-macro) +- host / software initiated flash controller access to [flash macro (read / program / erase)](#host--software-initiated-access-to-flash-macro) +- life cycle management interface / hardware initiated flash controller access to [flash macro (read / program / erase)](#life-cycle-management-interface-hardware-initiated-access-to-flash-macro) + +The impact of transmission integrity of each interface is described below. + +##### Host Direct Access to Flash Controller Register Files +This category of transmission integrity behaves identically to other modules. +A bus transaction, when received, is checked for command and data payload integrity. +If an integrity error is seen, the issuing bus host receives an in-band error response and a fault is registered in [`STD_FAULT_STATUS.REG_INTG_ERR`](registers.md#std_fault_status). + +##### Host Direct Access to Flash Macro +Flash can only be read by the host. +The transmission integrity scheme used is end-to-end, so integrity generated inside the flash is fed directly to the host. +It is the host's responsibility to check for integrity correctness and react accordingly. + +##### Host / Software Initiated Access to Flash Macro +Since controller operations are initiated through writes to the register file, the command check is identical to host direct access to [regfiles](#host-direct-access-to-flash-controller-register-files). +Controller reads behave similarly to [host direct access to macro](#host-direct-access-to-flash-macro), the read data and its associated integrity are returned through the controller read FIFO for the initiating host to handle. + +For program operations, the write data and its associated integrity are stored and propagated through the flash protocol and physical controllers. +Prior to packing the data for final flash program, the data is then checked for integrity correctness. +If the data integrity is incorrect, an in-band error response is returned to the initiating host and an error is registered in [`ERR_CODE.PROG_INTG_ERR`](registers.md#err_code). +An error is also registered in [`STD_FAULT_STATUS.PROG_INTG_ERR`](registers.md#std_fault_status) to indicate that a fatal fault has occurred. + +The reasons a program error is registered in two locations are two-fold: +- It is registered in [`ERR_CODE`](registers.md#err_code) so software can discover during operation status that a program has failed. +- It is registered in [`STD_FAULT_STATUS`](registers.md#std_fault_status) because transmission integrity failures represent a fatal failure in the standard structure of the design, something that should never happen. + +##### Life Cycle Management Interface / Hardware Initiated Access to Flash Macro +The life cycle management interface issues transactions directly to the flash controller and does not perform a command payload integrity check. + +For read operations, the read data and its associated integrity are directly checked by the life cycle management interface. +If an integrity error is seen, it is registered in [`FAULT_STATUS.LCMGR_INTG_ERR`](registers.md#fault_status). + +For program operations, the program data and its associated integrity are propagated into the flash controller. +If an integrity error is seen, an error is registered in [`FAULT_STATUS.PROG_INTG_ERR`](registers.md#fault_status). + +#### ECC and ICV Related Read Errors + +In addition to transmission integrity errors described above, the flash can also emit read errors based on [ECC and ICV checks](#flash-ecc-and-icv). + +Flash reliability ECC errors (multi-bit errors) and integrity check errors (integrity check errors) are both reflected as in-band errors to the entity that issued the transaction. +That means if a host direct read, controller initiated read or hardware initiated read encounters one of these errors, the error is directly reflected in the operation status. + +Further, reliability ECC / integrity check errors are also captured in [`FAULT_STATUS`](registers.md#fault_status) and can be used to generate fatal alerts. +The reason these are not captured in [`STD_FAULT_STATUS`](registers.md#std_fault_status) is because 1 or 2 bit errors can occur in real usage due to environmental conditions, thus they do not belong to the standard group of structural errors. +If we assume 2-bit errors can occur, then software must have a mechanism to recover from the error instead of [escalation](#flash-escalation). + +#### Flash Escalation + +Flash has two sources of escalation - global and local. + +Global escalation is triggered by the life cycle controller through `lc_escalate_en`. +Local escalation is triggered by a standard faults of flash, seen in [`STD_FAULT_STATUS`](registers.md#std_fault_status). +Local escalation is not configurable and automatically triggers when this subset of faults are seen. + +For the escalation behavior, see [flash access disable](#flash-access-disable) . + +#### Flash Access Disable + +Flash access can be disabled through global escalation trigger, local escalation trigger, rma process completion or software command. +The escalation triggers are described [here](#flash-escalation). +The software command to disable flash can be found in [`DIS`](registers.md#dis). +The description for rma entry can be found [here](#rma-entry-handling). + +When disabled, the flash has a two layered response: +- The flash protocol controller [memory protection](#memory-protection) errors back all controller initiated operations. +- The host-facing tlul adapter errors back all host initiated operations. +- The flash physical controller completes any existing stateful operations (program or erase) and drops all future flash transactions. +- The flash protocol controller arbiter completes any existing software issued commands and enters a disabled state where no new transactions can be issued. + + +### Flash Physical Controller + +The Flash Physical Controller is the wrapper module that contains the actual flash memory instantiation. +It is responsible for arbitrating high level protocol commands (such as read, program, erase) as well as any additional security (scrambling) and reliability (ECC) features. +The contained vendor wrapper module is then responsible for converting high level commands into low level signaling and timing specific to a particular flash vendor. +The vendor wrapper module is also responsible for any BIST, redundancy handling, remapping features or custom configurations required for the flash. + +The scramble keys are provided by an external static block such as the OTP. + +#### Host and Protocol Controller Handling + +Both the protocol controller and the system host converge on the physical controller. +The protocol controller has read access to all partitions as well as program and erase privileges. +The host on the other hand, can only read the data partitions. + +Even though the host has less access to flash, it is prioritized when competing against the protocol controller for access. +When a host request and a protocol controller request arrive at the same time, the host is favored and granted. +Every time the protocol controller loses such an arbitration, it increases an arbitration lost count. +Once this lost count reaches 5, the protocol controller is favored. +This ensures a stream of host activity cannot deny protocol controller access (for example a tight polling loop). + +#### Flash Bank Erase Behavior + +This section describes the open source modeling of flash memory. +The actual flash memory behavior may differ, and should consult the specific vendor or technology specification. + +When a bank erase command is issued and allowed, see [bank erase protection](#bank-erase-protection), the erase behavior is dependent on [`CONTROL.PARTITION_SEL`](registers.md#control). +- If data partition is selected, all data in the data partition is erased. +- If info partition is selected, all data in the data partition is erased AND all data in the info partitions (including all info types) is also erased. + +#### Flash Scrambling + +Flash scrambling is built using the [XEX tweakable block cipher](https://en.wikipedia.org/wiki/Disk_encryption_theory#Xor%E2%80%93encrypt%E2%80%93xor_(XEX)). + +When a read transaction is sent to flash, the following steps are taken: +* The tweak is calculated using the transaction address and a secret address key through a Galois multiplier. +* The data content is read out of flash. +* If the data content is scrambled, the tweak is XOR'd with the scrambled text and then decrypted through the PRINCE block cipher using a secret data key. +* The output of the PRINCE cipher is XOR'd again with the tweak and the final results are presented. +* If the data content is not scrambled, the PRINCE cipher and XOR steps are skipped and data provided directly back to the requestor. + +When a program transaction is sent to flash, the same steps are taken if the address in question has scrambling enabled. +During a program, the text is scrambled through the PRINCE block cipher. + +Scramble enablement is done differently depending on the type of partitions. +* For data partitions, the scramble enablement is done on contiguous page boundaries. + * Software has the ability to configure these regions and whether scramble is enabled. +* For information partitions, the scramble enablement is done on a per page basis. + * Software can configure for each page whether scramble is enabled. + +Note that while the minimum granularity for host and controller interface accesses is 32 bits, the scrambling as well as reliability ECC operate on full Flash words (64 bits). +Whenever reliability ECC and/or scrambling are enabled, read, program and erase operations should thus be based on 64-bit aligned addresses. + +#### Flash ECC and ICV + +Flash supports both ECC (error correction) and ICV (integrity check value). +While the two are used for different functions, they are implemented as two separate ECCs, thus flash supports two types of ECC. + +ICV is an integrity check, implemented as an ECC, used to detect whether the de-scrambled data has been modified. +The other is a reliability ECC used for error detection and correction on the whole flash word. + +The key differentiation here is that ICV is used only for detection, while the real error correction can correct single bit errors. +Both ICV and ECC are configurable based on the various page and memory property configurations. + +##### Overall ICV and ECC Application + +The following diagram shows how the various ICV / ECC tags are applied and used through the life of a transactions. +![Flash ECC_LIFE](../doc/flash_integrity.svg). + +Note that the ICV (integrity ECC) is calculated over the descrambled data and is only 4-bits, while the reliability ECC is calculated over both the scrambled data and the ICV. + +##### ICV + +The purpose of the ICV (integrity check value, implemented as an ECC) is to emulate end-to-end integrity like the other memories. +This is why the data is calculated over the descrambled data as it can be stored alongside for continuous checks. +When descrambled data is returned to the host, the ICV is used to validate the data is correct. + +The flash may not always have the capacity to store both the ICV and reliability ECC, the ICV is thus truncated since it is not used for error correction. + +##### Reliability ECC + +Similar to scrambling, the reliability ECC is enabled based on an address decode. +The ECC for flash is chosen such that a fully erased flash word has valid ECC. +Likewise a flash word that is completely 0 is also valid ECC. + +Unlike the integrity ECC, the reliability ECC is actually used for error correction if an accidental bit-flip is seen, it is thus fully stored and not truncated. + +ECC enablement is done differently depending on the type of partitions. +* For data partitions, the ECC enablement is done on contiguous page boundaries. + * Software has the ability to configure these regions and whether ECC is enabled. +* For information partitions,the ECC enablement is done on a per page basis. + * Software can configure for each page whether ECC is enabled. + +##### Scrambling Consistency + +The flash physical controller does not keep a history of when a particular memory location has scrambling enabled or disabled. +This means if a memory location was programmed while scrambled, disabling scrambling and then reading it back will result in garbage. +Similarly, if a location was programmed while non-scrambled, enabling scrambling and then reading it back will also result in garbage. + +It it thus the programmer's responsibility to maintain a consistent definition of whether a location is scrambled. +It is also highly recommended in a normal use case to setup up scramble and non-scramble regions and not change it further. + +#### Flash Read Pipeline + +Since the system host reads directly from the flash for instructions, it is critical to not add significant latency during read, especially if de-scrambling is required. +As such, the flash read is actually a two stage pipeline, where each stage can take multiple cycles. + +Additionally, since the flash word size is typically larger than the bus word, recently read flash entries are locally cached. +The cache behaves as a highly simplified read-only-cache and holds by default 4 flash words per flash bank. + +When a read transaction is sent to flash, the following steps are taken: +* A check is performed against the local cache + * If there is a hit (either the entry is already in cache, or the entry is currently being processed), the transaction is immediately forwarded to the response queue. + * If there is not a hit, an entry in the local cache is selected for allocation (round robin arbitration) and a flash read is issued. +* When the flash read completes, its descrambling attributes are checked: + * If descrambling is required, the read data begins the descrambling phase - at this time, a new flash read can be issued for the following transaction. + * if descrambling is not required, the descrambling phase is skipped and the transaction is pushed to the response queue. +* When the descrambling is complete, the descrambled text is pushed to the response queue. + +The following diagram shows how the flash read pipeline timing works. +![Flash Read Pipeline](../doc/flash_read_pipeline.svg) + + +In this example, the first two host requests trigger a full sequence. +The third host requests immediately hits in the local cache and responds in order after the first two. + +#### Flash Buffer + +The flash buffer is a small read-only memory that holds multiple entries of recently read flash words. +This is needed when the flash word is wider than a bus word. +The flash access time is amortized across the entire flash word if software accesses in a mostly +linear sequence. + +The flash buffer has a round robin replacement policy when more flash words are read. +When an erase / program is issued to the flash, the entries are evicted to ensure new words are fetched. + +When a page erase / program is issued to a flash bank, only entries that fall into that address range are evicted. +When a bank erase is issued, then all entries are evicted. + +The flash buffer is only enabled after [`INIT`](registers.md#init) is invoked. +When an RMA entry sequence is received, the flash buffers are disabled. + +As an example, assume a flash word is made up of 2 bus words. +Assume also the following address to word mapping: +- Address 0 - flash word 0, bus word 0 / bus word 1 +- Address 2 - flash word 1, bus word 2 / bus word 3 + +When software reads bus word 1, the entire flash word 0 is captured into the flash buffer. +When software comes back to read bus word 0, instead of accessing the flash again, the data is retrieved directly from the buffer. + +The recently read entries store both the de-scrambled data and the [integrity ECC](#integrity-ecc). +The [reliability ECC](#reliability-ecc) is not stored because the small buffer is purely flip-flop based and does not have storage reliability concerns like the main flash macro. + +When a read hits in the flash buffer, the integrity ECC is checked against the de-scrambled data and an error is returned to the initiating entity, whether it is a the controller itself or a host. + + +#### Accessing Information Partition + +The information partition uses the same address scheme as the data partition - which is directly accessible by software. +This means the address of page{N}.word{M} is the same no matter which type of partition is accessed. + +Which partition a specific transaction accesses is denoted through a separate field [`CONTROL.PARTITION_SEL`](registers.md#control) in the [`CONTROL`](registers.md#control) register. +If [`CONTROL.PARTITION_SEL`](registers.md#control) is set, then the information partition is accessed. +If [`CONTROL.PARTITION_SEL`](registers.md#control) is not set, then the corresponding word in the data partition is accessed. + +Flash scrambling, if enabled, also applies to information partitions. +It may be required for manufacturers to directly inject data into specific pages flash information partitions via die contacts. +For these pages, scramble shall be permanently disabled as the manufacturer should not be aware of scrambling functions. + +##### JTAG Connection + +The flash physical controller provides a JTAG connection to the vendor flash module. +The vendor flash module can use this interface to build a testing setup or to provide backdoor access for debug. + +Due to the ability of this connection to bypass access controls, this connection is modulated by life cycle and only enabled when non-volatile debug, or `lc_nvm_debug_en` is allowed in the system. + +## Flash Default Configuration +Since the flash controller is highly dependent on the specific flavor of flash memory chosen underneath, its configuration can vary widely between different integrations. + +This sections details the default settings used by the flash controller: +* Number of banks: 2 +* Number of data partition pages per bank: 256 +* [Program resolution](#program-resolution): 8 flash words +* Flash word data bits: 64 +* Flash word metadata bits: 8 +* ECC choice: Hamming code SECDED +* Information partition types: 3 +* Number of information partition type 0 pages per bank: 10 +* Number of information partition type 1 pages per bank: 1 +* Number of information partition type 2 pages per bank: 2 +* Secret partition 0 (used for creator): Bank 0, information partition 0, page 1 +* Secret partition 1 (used for owner): Bank 0, information partition 0, page 2 +* Isolated partition: Bank 0, information partition 0, page 3 + +## Design Details + +### Flash Protocol Controller Description + +The flash protocol controller uses a simple FIFO interface to communicate between the software and flash physical controller. +There is a read FIFO for read operations, and a program FIFO for program operations. +Note, this means flash can be read both through the controller and the main bus interface. +This may prove useful if the controller wishes to allocate specific regions to HW FSMs only, but is not a necessary feature. + +When software initiates a read transaction of a programmable number of flash words, the flash controller will fill up the read FIFO for software to consume. +Likewise, when software initiates a program transaction, software will fill up the program FIFO for the controller to consume. + +The controller is designed such that the overall number of words in a transaction can significantly exceed the FIFO depth. +In the case of read, once the FIFO is full, the controller will cease writing more entries and wait for software to consume the contents (an interrupt will be triggered to the software to alert it to such an event). +In the case of program, the controller will stop writing to flash once all existing data is consumed - it will likewise trigger an interrupt to software to prepare more data. +See detailed steps in theory of operation. +The following is a diagram of the controller construction as well as its over connectivity with the flash module. + +![Flash Protocol Controller](../doc/flash_protocol_controller.svg) + + +### Host Read + +Unlike controller initiated reads, host reads have separate rdy / done signals to ensure transactions can be properly pipelined. +As host reads are usually tied to host execution upstream, additional latency can severely harm performance and is not desired. +The expected waveform from the perspective of the physical controller is shown below. + +```wavejson +{signal: [ + {name: 'clk_i', wave: 'p..............'}, + {name: 'rst_ni', wave: '0.1............'}, + {name: 'host_req_i', wave: '0..10.1...0....'}, + {name: 'host_addr_i', wave: 'x..3x.3.33x....', data: ['Adr0', 'Adr1', 'Adr2', 'Adr3']}, + {name: 'host_req_rdy_o', wave: '1...0..1.......'}, + {name: 'host_req_done_o', wave: '0...10..1110...'}, + {name: 'host_rdata_o', wave: 'x...4x..444x...',data: ['Dat0', 'Dat1', 'Dat2', 'Dat3']}, +]} +``` + +The `host_req_done_o` is always single cycle pulsed and upstream logic is expected to always accept and correctly handle the return. +The same cycle the return data is posted a new command / address can be accepted. +While the example shows flash reads completing in back to back cycles, this is typically not the case. + +### Controller Read + +Unlike host reads, controller reads are not as performance critical and do not have command / data pipeline requirements. +Instead, the protocol controller will hold the read request and address lines until the done is seen. +Once the done is seen, the controller then transitions to the next read operation. +The expected waveform from the perspective of the physical controller is shown below. + +```wavejson +{signal: [ + {name: 'clk_i', wave: 'p..............'}, + {name: 'rst_ni', wave: '0.1............'}, + {name: 'flash_ctrl_i.req', wave: '0..1.....0.....'}, + {name: 'flash_ctrl_i.addr', wave: 'x..3..3..x.3..x', data: ['Adr0', 'Adr1', 'Adr2']}, + {name: 'flash_ctrl_i.rd', wave: '0..1.....0.1..0'}, + {name: 'flash_ctrl_o.rd_done', wave: '0....10.10...10'}, + {name: 'flash_ctrl_o.rdata', wave: 'x....4x.4x...4x', data: ['Dat0', 'Dat1', 'Dat2']}, +]} +``` + +Note that upon experiencing errors during multi-word controller read operations, the flash controller aborts the internal read operation but still returns the requested amount of data. +For the word triggering the first error, the actual flash data is returned. +For subsequent words, the flash controller may return: +- An all-one word in case of an access permission error. +- An all-zero word in case of a flash read error (e.g. reliability ECC and ICV errors) and if the flash read pipeline remains idle. +- The data belonging to other read operations in case of a flash read error and if the flash read pipeline continues doing, e.g., host initiated read operations. + + +### Controller Program + +Program behavior is similar to reads. +The protocol controller will hold the request, address and data lines until the programming is complete. +The expected waveform from the perspective of the physical controller is shown below. + +```wavejson +{signal: [ + {name: 'clk_i', wave: 'p..............'}, + {name: 'rst_ni', wave: '0.1............'}, + {name: 'flash_ctrl_i.req', wave: '0..1.....0.....'}, + {name: 'flash_ctrl_i.addr', wave: 'x..3..3..x.3..x', data: ['Adr0', 'Adr1', 'Adr2']}, + {name: 'flash_ctrl_i.prog', wave: '0..1.....0.1..0'}, + {name: 'flash_ctrl_o.prog_data', wave: 'x..4..4..x.4..x', data: ['Dat0', 'Dat1', 'Dat2']}, + {name: 'flash_ctrl_o.prog_done', wave: '0....10.10...10'}, +]} +``` + +### Read Data Infection Feature + +This feature aims to provide additional security against fault injection attacks targeting the addresses of host flash read requests. +By default, on each host read request, the data fetched from the underyling memory is infected with the address used for the memory access. +Before returning the data to the host over the bus, the address is removed from the infected data. +When the address used for the infection matches the original address, the plain data is restored. +Otherwise, faulty data is generated, which can be detected by the data integrity mechanism. diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/README.md b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/README.md new file mode 100644 index 0000000000000..c3b09b6a1e14e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/README.md @@ -0,0 +1,209 @@ +# FLASH_CTRL DV document + +## Goals +* **DV** + * Verify all `flash_ctrl` 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](../../../../README.md) + * [HW development stages](../../../../../doc/project_governance/development_stages.md) +* [Simulation results](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/latest/report.html) + +## Design features +For detailed information on `flash_ctrl` design features, please see the [`flash_ctrl` HWIP technical specification](../README.md). +The design-under-test (DUT) wraps the `flash_ctrl` IP, `flash_phy` and the TLUL SRAM adapter that converts the incoming TL accesses from the from host (CPU) interface into flash requests. +These modules are instantiated and connected to each other and to the rest of the design at the top level. +For the IP level DV, we replicate the instantiations and connections in `flash_ctrl_wrapper` module maintained in DV, located at `hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tb/flash_ctrl_wrapper.sv`. +In future, we will consider having the wrapper maintained in the RTL area instead. + +## Testbench architecture +The `flash_ctrl` UVM DV 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/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tb/tb.sv`. +It instantiates the `flash_ctrl_wrapper`. +In addition, the testbench 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 for the flash controller](../../../../dv/sv/tl_agent/README.md) +* [TileLink host interface for the eflash](../../../../dv/sv/tl_agent/README.md) +* TileLink host interface for the prim registers +* Interrupts ([`pins_if`](../../../../dv/sv/common_ifs/README.md) +* [Memory backdoor utility](../../../../dv/sv/mem_bkdr_util/README.md) +* Secret key interface from the OTP +* Interface from the life cycle manager +* Interface to the `keymgr` and `pwrmgr` + +### 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) + +### TL_agent +`flash_ctrl` UVM environment instantiates a (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 `flash_ctrl` device. +There are two additional instances of the `tl_agent`. +* Host interface to the `flash_phy`, to directly fetch the contents of the flash memory, bypassing the `flash_ctrl`. +* Host interface to the `prim registers`. + +The `tl_agent` monitor supplies partial TileLink request packets as well as completed TileLink response packets over the TLM analysis port for further processing within the `flash_ctrl` scoreboard. + +### UVM RAL Model +The `flash_ctrl` 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): + +#### Sequence cfg +An efficient way to develop test sequences is by providing some random variables that are used to configure the DUT / drive stimulus. +The random variables are constrained using weights and knobs that can be controlled. +These weights and knobs take on a "default" value that will result in the widest exploration of the design state space, when the test sequence is randomized and run as-is. +To steer the randomization towards a particular distribution or to achieve interesting combinations of the random variables, the test sequence can be extended to create a specialized variant. +In this extended sequence, nothing would need to be done, other than setting those weights and knobs appropriately. +This helps increase the likelihood of hitting the design corners that would otherwise be difficult to achieve, while maximizing reuse. + +This object aims to provide such run-time controls. +An example of such a knob is `num_en_mp_regions`, which controls how many flash memory protection regions to configure, set to 'all' by default. + +#### Env cfg +The `flash_ctrl_env_cfg`, environment configuration object provides access to the following elements: +* Build-time controls to configure the UVM environment composition during the `build_phase` +* Downstream agent configuration objects for ease of lookup from any environment component + * This includes the `tl_agent_cfg` objects for both TL interfaces +* All virtual interfaces that connect to the DUT listed above (retrieved from the `uvm_config_db`) +* Sequence configuration object described above + +All environment components contain a handle to an instance of this class (that was created in the test class via the parent `dv_base_test`). +By housing all of the above, all pertinent information is more easily shared with all environment components. + +### Stimulus strategy +#### Test sequences +All test sequences reside in `hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib`. +The `flash_ctrl_base_vseq` virtual sequence is extended from `cip_base_vseq` and serves as a starting point. +All test sequences are extended from `flash_ctrl_base_vseq`. +It provides commonly used handles, variables, functions and tasks that the test sequences can simple use / call. +Some of the most commonly used tasks / functions are as follows: From `hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq/flash_ctrl_base_vseq.sv`, +* reset_flash + Reset flash controller and initialize flash device using back door interface. +* flash_ctrl_start_op + Start operation on the flash controller +* flash_ctrl_write + Send data to `prog_fifo`. This task is used for `program operation` from controller combined with `flash_ctrl_start_op`. +* flash_ctrl_read + Read data from `rd_fifo`. This task is used for `read operation` from controller combined with `flash_ctrl_start_op`. +* wait_flash_op_done + Polling `op_status` until op_status.done is set. +* do_direct_read + Task to read flash from the host interface. Transaction size is 4 byte per transaction. +* flash_ctrl_intr_read + Task to read flash with interrupt mode. +* flash_ctrl_intr_write + Task to program flash with interrupt mode. +* send_rma_req + Task to initiate rma request. Once rma started, task polls `rma ack` until it completes. + +#### 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: +`hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cov.sv` +* control_cg + Collects operation types, partition and cross coverage of both. +* erase_susp_cg + Check if request of erase suspension occurred. +* msgfifo_level_cg + Covers all possible fifo status to generate interrupt for read / program. +* eviction_cg + Check whether eviction happens at all 4 caches with write / erase operation. + Also check each address belongs to randomly enabled scramble and ecc. +* error_cg + Check errors defined in error code registers. +### Self-checking strategy +#### Scoreboard +The `flash_ctrl_scoreboard` is primarily used for csr transaction integrity. +Test bench also maintains a reference memory model (associative array) per partition. +The reference model is updated on each operation and used for expected partition values at the end of test check. +Given large memory size (mega bytes), maintaining an associative array per operation until the end of the test causes huge simulation overhead. +Also, this model is not suitable for read only test, same address write test, descramble tests and error injection test for ecc. +To address such issues, `on-the-fly` method is also used on top of legacy test component. +In `on-the-fly` test mode, test does not rely on reference memory mode. +Instead, it creates reference data for each operation. +For the program(write) operation, rtl output is collected from flash phy interface and compared with each operation's pre calculated write data. +For the read operation, the expected data is written via memory backdoor interface, read back, and compared. +The `flash_ctrl_otf_scoreboard` is used for `on-the-fly` mode flash transaction integrity check, while `flash_ctrl_scoreboard` is still used for csr transaction integrity check. +Since there is still uncovered logic within the model before data reaches the actual device, we add extra scoreboard to check that path and call it `last mile scoreboard`. +The `last mile scoreboard` is added to compensate `on-the-fly` model. +For the write transaction, `on-the-fly` model collects rtl data at the boundary of the controller and flash model. + +#### Assertions +* TLUL assertions: The `hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_bind.sv` binds the `tlul_assert` [assertions](../../../../ip/tlul/doc/TlulProtocolChecker.md) to the IP to ensure TileLink interface protocol compliance. +* Unknown checks on DUT outputs: The RTL has assertions to ensure all outputs are initialized to known values after coming out of reset. + +### Global types and methods +All common types and methods defined at the package level can be found in +`flash_ctrl_env_pkg`. Some of them in use are: +```systemverilog +** types and enums +// Interrupt enums + typedef enum int { + FlashCtrlIntrProgEmpty = 0, + FlashCtrlIntrProgLvl = 1, + FlashCtrlIntrRdFull = 2, + FlashCtrlIntrRdLvl = 3, + FlashCtrlIntrOpDone = 4, + FlashCtrlIntrErr = 5, + NumFlashCtrlIntr = 6 + } flash_ctrl_intr_e; + +// Flash initialization mode + typedef enum { + FlashMemInitCustom, // Initialize flash (via bkdr) with custom data set. + FlashMemInitSet, // Initialize with all 1s. + FlashMemInitClear, // Initialize with all 0s. + FlashMemInitRandomize, // Initialize with random data. + FlashMemInitInvalidate, // Initialize with Xs. + FlashMemInitEccMode // Flash init for ecc_mode + } flash_mem_init_e; + +// Ecc test mode + typedef enum { + FlashEccDisabled, // No ecc enable + FlashEccEnabled, // Ecc enable but no error injection + FlashSerrTestMode, // Ecc enable and single bit error injection + FlashDerrTestMode, // Ecc enable and double bit error injection + FlashIerrTestMode // Ecc enable and integrity error injection + } ecc_mode_e; + +// 4-states flash data type +typedef logic [TL_DW-1:0] data_4s_t; +// flash address type +typedef bit [TL_AW-1:0] addr_t; +// Queue of 4-states data words +typedef data_4s_t data_q_t[$]; +// Flash op struct +typedef struct packed { + flash_dv_part_e partition; // data or one of the info partitions + flash_erase_e erase_type; // erase page or the whole bank + flash_op_e op; // read / program or erase + flash_prog_sel_e prog_sel; // program select + uint num_words; // number of words to read or program (TL_DW) + addr_t addr; // starting addr for the op + // addres for the ctrl interface per bank, 18:0 + bit [flash_ctrl_pkg::BusAddrByteW-2:0] otf_addr; + } flash_op_t; + +``` + +## 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 +$ cd $REPO_TOP +$ ./util/dvsim/dvsim.py hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson -i flash_ctrl_smoke +``` + +## Testplan +[Testplan](../data/flash_ctrl_testplan.hjson) diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.core new file mode 100644 index 0000000000000..f9dcbf461aeb0 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.core @@ -0,0 +1,21 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_cov +description: "FLASH_CTRL functional coverage interface & bind." + +filesets: + files_dv: + depend: + - lowrisc:dv:dv_utils + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl + files: + - flash_ctrl_cov_bind.sv + - flash_ctrl_phy_cov_if.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.vRefine b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.vRefine new file mode 100644 index 0000000000000..c1907cb0a8f28 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov.vRefine @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv new file mode 100644 index 0000000000000..4c20c8dd9142f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_cov_bind.sv @@ -0,0 +1,35 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Binds FLASH_CTRL functional coverage interface to the top level FLASH_CTRL module. +`define FLASH_COV_LC_TX_BIND(__name) \ + bind flash_ctrl cip_lc_tx_cov_if u_``__name``_cov_if( \ + .rst_ni (rst_ni), \ + .val (``__name``_i) \ + ); + +module flash_ctrl_cov_bind; + + `FLASH_COV_LC_TX_BIND(lc_creator_seed_sw_rw_en) + `FLASH_COV_LC_TX_BIND(lc_owner_seed_sw_rw_en) + `FLASH_COV_LC_TX_BIND(lc_iso_part_sw_rd_en) + `FLASH_COV_LC_TX_BIND(lc_iso_part_sw_wr_en) + `FLASH_COV_LC_TX_BIND(lc_seed_hw_rd_en) + `FLASH_COV_LC_TX_BIND(lc_escalate_en) + `FLASH_COV_LC_TX_BIND(lc_nvm_debug_en) + + bind prim_generic_flash_bank flash_ctrl_phy_cov_if u_phy_cov_if + ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .rd_buf_en(tb.dut.u_flash_hw_if.rd_buf_en_o), + .rd_req(rd_i), + .prog_req(prog_i), + .pg_erase_req(pg_erase_i), + .bk_erase_req(bk_erase_i), + .ack(ack_o), + .addr(addr_i) + ); + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_phy_cov_if.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_phy_cov_if.sv new file mode 100644 index 0000000000000..cc067fd7c695c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/cov/flash_ctrl_phy_cov_if.sv @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Sampling physical interface of the flash +// tb.dut.u_eflash.u_flash +import flash_ctrl_pkg::*; +interface flash_ctrl_phy_cov_if +( + input logic clk_i, + input logic rst_ni, + input logic rd_buf_en, + input logic rd_req, + input logic prog_req, + input logic pg_erase_req, + input logic bk_erase_req, + input logic ack, + input logic [15:0] addr +); + + bit en_cov = 0; + + logic any_req; + assign any_req = rd_req || prog_req || pg_erase_req || bk_erase_req; + logic any_vld_req; + assign any_vld_req = any_req && ack; + + // Decode current command + typedef enum logic[1:0] {READ, PROG, ERASE, NONE} cmd_e; + cmd_e cur_cmd; + always_comb begin + cur_cmd = NONE; + if (any_vld_req) begin + if (rd_req) cur_cmd = READ; + else if (prog_req) cur_cmd = PROG; + else if (pg_erase_req || bk_erase_req) cur_cmd = ERASE; + end + end + + // previous command + cmd_e prv_cmd_q; + always @(posedge clk_i) begin + if (!rst_ni) begin + prv_cmd_q <= NONE; + end else begin + if (any_vld_req) begin + prv_cmd_q <= cur_cmd; + end + end + end + + // command interval counter + // couter will be saturated when it hits maxium + bit [31:0] idle_cnt; + always @(posedge clk_i) begin + if (!rst_ni || !rd_buf_en) idle_cnt <= 0; + else idle_cnt <= (any_vld_req)? 0 : + (idle_cnt == 32'hffff_ffff)? 32'hffff_ffff : idle_cnt + 32'h1; + end + + // back to back read sequence + logic b2b_read; + assign b2b_read = (cur_cmd == READ && prv_cmd_q == READ); + + // Covergroup to sample read after any of {read,prog,erase} operations + // Which was asked in #3353 + // Due to cache operation, all addresses for read after read are not the same. + // Only exception is when eviction happens, which is captured in separate covergroup (eviction_cg) + + covergroup phy_rd_cg @(posedge any_vld_req); + read_pat : + coverpoint cur_cmd { + bins any2read[] = (READ,PROG,ERASE => READ); + } + endgroup // phy_rd + + // Covergroup to sample interval of back to back read operation + covergroup b2b_read_interval_cg @(posedge b2b_read); + read_interval: + coverpoint idle_cnt { + bins duration[] = {1, [2:5], [5:9], [10:30], [31:99]}; + bins others = default; + } + endgroup + + initial begin + phy_rd_cg phy_rd_cg_inst; + b2b_read_interval_cg rd_intv_cg_inst; + void'($value$plusargs("en_cov=%0b", en_cov)); + if (en_cov) begin + phy_rd_cg_inst = new(); + rd_intv_cg_inst = new(); + end + end +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/doc/tb.svg b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/doc/tb.svg new file mode 100644 index 0000000000000..45dd2da61a0aa --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/doc/tb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_dv_if.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_dv_if.sv new file mode 100644 index 0000000000000..9c4aa2ee67c87 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_dv_if.sv @@ -0,0 +1,19 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +interface flash_ctrl_dv_if ( + input logic clk_i, + input logic rst_ni +); + + import flash_ctrl_pkg::*; + import lc_ctrl_pkg::*; + + logic rd_buf_en; + lc_tx_t rma_req; + rma_state_e rma_state; + logic [10:0] prog_state0; + logic [10:0] prog_state1; + logic [10:0] lcmgr_state; + +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_eflash_ral_pkg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_eflash_ral_pkg.sv new file mode 100644 index 0000000000000..98129d8469230 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_eflash_ral_pkg.sv @@ -0,0 +1,61 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package flash_ctrl_eflash_ral_pkg; + + import uvm_pkg::*; + import dv_base_reg_pkg::*; + + `include "uvm_macros.svh" + + typedef class flash_ctrl_eflash_mem; + typedef class flash_ctrl_eflash_reg_block; + + class flash_ctrl_eflash_mem #( + parameter int MemDepth = flash_ctrl_reg_pkg::BytesPerBank / 4 + ) extends dv_base_mem; + + `uvm_object_param_utils(flash_ctrl_eflash_mem#(MemDepth)) + + function new(string name = "flash_ctrl_eflash_mem", longint unsigned size = MemDepth, + int unsigned n_bits = 32, string access = "RO", + int has_coverage = UVM_NO_COVERAGE); + super.new(name, size, n_bits, access, has_coverage); + endfunction : new + + endclass : flash_ctrl_eflash_mem + + + class flash_ctrl_eflash_reg_block extends dv_base_reg_block; + // memories + rand flash_ctrl_eflash_mem flash_mem[flash_ctrl_reg_pkg::RegNumBanks]; + + `uvm_object_utils(flash_ctrl_eflash_reg_block) + + function new(string name = "flash_ctrl_eflash_ral_pkg", int has_coverage = UVM_NO_COVERAGE); + super.new(name, has_coverage); + endfunction : new + + virtual function void build(uvm_reg_addr_t base_addr, csr_excl_item csr_excl = null); + // create default map + this.default_map = create_map(.name("default_map"), .base_addr(base_addr), .n_bytes( + 4), .endian(UVM_LITTLE_ENDIAN)); + if (csr_excl == null) begin + csr_excl = csr_excl_item::type_id::create("csr_excl"); + this.csr_excl = csr_excl; + end + + // create memories + foreach (flash_mem[i]) begin + flash_mem[i] = + flash_ctrl_eflash_mem#(flash_ctrl_reg_pkg::BytesPerBank/4)::type_id::create( + $sformatf("flash_mem[%0d]", i)); + flash_mem[i].configure(.parent(this)); + default_map.add_mem(.mem(flash_mem[i]), .offset(i * flash_ctrl_reg_pkg::BytesPerBank), + .rights("RO")); + end + endfunction : build + endclass : flash_ctrl_eflash_reg_block + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.core new file mode 100644 index 0000000000000..fb421214dce0d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.core @@ -0,0 +1,113 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_env:0.1 +description: "FLASH_CTRL DV UVM environment" +filesets: + files_dv: + depend: + - lowrisc:dv:ralgen + - lowrisc:dv:dv_base_reg + - lowrisc:dv:dv_lib + - lowrisc:dv:cip_lib + - lowrisc:dv:mem_bkdr_util + - lowrisc:dv:flash_phy_prim_agent + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_pkg + - lowrisc:constants:top_englishbreakfast_top_pkg + files: + - flash_ctrl_eflash_ral_pkg.sv + - flash_ctrl_env_pkg.sv + - flash_ctrl_if.sv + - flash_ctrl_mem_if.sv + - flash_mem_bkdr_util.sv: {is_include_file: true} + - flash_mem_addr_attrs.sv: {is_include_file: true} + - flash_otf_item.sv: {is_include_file: true} + - flash_otf_read_entry.sv: {is_include_file: true} + - flash_otf_mem_entry.sv: {is_include_file: true} + - flash_ctrl_seq_cfg.sv: {is_include_file: true} + - flash_ctrl_env_cfg.sv: {is_include_file: true} + - flash_ctrl_env_cov.sv: {is_include_file: true} + - flash_ctrl_virtual_sequencer.sv: {is_include_file: true} + - flash_ctrl_scoreboard.sv: {is_include_file: true} + - flash_ctrl_otf_scoreboard.sv: {is_include_file: true} + - flash_ctrl_env.sv: {is_include_file: true} + - seq_lib/flash_ctrl_vseq_list.sv: {is_include_file: true} + - seq_lib/flash_ctrl_callback_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_base_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_common_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rand_ops_base_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_smoke_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_smoke_hw_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rand_ops_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_sw_op_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_host_dir_rd_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rd_buff_evict_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_phy_arb_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_hw_sec_otp_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_erase_suspend_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_hw_rma_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_host_ctrl_arb_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_mp_regions_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_fetch_code_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_full_mem_access_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_error_prog_type_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_error_prog_win_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_error_mp_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_invalid_op_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_mid_op_rst_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_otf_base_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_wo_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_ro_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rw_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_write_word_sweep_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_write_rnd_wd_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_read_word_sweep_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_read_rnd_wd_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_serr_counter_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_serr_address_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_derr_detect_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_hw_rma_reset_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_otp_reset_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_intr_rd_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_intr_wr_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_prog_reset_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_legacy_base_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rw_evict_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_re_evict_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_oversize_error_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_connect_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_disable_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_host_addr_infection_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rd_path_intg_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_wr_path_intg_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_info_part_access_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_filesystem_support_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_stress_all_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_access_after_disable_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_err_base_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_phy_arb_redun_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_phy_host_grant_err_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_phy_ack_consistency_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_config_regwen_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_hw_rma_err_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_lcmgr_intg_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_hw_read_seed_err_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_hw_prog_rma_wipe_err_vseq.sv: {is_include_file: true} + - seq_lib/flash_ctrl_rd_ooo_vseq.sv: {is_include_file: true} + file_type: systemVerilogSource + +generate: + ral: + generator: ralgen + parameters: + name: flash_ctrl + ip_hjson: ../../data/flash_ctrl.hjson + +targets: + default: + filesets: + - files_dv + generate: + - ral diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.sv new file mode 100644 index 0000000000000..b33df7ad5ba1e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env.sv @@ -0,0 +1,102 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_env #( + type CFG_T = flash_ctrl_env_cfg, + type SCOREBOARD_T = flash_ctrl_scoreboard, + type VIRTUAL_SEQUENCER_T = flash_ctrl_virtual_sequencer +) extends cip_base_env #( + .CFG_T (CFG_T), + .COV_T (flash_ctrl_env_cov), + .VIRTUAL_SEQUENCER_T(VIRTUAL_SEQUENCER_T), + .SCOREBOARD_T (SCOREBOARD_T) +); + `uvm_component_param_utils(flash_ctrl_env#(CFG_T, SCOREBOARD_T, VIRTUAL_SEQUENCER_T)) + + flash_ctrl_otf_scoreboard m_otf_scb; + flash_phy_prim_agent m_fpp_agent; + virtual flash_ctrl_if flash_ctrl_vif; + + string hdl_path_root; + + `uvm_component_new + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + + if (!uvm_config_db#(virtual flash_ctrl_if)::get( + this, "", "flash_ctrl_vif", cfg.flash_ctrl_vif + )) begin + `uvm_fatal(`gfn, "failed to get flash_ctrl_vif from uvm_config_db") + end + for (int i = 0; i < NumBanks; i++) begin + if (!uvm_config_db#(virtual flash_ctrl_mem_if)::get( + this, "", $sformatf("flash_ctrl_mem_vif[%0d]", i), cfg.flash_ctrl_mem_vif[i])) begin + `uvm_fatal(`gfn, "failed to get flash_ctrl_mem_vif from uvm_config_db") + end + end + // Retrieve the mem backdoor util instances. + for ( + int i = 0, flash_dv_part_e part = part.first(); i < part.num(); i++, part = part.next() + ) begin + foreach (cfg.mem_bkdr_util_h[, bank]) begin + string name = $sformatf("mem_bkdr_util[%0s][%0d]", part.name(), bank); + if (!uvm_config_db#(mem_bkdr_util)::get( + this, "", name, cfg.mem_bkdr_util_h[part][bank] + )) begin + `uvm_fatal(`gfn, $sformatf("failed to get %s from uvm_config_db", name)) + end + end + end + + m_fpp_agent = flash_phy_prim_agent::type_id::create("m_fpp_agent", this); + uvm_config_db#(flash_phy_prim_agent_cfg)::set(this, "m_fpp_agent", "cfg", cfg.m_fpp_agent_cfg); + cfg.m_fpp_agent_cfg.mon_start = 0; + m_otf_scb = flash_ctrl_otf_scoreboard::type_id::create("m_otf_scb", this); + uvm_config_db#(flash_ctrl_env_cfg)::set(this, "m_otf_scb", "cfg", cfg); + endfunction + + virtual function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + if (cfg.en_scb) begin + m_tl_agents[cfg.flash_ral_name].monitor.a_chan_port.connect( + scoreboard.eflash_tl_a_chan_fifo.analysis_export); + m_tl_agents[cfg.flash_ral_name].monitor.d_chan_port.connect( + scoreboard.eflash_tl_d_chan_fifo.analysis_export); + end + + if (cfg.scb_otf_en) begin + for (int i = 0; i < flash_ctrl_pkg::NumBanks; ++i) begin + virtual_sequencer.eg_exp_ctrl_port[i].connect( + m_otf_scb.eg_exp_ctrl_fifo[i].analysis_export); + virtual_sequencer.eg_exp_host_port[i].connect( + m_otf_scb.eg_exp_host_fifo[i].analysis_export); + m_fpp_agent.monitor.eg_rtl_port[i].connect( + m_otf_scb.eg_rtl_fifo[i].analysis_export); + m_fpp_agent.monitor.rd_cmd_port[i].connect( + m_otf_scb.rd_cmd_fifo[i].analysis_export); + m_fpp_agent.monitor.eg_rtl_lm_port[i].connect( + m_otf_scb.eg_exp_lm_fifo[i].analysis_export); + end + end + + // scb_otf_en is sampled at the end of build_phase in + // flash_ctrl_base_test. + // So this value has to be updated 'after' build_phase. + cfg.m_fpp_agent_cfg.scb_otf_en = cfg.scb_otf_en; + endfunction + + virtual function void end_of_elaboration_phase(uvm_phase phase); + super.end_of_elaboration_phase(phase); + // For fast receiver, set the range of asyn frequency between 1/5 and 10 times + // of core frequency + foreach (cfg.m_alert_agent_cfgs[i]) begin + if (cfg.m_alert_agent_cfgs[i].fast_rcvr) begin + int freq_mhz = cfg.clk_freq_mhz / 5; + cfg.m_alert_agent_cfgs[i].vif.clk_rst_async_if.set_freq_mhz( + $urandom_range(freq_mhz, cfg.clk_freq_mhz * 10)); + end + end + endfunction +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv new file mode 100644 index 0000000000000..1812badc2c99a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cfg.sv @@ -0,0 +1,1297 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +typedef class flash_ctrl_scoreboard; +typedef class flash_ctrl_otf_scoreboard; + +class flash_ctrl_env_cfg extends cip_base_env_cfg #( + .RAL_T(flash_ctrl_core_reg_block) +); + + // Type for an associative array on address and partition to record injected errors. + typedef bit per_caller_err_addr_tbl_t[addr_t][flash_dv_part_e]; + // Type for a regular array per read_task_e of the associative array above. + typedef per_caller_err_addr_tbl_t err_addr_tbl_t[NumReadTask]; + + // Memory backdoor util instances for each partition in each bank. + mem_bkdr_util mem_bkdr_util_h[flash_dv_part_e][flash_ctrl_pkg::NumBanks]; + + // Pass scoreboard handle to address multiple exp_alert issue. + flash_ctrl_scoreboard scb_h; + flash_ctrl_otf_scoreboard otf_scb_h; + + // seq cfg + flash_ctrl_seq_cfg seq_cfg; + + // Flash phy prim interface agent config + flash_phy_prim_agent_cfg m_fpp_agent_cfg; + // interface + virtual flash_ctrl_if flash_ctrl_vif; + virtual clk_rst_if clk_rst_vif_flash_ctrl_eflash_reg_block; + virtual clk_rst_if clk_rst_vif_flash_ctrl_prim_reg_block; + virtual flash_ctrl_mem_if flash_ctrl_mem_vif[NumBanks]; + + // knobs + // ral.status[init_wip] status is set for the very first clock cycle right out of reset. + // This causes problems in the read value especially in CSR tests. + int post_reset_delay_clks = 1; + + // Knob for blocking host reads + bit block_host_rd = 0; + + // Knob for control direct read checking + bit dir_rd_in_progress = 1'b0; + + // Knob for scoreboard write and check on reads + bit scb_check = 0; + + // Knob for scoreboard set expected alert + bit scb_set_exp_alert = 0; + + // Knob for Bank Erase + bit bank_erase_enable = 1; + + // Enable full checks of the scoreboard memory model, enabled by default. + bit check_full_scb_mem_model = 1'b1; + + // mem for scoreboard + data_model_t scb_flash_data = '{default: 1}; + data_model_t scb_flash_info = '{default: 1}; + data_model_t scb_flash_info1 = '{default: 1}; + data_model_t scb_flash_info2 = '{default: 1}; + + // Run small page rma + bit en_small_rma = 0; + + // Knob to enable on the fly scoreboard. + bit scb_otf_en = 0; + + // TB ecc support enable + // With ecc enabled, read path requires pre encoded data patterns. + // 0 : no ecc + // 1 : ecc enable + // Below mode use address split. + // 2 : 1 bit error test mode + // Based on serr_pct, single bit error is injected in 'flash_mem_otf_read' + // 3 : 2 bit error test mode + // 4 : integrity error test mode + ecc_mode_e ecc_mode = FlashEccDisabled; + + // For tracking addresses that have had errors injected use *err_addr_tbl, since they + // persist past each transaction. + + // single bit error rate scale of 0~10. 10: 100%. + int serr_pct = 0; + // Tracks lines with single bit errors. + local err_addr_tbl_t serr_addr_tbl; + + int serr_cnt[NumBanks] = '{default : 0}; + // latest single bit error address + bit [OTFBankId:0] serr_addr[NumBanks]; + + // Create serr only once. Used in directed test case. + bit serr_once = 0; + bit serr_created = 0; + + // Double bit error test + int derr_pct = 0; + int derr_idx[76]; + // Tracks lines with double bit errors. + local err_addr_tbl_t derr_addr_tbl; + bit derr_once = 0; + bit derr_created[read_task_e]; + + // Mark out standing transactions. + // With heavy concurrency, derr can be injected where read transaction + // is issued and outstanding. + // This can change error expectation of the first transaction. + // To handle this cornercase, don't assert derr on outstanding read location. + int derr_otd[rd_cache_t]; + + // Integrity ecc err + int ierr_pct = 0; + // Tracks lines with integrity errors. + local err_addr_tbl_t ierr_addr_tbl; + bit ierr_created [read_task_e]; + // Transaction counters for otf + int otf_ctrl_wr_sent = 0; + int otf_ctrl_wr_rcvd = 0; + int otf_ctrl_rd_sent = 0; + int otf_ctrl_rd_rcvd = 0; + int otf_host_rd_sent = 0; + int otf_host_rd_rcvd = 0; + + // Page to region map. + // This is used to validate transactions based on their page address + // and policy config associate with it. + // 8 : default region + int p2r_map[FlashNumPages] = '{default : 8}; + + flash_mp_region_cfg_t mp_regions[MpRegions]; + flash_bank_mp_info_page_cfg_t mp_info[NumBanks][InfoTypes][]; + + // Permission to access special partition + // 0: secret / creator + // 1: secret / owner + // 2: isolated + bit [2:0] allow_spec_info_acc = 3'h0; + + // Allow multiple expected allert in a single test + bit multi_alert_en = 0; + + // Max delay for alerts in clocks + uint alert_max_delay; + + // Max delay for alerts in ns + int alert_max_delay_in_ns; + + // read data by host if + data_q_t flash_rd_data; + + // 2bit of target prefix. Use with cfg.ecc_mode > FlashEccEnabled + // When cfg.ecc_mode > FlashEccEnabled, this will be randomized + // before sequence starts. + // tgt_pre[0]: rd + // tgt_pre[1]: direct_rd + // tgt_pre[2]: wr + // tgt_pre[3]: erase + // then assigned to bit 18:17 + bit [1:0] tgt_pre[flash_dv_part_e][NumTgt]; + + // Store recent 4 read address. + // If address is here, there is high chance read data is in cache. + // This can nullify error injection so task should avoid injecting error + // for these addresses. + flash_otf_read_entry otf_read_entry; + + // OTF Sequence parameters + int otf_num_rw = 250; + int otf_num_hr = 2500; + int otf_wr_pct = 1; + int otf_rd_pct = 1; + // overflow error rate + int otf_bwr_pct = 1; + int otf_brd_pct = 1; + + // interrupt mode + bit intr_mode = 0; + + // interrupt mode buffer credit + int rd_crd = 16; + + // fifo level to trigger lvl interrupt + int rd_lvl = 0; + int wr_lvl = 0; + + // force all region enable to '1' + // '0' doesn't affect randomization + bit en_always_read = 0; + bit en_always_erase = 0; + bit en_always_prog = 0; + bit en_always_all = 0; + + // This is not tied to plusarg. + // Internal use only. + bit en_always_any = 0; + + bit en_all_info_acc = 0; + // tlul error transaction counter + // compare at the end of sim + int tlul_core_exp_cnt = 0; + int tlul_core_obs_cnt = 0; + + int tlul_eflash_exp_cnt = 0; + int tlul_eflash_obs_cnt = 0; + + // stop rma process + bit rma_ack_polling_stop = 0; + + // Store program data for read back check + data_q_t prog_data[flash_op_t]; + + // Pointer for bkdr mem task. + logic [KeyWidth-1:0] otp_addr_key; + logic [KeyWidth-1:0] otp_data_key; + + bit skip_init = 0; + bit skip_init_buf_en = 0; + bit wr_rnd_data = 1; + int wait_rd_buf_en_timeout_ns = 100_000; // 100 us + + // hw info cfg override + mubi4_t ovrd_scr_dis = MuBi4False; + mubi4_t ovrd_ecc_dis = MuBi4False; + + `uvm_object_utils(flash_ctrl_env_cfg) + `uvm_object_new + + string flash_ral_name = "flash_ctrl_eflash_reg_block"; + + // default region cfg + flash_mp_region_cfg_t default_region_cfg = '{ + default: MuBi4True, + scramble_en: MuBi4False, + ecc_en: MuBi4False, + he_en: MuBi4False, + // Below two values won't be programmed + // rtl uses hardcoded values + // start:0 + // size : 2 * 256 (0x200) + num_pages: 512, + start_page: 0 + }; + + // default info cfg + flash_bank_mp_info_page_cfg_t default_info_page_cfg = '{ + default: MuBi4True, + scramble_en: MuBi4False, + ecc_en: MuBi4False, + he_en: MuBi4False + }; + + // 1page : 2048Byte + // returns 9 bit (max 512) pages + function int addr2page(bit[OTFBankId:0] addr); + return (int'(addr[OTFBankId:11])); + endfunction // addr2page + + virtual function flash_mp_region_cfg_t get_region(int page, bit dis = 1); + flash_mp_region_cfg_t my_region; + if (p2r_map[page] == 8) begin + my_region = default_region_cfg; + end else begin + my_region = mp_regions[p2r_map[page]]; + if (my_region.en != MuBi4True) my_region = default_region_cfg; + end + if (dis) begin + `uvm_info("get_region", $sformatf("page:%0d --> region:%0d", + page, p2r_map[page]), UVM_MEDIUM) + end + return my_region; + endfunction // get_region + + function flash_mp_region_cfg_t get_region_from_info(flash_bank_mp_info_page_cfg_t info); + flash_mp_region_cfg_t region; + region.en = info.en; + region.read_en = info.read_en; + region.program_en = info.program_en; + region.erase_en = info.erase_en; + region.scramble_en = info.scramble_en; + region.ecc_en = info.ecc_en; + region.he_en = info.he_en; + return region; + endfunction // get_region_from_info + + virtual function void initialize(addr_t csr_base_addr = '1); + string prim_ral_name = "flash_ctrl_prim_reg_block"; + string fast_rcvr_name = ""; + + list_of_alerts = flash_ctrl_env_pkg::LIST_OF_ALERTS; + tl_intg_alert_name = "fatal_std_err"; + sec_cm_alert_name = tl_intg_alert_name; + // Set up second RAL model for Flash memory + ral_model_names.push_back(flash_ral_name); + ral_model_names.push_back(prim_ral_name); + + // both RAL models use same clock frequency + clk_freqs_mhz[flash_ral_name] = clk_freq_mhz; + clk_freqs_mhz[prim_ral_name] = clk_freq_mhz; + super.initialize(csr_base_addr); + + void'($value$plusargs("fast_rcvr_%s", fast_rcvr_name)); + if (fast_rcvr_name != "") begin + m_alert_agent_cfgs[fast_rcvr_name].fast_rcvr = 1; + end + tl_intg_alert_fields[ral.std_fault_status.reg_intg_err] = 1; + shadow_update_err_status_fields[ral.err_code.update_err] = 1; + shadow_storage_err_status_fields[ral.std_fault_status.storage_err] = 1; + + // create the seq_cfg and call configure + seq_cfg = flash_ctrl_seq_cfg::type_id::create("seq_cfg"); + seq_cfg.configure(); + + m_fpp_agent_cfg = flash_phy_prim_agent_cfg::type_id::create("m_fpp_agent_cfg"); + m_fpp_agent_cfg.is_active = 0; + m_fpp_agent_cfg.en_cov = 0; + + // set num_interrupts & num_alerts + num_interrupts = ral.intr_state.get_n_used_bits(); + + m_tl_agent_cfg.max_outstanding_req = 1; + m_tl_agent_cfgs[flash_ral_name].max_outstanding_req = 2; + m_tl_agent_cfgs[prim_ral_name].max_outstanding_req = 1; + + alert_max_delay = 20000; + `uvm_info(`gfn, $sformatf("ral_model_names: %0p", ral_model_names), UVM_LOW) + + foreach (tgt_pre[FlashPartData][i]) tgt_pre[FlashPartData][i] = i; + foreach (tgt_pre[FlashPartInfo][i]) tgt_pre[FlashPartInfo][i] = i; + foreach (tgt_pre[FlashPartInfo1][i]) tgt_pre[FlashPartInfo1][i] = i; + foreach (tgt_pre[FlashPartInfo2][i]) tgt_pre[FlashPartInfo2][i] = i; + + foreach (derr_idx[i]) derr_idx[i] = i; + foreach (mp_info[i, j]) mp_info[i][j] = new[InfoTypeSize[j]]; + otf_read_entry = new("otf_read_entry"); + endfunction : initialize + + // For a given partition returns its size in bytes in each of the banks. + function uint get_partition_words_num(flash_dv_part_e part); + case(part) + FlashPartData: return BytesPerBank / 4; + FlashPartInfo: return InfoTypeBytes[0] / 4; + FlashPartInfo1: return InfoTypeBytes[1] / 4; + FlashPartInfo2: return InfoTypeBytes[2] / 4; + default: `uvm_error(`gfn, $sformatf("Undefined partition - %s", part.name())) + endcase + endfunction : get_partition_words_num + + // Method to do a back-door update of a selected partition memory model to the actual flash data. + // Usualy should only be done after flash initialization. + task update_partition_mem_model(flash_dv_part_e part); + flash_mem_addr_attrs addr_attr; + data_4s_t bkdr_rd_data; + uint partition_words_num; + data_model_t scb_flash_model; + addr_attr = new(); + partition_words_num = get_partition_words_num(part); + + `uvm_info(`gfn, $sformatf("\nStart back-door updating partition %s memory model\n", + part.name()), UVM_MEDIUM) + + for (int i = 0; i < flash_ctrl_pkg::NumBanks; i++) begin : iterate_all_banks + addr_attr.set_attrs(i * BytesPerBank); + for (int j = 0; j < partition_words_num; j++) begin : iterate_all_bank_partition_words + bkdr_rd_data = mem_bkdr_util_h[part][addr_attr.bank].read32(addr_attr.bank_addr); + if ($isunknown(bkdr_rd_data)) begin + scb_flash_model[addr_attr.addr] = ALL_ONES; + end else begin + scb_flash_model[addr_attr.addr] = bkdr_rd_data; + end + addr_attr.incr(flash_ctrl_pkg::BusBytes); + end : iterate_all_bank_partition_words + end : iterate_all_banks + + case(part) + flash_ctrl_env_pkg::FlashPartData: scb_flash_data = scb_flash_model; + flash_ctrl_env_pkg::FlashPartInfo: scb_flash_info = scb_flash_model; + flash_ctrl_env_pkg::FlashPartInfo1: scb_flash_info1 = scb_flash_model; + flash_ctrl_env_pkg::FlashPartInfo2: scb_flash_info2 = scb_flash_model; + default: `uvm_error(`gfn, $sformatf("Undefined partition - %s", part.name())) + endcase + + `uvm_info(`gfn, $sformatf("\nFinished back-door updating partition %s memory model\n", + part.name()), UVM_MEDIUM) + + endtask : update_partition_mem_model + + // Backdoor initialize flash memory elements. + // Applies the initialization scheme to the given flash partition in all banks. + // @part is the type of flash partition. + // @scheme is the type of initialization to be done. + virtual task flash_mem_bkdr_init(flash_dv_part_e part = FlashPartData, + flash_mem_init_e scheme); + + `uvm_info("flash_mem_bkdr_init", $sformatf("scheme: %s", scheme.name), UVM_MEDIUM) + case (scheme) + FlashMemInitSet: begin + foreach (mem_bkdr_util_h[part][i]) mem_bkdr_util_h[part][i].set_mem(); + end + FlashMemInitClear: begin + foreach (mem_bkdr_util_h[part][i]) mem_bkdr_util_h[part][i].clear_mem(); + end + FlashMemInitRandomize: begin + foreach (mem_bkdr_util_h[part][i]) mem_bkdr_util_h[part][i].randomize_mem(); + end + FlashMemInitInvalidate: begin + foreach (mem_bkdr_util_h[part][i]) mem_bkdr_util_h[part][i].invalidate_mem(); + end + FlashMemInitEccMode: begin + foreach (mem_bkdr_util_h[part][i]) mem_bkdr_util_h[part][i].set_mem(); + end + default: begin + `uvm_error(`gfn, $sformatf("Undefined initialization scheme - %s", scheme.name())) + end + endcase + + // Update the memory model with the initialization data + if (scb_check) update_partition_mem_model(part); + endtask : flash_mem_bkdr_init + + // For a given partition returns its respective memory model. + function data_model_t get_partition_mem_model(flash_ctrl_env_pkg::flash_dv_part_e part); + case(part) + flash_ctrl_env_pkg::FlashPartData: return scb_flash_data; + flash_ctrl_env_pkg::FlashPartInfo: return scb_flash_info; + flash_ctrl_env_pkg::FlashPartInfo1: return scb_flash_info1; + flash_ctrl_env_pkg::FlashPartInfo2: return scb_flash_info2; + default: `uvm_error(`gfn, $sformatf("Undefined partition - %s", part.name())) + endcase + endfunction : get_partition_mem_model + + // Task to back-door check a selected partition memory model + // This will be called in the scoreboard check_phase if the check_full_scb_mem_model will + // be set to 1 (enabled by default). + function void check_partition_mem_model(flash_ctrl_env_pkg::flash_dv_part_e part); + flash_mem_addr_attrs addr_attr; + data_4s_t bkdr_rd_data; + data_model_t scb_flash_model = get_partition_mem_model(part); + addr_attr = new(); + foreach (scb_flash_model[addr]) begin + addr_attr.set_attrs(addr); + bkdr_rd_data = mem_bkdr_util_h[part][addr_attr.bank].read32(addr_attr.bank_addr); + if ($isunknown(bkdr_rd_data)) bkdr_rd_data = ALL_ONES; + `DV_CHECK_EQ(bkdr_rd_data, scb_flash_model[addr], + $sformatf({"Memory model check failed in partition %s, bank %0d, addr 0x%0x ", + "(%0d)"}, part.name(), addr_attr.bank, addr_attr.bank_addr, + addr_attr.bank_addr)) + end + endfunction : check_partition_mem_model + + // Task to back-door check the full memory model + // This will be called in the scoreboard check_phase & between calls to the inner rand_ops vseq + // (in partner_flash_ctrl_base_vseq post_tran task) if the check_full_scb_mem_model will + // be set to 1 (enabled by default). + function void check_mem_model(); + flash_ctrl_env_pkg::flash_dv_part_e part = part.first(); + `uvm_info(`gfn, $sformatf("\nStart checking all memory model\n"), UVM_MEDIUM) + do begin + check_partition_mem_model(part); + part = part.next(); + end while (part != part.first()); + `uvm_info(`gfn, $sformatf("\nFinished checking all memory model\n"), UVM_MEDIUM) + endfunction : check_mem_model + + // Read full word from the memory. (76bits per word line) + // flash_op.op should be FlashOpRead + function void flash_mem_otf_read(flash_op_t flash_op, ref fdata_q_t data); + flash_dv_part_e partition; + int bank; + logic [flash_phy_pkg::FullDataWidth-1:0] rdata; + int size, is_odd, tail; + + // If address is not 8byte aligned, full 76bit has to be read. + // This exception is identified using 4Byte address bit, (addr[2]) + // and size of 4byte word. + is_odd = flash_op.addr[2]; + size = (flash_op.num_words + is_odd) / 2; + tail = (flash_op.num_words + is_odd) % 2; + // QW (8byte) align + flash_op.addr[2:0] = 'h0; + + `uvm_info("flash_mem_otf_read", $sformatf( + "addr:0x%x is_odd:%0d size:%0d tail:%0d wd:%0d", flash_op.addr, is_odd, size, tail, + flash_op.num_words), UVM_MEDIUM) + for (int i = 0; i < size; i++) begin + flash_bkdr_read_full_word(flash_op, rdata); + `uvm_info("flash_mem_otf_read", $sformatf("addr:0x%x data:0x%x", flash_op.addr, rdata), + UVM_MEDIUM) + data.push_back(rdata); + flash_op.addr += 8; + end + if (tail) begin + flash_bkdr_read_full_word(flash_op, rdata); + `uvm_info("flash_mem_otf_read", $sformatf("addr:0x%x data:0x%x", flash_op.addr, rdata), + UVM_MEDIUM) + data.push_back(rdata); + end + endfunction // flash_mem_otf_read + + // Method to read one full width word of the flash. + virtual function void flash_bkdr_read_full_word(flash_op_t flash_op, + ref logic [flash_phy_pkg::FullDataWidth-1:0] word_data); + flash_mem_addr_attrs addr_attrs = new(flash_op.addr); + word_data = mem_bkdr_util_h[flash_op.partition][addr_attrs.bank].read(addr_attrs.bank_addr); + endfunction : flash_bkdr_read_full_word + + // Reads flash mem contents via backdoor. + // + // The addr arg need not be word aligned - its the same addr programmed into the `control` CSR. + virtual function void flash_mem_bkdr_read(flash_op_t flash_op, ref data_q_t data); + flash_mem_addr_attrs addr_attrs = new(flash_op.addr); + + if (flash_op.op == flash_ctrl_pkg::FlashOpErase) begin + case (flash_op.erase_type) + flash_ctrl_pkg::FlashErasePage: begin + addr_attrs.set_attrs(addr_attrs.bank_start_addr + addr_attrs.page_start_addr); + flash_op.num_words = FlashNumBusWordsPerPage; + end + flash_ctrl_pkg::FlashEraseBank: begin + addr_attrs.set_attrs(addr_attrs.bank * BytesPerBank); + case (flash_op.partition) + FlashPartData: begin + flash_op.num_words = FlashNumBusWordsPerBank; + end + FlashPartInfo: begin + flash_op.num_words = InfoTypeBusWords[0]; + end + default: begin + `uvm_fatal(`gfn, $sformatf( + { + "Invalid partition for bank_erase: %0s. ", + "Bank erase is only valid in the data partition ", + "(FlashPartData) and the first info partition ", + "(FlashPartInfo)." + }, + flash_op.partition.name() + )) + end + endcase + end + default: begin + `uvm_fatal(`gfn, $sformatf("Invalid erase_type: %0s", flash_op.erase_type.name())) + end + endcase + end + + data.delete(); + for (int i = 0; i < flash_op.num_words; i++) begin + data[i] = mem_bkdr_util_h[flash_op.partition][addr_attrs.bank].read32(addr_attrs.bank_addr); + `uvm_info(`gfn, $sformatf( + "flash_mem_bkdr_read: partition = %s , {%s} = 0x%0h", + flash_op.partition.name(), + addr_attrs.sprint(), + data[i] + ), UVM_HIGH) + addr_attrs.incr(TL_DBW); + end + endfunction : flash_mem_bkdr_read + + // Writes the flash mem contents via backdoor. + // + // The addr need not be bus word aligned, Its the same addr programmed into the `control` CSR. + // The data queue is sized for the bus word. + virtual function void flash_mem_bkdr_write(flash_op_t flash_op, flash_mem_init_e scheme, + data_q_t data = {}); + flash_mem_addr_attrs addr_attrs = new(flash_op.addr); + data_4s_t wr_data; + data_b_t mem_data; + + // Randomize the lower half-word (if Xs) if the first half-word written in the below loop is + // corresponding upper half-word. + if (addr_attrs.bank_addr[flash_ctrl_pkg::DataByteWidth-1]) begin + _randomize_uninitialized_half_word(.partition(flash_op.partition), .bank(addr_attrs.bank), + .addr(addr_attrs.word_addr)); + end + + case (scheme) + FlashMemInitCustom: begin + flash_op.num_words = data.size(); + end + FlashMemInitSet: begin + wr_data = {flash_ctrl_pkg::DataWidth{1'b1}}; + end + FlashMemInitClear: begin + wr_data = {flash_ctrl_pkg::DataWidth{1'b0}}; + end + FlashMemInitInvalidate: begin + wr_data = {flash_ctrl_pkg::DataWidth{1'bx}}; + end + default: ; // Do nothing. + endcase + + for (int i = 0; i < flash_op.num_words; i++) begin + data_4s_t loc_data = (scheme == FlashMemInitCustom) ? data[i] : + (scheme == FlashMemInitRandomize) ? $urandom() : wr_data; + + _flash_full_write(flash_op.partition, addr_attrs.bank, addr_attrs.bank_addr, loc_data); + `uvm_info(`gfn, $sformatf( + "flash_mem_bkdr_write: partition = %s, {%s} = 0x%0h", + flash_op.partition.name(), + addr_attrs.sprint(), + loc_data + ), UVM_HIGH) + + // update the scoreboard on backdoor-programs as well + mem_data[0] = loc_data; + set_scb_mem(1, flash_op.partition, + addr_attrs.addr, CustomVal, mem_data); + + // increment after all updates are complete + addr_attrs.incr(TL_DBW); + end + + // Randomize the upper half-word (if Xs) if the last word written in the above loop is + // corresponding lower half-word. + if (addr_attrs.bank_addr[flash_ctrl_pkg::DataByteWidth-1]) begin + _randomize_uninitialized_half_word(.partition(flash_op.partition), .bank(addr_attrs.bank), + .addr(addr_attrs.bank_addr)); + end + endfunction : flash_mem_bkdr_write + + // Helper function that takes a 32-bit data and correctly populates the integrity ECC + // + function void _flash_full_write(flash_dv_part_e partition, uint bank, + // bus word aligned address + addr_t addr, + data_t wr_data); + + // read back the full flash word + logic [flash_ctrl_pkg::DataWidth-1:0] data; + logic [7:0] intg_data; + logic is_upper = addr[flash_ctrl_pkg::DataByteWidth-1]; + addr_t aligned_addr = addr; + + if (is_upper) begin + aligned_addr = {addr[TL_AW-1:FlashDataByteWidth], {FlashDataByteWidth{1'b0}}}; + end + + // get the full flash word + data = mem_bkdr_util_h[partition][bank].read64(aligned_addr); + + // writing the upper portion of the flash word + if (is_upper) begin + data = {wr_data, data[TL_DW-1:0]}; + end else begin + data = {data[flash_ctrl_pkg::DataWidth-1:TL_DW], wr_data}; + end + + // calculate truncated integrity + {intg_data, data} = prim_secded_pkg::prim_secded_hamming_72_64_enc(data); + + // program fully via backdoor + // TODO: review this later. + // it has to be write(aligned_addr, instead of write64(aligned_addr + mem_bkdr_util_h[partition][bank].write64(aligned_addr, {intg_data[3:0], data}); + + // Update scoreboard memory model with this back-door write + if (scb_check) begin + write_data_all_part(.part(partition), .addr({bank, addr[FlashMemAddrPageMsbBit:0]}), + .is_front_door(1'b0), .data(wr_data)); + end + + endfunction : _flash_full_write + + + // Helper function that randomizes the half-word at the given address if unknown. + // + // When the 'other' flash half-word is being written by the flash_mem_bkdr_write() method, the + // half-word at the given address needs to also be updated, of the data at that address is + // unknown. This is needed because the flash_ctrl RTL internally fetches full words. This method + // randomizes the data at the given address via backdoor. + function void _randomize_uninitialized_half_word(flash_dv_part_e partition, uint bank, + addr_t addr); + data_4s_t data = mem_bkdr_util_h[partition][bank].read32(addr); + if ($isunknown(data)) begin + `DV_CHECK_STD_RANDOMIZE_FATAL(data) + `uvm_info(`gfn, $sformatf("Data at 0x%0h is Xs, writing random 0x%0h", addr, data), UVM_HIGH) + _flash_full_write(partition, bank, addr, data); + end + endfunction + + // Checks flash mem contents via backdoor. + // + // The addr need not be bus word aligned. Its the same addr programmed into the `control` CSR. + // The exp data queue is sized for the bus word. + // TODO: support for partition. + virtual function void flash_mem_bkdr_read_check(flash_op_t flash_op, + const ref data_q_t exp_data, + input bit check_match = 1, + bit scr_en = 0, + int ecc_en = 2); + data_q_t data; + flash_otf_item item; + + // Default value of ecc_en in this function should be the same as scr_en + if (ecc_en == 2) ecc_en = scr_en; + // If scramble is enabled, read data and descramble before return. + if (scr_en) begin + `uvm_create_obj(flash_otf_item, item) + flash_mem_otf_read(flash_op, item.fq); + flash_op.otf_addr = flash_op.addr; + flash_op.otf_addr[BusAddrByteW-2:OTFHostId] = 'h0; + + item.region.scramble_en = MuBi4True; + item.region.ecc_en = (ecc_en)? MuBi4True : MuBi4False; + item.mem_addr = flash_op.otf_addr>>3; + item.descramble(otp_addr_key, otp_data_key); + foreach (item.dq[i]) data[i] = item.dq[i]; + end else begin + flash_mem_bkdr_read(flash_op, data); + end + + foreach (data[i]) begin + if (check_match) begin + `DV_CHECK_CASE_EQ(data[i], exp_data[i]) + end else begin + `DV_CHECK_CASE_NE(data[i], exp_data[i]) + end + end + endfunction : flash_mem_bkdr_read_check + + // Verifies that the flash page / bank has indeed been erased. + virtual function void flash_mem_bkdr_erase_check(flash_op_t flash_op, data_q_t exp_data = {}, + bit check_match = 1); + flash_mem_addr_attrs addr_attrs = new(flash_op.addr); + bit [TL_AW-1:0] erase_check_addr; + string erase_page_num_msg; + uint num_words; + + case (flash_op.erase_type) + flash_ctrl_pkg::FlashErasePage: begin + erase_check_addr = addr_attrs.page_start_addr; + num_words = FlashNumBusWordsPerPage; + erase_page_num_msg = $sformatf("page = %0d, ", addr_attrs.page); + end + flash_ctrl_pkg::FlashEraseBank: begin + // This address is relative to the bank it's in. + erase_check_addr = 0; + // No need to state page for bank erase. + erase_page_num_msg = ""; + case (flash_op.partition) + FlashPartData: begin + num_words = FlashNumBusWordsPerBank; + end + FlashPartInfo: begin + num_words = InfoTypeBusWords[0]; + end + default: begin + `uvm_fatal(`gfn, $sformatf( + { + "Invalid partition for bank_erase: %0s. ", + "Bank erase is only valid in the data partition ", + "(FlashPartData) and the first info partition ", + "(FlashPartInfo)." + }, + flash_op.partition.name() + )) + end + endcase + end + default: begin + `uvm_fatal(`gfn, $sformatf("Invalid erase_type: %0s", flash_op.erase_type.name())) + end + endcase + `uvm_info(`gfn, $sformatf( + { + "flash_mem_bkdr_erase_check: Erase type = %s, bank = %0d, ", + "partition = %s , %snum_words = %0d" + }, + flash_op.erase_type.name(), + addr_attrs.bank, + flash_op.partition.name(), + erase_page_num_msg, + num_words + ), UVM_MEDIUM) + + for (int i = 0; i < num_words; i++) begin + data_4s_t data; + data = mem_bkdr_util_h[flash_op.partition][addr_attrs.bank].read32(erase_check_addr); + `uvm_info(`gfn, $sformatf( + { + "flash_mem_bkdr_erase_check: Erase type = %s, bank: %0d, ", + "partition: %s , %saddr: 0x%0h, data: 0x%0h" + }, + flash_op.erase_type.name(), + addr_attrs.bank, + flash_op.partition.name(), + erase_page_num_msg, + erase_check_addr, + data + ), UVM_HIGH) + // If the expected data is not empty then it should be taken is expected. If it is empty the + // default expected value is checked - which for successful erase is all 1s. + if (check_match) begin + if (exp_data.size() <= i) begin + `DV_CHECK_CASE_EQ(data, '1) + end else begin + `DV_CHECK_CASE_EQ(data, exp_data[i]) + end + end else begin + `DV_CHECK_CASE_NE(data, '1) + end + erase_check_addr += TL_DBW; + end + endfunction : flash_mem_bkdr_erase_check + + // Function to enable changing of the expected data to be checked in the post-transaction + // checks. + virtual function data_q_t calculate_expected_data(flash_op_t flash_op, + const ref data_q_t exp_data); + data_q_t rdata; + data_q_t data; + flash_mem_bkdr_read(flash_op, rdata); + foreach(exp_data[i]) data[i] = exp_data[i] & rdata[i]; + + return data; + endfunction : calculate_expected_data + + // Writing data to the scoreboard memory model, this writes one word of data to the selected + // address in the selected partition. + // is_front_door added to indicate if this method called by front-door + // write (program transaction), which is the default, or by back-door methods. + // This is required for extending env. + virtual function void write_data_all_part(flash_dv_part_e part, addr_t addr, + bit is_front_door = 1'b1, ref data_t data); + `uvm_info(`gfn, $sformatf("WRITE SCB MEM part: %0s addr:%0h data:0x%0h", + part.name, addr, data), UVM_HIGH) + case (part) + FlashPartData: scb_flash_data[addr] = data; + FlashPartInfo: scb_flash_info[addr] = data; + FlashPartInfo1: scb_flash_info1[addr] = data; + FlashPartInfo2: scb_flash_info2[addr] = data; + default: `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Partition type not supported!") + endcase + endfunction + + // Task for clean scb memory + virtual function reset_scb_mem(); + scb_flash_data.delete(); + scb_flash_info.delete(); + scb_flash_info1.delete(); + scb_flash_info2.delete(); + endfunction : reset_scb_mem + + // Task for set scb memory + virtual function set_scb_mem(int bkd_num_words, flash_dv_part_e bkd_partition, + addr_t write_bkd_addr,flash_scb_wr_e val_type, + data_b_t custom_val = {}); + addr_t wr_bkd_addr; + data_t wr_value; + + `uvm_info(`gfn, $sformatf( + "SET SCB MEM TEST part: %0s addr:%0h data:0x%0h num: %0d", + bkd_partition.name, + write_bkd_addr, + wr_value, + bkd_num_words + ), UVM_HIGH) + wr_bkd_addr = {write_bkd_addr[TL_AW-1:2], 2'b00}; + `uvm_info(`gfn, $sformatf("SET SCB MEM ADDR:%0h", wr_bkd_addr), UVM_HIGH) + for (int i = 0; i < bkd_num_words; i++) begin + case (val_type) + AllOnes: begin + wr_value = ALL_ONES; + end + AllZeros: begin + wr_value = ALL_ZEROS; + end + CustomVal: begin + wr_value = custom_val[i]; + end + default: `uvm_fatal(`gfn, "Unknown write type, allowed: AllOnes, AllZeros, CustomVal") + endcase + `uvm_info(`gfn, $sformatf( + "SET SCB MEM part: %0s addr:%0h data:0x%0h num: %0d", + bkd_partition.name, + wr_bkd_addr, + wr_value, + bkd_num_words + ), UVM_HIGH) + write_data_all_part(.part(bkd_partition), .addr(wr_bkd_addr), .is_front_door(1'b0), + .data(wr_value)); + wr_bkd_addr = wr_bkd_addr + 4; + end + endfunction : set_scb_mem + + // Increase single bit error count. + function void inc_serr_cnt(int bank, bit dis = 0); + if (serr_cnt[bank] < 255) serr_cnt[bank]++; + if (dis) begin + `uvm_info("inc_serr_cnt", $sformatf("serr_cnt[%0d]=%0d", bank, serr_cnt[bank]), UVM_MEDIUM) + end + endfunction + + // Flip a bit at given address. + function void flash_bit_flip(mem_bkdr_util _h, addr_t addr, int idx); + bit [75:0] rdata; + rdata = _h.read(addr); + `uvm_info(`gfn, $sformatf("ECC error injection at address 0x%x for bit %0d", addr, idx), + UVM_MEDIUM) + rdata[idx] = ~rdata[idx]; + _h.write(addr, rdata); + endfunction + + // Corrupt integrity check value only + virtual function void flash_icv_flip(mem_bkdr_util _h, addr_t addr, flash_dv_part_e part, + bit bank, flash_otf_item exp_item); + flash_otf_item item; + + `uvm_create_obj(flash_otf_item, item) + item.dq.push_back($urandom()); + item.dq.push_back($urandom()); + if (part == FlashPartData) begin + addr_t full_addr = addr; + full_addr[OTFBankId] = bank; + item.region = get_region(addr2page(full_addr)); + end else begin + item.region = get_region_from_info(mp_info[bank][part>>1][addr2page(addr)]); + end + `uvm_info(`gfn, $sformatf("Integrity error injection at address 0x%x", addr), UVM_MEDIUM) + item.scramble(exp_item.addr_key, exp_item.data_key, addr, 1, 1); + _h.write(addr, item.fq[0]); + item.clear_qs(); + endfunction + + // This shows errors injected per the given caller table. + local function void show_errors(ref per_caller_err_addr_tbl_t addr_tbl); + addr_t addr; + if (addr_tbl.first(addr) == 0) return; + while (addr_tbl.next(addr) != 0) begin + flash_dv_part_e part; + `DV_CHECK_EQ(addr_tbl[addr].first(part), 1) + do + `uvm_info(`gfn, $sformatf("error injected at addr:0x%x, part:%0s", addr, part.name), + UVM_MEDIUM) + while (addr_tbl[addr].next(part) != 0); + end + endfunction + + function void show_derrors(read_task_e caller); + `uvm_info(`gfn, $sformatf("Double bit errors injected for %s caller:", caller.name), + UVM_MEDIUM) + show_errors(derr_addr_tbl[caller]); + endfunction + + local function int err_count(ref per_caller_err_addr_tbl_t err_addr_tbl); + int count = 0; + addr_t addr; + if (err_addr_tbl.first(addr) == 0) return 0; + while (err_addr_tbl.next(addr) != 0) begin + flash_dv_part_e part; + `DV_CHECK_EQ(err_addr_tbl[addr].first(part), 1) + do count++; while (err_addr_tbl[addr].next(part) != 0); + end + return count; + endfunction + + // These count the total number of errors per caller for the different error kinds. + function int derr_count(input read_task_e caller); + return err_count(derr_addr_tbl[caller]); + endfunction + + function int ierr_count(input read_task_e caller); + return err_count(ierr_addr_tbl[caller]); + endfunction + + function int serr_count(input read_task_e caller); + return err_count(serr_addr_tbl[caller]); + endfunction + + local function bit address_has_err(ref err_addr_tbl_t err_addr_tbl, input addr_t addr, + input flash_dv_part_e part); + return (err_addr_tbl[ReadTaskCtrl].exists(addr) && + err_addr_tbl[ReadTaskCtrl][addr].exists(part)) || + (err_addr_tbl[ReadTaskHost].exists(addr) && + err_addr_tbl[ReadTaskHost][addr].exists(part)); + endfunction + + // These functions are used to track the creation of lines with bit errors. + function bit address_has_derr(addr_t addr, flash_dv_part_e part); + return address_has_err(derr_addr_tbl, addr, part); + endfunction + + function bit address_has_ierr(addr_t addr, flash_dv_part_e part); + return address_has_err(ierr_addr_tbl, addr, part); + endfunction + + function bit address_has_serr(addr_t addr, flash_dv_part_e part); + return address_has_err(serr_addr_tbl, addr, part); + endfunction + + function bit address_has_some_injected_error(addr_t addr, flash_dv_part_e part); + return address_has_derr(addr, part) || address_has_ierr(addr, part) || + address_has_serr(addr, part); + endfunction + + virtual function bit address_has_ecc_injected_error(addr_t addr, flash_dv_part_e part); + return address_has_derr(addr, part) || address_has_serr(addr, part); + endfunction + + protected function void add_derr(input addr_t addr, input flash_dv_part_e partition, + input read_task_e caller, input int idx_0, input int idx_1); + int bank = addr[OTFBankId]; + + `uvm_info(`gfn, $sformatf( + "double bit ecc error injected for %s at bank %0d %s addr:0x%x bits %0d and %0d", + caller.name, bank, partition.name, addr, idx_0, idx_1), + UVM_MEDIUM) + derr_addr_tbl[caller][addr][partition] = 1; + derr_created[caller] = 1; + endfunction + + protected function void add_ierr(input addr_t addr, input flash_dv_part_e partition, + input read_task_e caller); + int bank = addr[OTFBankId]; + + `uvm_info(`gfn, $sformatf("icv error injected for %s at bank %0d %s addr:0x%x", + caller.name, bank, partition.name, addr), + UVM_MEDIUM) + ierr_addr_tbl[caller][addr][partition] = 1; + ierr_created[caller] = 1; + endfunction + + function void add_serr(input addr_t addr, input flash_dv_part_e partition, + input read_task_e caller, input int bit_index); + int bank = addr[OTFBankId]; + + `uvm_info(`gfn, $sformatf( + "single bit ecc error injected for %s at bank %0d %s addr:0x%x bit %0d", + caller.name, bank, partition.name, addr, bit_index), UVM_MEDIUM) + serr_addr_tbl[caller][addr][partition] = 1; + endfunction + + // Create bit error following flash_op and ecc_mode. + // @caller : 0 controller, 1: host + virtual function void add_bit_err(flash_op_t flash_op, read_task_e caller = ReadTaskCtrl, + flash_otf_item item = null); + flash_dv_part_e partition; + int bank; + bit [75:0] rdata; + int size, is_odd, tail; + // The flash word aligned address including the bank. + addr_t addr_cp; + rd_cache_t rd_entry; + string name = $sformatf("add_bit_err from %s", caller.name); + + bank = flash_op.addr[OTFBankId]; + partition = flash_op.partition; + rd_entry.bank = bank; + rd_entry.part = partition; + // If address is not 8byte aligned, full 76bit has to be read. + // This exception is identified using 4Byte address bit, (addr[2]) + // and size of 4byte word. + is_odd = flash_op.addr[2]; + size = (flash_op.num_words + is_odd) / 2; + tail = (flash_op.num_words + is_odd) % 2; + + addr_cp = flash_op.addr; + // flash word is 8 byte aligned + addr_cp[2:0] = 'h0; + + // Include tail in the range of flash words to consider for error injection. + for (int i = 0; i < size + tail; i++) begin + // For controller initiated read, in the worst case, each word (8byte) can belong to + // different memory protection region. + // So before inject bit error, we have to check per word ecc_en + // to make sure bit error injection become valid. + // If ecc is not enabled, bit error cannot be detected. + if (caller == ReadTaskHost || (item.ctrl_rd_region_q[i].ecc_en == MuBi4True)) begin + otf_addr_t otf_addr = otf_addr_t'(addr_cp); + rd_entry.addr = addr_cp; + if (ecc_mode == FlashSerrTestMode) begin + randcase + serr_pct: begin + int err_idx; + if (serr_once && serr_created) continue; + // Do not inject more than one error per address. + if (address_has_some_injected_error(addr_cp, partition)) begin + `uvm_info(`gfn, $sformatf( + "single bit error injection %s bank:%0d addr:0x%x blocked by prior", + partition.name, bank, otf_addr), UVM_MEDIUM) + continue; + end + err_idx = $urandom_range(0, 75); + flash_bit_flip(mem_bkdr_util_h[partition][bank], otf_addr, err_idx); + add_serr(addr_cp, partition, caller, err_idx); + end + 10-serr_pct: begin + end + endcase + end else if (ecc_mode == FlashIerrTestMode) begin + randcase + ierr_pct: begin + if (derr_otd.exists(rd_entry)) begin + `uvm_info(`gfn, $sformatf( + "icv error injection %s bank:%0d addr:0x%x blocked by otd", + partition.name, bank, otf_addr), UVM_MEDIUM) + continue; + end + if (address_has_some_injected_error(addr_cp, partition)) begin + `uvm_info(`gfn, $sformatf( + "icv error injection %s bank:%0d addr:0x%x blocked by prior error", + partition.name, bank, otf_addr), UVM_MEDIUM) + continue; + end + flash_icv_flip(mem_bkdr_util_h[partition][bank], otf_addr, partition, bank, + item); + add_ierr(addr_cp, partition, caller); + end + 10-ierr_pct: begin + end + endcase // randcase + end else begin // ecc_mode == FlashDerrTestMode) + randcase + derr_pct: begin + string block_reason = ""; + if (derr_once == 1 && derr_created[caller] == 1'b1) continue; + if (derr_otd.exists(rd_entry)) begin + block_reason = "otd"; + end else if (address_has_some_injected_error(addr_cp, partition)) begin + block_reason = "prior error"; + end else if (otf_read_entry.hash.exists(rd_entry)) begin + block_reason = "otf_read_entry"; + end + if (block_reason != "") begin + `uvm_info(`gfn, $sformatf( + "double bit error injection %s bank:%0d addr:0x%x blocked by %s", + partition.name, bank, otf_addr, block_reason), UVM_MEDIUM) + continue; + end + derr_idx.shuffle(); + flash_bit_flip(mem_bkdr_util_h[partition][bank], otf_addr, derr_idx[0]); + flash_bit_flip(mem_bkdr_util_h[partition][bank], otf_addr, derr_idx[1]); + add_derr(addr_cp, partition, caller, derr_idx[0], derr_idx[1]); + end + 10-derr_pct: begin + end + endcase + end + addr_cp += 8; + // Don't change banks. + if (addr_cp[OTFBankId] != bank) break; + end + end + endfunction : add_bit_err + + // Increase outstanding table entry. + function void inc_otd_tbl(bit bank, addr_t addr, flash_dv_part_e part); + rd_cache_t ent; + ent.bank = bank; + ent.addr = align_to_flash_word(addr); + ent.part = part; + if (!derr_otd.exists(ent)) begin + derr_otd[ent] = 1; + end else begin + derr_otd[ent]++; + end + endfunction // inc_otd_tbl + + // Descrease outstanding table entry. + function void dec_otd_tbl(bit bank, addr_t addr, flash_dv_part_e part); + rd_cache_t ent; + ent.bank = bank; + ent.addr = align_to_flash_word(addr); + ent.part = part; + if (!derr_otd.exists(ent)) begin + `uvm_error("dec_otd_tbl", $sformatf("addr %x %s doesn't exits", addr, part.name)) + end else begin + derr_otd[ent]--; + if (derr_otd[ent] == 0) derr_otd.delete(ent); + end + endfunction // dec_otd_tbl + + function flash_dv_part_e get_part(flash_part_e part, + logic [InfoTypesWidth-1:0] mem_info_sel); + if (part == FlashPartData) begin + return FlashPartData; + end else begin + case (mem_info_sel) + 1: return FlashPartInfo1; + 2: return FlashPartInfo2; + default: return FlashPartInfo; + endcase + end + endfunction // get_part + + virtual function void load_otf_mem_page(flash_dv_part_e part, + int bank, + int page); + addr_t addr = '0; + addr[OTFBankId-1:11] = page; + `uvm_info(`gfn, $sformatf("in load_otf_mem_page bank:%0d %s, page:%0d", bank, part.name, page), + UVM_HIGH) + update_otf_mem_read_zone(part, bank, addr, addr + BytesPerPage - 1); + endfunction : load_otf_mem_page + + function void update_otf_mem_read_zone(flash_dv_part_e part, int bank, + addr_t start_addr, addr_t end_addr); + start_addr = align_to_flash_word(start_addr); + `uvm_info(`gfn, $sformatf( + "mem_bkdr initializing bank:%0d %s from 0x%x to 0x%x per attributes", + bank, part.name, start_addr, end_addr), + UVM_HIGH) + for (addr_t addr = start_addr; addr <= end_addr; addr += 8) begin + flash_otf_item item; + int page; + bit [BankAddrW-1:0] mem_addr; + + `uvm_create_obj(flash_otf_item, item) + item.dq.push_back($urandom()); + item.dq.push_back($urandom()); + if (part == FlashPartData) begin + addr_t pd_addr = addr; + pd_addr[OTFBankId] = bank; + page = addr2page(pd_addr); + item.region = get_region(page, 0); + end else begin + page = addr2page(addr); + item.region = get_region_from_info(mp_info[bank][part>>1][page]); + end + item.page = page; + `uvm_info(`gfn, $sformatf( + "update_otf_mem_read_zone part:%0d, bank:%0d addr:0x%08x orig data:0x%0x%0x", + part, bank, addr, item.dq[1], item.dq[0]), UVM_HIGH) + item.scramble(otp_addr_key, otp_data_key, addr, 0); + `uvm_info(`gfn, $sformatf( + "update_otf_mem_read_zone part:%0d, bank:%0d addr:0x%08x scr data:0x%x", + part, bank, addr, item.fq[0]), UVM_HIGH) + + mem_bkdr_util_h[part][bank].write(addr, item.fq[0]); + // address should be mem_addr + mem_addr = addr >> 3; + if (part == FlashPartData) otf_scb_h.data_mem[bank][mem_addr] = item.fq[0]; + else otf_scb_h.info_mem[bank][part>>1][mem_addr] = item.fq[0]; + end + endfunction : update_otf_mem_read_zone + + // Update memory with random data through backdoor. + // Data can be either scrambled or attached calculated ecc if config in the address + // is enabled. + virtual task preload_mem(); + for (int j = 0; j < NumBanks; j++) begin + for (int i = 0; i < InfoTypeSize[0]; i++) + load_otf_mem_page(flash_ctrl_env_pkg::FlashPartInfo, j, i); + for (int i = 0; i < InfoTypeSize[1]; i++) + load_otf_mem_page(flash_ctrl_env_pkg::FlashPartInfo1, j, i); + for (int i = 0; i < InfoTypeSize[2]; i++) + load_otf_mem_page(flash_ctrl_env_pkg::FlashPartInfo2, j, i); + for (int i = 0; i < PagesPerBank; i++) + load_otf_mem_page(flash_ctrl_env_pkg::FlashPartData, j, i); + end + endtask + + // Print a page of the memory + function void print_page(int bank, flash_dv_part_e part, int page); + string name = $sformatf("%s_bank%0d_page%0d",part.name, bank, page); + addr_t addr; + bit [75:0] rdata; + addr[OTFBankId-1:11] = page; + for (int i = 0; i < 256; i++) begin + rdata = mem_bkdr_util_h[part][bank].read(addr); + `uvm_info(name,$sformatf("addr:%x(%x) data:%x",addr,(addr>>3), rdata), UVM_NONE) + addr += 8; + end + endfunction + + // Cleans up some variables to support multiple sequence runs. + task otf_clean_up(); + scb_h.alert_count["fatal_err"] = 0; + scb_h.exp_alert_contd["fatal_err"] = 0; + scb_h.alert_count["recov_err"] = 0; + scb_h.exp_alert_contd["recov_err"] = 0; + scb_h.eflash_addr_phase_queue = '{}; + + derr_addr_tbl[ReadTaskCtrl].delete(); + derr_addr_tbl[ReadTaskHost].delete(); + derr_created = '{default: ReadTaskCtrl}; + derr_otd.delete(); + ierr_addr_tbl[ReadTaskCtrl].delete(); + ierr_addr_tbl[ReadTaskHost].delete(); + serr_addr_tbl[ReadTaskCtrl].delete(); + serr_addr_tbl[ReadTaskHost].delete(); + + scb_h.ecc_error_addr.delete(); + scb_h.in_error_addr.delete(); + + otf_scb_h.stop = 1; + otf_read_entry.hash.delete(); + foreach (otf_read_entry.prv_read[i]) otf_read_entry.prv_read[i] = '{}; + otf_scb_h.clear_fifos(); + + for (int i = 0; i < NumBanks; i++) begin + otf_scb_h.data_mem[i].delete(); + foreach (otf_scb_h.info_mem[i][j]) + otf_scb_h.info_mem[i][j].delete(); + end + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cov.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cov.sv new file mode 100644 index 0000000000000..ca5071524ca8d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_cov.sv @@ -0,0 +1,132 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 "dv_fcov_macros.svh" + +class flash_ctrl_env_cov extends cip_base_env_cov #(.CFG_T(flash_ctrl_env_cfg)); + `uvm_component_utils(flash_ctrl_env_cov) + + // the base class provides the following handles for use: + // flash_ctrl_env_cfg: cfg + + // covergroups + + covergroup control_cg with function sample (flash_op_t flash_cfg_opts); + part_cp: coverpoint flash_cfg_opts.partition; + erase_cp: coverpoint flash_cfg_opts.erase_type; + op_cp: coverpoint flash_cfg_opts.op; + op_evict_cp: coverpoint flash_cfg_opts.op { + bins op[] = {FlashOpRead, FlashOpProgram, FlashOpErase}; + bins read_prog_read = (FlashOpRead => FlashOpProgram => FlashOpRead); + bins read_erase_read = (FlashOpRead => FlashOpErase => FlashOpRead); + } + op_part_cross : cross part_cp, op_cp; + endgroup : control_cg + + covergroup erase_susp_cg with function sample (bit erase_req = 0); + erase_susp_cp: coverpoint erase_req { + bins erase_susp_true = {1}; + } + endgroup : erase_susp_cg + + covergroup sw_error_cg with function sample(input bit [NumFlashErrBits-1:0] err_val); + `DV_FCOV_EXPR_SEEN(op_err, err_val[FlashOpErr]) + `DV_FCOV_EXPR_SEEN(mp_err, err_val[FlashMpErr]) + `DV_FCOV_EXPR_SEEN(rd_err, err_val[FlashRdErr]) + `DV_FCOV_EXPR_SEEN(prog_err, err_val[FlashProgErr]) + `DV_FCOV_EXPR_SEEN(prog_win_err, err_val[FlashProgWinErr]) + `DV_FCOV_EXPR_SEEN(prog_type_err, err_val[FlashProgTypeErr]) + `DV_FCOV_EXPR_SEEN(update_err, err_val[FlashUpdateErr]) + endgroup : sw_error_cg + + covergroup std_fault_cg with function sample(input bit [31:0] err_val); + `DV_FCOV_EXPR_SEEN(prog_intg_err, err_val[FlashStdFaultProgIntgErr]) + `DV_FCOV_EXPR_SEEN(lcmgr_err, err_val[FlashStdFaultLcmgrErr]) + `DV_FCOV_EXPR_SEEN(lcmgr_intg_err, err_val[FlashStdFaultLcmgrIntgErr]) + `DV_FCOV_EXPR_SEEN(arb_fsm_err, err_val[FlashStdFaultArbFsmErr]) + `DV_FCOV_EXPR_SEEN(storage_err, err_val[FlashStdFaultStorageErr]) + `DV_FCOV_EXPR_SEEN(phy_fsm_err, err_val[FlashStdFaultPhyFsmErr]) + `DV_FCOV_EXPR_SEEN(ctrl_cnt_err, err_val[FlashStdFaultCtrlCntErr]) + `DV_FCOV_EXPR_SEEN(fifo_err, err_val[FlashStdFaultFifoErr]) + endgroup + + covergroup hw_error_cg with function sample(input bit [31:0] err_val); + `DV_FCOV_EXPR_SEEN(op_err, err_val[FlashFaultOpErr]) + `DV_FCOV_EXPR_SEEN(mp_err, err_val[FlashFaultMpErr]) + `DV_FCOV_EXPR_SEEN(rd_err, err_val[FlashFaultRdErr]) + `DV_FCOV_EXPR_SEEN(prog_err, err_val[FlashFaultProgErr]) + `DV_FCOV_EXPR_SEEN(prog_win_err, err_val[FlashFaultProgWinErr]) + `DV_FCOV_EXPR_SEEN(prog_type_err, err_val[FlashFaultProgTypeErr]) +// Disable for now +// `DV_FCOV_EXPR_SEEN(flash_macro_err, err_val[FlashFaultFlashMacroErr]) + `DV_FCOV_EXPR_SEEN(seed_err, err_val[FlashFaultSeedErr]) + `DV_FCOV_EXPR_SEEN(phy_relbl_err, err_val[FlashFaultPhyRelblErr]) + `DV_FCOV_EXPR_SEEN(phy_storage_err, err_val[FlashFaultPhyStorageErr]) + `DV_FCOV_EXPR_SEEN(spurious_ack, err_val[FlashFaultSpuriousAck]) + `DV_FCOV_EXPR_SEEN(arb_err, err_val[FlashFaultArbErr]) + `DV_FCOV_EXPR_SEEN(host_gnt_err, err_val[FlashFaultHostGntErr]) + endgroup + + covergroup msgfifo_level_cg with function sample (bit[4:0] prog, bit[4:0] rd, bit prog_lvl_int, + bit rd_lvl_int); + prog_lvl_cp: coverpoint prog iff (prog_lvl_int) { + bins prog_lvl[] = {[1:3]}; + } + + rd_lvl_cp: coverpoint rd iff (rd_lvl_int) { + bins rd_lvl[] = {[1:15]}; + } + endgroup : msgfifo_level_cg + + covergroup eviction_cg with function sample (int idx, bit[1:0] op, + bit [1:0] scr_ecc); + evic_idx_cp : coverpoint idx { + bins evic_idx[] = {[0:3]}; + } + evic_op_cp : coverpoint op { + bins evic_op[] = {1, 2}; + } + evic_cfg_cp : coverpoint scr_ecc; + evic_all_cross : cross evic_idx_cp, evic_op_cp, evic_cfg_cp; + endgroup // eviction_cg + + covergroup fetch_code_cg with function sample(bit is_exec_key, logic [MuBi4Width-1:0] instr); + key_cp: coverpoint is_exec_key; + instr_type_cp: coverpoint instr { + bins instr_types[2] = {MuBi4True, MuBi4False}; + bins others = {[0:15]} with (!(item inside {MuBi4True, MuBi4False})); + } + key_instr_cross : cross key_cp, instr_type_cp; + endgroup // fetch_code_cg + + covergroup rma_init_cg with function sample(flash_ctrl_pkg::rma_state_e st); + rma_start_cp: coverpoint st { + bins rma_st[2] = {StRmaIdle, [StRmaPageSel:StRmaInvalid]}; + } + endgroup // rma_init_cg + + function new(string name, uvm_component parent); + super.new(name, parent); + control_cg = new(); + erase_susp_cg = new(); + sw_error_cg = new(); + msgfifo_level_cg = new(); + eviction_cg = new(); + fetch_code_cg = new(); + rma_init_cg = new(); + std_fault_cg = new(); + hw_error_cg = new(); + endfunction : new + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + endfunction + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv new file mode 100644 index 0000000000000..d7014d0084e4e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv @@ -0,0 +1,570 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package flash_ctrl_env_pkg; + // dep packages + import uvm_pkg::*; + import top_pkg::*; + import dv_utils_pkg::*; + import dv_base_reg_pkg::*; + import dv_lib_pkg::*; + import tl_agent_pkg::*; + import cip_base_pkg::*; + import csr_utils_pkg::*; + import flash_ctrl_pkg::*; + import flash_ctrl_core_ral_pkg::*; + import flash_ctrl_eflash_ral_pkg::*; + import flash_ctrl_prim_ral_pkg::*; + import mem_bkdr_util_pkg::*; + import prim_mubi_pkg::*; + import lc_ctrl_pkg::*; + import flash_phy_prim_agent_pkg::*; + import sec_cm_pkg::*; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + // parameters + parameter string LIST_OF_ALERTS[] = {"recov_err", "fatal_std_err", "fatal_err", + "fatal_prim_flash_alert", "recov_prim_flash_alert"}; + + // Some paths are added multiple times to accomodate + // indexing in the loop + parameter string LIST_OF_READ_SEED_FORCE_PATHS[] = { + "tb.dut.u_flash_hw_if.op", + "tb.dut.u_flash_hw_if.op", + "tb.dut.u_flash_hw_if.part_sel", + "tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd.data_i[31:0]", + "tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd.data_i[31:0]" + }; + + parameter string LIST_OF_PROG_RMA_WIPE_FORCE_PATHS[] = { + "tb.dut.u_eflash.gen_flash_cores[0].u_core.gen_prog_data.u_prog.data_i[31:0]", + "tb.dut.u_eflash.gen_flash_cores[0].u_core.gen_prog_data.u_prog.data_i[31:0]", + "tb.dut.u_flash_hw_if.rma_num_words" + }; + + parameter uint NUM_ALERTS = 5; + parameter uint FlashNumPages = flash_ctrl_pkg::NumBanks * flash_ctrl_pkg::PagesPerBank; + parameter uint FlashSizeBytes = FlashNumPages * flash_ctrl_pkg::WordsPerPage * + flash_ctrl_pkg::DataWidth / 8; + + parameter uint ProgFifoDepth = 4; + parameter uint ReadFifoDepth = 16; + + // Number of bytes in each of the flash pages. + parameter uint BytesPerPage = FlashSizeBytes / FlashNumPages; + + // Num of bytes in each of the flash banks for each of the flash partitions. + parameter uint BytesPerBank = FlashSizeBytes / flash_ctrl_pkg::NumBanks; + + parameter uint InfoTypeBytes[flash_ctrl_pkg::InfoTypes] = '{ + flash_ctrl_pkg::InfoTypeSize[0] * BytesPerPage, + flash_ctrl_pkg::InfoTypeSize[1] * BytesPerPage, + flash_ctrl_pkg::InfoTypeSize[2] * BytesPerPage + }; + + parameter uint FlashNumBusWords = FlashSizeBytes / top_pkg::TL_DBW; + parameter uint FlashNumBusWordsPerBank = FlashNumBusWords / flash_ctrl_pkg::NumBanks; + parameter uint FlashNumBusWordsPerPage = FlashNumBusWordsPerBank / flash_ctrl_pkg::PagesPerBank; + + parameter uint InfoTypeBusWords[flash_ctrl_pkg::InfoTypes] = '{ + flash_ctrl_pkg::InfoTypeSize[0] * FlashNumBusWordsPerPage, + flash_ctrl_pkg::InfoTypeSize[1] * FlashNumBusWordsPerPage, + flash_ctrl_pkg::InfoTypeSize[2] * FlashNumBusWordsPerPage + }; + + parameter uint FlashBankBytesPerWord = flash_ctrl_pkg::DataWidth / 8; + + parameter uint FlashDataByteWidth = $clog2(FlashBankBytesPerWord); + parameter uint FlashWordLineWidth = $clog2(flash_ctrl_pkg::WordsPerPage); + parameter uint FlashPageWidth = $clog2(flash_ctrl_pkg::PagesPerBank); + parameter uint FlashBankWidth = $clog2(flash_ctrl_pkg::NumBanks); + parameter uint FlashPgmRes = flash_ctrl_pkg::BusPgmRes; + parameter uint FlashPgmResWidth = $clog2(FlashPgmRes); + + parameter uint FlashMemAddrWordMsbBit = FlashDataByteWidth - 1; + parameter uint FlashMemAddrLineMsbBit = FlashDataByteWidth + FlashWordLineWidth - 1; + parameter uint FlashMemAddrPageMsbBit = FlashDataByteWidth + FlashWordLineWidth + + FlashPageWidth - 1; + parameter uint FlashMemAddrBankMsbBit = FlashDataByteWidth + FlashWordLineWidth + + FlashPageWidth + FlashBankWidth - 1; + + // params for words + parameter uint NUM_PAGE_WORDS = FlashNumBusWordsPerPage; + parameter uint NUM_BK_DATA_WORDS = FlashNumBusWordsPerBank; // 256 pages + parameter uint NUM_BK_INFO_WORDS = InfoTypeBusWords[0]; // 10 pages + + // params for num of pages + parameter uint NUM_PAGE_PART_DATA = flash_ctrl_pkg::PagesPerBank; + parameter uint NUM_PAGE_PART_INFO0 = flash_ctrl_pkg::InfoTypeSize[0]; + parameter uint NUM_PAGE_PART_INFO1 = flash_ctrl_pkg::InfoTypeSize[1]; + parameter uint NUM_PAGE_PART_INFO2 = flash_ctrl_pkg::InfoTypeSize[2]; + + parameter otp_ctrl_pkg::flash_otp_key_rsp_t FLASH_OTP_RSP_DEFAULT = '{ + data_ack: 1'b1, + addr_ack: 1'b1, + key: '0, + rand_key: '0, + seed_valid: 1'b0 + }; + + // For Secret Partitions and RMA + parameter uint FlashSecretPartWords = 8; // Size Of Secret Part - (8x32=256 Bits) + parameter uint FlashCreatorPartStartAddr = 32'h00000800; // Info Partition Page 1 + parameter uint FlashOwnerPartStartAddr = 32'h00001000; // Info Partition Page 2 + parameter uint FlashIsolPartStartAddr = 32'h00001800; + parameter uint FlashIsolPartEndAddr = 32'h00001FFF; + + parameter uint FlashData0StartAddr = 32'h00000000; + parameter uint FlashData0EndAddr = 32'h00080000; + parameter uint FlashData1StartAddr = 32'h00080000; + parameter uint FlashData1EndAddr = 32'h00100000; + + parameter uint FullPageNumWords = 512; // 32 Cycles of 16 Words = 512 Words + parameter uint FullBankNumWords = 131072; // 8192 Cycles of 16 Words = 131072 Words + + parameter uint MaxNumPages = 256; // Number of Pages in a Bank + parameter uint FIFO_DEPTH = 16; // Depth of the Program and Read FIFO in words + + // Read Check Parameters + parameter bit READ_CHECK_NORM = 0; // Check Read Data via the Backdoor + parameter bit READ_CHECK_EXPLICIT = 1; // Check Read Data Explicitly + + // Code Fetch Key + parameter uint CODE_EXEC_KEY_W = 32; + parameter uint CODE_EXEC_KEY = 32'ha26a38f7; + + // MP Access Flags + parameter bit MP_PASS = 0; + parameter bit MP_VIOLATION = 1; + + // Flash Error Bits (flash_ctrl.err_code) + parameter uint NumFlashErrBits = 7; + parameter uint FlashOpErr = 0; + parameter uint FlashMpErr = 1; + parameter uint FlashRdErr = 2; + parameter uint FlashProgErr = 3; + parameter uint FlashProgWinErr = 4; + parameter uint FlashProgTypeErr = 5; + parameter uint FlashUpdateErr = 6; + + // Flash STD Fault Bits (flash_ctrl.std_fault_status) + parameter uint FlashStdFaultRegIntgErr = 0; + parameter uint FlashStdFaultProgIntgErr = 1; + parameter uint FlashStdFaultLcmgrErr = 2; + parameter uint FlashStdFaultLcmgrIntgErr = 3; + parameter uint FlashStdFaultArbFsmErr = 4; + parameter uint FlashStdFaultStorageErr = 5; + parameter uint FlashStdFaultPhyFsmErr = 6; + parameter uint FlashStdFaultCtrlCntErr = 7; + parameter uint FlashStdFaultFifoErr = 8; + + // Flash Fault Bits (flash_ctrl.fault_status) + parameter uint FlashFaultOpErr = 0; + parameter uint FlashFaultMpErr = 1; + parameter uint FlashFaultRdErr = 2; + parameter uint FlashFaultProgErr = 3; + parameter uint FlashFaultProgWinErr = 4; + parameter uint FlashFaultProgTypeErr = 5; + parameter uint FlashFaultFlashMacroErr = 6; + parameter uint FlashFaultSeedErr = 7; + parameter uint FlashFaultPhyRelblErr = 8; + parameter uint FlashFaultPhyStorageErr = 9; + parameter uint FlashFaultSpuriousAck = 10; + parameter uint FlashFaultArbErr = 11; + parameter uint FlashFaultHostGntErr = 12; + + // From flash_ctrl_lcmgr.sv + parameter logic [10:0] FlashLcDisabled = 11'b11111100011; + parameter logic [10:0] FlashLcInvalid = 11'b11101011000; + // types + typedef enum bit [1:0] { + OTFCfgTrue, + OTFCfgFalse, + OTFCfgRand + } otf_cfg_mode_e; + + typedef enum { + ReadCheckNorm = 0, + ReadCheckRand = 1, + ReadCheckErased = 2 + } read_check_e; + + typedef enum int { + FlashCtrlIntrProgEmpty = 0, + FlashCtrlIntrProgLvl = 1, + FlashCtrlIntrRdFull = 2, + FlashCtrlIntrRdLvl = 3, + FlashCtrlIntrOpDone = 4, + FlashCtrlIntrErr = 5, + NumFlashCtrlIntr = 6 + } flash_ctrl_intr_e; + + typedef enum { + FlashMemInitCustom, // Initialize flash (via bkdr) with custom data set. + FlashMemInitSet, // Initialize with all 1s. + FlashMemInitClear, // Initialize with all 0s. + FlashMemInitRandomize, // Initialize with random data. + FlashMemInitInvalidate, // Initialize with Xs. + FlashMemInitEccMode // Flash init for ecc_mode + } flash_mem_init_e; + + // Partition select for DV + typedef enum logic [flash_ctrl_pkg::InfoTypes:0] { // Data partition and all info partitions + FlashPartData = 0, + FlashPartInfo = 1, + FlashPartInfo1 = 2, + FlashPartInfo2 = 4 + } flash_dv_part_e; + + // Program Type Select Normal/Repair + typedef enum bit { + FlashProgSelNormal = 0, + FlashProgSelRepair = 1 + } flash_prog_sel_e; + + // Special Partitions + typedef enum logic [2:0] { + FlashCreatorPart = 0, + FlashOwnerPart = 1, + FlashIsolPart = 2, + FlashData0Part = 3, + FlashData1Part = 4 + } flash_sec_part_e; + + typedef enum { + AllOnes, // All 1s + AllZeros, // All 0s + CustomVal // Custom Value + } flash_scb_wr_e; + + typedef enum { + TgtRd = 0, + TgtDr = 1, // direct read + TgtWr = 2, // program + TgtEr = 3, // erase + NumTgt = 4 + } flash_tgt_prefix_e; + + typedef enum { + FlashEccDisabled, + FlashEccEnabled, + FlashSerrTestMode, + FlashDerrTestMode, + FlashIerrTestMode + } ecc_mode_e; + + typedef enum { + ReadTaskCtrl = 0, + ReadTaskHost = 1, + NumReadTask = 2 + } read_task_e; + + typedef struct packed { + mubi4_t en; // enable this region + mubi4_t read_en; // enable reads + mubi4_t program_en; // enable write + mubi4_t erase_en; // enable erase + mubi4_t scramble_en; // enable scramble + mubi4_t ecc_en; // enable ecc + mubi4_t he_en; // enable high endurance + uint num_pages; // 0:NumPages % start_page + uint start_page; // 0:NumPages-1 + } flash_mp_region_cfg_t; + + typedef struct packed { + mubi4_t en; // enable this page + mubi4_t read_en; // enable reads + mubi4_t program_en; // enable write + mubi4_t erase_en; // enable erase + mubi4_t scramble_en; // enable scramble + mubi4_t ecc_en; // enable ecc + mubi4_t he_en; // enable high endurance + } flash_bank_mp_info_page_cfg_t; + + // 2-states flash data type + typedef bit [TL_DW-1:0] data_t; + // 4-states flash data type + typedef logic [TL_DW-1:0] data_4s_t; + // flash address type + typedef bit [TL_AW-1:0] addr_t; + // Queue of 4-states data words + typedef data_4s_t data_q_t[$]; + // Queue of 2-states data words + typedef data_t data_b_t[$]; + // Array of 2-states data words indexed with flash addresses. + // Useful for the flash model. + typedef data_t data_model_t[addr_t]; + // Otf address in a bank. + typedef bit [flash_ctrl_pkg::BusAddrByteW-FlashBankWidth-1 : 0] otf_addr_t; + + typedef struct packed { + flash_dv_part_e partition; // data or one of the info partitions + flash_erase_e erase_type; // erase page or the whole bank + flash_op_e op; // read / program or erase + flash_prog_sel_e prog_sel; // program select: normal or repair + uint num_words; // number of words to read or program (TL_DW) + addr_t addr; // starting addr for the op + // address for the ctrl interface per bank, 18:0 + bit [flash_ctrl_pkg::BusAddrByteW-2:0] otf_addr; + } flash_op_t; + + // Address combined with region + // Need for error injection. + typedef struct packed { + bit bank; + addr_t addr; + flash_dv_part_e part; + } rd_cache_t; + + parameter uint ALL_ZEROS = 32'h0000_0000; + parameter uint ALL_ONES = 32'hffff_ffff; + + // Parameter for Probing into the DUT RMA FSM + parameter string PRB_RMA_FSM = "tb.dut.u_flash_hw_if.state_q"; + + // Taken from enum type lcmgr_state_e in flash_ctrl_lcmgr.sv + parameter uint RMA_FSM_STATE_ST_RMA_RSP = 11'b10110001010; + + // Indicate host read + parameter int unsigned OTFBankId = flash_ctrl_pkg::BusAddrByteW - FlashBankWidth; // bit19 + parameter int unsigned OTFHostId = OTFBankId - 1; // bit 18 + parameter int unsigned DVPageMSB = 18; + parameter int unsigned DVPageLSB = 11; + localparam int unsigned CtrlTransMin = 1; + localparam int unsigned CtrlTransMax = 32; + + // functions + // Add below for the temporary until PR12492 is merged. + // Will be removed after. + localparam int unsigned FlashDataWidth = flash_phy_pkg::DataWidth; + localparam int unsigned FlashStagesPerCycle = FlashDataWidth / flash_phy_pkg::GfMultCycles; + localparam int unsigned FlashKeySize = flash_phy_pkg::KeySize; + localparam int unsigned FlashNumRoundsHalf = crypto_dpi_prince_pkg::NumRoundsHalf; + localparam int unsigned FlashAddrWidth = 16; + + // remove bank select + localparam int unsigned FlashByteAddrWidth = flash_ctrl_pkg::BusAddrByteW - 1; + + function automatic bit [FlashDataWidth-1:0] flash_gf_mult2(bit [FlashDataWidth-1:0] operand); + bit [FlashDataWidth-1:0] mult_out; + + mult_out = operand[FlashDataWidth-1] ? (operand << 1) ^ + flash_phy_pkg::ScrambleIPoly : (operand << 1); + return mult_out; + endfunction + + function automatic bit [FlashStagesPerCycle-1:0][FlashDataWidth-1:0] flash_gen_matrix( + bit [FlashDataWidth-1:0] seed, bit init); + bit [FlashStagesPerCycle-1:0][FlashDataWidth-1:0] matrix_out; + + matrix_out[0] = init ? seed : flash_gf_mult2(seed); + matrix_out[FlashStagesPerCycle-1:1] = '0; + for (int i = 1; i < FlashStagesPerCycle; i++) begin + matrix_out[i] = flash_gf_mult2(matrix_out[i-1]); + end + return matrix_out; + endfunction + + function automatic bit [FlashDataWidth-1:0] flash_galois_multiply(bit [FlashKeySize-1:0] addr_key, + bit [FlashAddrWidth-1:0] addr); + bit [FlashStagesPerCycle-1:0][FlashDataWidth-1:0] matrix[2]; + bit [FlashDataWidth-1:0] product[2]; + bit [FlashDataWidth-1:0] add_vector; + bit [FlashDataWidth-1:0] mult_out; + + // generate matrix. + matrix[0] = + flash_gen_matrix({addr_key[FlashKeySize-FlashAddrWidth-1:FlashKeySize-64], addr}, 1'b1); + matrix[1] = flash_gen_matrix(matrix[0][FlashStagesPerCycle-1], 1'b0); + `uvm_info("SCR_DBG", $sformatf("waddr: %x op_a_i : %x vector: %x", + addr, {addr_key[FlashKeySize-FlashAddrWidth-1:FlashKeySize-64], addr}, + matrix[0][FlashStagesPerCycle-1]), UVM_HIGH) + + // galois multiply. + for (int j = 0; j < 2; j++) begin + mult_out = '0; + for (int i = 0; i < FlashStagesPerCycle; i++) begin + add_vector = addr_key[(j*FlashStagesPerCycle)+i] ? matrix[j][i] : '0; + mult_out = mult_out ^ add_vector; + end + product[j] = mult_out; + end + product[1] = product[1] ^ product[0]; + `uvm_info("SCR_DBG", $sformatf("prod1:%x prod0:%x",product[1],product[0]), UVM_HIGH) + + return product[1]; + endfunction + + function automatic bit[63:0] create_flash_data( + bit [FlashDataWidth-1:0] data, bit [FlashByteAddrWidth-1:0] byte_addr, + bit [FlashKeySize-1:0] flash_addr_key, bit [FlashKeySize-1:0] flash_data_key, + bit dis = 1); + bit [FlashAddrWidth-1:0] word_addr; + bit [FlashDataWidth-1:0] mask; + bit [FlashDataWidth-1:0] masked_data; + bit [FlashNumRoundsHalf-1:0][FlashDataWidth-1:0] scrambled_data; + + // These parameters will be removed once it is included in mem_bkdr_util.sv + int addr_lsb = 3; + + word_addr = byte_addr >> addr_lsb; + mask = flash_galois_multiply(flash_addr_key, word_addr); + masked_data = data ^ mask; + crypto_dpi_prince_pkg::sv_dpi_prince_encrypt(.plaintext(masked_data), .key(flash_data_key), + .old_key_schedule(0), .ciphertext(scrambled_data)); + masked_data = scrambled_data[FlashNumRoundsHalf-1] ^ mask; + + if (dis) begin + `uvm_info("SCR_DBG", $sformatf("addr:%x mask:%x din:%x dout:%x", + word_addr, mask, data, masked_data), UVM_MEDIUM) + end + return masked_data; + endfunction + + // 64bit in out + function automatic bit[FlashDataWidth-1:0] create_raw_data( + input bit [FlashDataWidth-1:0] data, + input bit [FlashAddrWidth-1:0] bank_addr, + input bit [FlashKeySize-1:0] flash_addr_key, + input bit [FlashKeySize-1:0] flash_data_key, + input bit dis = 1, + input uvm_verbosity verbosity = UVM_MEDIUM); + bit [FlashDataWidth-1:0] mask; + bit [FlashDataWidth-1:0] masked_data; + bit [FlashDataWidth-1:0] plain_text; + bit [FlashNumRoundsHalf-1:0][FlashDataWidth-1:0] descrambled_data; + + mask = flash_galois_multiply(flash_addr_key, bank_addr); + masked_data = data ^ mask; + plain_text = crypto_dpi_prince_pkg::c_dpi_prince_decrypt(masked_data, + flash_data_key[127:64], + flash_data_key[63:0], + FlashNumRoundsHalf, + 0); + if (dis) begin + `uvm_info("DCR_DBG", $sformatf("datakey:%x", flash_data_key), verbosity) + `uvm_info("DCR_DBG", $sformatf("masked_data:%x cout:%x", masked_data, plain_text), verbosity) + `uvm_info("DCR_DBG", $sformatf( + "addr:%x mask:%x din:%x dout:%x ", + bank_addr, mask, data, (plain_text^mask)), + verbosity) + end + + return (plain_text ^ mask); + endfunction // create_raw_data + + // Temp add end + // Print 16 byte per line + function automatic void flash_otf_print_data64(data_q_t data, string str = "data"); + int size, tail, line, idx; + bit [127:0] vec; + size = data.size(); + line = size / 4; + tail = size % 4; + idx = 0; + `dv_info($sformatf("size : %0d byte (%0d x 4B)", (size * 4), size), UVM_MEDIUM, str) + + for (int i = 0; i < line; ++i) begin + for (int j = 0; j < 4; ++j) begin + vec[127-(32*j) -:32] = data[idx]; + idx++; + end + `dv_info($sformatf("%4d:%8x_%8x_%8x_%8x", i, + vec[127:96], vec[95:64], vec[63:32], vec[31:0]), + UVM_MEDIUM, str) + vec = 'h0; + end + + if (tail > 0) begin + // print tail + for (int j = 0; j < tail; ++j) begin + vec[127-(32*j) -:32] = data[idx]; + idx++; + end + `dv_info($sformatf("%4d:%8x_%8x_%8x_%8x", line, + vec[127:96], vec[95:64], vec[63:32], vec[31:0]), + UVM_MEDIUM, str) + end + endfunction // flash_otf_print_data64 + + function automatic flash_dv_part_e get_part_name(flash_phy_pkg::flash_phy_prim_flash_req_t req); + flash_dv_part_e part; + + if (req.part == 0) return FlashPartData; + else begin + case(req.info_sel) + 0: begin + return FlashPartInfo; + end + 1: begin + return FlashPartInfo1; + end + 2: begin + return FlashPartInfo2; + end + default: begin + `uvm_error("get_partition_name", $sformatf("part:%0d info_sel:%0d doesn't exist", + req.part, req.info_sel)) + end + endcase + end + + `uvm_error("get_partition_name", $sformatf("part:%0d info_sel:%0d doesn't exist", + req.part, req.info_sel)) + return FlashPartData; + endfunction // get_part_name + + // Struct convertion from rtl to dv. + function automatic flash_bank_mp_info_page_cfg_t conv2env_mp_info(info_page_cfg_t info); + flash_bank_mp_info_page_cfg_t env_info; + + env_info.en = info.en; + env_info.read_en = info.rd_en; + env_info.program_en = info.prog_en; + env_info.erase_en = info.erase_en; + env_info.scramble_en = info.scramble_en; + env_info.ecc_en = info.ecc_en; + env_info.he_en = info.he_en; + return env_info; + endfunction + + function automatic void print_flash_op(input flash_op_t fop, uvm_verbosity verbosity); + `uvm_info("print_flash_op", $sformatf( + "flash_op: op=%s, part=%s, addr=0x%x, otf_addr=0x%x, words=%0d", + fop.op.name, fop.partition.name, fop.addr, fop.otf_addr, fop.num_words), + verbosity) + if (fop.op == FlashOpErase) begin + `uvm_info("print_flash_op", $sformatf( + "flash_op: erase_type=%s", fop.erase_type.name), verbosity) + end + endfunction + + function automatic addr_t align_to_flash_word(addr_t addr); + return {addr[$bits(addr_t) - 1 : FlashDataByteWidth], {FlashDataByteWidth{1'b0}}}; + endfunction + + // Round an address down to a program resolution window. + function automatic addr_t round_to_prog_resolution(addr_t addr); + return addr - (addr & (BusPgmResBytes - 1)); + endfunction + + // package sources + `include "flash_mem_bkdr_util.sv" + `include "flash_mem_addr_attrs.sv" + `include "flash_otf_item.sv" + `include "flash_otf_read_entry.sv" + `include "flash_otf_mem_entry.sv" + `include "flash_ctrl_seq_cfg.sv" + `include "flash_ctrl_env_cfg.sv" + `include "flash_ctrl_env_cov.sv" + `include "flash_ctrl_virtual_sequencer.sv" + `include "flash_ctrl_scoreboard.sv" + `include "flash_ctrl_otf_scoreboard.sv" + `include "flash_ctrl_env.sv" + `include "flash_ctrl_vseq_list.sv" + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_if.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_if.sv new file mode 100644 index 0000000000000..91247d0194841 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_if.sv @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// interface for OTP, Life cycle, RMA, PWRMGR and KEYMGR +interface flash_ctrl_if ( + input logic clk, + input logic rst_n +); + + import lc_ctrl_pkg::*; + import pwrmgr_pkg::*; + import flash_ctrl_pkg::*; + import flash_phy_pkg::*; + import otp_ctrl_pkg::*; + import ast_pkg::*; + + lc_tx_t lc_creator_seed_sw_rw_en = lc_ctrl_pkg::Off; + lc_tx_t lc_owner_seed_sw_rw_en = lc_ctrl_pkg::Off; + lc_tx_t lc_seed_hw_rd_en = lc_ctrl_pkg::On; + + lc_tx_t lc_iso_part_sw_rd_en = lc_ctrl_pkg::Off; + lc_tx_t lc_iso_part_sw_wr_en = lc_ctrl_pkg::Off; + + lc_tx_t lc_nvm_debug_en = lc_ctrl_pkg::Off; + lc_tx_t lc_escalate_en = lc_ctrl_pkg::Off; + + pwr_flash_t pwrmgr; + + keymgr_flash_t keymgr; + + lc_tx_t rma_req; + lc_flash_rma_seed_t rma_seed; + lc_tx_t rma_ack; + + otp_ctrl_pkg::flash_otp_key_req_t otp_req; + otp_ctrl_pkg::flash_otp_key_rsp_t otp_rsp; + + // JTAG + logic cio_tck; + logic cio_tms; + logic cio_tdi; + logic cio_tdo_en; + logic cio_tdo; + + // power ready + logic power_ready_h = 1'b1; + + // eviction + logic [flash_ctrl_pkg::NumBanks-1:0][NumBuf-1:0] hazard; + rd_buf_t [flash_ctrl_pkg::NumBanks-1:0][NumBuf-1:0] rd_buf; + logic [flash_ctrl_pkg::NumBanks-1:0] evict_prog; + logic [flash_ctrl_pkg::NumBanks-1:0] evict_erase; + logic fatal_err; + + // rma coverage + logic rd_buf_en; + rma_state_e rma_state; + logic [10:0] prog_state0; + logic [10:0] prog_state1; + logic [10:0] lcmgr_state; + logic init; + logic hw_rvalid; + + // v2s error injection + logic host_gnt; + logic ctrl_fsm_idle; + logic [1:0] host_outstanding; + + // Time to wait from reset assertion to power-down assertion. Default is 0. + // Defined here so it will be accessible by both the TB and the env cfg. + int unsigned rst_to_pd_time_ns = 0; + + clocking cb @(posedge clk); + default input #1step output #2; + output rma_req, rma_seed; + input rma_ack; + endclocking +endinterface : flash_ctrl_if diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_mem_if.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_mem_if.sv new file mode 100644 index 0000000000000..b8a2be9ce414c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_mem_if.sv @@ -0,0 +1,18 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +import flash_ctrl_pkg::*; +interface flash_ctrl_mem_if ( + input logic clk_i, + input logic rst_ni, + input logic data_mem_req, + input logic mem_wr, + input logic [BankAddrW-1:0] mem_addr, + input logic [flash_phy_pkg::FullDataWidth-1:0] mem_wdata, + input flash_part_e mem_part, + input logic [InfoTypesWidth-1:0] mem_info_sel, + input logic info0_mem_req, + input logic info1_mem_req, + input logic info2_mem_req +); +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv new file mode 100644 index 0000000000000..b3af4ae728d27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_otf_scoreboard.sv @@ -0,0 +1,576 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_otf_scoreboard extends uvm_scoreboard; + `uvm_component_utils(flash_ctrl_otf_scoreboard) + `uvm_component_new + + // OTF data path fifos + // Assuming egress (host -> flash) ordering is maintained per bank. + uvm_tlm_analysis_fifo #(flash_otf_item) eg_exp_ctrl_fifo[NumBanks]; + uvm_tlm_analysis_fifo #(flash_otf_item) eg_exp_host_fifo[NumBanks]; + uvm_tlm_analysis_fifo #(flash_otf_item) eg_rtl_ctrl_fifo[NumBanks]; + uvm_tlm_analysis_fifo #(flash_otf_item) eg_rtl_host_fifo[NumBanks]; + uvm_tlm_analysis_fifo #(flash_phy_prim_item) eg_rtl_fifo[NumBanks]; + uvm_tlm_analysis_fifo #(flash_phy_prim_item) rd_cmd_fifo[NumBanks]; + + // Check last mile write /erase transactions + uvm_tlm_analysis_fifo #(flash_phy_prim_item) eg_exp_lm_fifo[NumBanks]; + + // tb memory model + // This is used for the last mile write data integrity check + bit[flash_phy_pkg::FullDataWidth-1:0] data_mem[NumBanks][bit[BankAddrW-1:0]]; + bit[flash_phy_pkg::FullDataWidth-1:0] info_mem[NumBanks][InfoTypes][bit[BankAddrW-1:0]]; + + // register double written entries + bit corrupt_entry[rd_cache_t]; + flash_ctrl_env_cfg cfg; + + int eg_exp_cnt = 0; + bit comp_off = 0; + bit derr_expected = 0; + + // monitor_tb_mem off + bit mem_mon_off = 0; + + // Stop egress forever process + bit stop = 0; + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + foreach (eg_exp_ctrl_fifo[i]) begin + eg_exp_ctrl_fifo[i] = new($sformatf("eg_exp_ctrl_fifo[%0d]", i), this); + eg_exp_host_fifo[i] = new($sformatf("eg_exp_host_fifo[%0d]", i), this); + eg_rtl_ctrl_fifo[i] = new($sformatf("eg_rtl_ctrl_fifo[%0d]", i), this); + eg_rtl_host_fifo[i] = new($sformatf("eg_rtl_host_fifo[%0d]", i), this); + eg_rtl_fifo[i] = new($sformatf("eg_rtl_fifo[%0d]", i), this); + rd_cmd_fifo[i] = new($sformatf("rd_cmd_fifo[%0d]", i), this); + eg_exp_lm_fifo[i] = new($sformatf("eg_exp_lm_fifo[%0d]", i), this); + end + endfunction + + task clear_fifos(); + flash_otf_item dummy1; + flash_phy_prim_item dummy2; + + foreach (eg_exp_ctrl_fifo[i]) begin + while (eg_exp_ctrl_fifo[i].used() > 0) eg_exp_ctrl_fifo[i].get(dummy1); + while (eg_exp_host_fifo[i].used() > 0) eg_exp_host_fifo[i].get(dummy1); + while (eg_rtl_ctrl_fifo[i].used() > 0) eg_rtl_ctrl_fifo[i].get(dummy1); + while (eg_rtl_host_fifo[i].used() > 0) eg_rtl_host_fifo[i].get(dummy1); + while (eg_rtl_fifo[i].used() > 0) eg_rtl_fifo[i].get(dummy2); + while (rd_cmd_fifo[i].used() > 0) rd_cmd_fifo[i].get(dummy2); + while (eg_exp_lm_fifo[i].used() > 0) eg_exp_lm_fifo[i].get(dummy2); + end + endtask + + virtual function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + uvm_config_db#(flash_ctrl_env_cfg)::get(this, "", "cfg", cfg); + cfg.otf_scb_h = this; + endfunction // connect_phase + + task run_phase(uvm_phase phase); + flash_otf_item exp_ctrl_item[NumBanks]; + flash_otf_item exp_host_item[NumBanks]; + flash_phy_prim_item phy_item[NumBanks]; + flash_phy_prim_item rcmd[NumBanks]; + + for (int i = 0; i < NumBanks; i++) begin + int j = i; + fork begin + forever begin + eg_exp_ctrl_fifo[j].get(exp_ctrl_item[j]); + process_eg(exp_ctrl_item[j], j); + end + end join_none + fork begin + forever begin + eg_exp_host_fifo[j].get(exp_host_item[j]); + process_eg_host(exp_host_item[j], j); + end + end join_none + fork begin + forever begin + eg_rtl_fifo[j].get(phy_item[j]); + process_phy_item(phy_item[j], j); + end + end join_none + fork begin + forever begin + rd_cmd_fifo[j].get(rcmd[j]); + process_rcmd(rcmd[j], j); + end + end join_none + fork begin + monitor_tb_mem(j); + end join_none + end + endtask // run_phase + + task process_eg_host(flash_otf_item exp, int bank); + flash_otf_item obs; + data_4s_t rcvd_data; + fdata_q_t fq; + addr_t err_addr; + string str = $sformatf("host_read_comp_bank%0d", bank); + + `uvm_info("EXPGET_HOST", $sformatf(" addr %x data:%x cnt:%0d rtlff:%0d ctrlff:%0d", + exp.start_addr, exp.dq[0], eg_exp_cnt++, + eg_rtl_host_fifo[bank].used(), + eg_rtl_ctrl_fifo[bank].used()), + UVM_MEDIUM) + + // backdoor read from memory model + `uvm_create_obj(flash_otf_item, obs) + // Host can only access data partitions. + obs.cmd.partition = FlashPartData; + obs.cmd.op = FlashOpRead; + obs.cmd.addr = exp.start_addr; // tl_addr + // for debug print + obs.start_addr = exp.start_addr; + obs.cmd.num_words = 1; + obs.mem_addr = exp.start_addr >> 3; + + obs.print("RAW"); + cfg.flash_mem_otf_read(obs.cmd, obs.fq); + + obs.print("rtl_host: before"); + obs.region = exp.region; + if (cfg.ecc_mode > FlashSerrTestMode) obs.skip_err_chk = 1; + obs.skip_err_chk |= exp.derr; + + // descramble needs 2 buswords + obs.cmd.num_words = 2; + obs.descramble(exp.addr_key, exp.data_key); + obs.print("rtl_host: after"); + `uvm_info("process_eg_host", $sformatf(" rcvd:%0d",cfg.otf_host_rd_sent), UVM_MEDIUM) + + if (cfg.ecc_mode > FlashSerrTestMode && obs.derr == 1) begin + err_addr = {obs.cmd.addr[31:3],3'h0}; + // check expected derr + if (cfg.address_has_derr(err_addr, FlashPartData)) begin + `uvm_info("process_eg_host", + $sformatf("expected double bit error 0x%x", err_addr), UVM_MEDIUM) + end else if (cfg.address_has_ierr(err_addr, FlashPartData)) begin + `uvm_info("process_eg_host", + $sformatf("expected icv error 0x%x", err_addr), UVM_MEDIUM) + end else begin + `uvm_error("process_eg_host", + $sformatf("unexpected double bit error 0x%x", err_addr)) + end + end else begin + if (exp.exp_err) begin + `uvm_info("process_eg_host", + $sformatf("expected other tlul error start:%x", + exp.start_addr), + UVM_MEDIUM) + end else if (exp.derr & obs.derr) begin + `uvm_info("process_eg_host", + $sformatf("expected double bit error by redundant write start:%x", + exp.start_addr), + UVM_MEDIUM) + end else begin + if (!exp.derr) begin + if (exp.start_addr[2]) begin + rcvd_data = obs.dq[1]; + end else begin + rcvd_data = obs.dq[0]; + end + + if (rcvd_data == exp.dq[0]) begin + `dv_info("data match!!", UVM_MEDIUM, str) + end else begin + `dv_error($sformatf(" : obs:exp %8x:%8x mismatch!!", + rcvd_data, exp.dq[0]), str) + end + end else begin // if (!exp.derr) + `uvm_error("process_eg_host", + $sformatf("expected double bit error does not occur start:%x", + exp.start_addr)) + end + end + end + cfg.otf_host_rd_sent++; + + endtask // process_eg_host + + task process_eg(flash_otf_item item, int bank); + `uvm_info("EG_EXPGET", + $sformatf("op:%s fq:%0d cnt:%0d rtlff:%0d", item.cmd.op.name(), + item.fq.size(), eg_exp_cnt++, eg_rtl_fifo[bank].used()), + UVM_MEDIUM) + fork + begin : isolation_fork + fork + begin + case (item.cmd.op) + FlashOpProgram:begin + process_write(item, bank); + end + FlashOpRead:begin + process_read(item, bank); + end + default:begin + // Do nothing for the other commands + end + endcase // case (item.cmd.op) + end // fork begin + begin + wait (stop); + end + join_any + #0; + disable fork; + end // block: isolation_fork + join + endtask + + // Scoreboard process read in following order. + // - Received expected transactions (exp). + // - Pop the same number (col_sz) of transaction from rtl received q. + // - Transform rtl transactions to have the same data format as exp. + // - Compare read data. + task process_read(flash_otf_item exp, int bank); + flash_otf_item send; + addr_t err_addr, cp_addr; + int page; + int col_sz = exp.fq.size; + `uvm_info("process_read", $sformatf("bank:%0d colsz:%0d ffsz:%0d", + bank, col_sz, eg_rtl_fifo[bank].used()), UVM_MEDIUM) + + exp.print("obs_read"); + `uvm_create_obj(flash_otf_item, send) + send.cmd = exp.cmd; + send.cmd.addr[OTFBankId] = bank; + // print purpose + send.start_addr = exp.start_addr; + cfg.flash_mem_otf_read(send.cmd, send.fq); + send.print("exp_read: enc_data"); + if (cfg.ecc_mode > FlashSerrTestMode) send.skip_err_chk = 1; + send.skip_err_chk |= exp.derr; + + if (exp.cmd.addr[2]) begin + send.head_pad = 1; + send.cmd.num_words++; + end + if (send.cmd.num_words % 2) begin + send.cmd.num_words++; + send.tail_pad = 1; + end + + // Read descramble has to be done Qword by Qword because + // Each Qword can be in different region. + send.mem_addr = exp.start_addr >> 3; + send.ctrl_rd_region_q = exp.ctrl_rd_region_q; + + // Mask descramble error chk whem comp_off is set. + if (comp_off) send.skip_err_chk = 1; + send.descramble(exp.addr_key, exp.data_key); + send.print("exp_read: raw_data"); + `dv_info($sformatf("RDATA size: %d x 8B bank:%0d sent_cnt:%0d", + send.raw_fq.size(), bank, cfg.otf_ctrl_rd_sent++), + UVM_MEDIUM, "process_read") + + if (cfg.ecc_mode > FlashSerrTestMode && send.derr == 1) begin + foreach(send.eaddr_q[i]) begin + err_addr = send.eaddr_q[i]; + err_addr[OTFBankId] = bank; + + // check expected derr + if (cfg.address_has_derr(err_addr, exp.cmd.partition)) begin + `uvm_info("process_read", + $sformatf("expected double bit error 0x%x", err_addr), UVM_MEDIUM) + end else if (cfg.address_has_ierr(err_addr, exp.cmd.partition)) begin + `uvm_info("process_read", + $sformatf("expected icv error 0x%x", err_addr), UVM_MEDIUM) + end else if (derr_expected == 0) begin + `uvm_error("process_read", + $sformatf("unexpected double bit error 0x%x", err_addr)) + end + end + end else begin // if (cfg.ecc_mode > FlashSerrTestMode && send.derr == 1) + // Skip data comp for no ecc erase workd read + foreach (send.ctrl_rd_region_q[i]) begin + if (send.ctrl_rd_region_q[i].ecc_en != MuBi4True && + (exp.fq[i][63:32] == ALL_ONES || exp.fq[i][31:0] == ALL_ONES)) begin + send.raw_fq[i] = exp.fq[i]; + end + end + if (exp.exp_err) begin + `uvm_info("process_read", + $sformatf("expected other tlul error start:%x", + exp.start_addr), + UVM_MEDIUM) + end else if (exp.derr & send.derr) begin + `uvm_info("process_read", + $sformatf("expected double bit error by redundant write start:%x", + exp.start_addr), + UVM_MEDIUM) + end else begin + if (!exp.derr) compare_data(send.raw_fq, exp.fq, bank, "rdata"); + else `uvm_error("process_read", + $sformatf("expected double bit error does not occur start:%x", + exp.start_addr)) + + end + end + endtask + + // Scoreboard process write in following order. + // - Received expected transactions (exp). + // - Pop the same number (col_sz) of transaction from rtl received q. + // - Transform rtl transactions to have the same data format as exp. + // - Compare read data. + task process_write(flash_otf_item exp, int bank); + flash_otf_item item; + flash_otf_item obs; + + // Write transactions coalesce upto 8 transactions. + // So each pop becomes 8 times of fqs. + int col_sz = exp.fq.size / 8; + `uvm_info("process_write", $sformatf("process_write: addr:0x%x bank:%0d colsz:%0d ffsz:%0d", + exp.cmd.otf_addr, bank, col_sz, eg_rtl_ctrl_fifo[bank].used()), UVM_MEDIUM) + eg_rtl_ctrl_fifo[bank].get(item); + + `uvm_create_obj(flash_otf_item, obs) + obs = item; + + repeat(col_sz - 1) begin + eg_rtl_ctrl_fifo[bank].get(item); + obs.fq = {obs.fq, item.fq}; + end + + `dv_info($sformatf("WDATA size: %0d x 8B bank:%0d rcvd_cnt:%0d", + obs.fq.size(), bank, cfg.otf_ctrl_wr_rcvd++), UVM_MEDIUM, "process_write") + + compare_data(obs.fq, exp.fq, bank, $sformatf("wdata_page%0d", exp.page), exp.ecc_en); + endtask // process_write + + // Compare 64 bit for now + task compare_data(fdata_q_t obs, fdata_q_t exp, int bank, string rw, bit is_ecc = 0); + string str = $sformatf("%s_comp_bank%0d", rw, bank); + bit err = 0; + + // Fatal alert from host interface can disturb core tlul + if (cfg.scb_h.alert_count["fatal_err"]) begin + `uvm_info(`gfn, "comparison skipped due to fatal error is detected", UVM_MEDIUM) + return; + end + if (comp_off) return; + + foreach (obs[i]) begin + if (is_ecc) begin + if (obs[i] != exp[i]) begin + err = 1; + `dv_error($sformatf("%4d: obs:exp %2x_%1x_%8x_%8x:%2x_%1x_%8x_%8x mismatch!!", i, + obs[i][75:68], obs[i][67:64], obs[i][63:32], obs[i][31:0], + exp[i][75:68], exp[i][67:64], exp[i][63:32], exp[i][31:0]), + str) + end + end else begin + if (obs[i][63:0] != exp[i][63:0]) begin + err = 1; + `dv_error($sformatf("%4d: obs:exp %8x_%8x:%8x_%8x mismatch!!", i, + obs[i][63:32], obs[i][31:0], exp[i][63:32], exp[i][31:0]), + str) + end + end + end + if (err == 0) begin + `dv_info("data match!!", UVM_MEDIUM, str) + end + endtask // compare_data + + // Transform phy_item to otf_item and + // classify to host or ctrl transaction + task process_phy_item(flash_phy_prim_item item, int bank); + flash_otf_item obs; + + `uvm_create_obj(flash_otf_item, obs); + if (item.req.prog_req) begin + obs.get_from_phy(item, "w"); + eg_rtl_ctrl_fifo[bank].write(obs); + end else begin // read request, guaranteed by monitor + obs.get_from_phy(item, "r"); + end + endtask // process_phy_item + + task process_rcmd(flash_phy_prim_item item, int bank); + addr_t serr_addr; + flash_dv_part_e part = get_part_name(item.req); + if (cfg.ecc_mode == FlashSerrTestMode) begin + serr_addr = item.req.addr << 3; + serr_addr[OTFBankId] = bank; + if (cfg.address_has_serr(serr_addr, part)) begin + cfg.inc_serr_cnt(bank); + cfg.serr_addr[bank] = serr_addr; + end + end + endtask + + task monitor_tb_mem(int bank); + flash_phy_prim_item exp; + flash_otf_mem_entry rcv; + string name = $sformatf("mon_tb_mem%0d", bank); + fork + begin : isolation_fork + fork + begin : working_thread + forever begin + @(posedge cfg.flash_ctrl_mem_vif[bank].mem_wr); + if (mem_mon_off == 0) begin + `uvm_info("mem_if", "got posedge wr", UVM_MEDIUM) + `uvm_create_obj(flash_otf_mem_entry, rcv) + #1ps; + rcv.mem_addr = cfg.flash_ctrl_mem_vif[bank].mem_addr; + rcv.mem_wdata = cfg.flash_ctrl_mem_vif[bank].mem_wdata; + rcv.mem_part = cfg.flash_ctrl_mem_vif[bank].mem_part; + rcv.mem_info_sel = cfg.flash_ctrl_mem_vif[bank].mem_info_sel; + @(negedge cfg.flash_ctrl_mem_vif[bank].clk_i); + if (cfg.seq_cfg.use_vendor_flash == 0) begin + if (rcv.mem_part == FlashPartData) begin + `DV_CHECK_EQ(cfg.flash_ctrl_mem_vif[bank].data_mem_req, 1,,, name) + end else begin + case (rcv.mem_info_sel) + 0: `DV_CHECK_EQ(cfg.flash_ctrl_mem_vif[bank].info0_mem_req, 1,,, name) + 1: `DV_CHECK_EQ(cfg.flash_ctrl_mem_vif[bank].info1_mem_req, 1,,, name) + 2: `DV_CHECK_EQ(cfg.flash_ctrl_mem_vif[bank].info2_mem_req, 1,,, name) + default: `uvm_error(name, $sformatf("bank%0d infosel%0d doesn't exists", + bank, rcv.mem_info_sel)) + endcase + end + end + // collect ref data + eg_exp_lm_fifo[bank].get(exp); + lm_wdata_comp(exp, rcv, bank); + end + end // forever begin + end // block: working_thread + begin : terminate_thread + wait (stop); + end + join_any + #0; + disable fork; + end // block: isolation_fork + join + endtask // monitor_tb_mem + + task lm_wdata_comp(flash_phy_prim_item exp, flash_otf_mem_entry rcv, int bank); + bit[flash_phy_pkg::FullDataWidth-1:0] rd_data; + rd_cache_t entry; + string name = $sformatf("lm_wdata_comp_bank%0d", bank); + + if (rcv.mem_addr == exp.req.addr) begin + `dv_info($sformatf("addr match 0x%x, bank %0d", rcv.mem_addr << 3, bank), UVM_MEDIUM, name) + end else begin + `DV_CHECK_EQ(rcv.mem_addr, exp.req.addr,,, name) + end + + // check if this is page erase + if (exp.req.pg_erase_req | exp.req.bk_erase_req) begin + // The below check won't always be valid when using the vendor flash. + if (cfg.seq_cfg.use_vendor_flash == 0) begin + int cnt = 0; + int cnt_max = (exp.req.bk_erase_req)? 65536 : 256; + + `uvm_info(name, $sformatf("erase detected pg_erase:%0d bk_erase:%0d", + exp.req.pg_erase_req, exp.req.bk_erase_req), + UVM_MEDIUM) + repeat (cnt_max) begin + rcv.mem_addr = cfg.flash_ctrl_mem_vif[bank].mem_addr; + rcv.mem_wdata = cfg.flash_ctrl_mem_vif[bank].mem_wdata; + rcv.mem_part = cfg.flash_ctrl_mem_vif[bank].mem_part; + rcv.mem_info_sel = cfg.flash_ctrl_mem_vif[bank].mem_info_sel; + + entry.bank = bank; + entry.addr = (rcv.mem_addr<<3); + entry.part = cfg.get_part(rcv.mem_part, rcv.mem_info_sel); + corrupt_entry.delete(entry); + + if (rcv.mem_addr == exp.req.addr) begin + `dv_info($sformatf("addr match %x", rcv.mem_addr), UVM_MEDIUM, name) + end else begin + `DV_CHECK_EQ(rcv.mem_addr, exp.req.addr,,, name) + end + `DV_CHECK_EQ(rcv.mem_wdata, {flash_phy_pkg::FullDataWidth{1'b1}},,, name) + + + if (rcv.mem_part == FlashPartData) begin + data_mem[bank].delete(rcv.mem_addr); + end else begin + info_mem[bank][rcv.mem_info_sel].delete(rcv.mem_addr); + end + exp.req.addr++; + @(negedge cfg.flash_ctrl_mem_vif[bank].clk_i); + end + end + end else begin + bit skip_comp = 0; + entry.bank = bank; + entry.addr = (rcv.mem_addr<<3); + entry.part = cfg.get_part(rcv.mem_part, rcv.mem_info_sel); + + // Skip data comparison if there are error injections on this address. + if (cfg.address_has_ecc_injected_error(entry.addr, entry.part)) begin + skip_comp = 1; + end + + // Data will be corrupted if some bits to be written cannot be flipped to 1. + if (rcv.mem_part == FlashPartData) begin + if (data_mem[bank].exists(rcv.mem_addr)) begin + rd_data = data_mem[bank][rcv.mem_addr]; + if ((exp.req.prog_full_data & rd_data) != exp.req.prog_full_data) begin + corrupt_entry[entry] = 1; + `uvm_info(`gfn, $sformatf( + "Overwriting data bank:%0d, %s, addr:0x%x, data:0x%x, wr_data:0x%x", + bank, rcv.mem_part.name, entry.addr, rd_data, exp.req.prog_full_data), + UVM_MEDIUM) + if (cfg.seq_cfg.use_vendor_flash == 0) begin + exp.req.prog_full_data &= rd_data; + end else begin + skip_comp = 1; + end + data_mem[bank].delete(rcv.mem_addr); + end + end + data_mem[bank][rcv.mem_addr] = exp.req.prog_full_data; + end else begin + `uvm_info(`gfn, $sformatf("bank:%0d sel:%0d addr:%x", + bank, rcv.mem_info_sel, rcv.mem_addr), UVM_HIGH) + `uvm_info(`gfn, $sformatf("scb_rd_data:%x prog_data:%x", + info_mem[bank][rcv.mem_info_sel][rcv.mem_addr], exp.req.prog_full_data), UVM_HIGH) + if (info_mem[bank][rcv.mem_info_sel].exists(rcv.mem_addr)) begin + rd_data = info_mem[bank][rcv.mem_info_sel][rcv.mem_addr]; + if ((exp.req.prog_full_data & rd_data) != exp.req.prog_full_data) begin + corrupt_entry[entry] = 1; + `uvm_info(`gfn, $sformatf( + "Overwriting data bank:%0d, %s, addr:0x%x, data:0x%x, wr_data:0x%x", + bank, rcv.mem_part.name, entry.addr, rd_data, exp.req.prog_full_data), + UVM_MEDIUM) + if (cfg.seq_cfg.use_vendor_flash == 0) begin + exp.req.prog_full_data &= rd_data; + end else begin + skip_comp = 1; + end + info_mem[bank][rcv.mem_info_sel].delete(rcv.mem_addr); + end + `uvm_info(`gfn, $sformatf( + "Updating info_mem bank:%0d, info:%0d, addr:0x%x", + bank, rcv.mem_info_sel, rcv.mem_addr << 3), + UVM_MEDIUM) + end + info_mem[bank][rcv.mem_info_sel][rcv.mem_addr] = exp.req.prog_full_data; + end + + if (rcv.mem_wdata == exp.req.prog_full_data) begin + `dv_info($sformatf("wdata match %x", rcv.mem_wdata), UVM_MEDIUM, name) + end else if (!skip_comp) begin + `uvm_info(`gfn, $sformatf("expected request %p", exp.req), UVM_MEDIUM) + `DV_CHECK_EQ(rcv.mem_wdata, exp.req.prog_full_data,,, name) + end + end + endtask // lm_wdata_cmp +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv new file mode 100644 index 0000000000000..d4765260119c6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_scoreboard.sv @@ -0,0 +1,947 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +import alert_esc_agent_pkg::*; + +class flash_ctrl_scoreboard #( + type CFG_T = flash_ctrl_env_cfg +) extends cip_base_scoreboard #( + .CFG_T(CFG_T), + .RAL_T(flash_ctrl_core_reg_block), + .COV_T(flash_ctrl_env_cov) +); + `uvm_component_param_utils(flash_ctrl_scoreboard#(CFG_T)) + + `uvm_component_new + + uvm_reg_data_t data; + uvm_reg csr; + string csr_name; + flash_dv_part_e part = FlashPartData; + addr_t wr_addr; + addr_t rd_addr; + addr_t erase_addr; + bit [1:0] erase_bank_en; + int num_wr = 0; + int num_rd = 0; + int idx_wr = 0; + int idx_rd = 0; + bit part_sel = 0; + bit [1:0] info_sel = 2'b00; + bit wr_access = 1'b0; + bit rd_access = 1'b0; + bit erase_access = 1'b0; + bit erase_sel; + bit [1:0] curr_op; + tl_seq_item eflash_addr_phase_queue[$]; + int num_erase_words; + int exp_alert_contd[string]; + bit exp_alert_ff[string][$]; + alert_handshake_e hs_state; + + // ecc error expected + bit ecc_error_addr[bit [AddrWidth - 1 : 0]]; + int over_rd_err[addr_t]; + bit exp_tl_rsp_intg_err = 0; + + //host error injection + bit in_error_addr[bit [AddrWidth - 1 : 0]]; + + // TLM agent fifos + uvm_tlm_analysis_fifo #(tl_seq_item) eflash_tl_a_chan_fifo; + uvm_tlm_analysis_fifo #(tl_seq_item) eflash_tl_d_chan_fifo; + + bit skip_read_check = 0; + bit skip_alert_chk[string]; + // Prevent to execute predict_tl_err during fatal error test + bit stop_tl_err_chk = 0; + flash_phy_pkg::rd_buf_t evict_q[NumBanks][$]; + + // utility function to word-align an input TL address + function addr_t word_align_addr(addr_t addr); + return {addr[TL_AW-1:2], 2'b00}; + endfunction + + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + eflash_tl_a_chan_fifo = new("eflash_tl_a_chan_fifo", this); + eflash_tl_d_chan_fifo = new("eflash_tl_d_chan_fifo", this); + hs_state = AlertComplete; + foreach(LIST_OF_ALERTS[i]) skip_alert_chk[i] = 1'b0; + endfunction + + virtual function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + cfg.scb_h = this; + endfunction + + virtual task run_phase(uvm_phase phase); + super.run_phase(phase); + fork + process_eflash_tl_a_chan_fifo(); + process_eflash_tl_d_chan_fifo(); + mon_eviction(); + mon_rma(); + join_none + endtask + + task mon_rma; + bit init_set = 0; + forever begin + @(negedge cfg.clk_rst_vif.clk); + if (init_set == 0 && cfg.flash_ctrl_vif.init == 1) begin + init_set = 1; + if (cfg.en_cov) cov.rma_init_cg.sample(cfg.flash_ctrl_vif.rma_state); + end + end + endtask // mon_rma + + task mon_eviction; + flash_mp_region_cfg_t my_region; + bit ecc_en, scr_en; + int page; + forever begin + @(negedge cfg.clk_rst_vif.clk); + for (int i = 0; i < NumBanks; i++) begin + foreach (cfg.flash_ctrl_vif.hazard[i][j]) begin + if (cfg.flash_ctrl_vif.hazard[i][j]) begin + otf_addr_t addr = cfg.flash_ctrl_vif.rd_buf[i][j].addr << 3; + page = cfg.addr2page(addr); + if (cfg.flash_ctrl_vif.rd_buf[i][j].part == 0) begin // data + my_region = cfg.get_region(page + 256*i); + end else begin // info + my_region = + cfg.get_region_from_info( + cfg.mp_info[i][cfg.flash_ctrl_vif.rd_buf[i][j].info_sel][page]); + end + ecc_en = (my_region.ecc_en == MuBi4True); + scr_en = (my_region.scramble_en == MuBi4True); + `uvm_info(`gfn, $sformatf( + "eviction bank:%0d buffer:%0d addr:0x%x(%x) page:%0d ecc_en:%0d scr_en:%0d", + i, j ,cfg.flash_ctrl_vif.rd_buf[i][j].addr, addr, page, ecc_en, scr_en), + UVM_MEDIUM) + if (cfg.en_cov) cov.eviction_cg.sample(j, {cfg.flash_ctrl_vif.evict_prog[i], + cfg.flash_ctrl_vif.evict_erase[i]}, + {scr_en, ecc_en}); + end + end + end + end + endtask // mon_eviction + + // Task for receiving addr trans and storing them for later usage + virtual task process_eflash_tl_a_chan_fifo(); + tl_seq_item item; + + forever begin + eflash_tl_a_chan_fifo.get(item); + if (!cfg.en_scb) continue; + `uvm_info(`gfn, $sformatf( + "Received eflash_tl a_chan item:\n%0s", item.sprint(uvm_default_line_printer)), + UVM_HIGH) + // write the item into the addr queue + eflash_addr_phase_queue.push_back(item); + `uvm_info({`gfn, "::process_eflash_tl_a_chan_fifo()"}, $sformatf( + "Put ADDR_PHASE transaction into eflash_item_q: %0p", item), UVM_HIGH) + end + endtask + + // Task for receiving data trans and checking if they matched with address trans + virtual task process_eflash_tl_d_chan_fifo(); + tl_seq_item item; + tl_seq_item addr_item; + + forever begin + eflash_tl_d_chan_fifo.get(item); + if (!cfg.en_scb) continue; + `uvm_info(`gfn, $sformatf( + "Received eflash_tl d_chan item:\n%0s", item.sprint(uvm_default_line_printer)), + UVM_HIGH) + // check tl packet integrity + void'(item.is_ok()); + + // check that address phase for this read is done + `DV_CHECK_GT_FATAL(eflash_addr_phase_queue.size(), 0) + addr_item = eflash_addr_phase_queue.pop_front(); + + `DV_CHECK_EQ(word_align_addr(item.a_addr), word_align_addr(addr_item.a_addr)) + `DV_CHECK_EQ(item.a_source, addr_item.a_source) + if (cfg.block_host_rd) begin // blocking reads are checked with backdoor reads + check_trans(item); + end else begin // non blocking reads are pushed to the queue and in test checked + cfg.flash_rd_data.push_back(item.d_data); + end + end + endtask + + // the TLUL response data are compared to the backdoor-read data using the bit-mask. + virtual function void check_trans(ref tl_seq_item trans); + flash_op_t flash_read; + logic [TL_DW-1:0] exp_data [$]; + // Flash read trans + + flash_read.partition = FlashPartData; + flash_read.erase_type = FlashErasePage; + flash_read.op = flash_ctrl_pkg::FlashOpRead; + flash_read.num_words = 1; + flash_read.addr = trans.a_addr; + + //comparing backdoor read data and direct read data + cfg.flash_mem_bkdr_read(flash_read, exp_data); + `DV_CHECK_EQ(exp_data[0], trans.d_data) + // check data with internal memory + if (cfg.scb_check) begin + `uvm_info(`gfn, $sformatf("Direct read address 0x%0h data: 0x%0h", trans.a_addr, trans.d_data + ), UVM_HIGH) + check_rd_data(flash_read.partition, trans.a_addr, trans.d_data); + `uvm_info(`gfn, $sformatf("Direct read successfully!!!"), UVM_HIGH) + end + endfunction + + virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name); + uvm_reg csr; + string csr_wr_name = ""; + bit do_read_check = 1'b1; + 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); + bit erase_req; + if (skip_read_check) do_read_check = 0; + // if access was to a valid csr, get the csr handle + if ((is_mem_addr( + item, ral_name + ) || (csr_addr inside {cfg.ral_models[ral_name].csr_addrs})) && + !cfg.dir_rd_in_progress) begin + + // if incoming access is a write to a valid csr, then make updates right away. + if (addr_phase_write) begin + if (is_mem_addr(item, ral_name) && cfg.scb_check) begin // prog fifo + if (idx_wr == 0) begin + csr_rd(.ptr(ral.addr), .value(data), .backdoor(1'b1)); + wr_addr = word_align_addr(get_field_val(ral.addr.start, data)); + csr_rd(.ptr(ral.control), .value(data), .backdoor(1'b1)); + num_wr = get_field_val(ral.control.num, data); + part_sel = get_field_val(ral.control.partition_sel, data); + info_sel = get_field_val(ral.control.info_sel, data); + part = calc_part(part_sel, info_sel); + `uvm_info(`gfn, $sformatf("SCB WRITE ADDR: 0x%0h EXP ADDR: 0x%0h", csr_addr, wr_addr), + UVM_HIGH) + end else begin + wr_addr += 4; + end + write_allowed(part, wr_addr); + `uvm_info(`gfn, $sformatf("wr_access: 0x%0b wr_addr: 0x%0h", wr_access, wr_addr), UVM_LOW) + if (wr_access) begin + cfg.write_data_all_part(.part(part), .addr(wr_addr), .data(item.a_data)); + end + if (idx_wr == num_wr) begin + idx_wr = 0; + end else begin + idx_wr += 1; + end + end else 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) + csr_wr_name = csr.get_name(); + void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask))); + `uvm_info(`gfn, $sformatf("SCB EXP FLASH REG: 0x%0h", csr_addr), UVM_HIGH) + if ((csr_wr_name == "control") && cfg.scb_check) begin + csr_rd(.ptr(ral.control), .value(data), .backdoor(1'b1)); + curr_op = get_field_val(ral.control.op, data); + if (curr_op == 2) begin //erase op + erase_sel = get_field_val(ral.control.erase_sel, data); + part_sel = get_field_val(ral.control.partition_sel, data); + info_sel = get_field_val(ral.control.info_sel, data); + part = calc_part(part_sel, info_sel); + csr_rd(.ptr(ral.addr), .value(data), .backdoor(1'b1)); + erase_addr = word_align_addr(get_field_val(ral.addr.start, data)); + csr_rd(.ptr(ral.mp_bank_cfg_shadowed[0]), .value(data), .backdoor(1'b1)); + `uvm_info(`gfn, $sformatf("UVM_REG_DATA: 0x%0p", data), UVM_HIGH) + erase_bank_en = data; + `uvm_info( + `gfn, $sformatf( + "erase_sel: 0x%0b part sel: 0x%0b info sel 0x%0d", erase_sel, part_sel, info_sel), + UVM_LOW) + `uvm_info( + `gfn, $sformatf( + "part: %0s addr: 0x%0h erase_bank_en: 0x%0h", part.name, erase_addr, erase_bank_en + ), UVM_LOW) + erase_allowed(part, erase_sel, erase_addr, erase_bank_en); + `uvm_info(`gfn, $sformatf( + "erase_access: 0x%0b part:%0s erase_addr: 0x%0h", + erase_access, + part.name, + erase_addr + ), UVM_LOW) + if (erase_access) begin + if (erase_sel) erase_bank(erase_addr[OTFBankId], part_sel); + else erase_data(part, erase_addr, erase_sel); + end + end + end + // coverage collection + case (csr_wr_name) + "control": begin + if (skip_read_check == 0) begin + csr_rd(.ptr(ral.control), .value(data), .backdoor(1'b1)); + curr_op = get_field_val(ral.control.op, data); + erase_sel = get_field_val(ral.control.erase_sel, data); + part_sel = get_field_val(ral.control.partition_sel, data); + info_sel = get_field_val(ral.control.info_sel, data); + part = calc_part(part_sel, info_sel); + if (cfg.en_cov) begin + flash_op_t flash_op_cov; + flash_op_cov.partition = part; + flash_op_cov.erase_type = flash_erase_e'(erase_sel); + flash_op_cov.op = flash_op_e'(curr_op); + cov.control_cg.sample(flash_op_cov); + end + end + end + "erase_suspend": begin + csr_rd(.ptr(ral.erase_suspend), .value(data), .backdoor(1'b1)); + erase_req = get_field_val(ral.erase_suspend.req, data); + if (cfg.en_cov) begin + cov.erase_susp_cg.sample(erase_req); + end + end + "intr_test": begin + bit [TL_DW-1:0] intr_en = `gmv(ral.intr_enable); + bit [NumFlashCtrlIntr-1:0] intr_exp = `gmv(ral.intr_state); + intr_exp |= item.a_data; + foreach (intr_exp[i]) begin + if (cfg.en_cov) begin + cov.intr_test_cg.sample(i, item.a_data[i], intr_en[i], intr_exp[i]); + end + end + end + default: begin + `uvm_info(`gfn, $sformatf("Not for func coverage: %0s", + csr.get_full_name()),UVM_HIGH) + end + endcase + end + end + + if (data_phase_read) begin + 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) + // 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 + if(!uvm_re_match("err_code*",csr.get_name())) begin + if (cfg.en_cov) begin + cov.sw_error_cg.sample(item.d_data); + end + end + case (csr.get_name()) + // add individual case item for each csr + "intr_state": begin + bit [TL_DW-1:0] intr_en = `gmv(ral.intr_enable); + bit [NumFlashCtrlIntr-1:0] intr_exp = `gmv(ral.intr_state); + csr_rd(.ptr(ral.curr_fifo_lvl), .value(data), .backdoor(1'b1)); + if (cfg.en_cov) begin + foreach (intr_exp[i]) begin + flash_ctrl_intr_e intr = flash_ctrl_intr_e'(i); + cov.intr_cg.sample(i, intr_en[i], item.d_data[i]); + cov.intr_pins_cg.sample(i, cfg.intr_vif.pins[i]); + end + cov.msgfifo_level_cg.sample(data[4:0], data[12:8], + cfg.intr_vif.pins[FlashCtrlIntrProgLvl], + cfg.intr_vif.pins[FlashCtrlIntrRdLvl]); + end + // Skip read check on intr_state CSR, since it is WO. + do_read_check = 1'b0; + end + + "op_status", "status", "erase_suspend", "curr_fifo_lvl", "debug_state", + "ecc_single_err_cnt", "ecc_single_err_addr_0", "ecc_single_err_addr_1", + "std_fault_status": begin + do_read_check = 1'b0; + end + "err_code", "fault_status": begin + do_read_check = 1'b0; + end + default: begin + // Do nothing. + // This is place holder for default csr test. + end + endcase + // On reads, if do_read_check, is set, then check mirrored_value against item.d_data + 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 else if (is_mem_addr(item, ral_name) && cfg.scb_check) begin // rd fifo + if (idx_rd == 0) begin + csr_rd(.ptr(ral.addr), .value(data), .backdoor(1'b1)); + rd_addr = word_align_addr(get_field_val(ral.addr.start, data)); + csr_rd(.ptr(ral.control), .value(data), .backdoor(1'b1)); + num_rd = get_field_val(ral.control.num, data); + part_sel = get_field_val(ral.control.partition_sel, data); + info_sel = get_field_val(ral.control.info_sel, data); + part = calc_part(part_sel, info_sel); + `uvm_info(`gfn, $sformatf("SCB READ ADDR: 0x%0h EXP ADDR: 0x%0h", csr_addr, rd_addr), + UVM_HIGH) + end else begin + rd_addr += 4; + end + read_allowed(part, rd_addr); + `uvm_info(`gfn, $sformatf("rd_access: 0x%0b", rd_access), UVM_LOW) + if (rd_access) begin + check_rd_data(part, rd_addr, item.d_data); + end + if (idx_rd == num_rd) begin + idx_rd = 0; + end else begin + idx_rd += 1; + end + end + end + end + endtask + + // Update scb_flash_* with bank erase command. + // If data partition is selected, erase data partition only, + // otherwise all partitions in the bank will be erased. + virtual function void erase_bank(int bank, bit part_sel); + uint partition_words_num; + data_model_t scb_flash_model; + flash_mem_addr_attrs addr_attr; + flash_dv_part_e part = part.first(); + do begin + partition_words_num = cfg.get_partition_words_num(part); + scb_flash_model = cfg.get_partition_mem_model(part); + addr_attr = new(); + addr_attr.set_attrs(bank * BytesPerBank); + if (part_sel == 1 || part == FlashPartData) begin + for (int j = 0; j < partition_words_num; j++) begin + scb_flash_model[addr_attr.addr] = ALL_ONES; + addr_attr.incr(flash_ctrl_pkg::BusBytes); + end + case (part) + FlashPartData: cfg.scb_flash_data = scb_flash_model; + FlashPartInfo: cfg.scb_flash_info = scb_flash_model; + FlashPartInfo1: cfg.scb_flash_info1 = scb_flash_model; + FlashPartInfo2: cfg.scb_flash_info2 = scb_flash_model; + default: `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Partition type not supported!") + endcase + end + part = part.next(); + end while (part != part.first()); + + endfunction + + virtual function void reset(string kind = "HARD"); + super.reset(kind); + foreach(cfg.list_of_alerts[i]) begin + exp_alert_contd[i] = 0; + end + // reset local fifos queues and variables + eflash_tl_a_chan_fifo.flush(); + eflash_tl_d_chan_fifo.flush(); + cfg.scb_flash_data.delete(); + cfg.scb_flash_info.delete(); + cfg.scb_flash_info1.delete(); + cfg.scb_flash_info2.delete(); + endfunction + + virtual function void check_phase(uvm_phase phase); + super.check_phase(phase); + // post test checks - ensure that all local fifos and queues are empty + `DV_EOT_PRINT_TLM_FIFO_CONTENTS(tl_seq_item, eflash_tl_a_chan_fifo) + `DV_EOT_PRINT_TLM_FIFO_CONTENTS(tl_seq_item, eflash_tl_d_chan_fifo) + if (cfg.en_scb) begin + `DV_CHECK_EQ(eflash_addr_phase_queue.size, 0) + end + if (cfg.scb_check && cfg.check_full_scb_mem_model) begin + cfg.check_mem_model(); + end + + `DV_CHECK_EQ(cfg.tlul_core_obs_cnt, cfg.tlul_core_exp_cnt, + "core_tlul_error_cnt mismatch") + endfunction + + virtual function flash_dv_part_e calc_part(bit part_sel, bit [1:0] info_sel); + if (!part_sel) begin + return FlashPartData; + end else begin + case (info_sel) + 2'b00: return FlashPartInfo; + 2'b01: return FlashPartInfo1; + 2'b10: return FlashPartInfo2; + default: begin + `uvm_fatal("flash_ctrl_scoreboard", $sformatf("unknown info part sel 0x%0h", info_sel)) + end + endcase + end + endfunction + + virtual function void check_rd_data(flash_dv_part_e part, addr_t addr, + ref data_t data); + case (part) + FlashPartData: begin + check_rd_part(cfg.scb_flash_data, addr, data); + end + FlashPartInfo: begin + check_rd_part(cfg.scb_flash_info, addr, data); + end + FlashPartInfo1: begin + check_rd_part(cfg.scb_flash_info1, addr, data); + end + FlashPartInfo2: begin + check_rd_part(cfg.scb_flash_info2, addr, data); + end + default: `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Partition type not supported!") + endcase + endfunction + + // In opensource, `sel` is always 0. + // When `sel` is 1, which indicates bank erase, + // task `erase_bank` is called. + virtual function void erase_data(flash_dv_part_e part, addr_t addr, bit sel); + case (part) + FlashPartData: begin + erase_page_bank(NUM_BK_DATA_WORDS, addr, sel, cfg.scb_flash_data, "scb_flash_data"); + end + FlashPartInfo: begin + if (sel) begin + erase_page_bank(NUM_BK_DATA_WORDS, addr, sel, cfg.scb_flash_data, "scb_flash_data"); + end + erase_page_bank(NUM_BK_INFO_WORDS, addr, sel, cfg.scb_flash_info, "scb_flash_info"); + end + FlashPartInfo1: begin + if (!sel) begin + erase_page_bank(NUM_PAGE_WORDS, addr, sel, cfg.scb_flash_info1, "scb_flash_info1"); + end else begin + `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Bank erase for INFO1 part not supported!") + end + end + FlashPartInfo2: begin + if (!sel) begin + erase_page_bank(NUM_PAGE_WORDS, addr, sel, cfg.scb_flash_info2, "scb_flash_info2"); + end else begin + `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Bank erase for INFO2 part not supported!") + end + end + default: `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Partition type not supported!") + endcase + + endfunction + + virtual task write_allowed(ref flash_dv_part_e part, ref addr_t in_addr); + bit en; + bit prog_en; + bit prog_en_def; + bit [8:0] base; + bit [9:0] size; + bit bk_idx; + int pg_idx; + bit wr_access_found; + + wr_access_found = 1'b0; + wr_access = 1'b0; + case (part) + FlashPartData: begin + for (int i = 0; i < cfg.seq_cfg.num_en_mp_regions; i++) begin + if (!wr_access_found) begin + csr_rd(.ptr(ral.mp_region_cfg[i]), .value(data), .backdoor(1'b1)); + en = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.mp_region_cfg[i].en, data))); + prog_en = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.mp_region_cfg[i].prog_en, data))); + csr_rd(.ptr(ral.mp_region[i]), .value(data), .backdoor(1'b1)); + base = get_field_val(ral.mp_region[i].base, data); + size = get_field_val(ral.mp_region[i].size, data); + if (in_addr inside {[base*BytesPerPage:base*BytesPerPage+size*BytesPerPage]}) begin + if (en) begin + wr_access = prog_en; + wr_access_found = 1'b1; + end + end + end + end + if (!wr_access_found) begin + csr_rd(.ptr(ral.default_region), .value(data), .backdoor(1'b1)); + prog_en_def = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.default_region.prog_en, data))); + wr_access = prog_en_def; + wr_access_found = 1'b1; + end + end + FlashPartInfo: begin + bk_idx = in_addr[19]; + pg_idx = in_addr[18:11]; + csr_name = $sformatf("bank%0d_info0_page_cfg_%0d", bk_idx, pg_idx); + write_access_info(); + end + FlashPartInfo1: begin + bk_idx = in_addr[19]; + csr_name = $sformatf("bank%0d_info1_page_cfg", bk_idx); + write_access_info(); + end + FlashPartInfo2: begin + bk_idx = in_addr[19]; + pg_idx = in_addr[18:11]; + csr_name = $sformatf("bank%0d_info2_page_cfg_%0d", bk_idx, pg_idx); + write_access_info(); + end + default: `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Partition type not supported!") + endcase + endtask + + virtual task read_allowed(ref flash_dv_part_e part, ref addr_t in_rd_addr); + bit en; + bit read_en; + bit read_en_def; + bit [8:0] base; + bit [9:0] size; + bit bk_idx; + int pg_idx; + bit rd_access_found; + + rd_access_found = 1'b0; + rd_access = 1'b0; + case (part) + FlashPartData: begin + for (int i = 0; i < cfg.seq_cfg.num_en_mp_regions; i++) begin + if (!rd_access_found) begin + csr_rd(.ptr(ral.mp_region_cfg[i]), .value(data), .backdoor(1'b1)); + en = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.mp_region_cfg[i].en, data))); + read_en = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.mp_region_cfg[i].rd_en, data))); + csr_rd(.ptr(ral.mp_region[i]), .value(data), .backdoor(1'b1)); + base = get_field_val(ral.mp_region[i].base, data); + size = get_field_val(ral.mp_region[i].size, data); + if (in_rd_addr inside {[base*BytesPerPage:base*BytesPerPage+size*BytesPerPage]}) begin + if (en) begin + rd_access_found = 1'b1; + end + end + end + end + if (!rd_access_found) begin + csr_rd(.ptr(ral.default_region), .value(data), .backdoor(1'b1)); + read_en_def = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.default_region.rd_en, data))); + rd_access = read_en_def; + rd_access_found = 1'b1; + end + end + FlashPartInfo: begin + bk_idx = in_rd_addr[19]; + pg_idx = in_rd_addr[18:11]; + csr_name = $sformatf("bank%0d_info0_page_cfg_%0d", bk_idx, pg_idx); + read_access_info(); + end + FlashPartInfo1: begin + bk_idx = in_rd_addr[19]; + csr_name = $sformatf("bank%0d_info1_page_cfg", bk_idx); + read_access_info(); + end + FlashPartInfo2: begin + bk_idx = in_rd_addr[19]; + pg_idx = in_rd_addr[18:11]; + csr_name = $sformatf("bank%0d_info2_page_cfg_%0d", bk_idx, pg_idx); + read_access_info(); + end + default: `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Partition type not supported!") + endcase + endtask + + virtual task erase_allowed(ref flash_dv_part_e part, bit erase_sel, + ref addr_t in_erase_addr, bit [1:0] bk_en); + bit en; + bit erase_en; + bit erase_en_def; + bit [8:0] base; + bit [9:0] size; + bit bk_idx; + int pg_idx; + bit erase_access_found; + + erase_access_found = 1'b0; + erase_access = 1'b0; + if (!erase_sel) begin // page erase + case (part) + FlashPartData: begin + for (int i = 0; i < cfg.seq_cfg.num_en_mp_regions; i++) begin + if (!erase_access_found) begin + csr_rd(.ptr(ral.mp_region_cfg[i]), .value(data), .backdoor(1'b1)); + en = mubi4_test_true_strict(mubi4_t'(get_field_val(ral.mp_region_cfg[i].en, data))); + erase_en = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.mp_region_cfg[i].erase_en, data))); + csr_rd(.ptr(ral.mp_region[i]), .value(data), .backdoor(1'b1)); + base = get_field_val(ral.mp_region[i].base, data); + size = get_field_val(ral.mp_region[i].size, data); + if (in_erase_addr + inside {[base*BytesPerPage:base*BytesPerPage+size*BytesPerPage-1]}) begin + if (en) begin + erase_access = erase_en; + erase_access_found = 1'b1; + end + end + end + end + if (!erase_access_found) begin + csr_rd(.ptr(ral.default_region), .value(data), .backdoor(1'b1)); + erase_en_def = mubi4_test_true_strict(mubi4_t'( + get_field_val(ral.default_region.erase_en, data))); + erase_access = erase_en_def; + erase_access_found = 1'b1; + end + end + FlashPartInfo: begin + bk_idx = in_erase_addr[19]; + pg_idx = in_erase_addr[18:11]; + csr_name = $sformatf("bank%0d_info0_page_cfg_%0d", bk_idx, pg_idx); + erase_access_info(); + end + FlashPartInfo1: begin + bk_idx = in_erase_addr[19]; + csr_name = $sformatf("bank%0d_info1_page_cfg", bk_idx); + erase_access_info(); + end + FlashPartInfo2: begin + bk_idx = in_erase_addr[19]; + pg_idx = in_erase_addr[18:11]; + csr_name = $sformatf("bank%0d_info2_page_cfg_%0d", bk_idx, pg_idx); + erase_access_info(); + end + default: `uvm_fatal(`gfn, "flash_ctrl_scoreboard: Partition type not supported!") + endcase + end else begin // bank erase + bk_idx = in_erase_addr[19]; + erase_access = bk_en[bk_idx]; + `uvm_info(`gfn, $sformatf("erase_access bank: 0x%0b", erase_access), UVM_LOW) + end + endtask + + virtual function void check_rd_part(const ref data_model_t exp_data_part, + addr_t addr, ref data_t data); + if (exp_data_part.exists(addr)) begin + `uvm_info( + `gfn, $sformatf( + "addr: 0x%0h scb data: 0x%0h data 0: 0x%0h", addr, exp_data_part[addr], exp_data_part[0]), + UVM_HIGH) + `DV_CHECK_EQ(exp_data_part[addr], data, $sformatf("read addr:0x%0h data: 0x%0h", addr, data)) + end else begin + `uvm_info(`gfn, $sformatf("addr %0h is not written!", addr), UVM_MEDIUM) + end + endfunction + + virtual task write_access_info(); + bit en; + bit prog_en; + + csr = ral.get_reg_by_name(csr_name); + csr_rd(.ptr(csr), .value(data), .backdoor(1'b1)); + en = mubi4_test_true_strict(mubi4_t'( + get_field_val(csr.get_field_by_name("en"), data))); + prog_en = mubi4_test_true_strict(mubi4_t'( + get_field_val(csr.get_field_by_name("prog_en"), data))); + if (en) begin + wr_access = prog_en; + end else begin + wr_access = 0; //protected + end + endtask + + virtual task read_access_info(); + bit en; + bit read_en; + + csr = ral.get_reg_by_name(csr_name); + csr_rd(.ptr(csr), .value(data), .backdoor(1'b1)); + en = mubi4_test_true_strict(mubi4_t'( + get_field_val(csr.get_field_by_name("en"), data))); + read_en = mubi4_test_true_strict(mubi4_t'( + get_field_val(csr.get_field_by_name("rd_en"), data))); + if (en) begin + rd_access = read_en; + end else begin + rd_access = 0; //protected + end + endtask + + virtual task erase_access_info(); + bit en; + bit erase_en; + + csr = ral.get_reg_by_name(csr_name); + csr_rd(.ptr(csr), .value(data), .backdoor(1'b1)); + en = mubi4_test_true_strict(mubi4_t'( + get_field_val(csr.get_field_by_name("en"), data))); + erase_en = mubi4_test_true_strict(mubi4_t'( + get_field_val(csr.get_field_by_name("erase_en"),data))); + if (en) begin + erase_access = erase_en; + end else begin + erase_access = 0; //protected + end + endtask + + virtual function void erase_page_bank(int num_bk_words, addr_t addr, bit sel, + ref data_model_t exp_part, + input string scb_mem_name); + int num_wr; + if (sel) begin // bank sel + num_wr = num_bk_words; + `uvm_info(`gfn, $sformatf("num_wr: %0d", num_wr), UVM_LOW) + if (addr[19]) begin // bank 1 + addr = BytesPerBank; + end else begin // bank 0 + addr = 0; + end + end else begin // page sel + num_wr = NUM_PAGE_WORDS; + addr = {addr[19:11], {11{1'b0}}}; + end + for (int i = 0; i < num_wr; i++) begin + if (exp_part.exists(addr)) begin + exp_part[addr] = {TL_DW{1'b1}}; + `uvm_info(`gfn, $sformatf("ERASE ADDR:0x%0h %s: 0x%0h", addr, scb_mem_name, exp_part[addr]), + UVM_LOW) + end + addr = addr + 4; + end + endfunction + + // Overriden function from cip_base_scoreboard, to handle TL/UL Error seen on Hardware Interface + // when using Code Access Restrictions (EXEC) + virtual function bit predict_tl_err(tl_seq_item item, tl_channels_e channel, string ral_name); + bit ecc_err, in_err; + + // Skip this routine when fatal error event is asserted + if (stop_tl_err_chk) return 1; + + // For flash, address has to be 8byte aligned. + ecc_err = ecc_error_addr.exists({item.a_addr[AddrWidth-1:3],3'b0}); + in_err = in_error_addr.exists({item.a_addr[AddrWidth-1:3],3'b0}); + `uvm_info("predict_tl_err_dbg", + $sformatf({"addr:0x%x(%x) ecc_err:%0d in_err:%0d channel:%s ral_name:%s", + " tlul_exp_cnt:%0d"}, + {item.a_addr[AddrWidth-1:3],3'b0}, + item.a_addr, ecc_err, in_err, + channel.name, ral_name, + cfg.tlul_core_exp_cnt + ), UVM_HIGH) + + if (over_rd_err.exists(item.a_addr)) begin + if (channel == DataChannel) begin + over_rd_err[item.a_addr]--; + if (over_rd_err[item.a_addr] == 0) over_rd_err.delete(item.a_addr); + `uvm_info(`gfn, $sformatf("addr is clear 0x%x", item.a_addr), UVM_HIGH) + end + return 1; + end + + if (ral_name == cfg.flash_ral_name) begin + if (get_flash_instr_type_err(item, channel)) return (1); + if (cfg.tlul_eflash_exp_cnt > 0 && item.d_error == 1) begin + cfg.tlul_eflash_obs_cnt++; + return 1; + end + end else begin + if (cfg.tlul_core_exp_cnt > 0 && item.d_error == 1) begin + cfg.tlul_core_obs_cnt++; + return 1; + end + end + + if (ecc_err | in_err) begin + if (channel == DataChannel) begin + `DV_CHECK_EQ(item.d_error, 1, + $sformatf("On interface %s, TL item: %s, ecc_err:%0d in_err:%0d", + ral_name, item.sprint(uvm_default_line_printer), + ecc_err, in_err)) + return 1; + end + end + + if (exp_tl_rsp_intg_err == 1 && channel == DataChannel) begin + return (!item.is_d_chan_intg_ok(.throw_error(0))); + end + + if (ral_name == cfg.flash_ral_name && channel == DataChannel) begin + bit has_error = cfg.address_has_some_injected_error({item.a_addr[TL_AW-1:3],3'h0}, + FlashPartData); + if (has_error) begin + `uvm_info(`gfn, $sformatf("A double ecc or integrity error for addr:0x%x", item.a_addr), + UVM_MEDIUM) + return 1; + end + end + return (super.predict_tl_err(item, channel, ral_name)); + endfunction : predict_tl_err + + // Check if the input tl_seq_item has any tl errors. + virtual function bit get_flash_instr_type_err(tl_seq_item item, tl_channels_e channel); + bit is_exec_key = `gmv(ral.exec) == CODE_EXEC_KEY; + // Local Variable + tlul_pkg::tl_a_user_t a_user = item.a_user; + if (cfg.en_cov) begin + if (channel == AddrChannel) begin + cov.fetch_code_cg.sample(is_exec_key, a_user.instr_type); + end + end + + // If Data Access, or a Write, or the CODE_EXEC_KEY Matches + if (((a_user.instr_type == MuBi4False) || (item.a_opcode != tlul_pkg::Get)) || + (`gmv(ral.exec) == CODE_EXEC_KEY)) return(0); // No Error Predicted + + // Error is Predicted, Expect an Error if Channel==DataChannel + if (channel == DataChannel) begin + `uvm_info(`gfn, "TL Error Expected", UVM_HIGH) + `DV_CHECK_EQ(item.d_error, 1) + end + return (1); // Error Predicted + + endfunction : get_flash_instr_type_err + + function void process_alert(string alert_name, alert_esc_seq_item item); + bit pop_out; + if (!(alert_name inside {cfg.list_of_alerts})) begin + `uvm_fatal(`gfn, $sformatf("alert_name %0s is not in cfg.list_of_alerts!", alert_name)) + end + hs_state = item.alert_handshake_sta; + + `uvm_info(`gfn, $sformatf("alert %0s detected, alert_status is %s exp:%0d contd:%0d", + alert_name, + item.alert_handshake_sta, + expected_alert[alert_name].expected, + exp_alert_contd[alert_name] + ), UVM_MEDIUM) + if (item.alert_handshake_sta == AlertReceived) begin + under_alert_handshake[alert_name] = 1; + if (exp_alert_ff[alert_name].size > 0) expected_alert[alert_name].expected = 1; + on_alert(alert_name, item); + alert_count[alert_name]++; + end else begin + if (!cfg.under_reset && under_alert_handshake[alert_name] == 0) begin + `uvm_error(`gfn, $sformatf("alert %0s is not received!", alert_name)) + end + pop_out = exp_alert_ff[alert_name].pop_front(); + if (exp_alert_ff[alert_name].size() == 0) expected_alert[alert_name].expected = 0; + under_alert_handshake[alert_name] = 0; + if (exp_alert_contd[alert_name] > 0) begin + expected_alert[alert_name].expected = 1; + exp_alert_contd[alert_name]--; + end + end + endfunction + + virtual function void on_alert(string alert_name, alert_esc_seq_item item); + if(!skip_alert_chk[alert_name]) begin + super.on_alert(alert_name, item); + end + endfunction + +endclass : flash_ctrl_scoreboard diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv new file mode 100644 index 0000000000000..19cc6622428f9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv @@ -0,0 +1,289 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This clas provides knobs to set the weights for various seq random variables. +class flash_ctrl_seq_cfg extends uvm_object; + `uvm_object_utils(flash_ctrl_seq_cfg) + + // Randomization weights in percentages, and other related settings. + + // Maximun number of times the vseq is randomized and rerun. + uint max_num_trans; + + // Memory protection configuration. + uint num_en_mp_regions; + + // This enables memory protection regions to overlap. + bit allow_mp_region_overlap; + + // Weights for enable bits for each of the flash banks information partitions memory protection + // configuration registers. + uint mp_info_page_en_pc[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes]; + + // When this knob is NOT FlashOpInvalid (default) the selected operation will be the only + // operation to run in the test (FlashOpRead, FlashOpProgram, FlashOpErase). + flash_ctrl_pkg::flash_op_e flash_only_op; + + // Weights to enable read / program and erase for each mem region. + uint mp_region_en_pc; + uint mp_region_read_en_pc; + uint mp_region_program_en_pc; + uint mp_region_erase_en_pc; + uint mp_region_scramble_en_pc; + uint mp_region_ecc_en_pc; + uint mp_region_he_en_pc; + uint mp_region_max_pages; + + // Knob to control bank level erasability. + uint bank_erase_en_pc; + + // Default region knobs. + uint default_region_read_en_pc; + uint default_region_program_en_pc; + uint default_region_erase_en_pc; + uint default_region_scramble_en_pc; + uint default_region_ecc_en_pc; + uint default_region_he_en_pc; + + // Weights to enable read / program and erase for each information partition page. + // For each of the information partitions in each of the banks there is a single variable to + // control all of this partition pages. + uint mp_info_page_read_en_pc[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes]; + uint mp_info_page_program_en_pc[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes]; + uint mp_info_page_erase_en_pc[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes]; + uint mp_info_page_scramble_en_pc[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes]; + uint mp_info_page_ecc_en_pc[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes]; + uint mp_info_page_he_en_pc[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes]; + + // Control the number of flash ops. + uint max_flash_ops_per_cfg; + + // Flash ctrl op randomization knobs. + + // Partition select. Make sure to keep sum equals to 100. + uint op_on_data_partition_pc; // Choose data partition. + uint op_on_info_partition_pc; // Choose info partition. + uint op_on_info1_partition_pc; // Choose info1 partition. + uint op_on_info2_partition_pc; // Choose info2 partition. + + bit avoid_ro_partitions; // Avoid partitions defined as read-only. + + // Avoid creating flash program operations that cross program resolution boundaries of 64 byte. + bit avoid_prog_res_fault; + + // Trigger program resolution error by using large fractions. + bit trigger_prog_res_fault; + + // This is used for ecc faults to choose the target addresses. + flash_tgt_prefix_e ecc_err_target = TgtRd; + + bit op_readonly_on_info_partition; // Make info partition read-only. + bit op_readonly_on_info1_partition; // Make info1 partition read-only. + bit op_readonly_on_info2_partition; // Make info2 partition read-only. + + // Vendor flash model hook + bit use_vendor_flash = 0; + string vendor_flash_path = ""; // Use to indicate a vendor flash hierarchical path. + bit exclude_info2 = 0; + // Used for expected_alert["fatal_err"].max_delay + // Vendor can use larger value + int long_fatal_err_delay = 2000; + + uint op_erase_type_bank_pc; + uint op_prog_type_repair_pc; + uint op_max_words; + bit op_allow_invalid; + + // Poll fifo status before writing to prog_fifo / reading from rd_fifo. + uint poll_fifo_status_pc; + + // Chances to start flash with all 1s and not with random values (default is 30%). + uint flash_init_set_pc; + + // Set by a higher level vseq that invokes this vseq. + bit external_cfg; + + // If pre-transaction back-door memory preperation isn't needed, set do_tran_prep_mem to 0. + bit do_tran_prep_mem; + + // When 0, the post-transaction back-door checks will be disabled. + // Added to enable other post-transaction checks and actions. + bit check_mem_post_tran; + + // Timeout for program transaction + uint prog_timeout_ns; + + // Timeout for erase transaction + uint erase_timeout_ns; + + // Expected time for the erase-suspend operation + uint erase_suspend_expected_time_ns; + + // Timeout for read transaction + uint read_timeout_ns; + + // Timeout for LC state transition + uint state_wait_timeout_ns; + + // Enable/Disable the Secret Seeds and Keys during Initialisation + bit en_init_keys_seeds; + + // States whether to wait for the flash_init to finish before starting the actual sequence. + bit wait_init_done; + + // Enable/Disable the Random Flash Initialisation After Reset + bit disable_flash_init; + + // Path to flash wrapper hierarchy. + string flash_path_str; + + // Restrict address to be flash word aligned + bit addr_flash_word_aligned; + + // NOTE: Make sure to keep + // cfg.flash_ctrl_vif.rst_to_pd_time_ns < reset_width_clks_lo * clk_period_ns. + // This will make sure that the power-down assertion will happen before reset deassertion. + + // Low limit of reset assertion time in clock cycles (from assertion to deassertion). + uint reset_width_clks_lo; + + // High limit of reset assertion time in clock cycles (from assertion to deassertion). + uint reset_width_clks_hi; + + `uvm_object_new + + // Set partition select percentages. Make sure to keep sum equals to 100. + virtual function void set_partition_pc(uint sel_data_part_pc = 100, uint sel_info_part_pc = 0, + uint sel_info1_part_pc = 0, + uint sel_info2_part_pc = 0); + + `DV_CHECK_EQ(sel_data_part_pc + sel_info_part_pc + sel_info1_part_pc + sel_info2_part_pc, + 100, $sformatf( + { + "Error! sum of arguments must be 100. Be aware of arguments ", + "default values - 100 for data partition and 0 for all the ", + "others. Arguments current value: sel_data_part_pc=%0d , ", + "sel_info_part_pc=%0d , sel_info1_part_pc=%0d , ", + "sel_info2_part_pc=%0d" + }, + sel_data_part_pc, + sel_info_part_pc, + sel_info1_part_pc, + sel_info2_part_pc + )) + + op_on_data_partition_pc = sel_data_part_pc; + op_on_info_partition_pc = sel_info_part_pc; + op_on_info1_partition_pc = sel_info1_part_pc; + op_on_info2_partition_pc = sel_info2_part_pc; + + endfunction : set_partition_pc + + virtual function void configure(); + max_num_trans = 20; + + num_en_mp_regions = flash_ctrl_pkg::MpRegions; + + allow_mp_region_overlap = 1'b0; + + mp_region_en_pc = 50; + mp_region_read_en_pc = 50; + mp_region_program_en_pc = 50; + mp_region_erase_en_pc = 50; + mp_region_scramble_en_pc = 0; + mp_region_ecc_en_pc = 0; + mp_region_he_en_pc = 0; + mp_region_max_pages = 32; + + bank_erase_en_pc = 50; + + default_region_read_en_pc = 50; + default_region_program_en_pc = 50; + default_region_erase_en_pc = 50; + default_region_scramble_en_pc = 0; + default_region_ecc_en_pc = 0; + default_region_he_en_pc = 0; + + foreach (mp_info_page_en_pc[i, j]) begin + mp_info_page_en_pc[i][j] = 50; + mp_info_page_read_en_pc[i][j] = 50; + mp_info_page_program_en_pc[i][j] = 50; + mp_info_page_erase_en_pc[i][j] = 50; + mp_info_page_scramble_en_pc[i][j] = 0; + mp_info_page_ecc_en_pc[i][j] = 0; + mp_info_page_he_en_pc[i][j] = 0; + end + + flash_only_op = FlashOpInvalid; + + max_flash_ops_per_cfg = 50; + + if (!$value$plusargs("op_readonly_on_info_partition=%0d", + op_readonly_on_info_partition)) begin + op_readonly_on_info_partition = 0; + end + if (!$value$plusargs("op_readonly_on_info1_partition=%0d", + op_readonly_on_info1_partition)) begin + // info1 partition will be read-only by default + op_readonly_on_info1_partition = 1; + end + if (!$value$plusargs("op_readonly_on_info2_partition=%0d", + op_readonly_on_info2_partition)) begin + op_readonly_on_info2_partition = 0; + end + + avoid_ro_partitions = 0; + + avoid_prog_res_fault = 1; + + op_erase_type_bank_pc = 20; + op_prog_type_repair_pc = 10; + op_max_words = 512; + op_allow_invalid = 1'b0; + + poll_fifo_status_pc = 30; + + flash_init_set_pc = 30; + + external_cfg = 1'b0; + + do_tran_prep_mem = 1'b1; + + check_mem_post_tran = 1'b1; + + addr_flash_word_aligned = 1'b0; + + prog_timeout_ns = 10_000_000; // 10ms + + read_timeout_ns = 100_000; // 100us + + erase_timeout_ns = 120_000_000; // 120ms + + erase_suspend_expected_time_ns = 50_000; // 50us + + state_wait_timeout_ns = 500_000; // 500us + + en_init_keys_seeds = 1'b0; // Off + + // By default, wait for flash to finish initializing process before sending transactions + // requests. + wait_init_done = 1'b1; + + disable_flash_init = 1'b0; // Off + + flash_path_str = "tb.dut.u_eflash.u_flash.gen_generic.u_impl_generic"; + + // NOTE: Make sure to keep + // cfg.flash_ctrl_vif.rst_to_pd_time_ns < reset_width_clks_lo * min clock period in ns. + // This will make sure that the power-down assertion will happen before reset deassertion. + + reset_width_clks_lo = 50; + + reset_width_clks_hi = 100; + + set_partition_pc(); + + endfunction : configure + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_virtual_sequencer.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_virtual_sequencer.sv new file mode 100644 index 0000000000000..80837cdaaf34e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_ctrl_virtual_sequencer.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_virtual_sequencer extends cip_base_virtual_sequencer #( + .CFG_T(flash_ctrl_env_cfg), + .COV_T(flash_ctrl_env_cov) +); + `uvm_component_utils(flash_ctrl_virtual_sequencer) + + uvm_analysis_port #(flash_otf_item) eg_exp_ctrl_port[NumBanks]; + uvm_analysis_port #(flash_otf_item) eg_exp_host_port[NumBanks]; + + function new(string name, uvm_component parent); + super.new(name, parent); + foreach (eg_exp_ctrl_port[i]) begin + eg_exp_ctrl_port[i] = new($sformatf("eg_exp_ctrl_port[%0d]", i), this); + eg_exp_host_port[i] = new($sformatf("eg_exp_host_port[%0d]", i), this); + end + endfunction // new + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_addr_attrs.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_addr_attrs.sv new file mode 100644 index 0000000000000..66704648cfd21 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_addr_attrs.sv @@ -0,0 +1,53 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Provides abstraction for mapping a flash memory address in flash organization. +class flash_mem_addr_attrs; + + addr_t addr; // Input addr, bus-word aligned. + addr_t bank_addr; // Addr within the bank, bus-word aligned. + addr_t word_addr; // Addr within the bank, flash word aligned. + int offset; // Byte offset within the flash word. + + addr_t bank_start_addr; // Start addr of the bank (bus word aligned). + addr_t page_start_addr; // Start addr of the page within the bank. + + uint bank; // The bank the address belongs to. + uint page; // The page within the bank. + uint line; // The word line within the page. + uint byte_offset; // Byte offset within the flash word. + + function new(addr_t addr = 0); + set_attrs(addr); + endfunction + + // Set attributes from a sample input addr. + function void set_attrs(addr_t addr); + this.addr = {addr[TL_AW-1:TL_SZW], {TL_SZW{1'b0}}}; + bank_addr = this.addr[FlashMemAddrPageMsbBit : 0]; + word_addr = {bank_addr[TL_AW-1:FlashDataByteWidth], {FlashDataByteWidth{1'b0}}}; + + bank_start_addr = {addr[TL_AW-1 : FlashMemAddrPageMsbBit+1], {FlashMemAddrPageMsbBit+1{1'b0}}}; + page_start_addr = {addr[FlashMemAddrPageMsbBit : FlashMemAddrLineMsbBit+1], + {FlashMemAddrLineMsbBit+1{1'b0}}}; + + bank = addr[FlashMemAddrBankMsbBit : FlashMemAddrPageMsbBit+1]; + page = addr[FlashMemAddrPageMsbBit : FlashMemAddrLineMsbBit+1]; + line = addr[FlashMemAddrLineMsbBit : FlashMemAddrWordMsbBit+1]; + byte_offset = addr[FlashDataByteWidth-1 : 0]; + endfunction + + function void incr(addr_t offset); + set_attrs(addr + offset); + endfunction + + function string sprint(); + return $sformatf({{"addr_attrs: addr = 0x%0h, word_addr = 0x%0h, bank_addr = 0x%0h "}, + {"bank_start_addr = 0x%0h, page_start_addr = 0x%0h "}, + {"bank = %0d, page = %0d, line = %0d, byte_offset = %0d"}}, + addr, word_addr, bank_addr, bank_start_addr, page_start_addr, + bank, page, line, byte_offset); + endfunction + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_bkdr_util.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_bkdr_util.sv new file mode 100644 index 0000000000000..d4f00f6db3937 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_mem_bkdr_util.sv @@ -0,0 +1,38 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Extends mem_bkdr_util to support 2 levels of ECC required for flash. +class flash_mem_bkdr_util extends mem_bkdr_util; + + // Initialize the class instance - reuse the base class' new. + function new(string name = "", string path, int unsigned depth, + longint unsigned n_bits, err_detection_e err_detection_scheme, + int extra_bits_per_subword = 0, int unsigned system_base_addr = 0); + super.new(.name(name), .path(path), .depth(depth), .n_bits(n_bits), + .err_detection_scheme(err_detection_scheme), + .extra_bits_per_subword(extra_bits_per_subword), + .system_base_addr(system_base_addr)); + // Error detection scheme is assumed to be 76_68, otherwise, the overrides below won't work. + `DV_CHECK_EQ_FATAL(err_detection_scheme, mem_bkdr_util_pkg::EccHamming_76_68) + endfunction + + // Flash has 2 levels of ECC - first on bits 63:0 applied to bits 71:64. + virtual function uvm_hdl_data_t get_ecc_computed_data(uvm_hdl_data_t data); + data = prim_secded_pkg::prim_secded_hamming_72_64_enc(data[63:0]); + return super.get_ecc_computed_data(data); + endfunction + + // Randomize the memory with correct ECC. + virtual function void randomize_mem(); + `uvm_info(`gfn, "Randomizing flash mem contents", UVM_LOW) + for (int i = 0; i < depth; i++) begin + uvm_hdl_data_t data; + `DV_CHECK_STD_RANDOMIZE_FATAL(data, "Randomization failed!", path) + data = prim_secded_pkg::prim_secded_hamming_72_64_enc(data[63:0]); + data = get_ecc_computed_data(data); + write(i * bytes_per_word, data); + end + endfunction + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_item.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_item.sv new file mode 100644 index 0000000000000..7b41ff21401f4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_item.sv @@ -0,0 +1,270 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_otf_item extends uvm_object; + `uvm_object_utils(flash_otf_item) + flash_op_t cmd; + data_q_t dq; + fdata_q_t raw_fq, fq; + bit[flash_ctrl_pkg::BusAddrByteW-1:0] start_addr; + bit[flash_phy_pkg::KeySize-1:0] addr_key, data_key; + bit [flash_ctrl_pkg::BusAddrByteW-2:0] mem_addr; + bit head_pad, tail_pad; + bit scr_en, ecc_en; + int page; + flash_mp_region_cfg_t region; + flash_mp_region_cfg_t ctrl_rd_region_q[$]; + + bit derr; + // other expected error than double bit ecc + bit exp_err; + + bit skip_err_chk; + addr_t err_addr, eaddr_q[$]; + + // For closed source features. + bit debug_flag; + addr_t debug_addr; + + function new(string name = "flash_otf_item"); + super.new(name); + head_pad = 0; + tail_pad = 0; + derr = 0; + exp_err = 0; + skip_err_chk = 0; + debug_flag = 0; + endfunction // new + + virtual function void print(string name = "flash_otf_item"); + `dv_info($sformatf("partition : %s", cmd.partition.name()), UVM_MEDIUM, name) + `dv_info($sformatf("erase_type: %s", cmd.erase_type.name()), UVM_MEDIUM, name) + `dv_info($sformatf("op : %s", cmd.op.name()), UVM_MEDIUM, name) + `dv_info($sformatf("prog_sel : %s", cmd.prog_sel.name()), UVM_MEDIUM, name) + `dv_info($sformatf("num_words : %0d", cmd.num_words), UVM_MEDIUM, name) + `dv_info($sformatf("s_addr : 0x%x(page:%0d)", start_addr, start_addr[18:11]), + UVM_MEDIUM, name) + `dv_info($sformatf("mem_addr : 0x%x", mem_addr), UVM_MEDIUM, name) + + if (dq.size() > 0) begin + flash_otf_print_data64(dq, name); + end else begin // read + printfq(fq, name); + end + endfunction // do_print + + function void printfq(fdata_q_t fq, string name = "printfq"); + foreach (fq[i]) begin + `dv_info($sformatf("rdata%0d: %8x_%8x", i, fq[i][63:32], fq[i][31:0]), UVM_MEDIUM, name) + end + endfunction + + function void get_from_phy(flash_phy_prim_item item, string rw); + this.cmd.partition = flash_dv_part_e'(item.req.part); + if (item.req.pg_erase_req) this.cmd.erase_type = FlashErasePage; + if (item.req.bk_erase_req) this.cmd.erase_type = FlashEraseBank; + if (rw == "w") begin + this.cmd.op = FlashOpProgram; + this.cmd.num_words = item.fq.size() * 2; + end else begin + this.cmd.op = FlashOpRead; + this.cmd.num_words = 1; + end + this.cmd.prog_sel = flash_prog_sel_e'(item.req.prog_type); + this.cmd.addr = item.req.addr; + // cmd.addr can be modified to call bkdr mem access + // So we need an extra copy of mem interface address. + this.mem_addr = item.req.addr; + fq = item.fq; + endfunction // get_from_phy + + // Layout: + // bit: 75...64 | 63..32, 31..0 + // fq = 0s... | dq[1] , dq[0]; + function fdata_q_t dq2fq(data_q_t dq); + logic [flash_phy_pkg::FullDataWidth-1:0] fdata; + int size = dq.size() / 2; + for (int i = 0 ; i < size; ++i) begin + fdata = 'h0; + fdata[top_pkg::TL_DW-1:0] = dq.pop_front(); + fdata[top_pkg::TL_DW*2-1:top_pkg::TL_DW] = dq.pop_front(); + dq2fq.push_back(fdata); + end + + // if wq size is odd number, + // push remainer to upper half of fdata. + if (dq.size() > 0) begin + fdata = 'h0; + fdata[top_pkg::TL_DW-1:0] = dq.pop_front(); + dq2fq.push_back(fdata); + end + endfunction // dq2fq + + // Inverse of dq2fq, copy fq to dq. + function data_q_t fq2dq(fdata_q_t fq); + int size = fq.size(); + + for (int i = 0; i < size; ++i) begin + fq2dq.push_back(fq[i][31:0]); + fq2dq.push_back(fq[i][63:32]); + end + endfunction + + // Scramble dq data and store result to fq. + // Use 'create_flash_data' function from package + function void scramble(bit [flash_phy_pkg::KeySize-1:0] addr_key, + bit [flash_phy_pkg::KeySize-1:0] data_key, + bit [flash_ctrl_pkg::BusAddrByteW-2:0] addr, + bit dis = 1, + bit add_icv_err = 0); + bit [FlashDataWidth-1:0] data; + bit [71:0] data_with_icv; + bit [75:0] ecc_76; + + scr_en = (region.scramble_en == MuBi4True); + ecc_en = (region.ecc_en == MuBi4True); + + raw_fq = dq2fq(this.dq); + if (raw_fq.size == 0) begin + `uvm_error(`gfn, "raw_fq is empty") + return; + end + if (dis) begin + `uvm_info("wr_scr", $sformatf( + "size:%0d addr:%x akey:%x dkey:%x scr_en:%0d ecc_en:%0d", + raw_fq.size(), addr, addr_key, data_key, scr_en, ecc_en), UVM_MEDIUM) + end + foreach(raw_fq[i]) begin + data = raw_fq[i][FlashDataWidth-1:0]; + if (ecc_en) begin + data_with_icv = prim_secded_pkg::prim_secded_hamming_72_64_enc(raw_fq[i][63:0]); + if (add_icv_err) begin + `uvm_info("icv_debug", $sformatf("before:%4b after:%4b", + data_with_icv[67:64], ~data_with_icv[67:64]), UVM_DEBUG) + data_with_icv[67:64] = ~data_with_icv[67:64]; + // if icv is all zero, use different pattern for error + if (data_with_icv[67:64] == 'h0) data_with_icv[67:64] = 4'b1100; + end + end else begin + // We only need bit 67:64 when ecc_en == true. + // So set all vector to zero when ecc_en is off. + data_with_icv = 'h0; + end + + if (scr_en) begin + data = create_flash_data(raw_fq[i], addr, addr_key, data_key, dis); + end + if (ecc_en) begin + fq.push_back( + prim_secded_pkg::prim_secded_hamming_76_68_enc({data_with_icv[67:64], data[63:0]})); + end else begin + fq.push_back({12'h0, data}); + end + addr += 8; + end + endfunction // scramble + + // Descramble fq data and store result to fq and dq. + // Use 'create_raw_data' function from package + function void descramble(bit[flash_phy_pkg::KeySize-1:0] addr_key, + bit[flash_phy_pkg::KeySize-1:0] data_key); + bit ecc_err, icv_err; + prim_secded_pkg::secded_hamming_76_68_t dec68; + bit [flash_phy_pkg::FullDataWidth-1:0] data; // 76 bits + bit [71:0] data_with_icv; + bit[flash_ctrl_pkg::BusAddrByteW-2:0] addr = mem_addr; + data_q_t tmp_dq; + + ecc_err = 'h0; + if (ctrl_rd_region_q.size == 0) begin + scr_en = (region.scramble_en == MuBi4True); + ecc_en = (region.ecc_en == MuBi4True); + `uvm_info("rd_scr", $sformatf("size:%0d addr:%x scr_en:%0d ecc_en:%0d", + fq.size(), addr, scr_en, ecc_en), UVM_MEDIUM) + end else begin + if (fq.size != ctrl_rd_region_q.size) begin + `uvm_fatal("descramble", $sformatf({"fq:%0d != region_q:%0d", + " region q should be the same size as read data"}, + fq.size, ctrl_rd_region_q.size)) + end + end + foreach (fq[i]) begin + // erase data skip descramble + if (fq[i] == {flash_phy_pkg::FullDataWidth{1'b1}}) begin + raw_fq.push_back(fq[i]); + end else begin + if (ctrl_rd_region_q.size > 0) begin + scr_en = (ctrl_rd_region_q[i].scramble_en == MuBi4True); + ecc_en = (ctrl_rd_region_q[i].ecc_en == MuBi4True); + `uvm_info("rd_scr", $sformatf("size:%0d idx:%0d addr:%x data:0x%x scr_en:%0d ecc_en:%0d", + fq.size(), i, addr, fq[i], scr_en, ecc_en), UVM_MEDIUM) + end + if (ecc_en) begin + dec68 = prim_secded_pkg::prim_secded_hamming_76_68_dec(fq[i]); + `uvm_info("rd_scr", $sformatf( + "ecc dec input=0x%x, out_data=0x%x, synd=0x%x, err=0x%x", fq[i], dec68.data, + dec68.syndrome, dec68.err), UVM_MEDIUM) + end else begin + dec68.data = fq[i][67:0]; + end + `uvm_info("rd_scr", $sformatf("data_scr:0x%x, err=0x%x", dec68.data, dec68.err), + UVM_MEDIUM) + + if (scr_en) begin + data = create_raw_data(dec68.data[63:0], addr, addr_key, data_key); + data[67:64] = dec68.data[67:64]; + `uvm_info("rd_scr", $sformatf( + "data_plain:0x%x, intg=0x%x", data, dec68.data[67:64]), UVM_MEDIUM) + end else begin + `uvm_info("rd_scr", $sformatf( + "data_plain no scramble:0x%x, intg=0x%x", dec68.data, dec68.data[67:64]), + UVM_MEDIUM) + data = dec68.data; + end + // check ecc + // chec icv + if (ecc_en) begin + data_with_icv = prim_secded_pkg::prim_secded_hamming_72_64_enc(data[63:0]); + icv_err = (data_with_icv[67:64] != data[67:64]); + ecc_err |= (dec68.err[1] | icv_err); + if (dec68.err[1] | icv_err) begin + err_addr = addr << 3; + eaddr_q.push_back(err_addr); + `uvm_info("DCR_DBG", $sformatf("%4d:err_addr:%x err76:%2b synd:%x icv_err:%2b", + i, err_addr, dec68.err, dec68.syndrome, icv_err), + UVM_MEDIUM) + end + if (dec68.err[0]) begin + `uvm_info("SERR_DBG", $sformatf("%4d: serr:%1b data:%x -- > %x", + i, dec68.err[0], fq[i], dec68.data), UVM_MEDIUM) + end + end + + raw_fq.push_back(data); + + if (skip_err_chk == 0 && ecc_err != 0) begin + `uvm_error("rd_scr", "ecc error is detected") + end + end + // Increase mem_addr by 1 + addr++; + end + // collect upto cmd.num_words + tmp_dq = fq2dq(raw_fq); + dq = '{}; + for (int i = 0; i < cmd.num_words; i++) begin + dq.push_back(tmp_dq[i]); + end + if (head_pad) dq = dq[1:$]; + if (tail_pad) dq = dq[0:$-1]; + raw_fq = dq2fq(dq); + derr = ecc_err; + endfunction // descramble + + function void clear_qs(); + this.dq = '{}; + this.raw_fq = '{}; + this.fq = '{}; + endfunction // clear_qs +endclass // flash_otf_item diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_mem_entry.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_mem_entry.sv new file mode 100644 index 0000000000000..b94a6adb29546 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_mem_entry.sv @@ -0,0 +1,15 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_otf_mem_entry extends uvm_object; + `uvm_object_utils(flash_otf_mem_entry) + `uvm_object_new + + logic [BankAddrW-1:0] mem_addr; + logic [flash_phy_pkg::FullDataWidth-1:0] mem_wdata; + flash_part_e mem_part; + logic [InfoTypesWidth-1:0] mem_info_sel; + + +endclass // flash_otf_mem_entry diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_read_entry.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_read_entry.sv new file mode 100644 index 0000000000000..a2752dec0cc7d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/flash_otf_read_entry.sv @@ -0,0 +1,134 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Miscellaneous class to maintain read address +class flash_otf_read_entry extends uvm_object; + `uvm_object_utils(flash_otf_read_entry) + string name; + rd_cache_t prv_read[NumBanks][$]; + bit hash[rd_cache_t]; + `uvm_object_new + + // Push to prv_read. + // When size > 4, pop the oldest entry + function void insert(rd_cache_t it, flash_op_t flash_op); + rd_cache_t ot; + int size, is_odd, tail; + addr_t aligned_addr; + is_odd = flash_op.addr[2]; + size = (flash_op.num_words + is_odd) / 2; + tail = (flash_op.num_words + is_odd) % 2; + aligned_addr = it.addr; + aligned_addr[2:0] = 'h0; + + for (int i = 0; i < size; i++) begin + it.addr = aligned_addr; + if (!hash.exists(it)) begin + prv_read[it.bank].push_back(it); + hash[it] = 1; + if (prv_read[it.bank].size > 4) begin + ot = prv_read[it.bank].pop_front(); + hash.delete(ot); + end + end + aligned_addr += 8; + end // for (int i = 0; i < size; i++) + if (tail) begin + it.addr = aligned_addr; + if (!hash.exists(it)) begin + prv_read[it.bank].push_back(it); + hash[it] = 1; + if (prv_read[it.bank].size > 4) begin + ot = prv_read[it.bank].pop_front(); + hash.delete(ot); + end + end + end + endfunction + + // Check whether a given flash_op has any overlap on + // read cache. + function bit check(rd_cache_t it, flash_op_t flash_op); + int size, is_odd, tail; + addr_t aligned_addr; + is_odd = flash_op.addr[2]; + size = (flash_op.num_words + is_odd) / 2; + tail = (flash_op.num_words + is_odd) % 2; + aligned_addr = it.addr; + aligned_addr[2:0] = 'h0; + + for (int i = 0; i < size; i++) begin + it.addr = aligned_addr; + if (hash.exists(it)) return 1; + aligned_addr += 8; + end // for (int i = 0; i < size; i++) + if (tail) begin + it.addr = aligned_addr; + if (hash.exists(it)) return 1; + end + return 0; + endfunction // check + + // Update hash for program, erase operation + function void update(rd_cache_t it, flash_op_t flash_op); + rd_cache_t d_ent[$]; + if (flash_op.op == FlashOpErase) begin + if (flash_op.erase_type == FlashErasePage) begin + // Collect entries which is the same as erase page number. + int epage = addr2page({it.bank, it.addr}); + foreach (hash[ent]) begin + if (addr2page({ent.bank, ent.addr}) == epage) d_ent.push_back(ent); + end + end else begin + // Collect entries which is the same erase bank id. + foreach (hash[ent]) begin + if (ent.bank == it.bank) d_ent.push_back(ent); + end + end + end else if (flash_op.op == FlashOpProgram) begin + int size, is_odd, tail; + addr_t aligned_addr; + is_odd = flash_op.addr[2]; + size = (flash_op.num_words + is_odd) / 2; + tail = (flash_op.num_words + is_odd) % 2; + aligned_addr = it.addr; + aligned_addr[2:0] = 'h0; + // Collect all write word collide with read cache + for (int i = 0; i < size; i++) begin + it.addr = aligned_addr; + if (hash.exists(it)) begin + d_ent.push_back(it); + end + end + if (tail) begin + it.addr = aligned_addr; + if (hash.exists(it)) begin + d_ent.push_back(it); + end + end + end + while (d_ent.size() > 0) begin + rd_cache_t my_ent = d_ent.pop_front(); + rd_cache_t cp_ent_q[$] = prv_read[my_ent.bank]; + prv_read[my_ent.bank] = {}; + + hash.delete(my_ent); + for (int i = 0; i < cp_ent_q.size(); i++) begin + if (cp_ent_q[i] != my_ent) prv_read[my_ent.bank].push_back(cp_ent_q[i]); + end + end + endfunction + + function int addr2page(bit[OTFBankId:0] addr); + return (int'(addr[OTFBankId:11])); + endfunction // addr2page + + function void print(string str = "flash_otf_read_entry"); + for(int i = 0; i < NumBanks; ++i) begin + foreach (prv_read[i][j]) begin + `uvm_info(str, $sformatf("ent[%0d][%0d]: %p", i, j, prv_read[i][j]), UVM_MEDIUM) + end + end + endfunction // print +endclass // flash_otf_read_entry diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_access_after_disable_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_access_after_disable_vseq.sv new file mode 100644 index 0000000000000..c1272f9d01032 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_access_after_disable_vseq.sv @@ -0,0 +1,63 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence disable flash access while a page write or erase is on going. +// Flash access is disabled by issuing host read intg error (a standard fault). +// After flash access is disabled, send a few random ctrl transactions +// to check those transactions are handled properly. +class flash_ctrl_access_after_disable_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_access_after_disable_vseq) + `uvm_object_new + + constraint op_partition_c {rand_op.partition == FlashPartData;} + + virtual task body(); + flash_op_t ctrl; + int bank, num; + // Enable ecc for all regions + flash_otf_region_cfg(.scr_mode(scr_ecc_cfg), .ecc_mode(OTFCfgTrue)); + + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + set_otf_exp_alert("recov_err"); + prog_flash(.flash_op(ctrl), .bank(bank), .num(1), .in_err(1)); + set_local_escalation(); + flash_access_after_disabled(); + endtask // body + + // Issue host read intg error + task set_local_escalation(); + flash_op_t host; + bit [TL_AW-1:0] tl_addr; + bit saw_err, completed; + data_4s_t rdata; + tl_intg_err_e intg_err; + + $assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(intg_err, + intg_err != TlIntgErrNone;) + `uvm_info(`gfn, $sformatf("set intg_err = %s", intg_err.name), UVM_MEDIUM) + tl_addr[OTFHostId-2:0] = $urandom(); + tl_addr[OTFBankId] = $urandom_range(0, 1); + + cfg.scb_h.exp_tl_rsp_intg_err = 1; + cfg.scb_h.expected_alert["fatal_std_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_std_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_std_err"] = 10000; + + // fatal_err.phy_storage_err + tl_access_w_abort( + .addr(tl_addr), .write(1'b0), .completed(completed), + .saw_err(saw_err), + .tl_access_timeout_ns(cfg.seq_cfg.erase_timeout_ns), + .data(rdata), .check_rsp(1'b0), .blocking(1), + .tl_intg_err_type(intg_err), + .tl_sequencer_h(p_sequencer.tl_sequencer_hs[cfg.flash_ral_name])); + + csr_utils_pkg::wait_no_outstanding_access(); + `DV_CHECK_EQ(saw_err, 1) + csr_rd_check(.ptr(ral.std_fault_status.reg_intg_err), .compare_value(1)); + `uvm_info(`gfn, "Wait until all drain", UVM_LOW) + cfg.clk_rst_vif.wait_clks(10); + endtask // set_local_escalation +endclass // flash_ctrl_access_after_disable_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv new file mode 100644 index 0000000000000..fbcad5ace5e5d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv @@ -0,0 +1,1690 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +typedef class flash_ctrl_callback_vseq; +class flash_ctrl_base_vseq extends cip_base_vseq #( + .RAL_T (flash_ctrl_core_reg_block), + .CFG_T (flash_ctrl_env_cfg), + .COV_T (flash_ctrl_env_cov), + .VIRTUAL_SEQUENCER_T(flash_ctrl_virtual_sequencer) +); + + `uvm_object_utils(flash_ctrl_base_vseq) + + // OTP Scramble Keys, Used In OTP MODEL + logic [KeyWidth-1:0] otp_addr_key; + logic [KeyWidth-1:0] otp_addr_rand_key; + logic [KeyWidth-1:0] otp_data_key; + logic [KeyWidth-1:0] otp_data_rand_key; + + // flash ctrl configuration settings. + bit [1:0] otp_key_init_done; + + // This tracks all addresses that have had a write to avoid multiple writes + // since they are most likely going to result in ECC errors, unless there is + // an erase. + typedef bit part_addresses_written_t[NumBanks][flash_dv_part_e][addr_t]; + + typedef struct packed { + addr_t first; + addr_t last; + } address_range_t; + + typedef address_range_t address_ranges_t[$]; + + typedef address_ranges_t part_address_ranges_t[NumBanks][flash_dv_part_e]; + + constraint num_trans_c {num_trans inside {[1 : cfg.seq_cfg.max_num_trans]};} + + `uvm_object_new + + // Determine post-reset initialization method. + rand flash_mem_init_e flash_init; + + // rand data for program + rand data_q_t flash_program_data; + + constraint flash_program_data_c {flash_program_data.size == 16;} + + // By default, in 30% of the times initialize flash as in initial state (all 1s), + // while in 70% of the times the initialization will be randomized (simulating working flash). + constraint flash_init_c { + flash_init dist { + FlashMemInitSet :/ cfg.seq_cfg.flash_init_set_pc, + FlashMemInitRandomize :/ 100 - cfg.seq_cfg.flash_init_set_pc + }; + } + + part_addresses_written_t part_addresses_written; + part_address_ranges_t part_address_ranges_written; + + // Page to region map. + // This is used to validate transactions based on their page address + // and policy config associate with it. + // 8 : default region + + // Vseq to do some initial post-reset actions. Can be overriden by extending envs. + flash_ctrl_callback_vseq callback_vseq; + + function void add_address_range(input int bank, input flash_dv_part_e part, + input addr_t first_address, input addr_t last_address); + `uvm_info("address_written", $sformatf( + "Adding address_range bank:%0d %s: [0x%x : 0x%x]", + bank, part.name, first_address, last_address), UVM_MEDIUM) + part_address_ranges_written[bank][part].push_back('{first: first_address, last: last_address}); + endfunction + + function void sort_all_address_ranges(); + foreach (part_address_ranges_written[bank, part]) begin + part_address_ranges_written[bank][part].sort(); + end + endfunction + + function void show_all_address_ranges(); + for (int bank = 0; bank < NumBanks; ++bank) begin + foreach (part_address_ranges_written[bank][part]) begin + `uvm_info("address_written", $sformatf("address_ranges bank:%0d %s:", bank, part.name), + UVM_MEDIUM) + foreach (part_address_ranges_written[bank][part][i]) begin + address_range_t range = part_address_ranges_written[bank][part][i]; + `uvm_info("address_written", $sformatf(" [0x%x : 0x%x]", range.first, range.last), + UVM_MEDIUM) + end + end + end + endfunction + + // This is a binary search for any overlap of an address range with any in the address ranges. + local function bit address_in_ranges(input int bank, input flash_dv_part_e part, + input address_ranges_t ranges, + input address_range_t addr_range); + int bottom = 0; + int top = ranges.size() - 1; + do + begin + int index = (top + bottom) / 2; + `uvm_info("address_written", $sformatf( + "bot:%0d, index:%0d, top:%0d, [0x%x : 0x%x]", bottom, index, top, + ranges[index].first, ranges[index].last), UVM_MEDIUM) + if (addr_range.last < ranges[index].first) top = index - 1; + else if (addr_range.first > ranges[index].last) bottom = index + 1; + else begin + `DV_CHECK( + addr_range.last >= ranges[index].first && addr_range.first <= ranges[index].last) + `uvm_info("address_written", $sformatf( + "address range:[0x%x : 0x%x] overlaps [0x%x : 0x%x] for bank:%0d, part %s", + addr_range.first, addr_range.last, ranges[index].first, ranges[index].last, + bank, part.name), UVM_MEDIUM) + return 1; + end + end + while (top >= bottom); + return 1'b0; + endfunction + + // This searches for any overap between the addresses in the given range and the address ranges + // for the given bank and partition. Notice if the binary search fails we still need to examine + // the range last examined by the binary search, denoted by the index returned. A miss is the + // most common outcome of this lookup so having this index is good for performance. + protected function bit address_range_in_address_ranges( + input int bank, input flash_dv_part_e part, + input addr_t start_addr, input addr_t end_addr); + if (part_address_ranges_written[bank].exists(part)) begin + address_range_t range = '{start_addr, end_addr}; + address_ranges_t ranges = part_address_ranges_written[bank][part]; + return address_in_ranges(bank, part, ranges, range); + end + return 1'b0; + endfunction + + local function bit address_in_words(input int bank, input flash_dv_part_e part, + input addr_t addr); + return part_addresses_written[bank].exists(part) && + part_addresses_written[bank][part].exists(addr); + endfunction + + // Returns non-zero if the given address has been written. It assumes the + // info secret pages were completely written. + protected function bit address_was_written(input int bank, input flash_dv_part_e part, + input addr_t addr); + if (part_address_ranges_written[bank].exists(part)) begin + address_ranges_t ranges = part_address_ranges_written[bank][part]; + address_range_t range = '{addr, addr + FlashBankBytesPerWord - 1}; + if (address_in_ranges(bank, part, ranges, range)) begin + return 1'b1; + end + end + return address_in_words(bank, part, addr); + endfunction + + // Returns 1 if any address between start_addr and end_addr were written. + protected function bit address_range_was_written(input int bank, input flash_dv_part_e part, + input addr_t start_addr, input addr_t end_addr); + `uvm_info(`gfn, $sformatf( + "Query address_range_written from %x to %x in bank:%0d %0s", + start_addr, end_addr, bank, part.name), + UVM_MEDIUM) + if (address_range_in_address_ranges(bank, part, start_addr, end_addr)) begin + return 1'b1; + end + `uvm_info("address_written", "Cleared ranges", UVM_MEDIUM) + for (addr_t addr = start_addr; addr < end_addr; addr += FlashBankBytesPerWord) begin + if (address_in_words(bank, part, addr)) begin + `uvm_info("address_words", $sformatf("addr:0x%x is already written", addr), UVM_MEDIUM) + return 1'b1; + end + end + `uvm_info("address_written", $sformatf( + "range [0x%x : 0x%x] has no overlaps in bank:%0d, %s", + start_addr, end_addr, bank, part.name), UVM_MEDIUM) + return 1'b0; + endfunction + + // Marks the given address as being written. It is fatal if it was already + // written. + protected function void update_addresses_written(input int bank, input flash_dv_part_e part, + input addr_t addr); + `DV_CHECK(!address_in_words(bank, part, addr), $sformatf( + "Overwriting address 0x%x in part %s", addr, part.name), fatal) + part_addresses_written[bank][part][addr] = 1; + endfunction + + // Marks all addresses between start_addr and end_addr as being written. + // It is fatal if any was already written. + protected function void update_range_addresses_written(input int bank, + input flash_dv_part_e part, + input addr_t start_addr, + input addr_t end_addr); + `uvm_info(`gfn, $sformatf("Update addresses_written from %x to %x", start_addr, end_addr), + UVM_MEDIUM) + for (addr_t addr = start_addr; addr < end_addr; addr += FlashBankBytesPerWord) begin + update_addresses_written(bank, part, addr); + end + `uvm_info(`gfn, "Update addresses done", UVM_MEDIUM) + endfunction + + // Check permission and page range of info partition + // Set exp recov_err alert if check fails + // Make sure your flash_op has right otf_addr associated with addr + function bit check_info_part(flash_op_t flash_op, string str); + bit drop = 0; + int bank, page, end_page, loop; + + bank = flash_op.addr[OTFBankId]; + page = cfg.addr2page(flash_op.otf_addr); + end_page = cfg.addr2page(flash_op.otf_addr + (flash_op.num_words * 4) - 1); + // For read, cross page boundary is allowed. So you need to check + // both start and end address + if (flash_op.op == FlashOpRead) loop = 2; + else loop = 1; + + for (int i = 0; i < loop; ++i) begin + if (i == 1) page = end_page; + if (flash_op.partition == FlashPartInfo && bank == 0 && + page inside {[1:3]}) begin + if (!cfg.allow_spec_info_acc[page-1]) begin + `uvm_info(str, $sformatf("check_info:page:%0d access is not allowed", page), UVM_MEDIUM) + set_otf_exp_alert("recov_err"); + drop = 1; + end + end + // check info page range + if (page >= InfoTypeSize[flash_op.partition>>1]) begin + `uvm_info(str, $sformatf("check_info:bank:%0d page:%0d addr:0x%0h is out of range", + bank, page, flash_op.otf_addr), UVM_MEDIUM) + set_otf_exp_alert("recov_err"); + drop = 1; + end + if (drop) break; + end + return drop; + endfunction // check_info_part + + virtual task pre_start(); + `uvm_create_on(callback_vseq, p_sequencer); + + // Create key before mem init + otp_addr_key = {$urandom, $urandom, $urandom, $urandom}; + otp_addr_rand_key = {$urandom, $urandom, $urandom, $urandom}; + otp_data_key = {$urandom, $urandom, $urandom, $urandom}; + otp_data_rand_key = {$urandom, $urandom, $urandom, $urandom}; + + cfg.otp_addr_key = otp_addr_key; + cfg.otp_data_key = otp_data_key; + + cfg.flash_ctrl_vif.rma_req <= lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.rma_seed <= LC_FLASH_RMA_SEED_DEFAULT; + otp_model(); // Start OTP Model + super.pre_start(); + cfg.alert_max_delay_in_ns = cfg.alert_max_delay * (cfg.clk_rst_vif.clk_period_ps / 1000.0); + + // Some test needs pre init states. + // Use this option to skip waiting for buffer enable. + if (cfg.skip_init == 0) begin + csr_wr(.ptr(ral.init), .value(1)); + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1 || cfg.skip_init_buf_en == 1);, + $sformatf("Timed out waiting for rd_buf_en (%0d)", + cfg.wait_rd_buf_en_timeout_ns), + cfg.wait_rd_buf_en_timeout_ns) + end + endtask : pre_start + + // Place holder for override + virtual task hw_info_cfg_update(); endtask + + // Reset the Flash Device + virtual task reset_flash(); + // Set all flash partitions to 1s. + flash_dv_part_e part = part.first(); + do begin + cfg.flash_mem_bkdr_init(part, flash_init); + part = part.next(); + end while (part != part.first()); + // After initialize flash, scramble secret partition + update_secret_partition(); + + // Wait for flash_ctrl to finish initializing on every reset + if (cfg.seq_cfg.wait_init_done) csr_spinwait(.ptr(ral.status.init_wip), .exp_data(1'b0)); + endtask : reset_flash + + // Apply a Reset to the DUT, then do some additional required actions with callback_vseq + virtual task apply_reset(string kind = "HARD"); + uvm_reg_data_t data; + bit init_busy; + if (kind == "HARD") begin + // reset assertion time in clock cycles (from assertion to deassertion). + // Limits can be configured to control randomization. + // Will be randomized before each apply_reset. + uint reset_width_clks; + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(reset_width_clks, + reset_width_clks inside + {[cfg.seq_cfg.reset_width_clks_lo:cfg.seq_cfg.reset_width_clks_hi]};) + cfg.clk_rst_vif.apply_reset(.reset_width_clks(reset_width_clks)); + cfg.clk_rst_vif.wait_clks(cfg.post_reset_delay_clks); + end + + if (cfg.seq_cfg.disable_flash_init == 0) begin + reset_flash(); // Randomly Inititalise Flash After Reset + end + + if (cfg.seq_cfg.en_init_keys_seeds == 1) begin + // Update hw_info_cfg if necessary + hw_info_cfg_update(); + csr_wr(.ptr(ral.init), .value(1)); // Enable Secret Seed Output during INIT + end + + // Do some additional required actions + callback_vseq.apply_reset_callback(); + endtask : apply_reset + + task post_apply_reset(string reset_kind = "HARD"); + super.post_apply_reset(reset_kind); + // Polling init wip is done + csr_spinwait(.ptr(ral.status.init_wip), .exp_data(1'b0)); + endtask + // Configure the memory protection regions. + virtual task flash_ctrl_mp_region_cfg(uint index, + flash_mp_region_cfg_t region_cfg = cfg.default_region_cfg); + uvm_reg_data_t data; + uvm_reg csr; + update_mp_region_cfg_mubifalse(region_cfg); + data = get_csr_val_with_updated_field(ral.mp_region_cfg[index].en, data, + region_cfg.en); + data = data | get_csr_val_with_updated_field(ral.mp_region_cfg[index].rd_en, data, + region_cfg.read_en); + data = data | get_csr_val_with_updated_field(ral.mp_region_cfg[index].prog_en, data, + region_cfg.program_en); + data = data | get_csr_val_with_updated_field(ral.mp_region_cfg[index].erase_en, data, + region_cfg.erase_en); + data = data | get_csr_val_with_updated_field(ral.mp_region_cfg[index].scramble_en, + data, region_cfg.scramble_en); + data = data | get_csr_val_with_updated_field(ral.mp_region_cfg[index].ecc_en, data, + region_cfg.ecc_en); + data = data | get_csr_val_with_updated_field(ral.mp_region_cfg[index].he_en, data, + region_cfg.he_en); + csr_wr(.ptr(ral.mp_region_cfg[index]), .value(data)); + + // reset for base/size register + data = 0; + data = get_csr_val_with_updated_field(ral.mp_region[index].base, data, + region_cfg.start_page); + data = data | get_csr_val_with_updated_field(ral.mp_region[index].size, data, + region_cfg.num_pages); + csr_wr(.ptr(ral.mp_region[index]), .value(data)); + endtask : flash_ctrl_mp_region_cfg + + // Configure the protection for the "default" region (all pages that do not fall + // into one of the memory protection regions). + virtual task flash_ctrl_default_region_cfg(mubi4_t read_en = MuBi4True, + mubi4_t program_en = MuBi4True, + mubi4_t erase_en = MuBi4True, + mubi4_t scramble_en = MuBi4False, + mubi4_t ecc_en = MuBi4False, + mubi4_t he_en = MuBi4False); + uvm_reg_data_t data; + + cfg.default_region_cfg.read_en = read_en; + cfg.default_region_cfg.program_en = program_en; + cfg.default_region_cfg.erase_en = erase_en; + cfg.default_region_cfg.scramble_en = scramble_en; + cfg.default_region_cfg.ecc_en = ecc_en; + cfg.default_region_cfg.he_en = he_en; + + data = get_csr_val_with_updated_field(ral.default_region.rd_en, data, read_en); + data = data | + get_csr_val_with_updated_field(ral.default_region.prog_en, data, program_en); + data = data | + get_csr_val_with_updated_field(ral.default_region.erase_en, data, erase_en); + data = data | + get_csr_val_with_updated_field(ral.default_region.scramble_en, data, scramble_en); + data = data | get_csr_val_with_updated_field(ral.default_region.ecc_en, data, ecc_en); + data = data | get_csr_val_with_updated_field(ral.default_region.he_en, data, he_en); + csr_wr(.ptr(ral.default_region), .value(data)); + endtask : flash_ctrl_default_region_cfg + + // Configure the memory protection of some selected page in one of the information partitions in + // one of the banks. + virtual task flash_ctrl_mp_info_page_cfg( + uint bank, uint info_part, uint page, + flash_bank_mp_info_page_cfg_t page_cfg = cfg.default_info_page_cfg); + + uvm_reg_data_t data; + uvm_reg csr; + + string csr_name = $sformatf("bank%0d_info%0d_page_cfg", bank, info_part); + // If the selected information partition has only 1 page, no suffix needed to the register + // name, if there is more than one page, the page index should be added to the register name. + if (flash_ctrl_pkg::InfoTypeSize[info_part] > 1) begin + csr_name = $sformatf({csr_name, "_%0d"}, page); + end + `uvm_info("mp_info_page_cfg", $sformatf("%s: %p", csr_name, page_cfg), UVM_DEBUG) + csr = ral.get_reg_by_name(csr_name); + update_mp_info_cfg_mubifalse(page_cfg); + data = get_csr_val_with_updated_field(csr.get_field_by_name("en"), data, page_cfg.en); + data = data | + get_csr_val_with_updated_field(csr.get_field_by_name("rd_en"), data, page_cfg.read_en); + data = data | + get_csr_val_with_updated_field(csr.get_field_by_name("prog_en"), data, page_cfg.program_en); + data = data | + get_csr_val_with_updated_field(csr.get_field_by_name("erase_en"), data, page_cfg.erase_en); + data = data | get_csr_val_with_updated_field(csr.get_field_by_name("scramble_en"), data, + page_cfg.scramble_en); + data = data | + get_csr_val_with_updated_field(csr.get_field_by_name("ecc_en"), data, page_cfg.ecc_en); + data = data | + get_csr_val_with_updated_field(csr.get_field_by_name("he_en"), data, page_cfg.he_en); + csr_wr(.ptr(csr), .value(data)); + endtask : flash_ctrl_mp_info_page_cfg + + // Configure bank erasability. + virtual task flash_ctrl_bank_erase_cfg(bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en); + csr_wr(.ptr(ral.mp_bank_cfg_shadowed[0]), .value(bank_erase_en)); + endtask : flash_ctrl_bank_erase_cfg + + // Configure read and program fifo levels for interrupt. + virtual task flash_ctrl_fifo_levels_cfg_intr(uint read_fifo_intr_level, + uint program_fifo_intr_level); + uvm_reg_data_t data; + data = get_csr_val_with_updated_field(ral.fifo_lvl.prog, data, program_fifo_intr_level) | + get_csr_val_with_updated_field(ral.fifo_lvl.rd, data, read_fifo_intr_level); + csr_wr(.ptr(ral.fifo_lvl), .value(data)); + endtask : flash_ctrl_fifo_levels_cfg_intr + + // Reset the program and read fifos. + virtual task flash_ctrl_fifo_reset(bit reset = 1'b1); + csr_wr(.ptr(ral.fifo_rst), .value(reset)); + endtask : flash_ctrl_fifo_reset + + // Configure intr_enable + virtual task flash_ctrl_intr_enable(bit[5:0] enable); + csr_wr(.ptr(ral.intr_enable), .value(enable)); + endtask + + // Wait for flash_ctrl op to finish. + virtual task wait_flash_op_done( + bit clear_op_status = 1'b1, time timeout_ns = 10_000_000 + ); // Added because mass(bank) erase is longer then default timeout. + csr_spinwait(.ptr(ral.op_status.done), + .exp_data(1'b1), + .timeout_ns(timeout_ns)); + + if (clear_op_status) begin + uvm_reg_data_t data; + csr_rd(.ptr(ral.op_status), .value(data)); + data = get_csr_val_with_updated_field(ral.op_status.done, data, 0); + csr_wr(.ptr(ral.op_status), .value(data)); + end + endtask : wait_flash_op_done + + // Wait for flash_ctrl op to finish with error. + virtual task wait_flash_op_err(bit clear_op_status = 1'b1); + uvm_reg_data_t data; + bit err; + `DV_SPINWAIT(do begin + csr_rd(.ptr(ral.op_status), .value(data)); + err = get_field_val(ral.op_status.err, data); + end while (err == 1'b0);, "wait_flash_op_err timeout occurred!") + if (clear_op_status) begin + data = get_csr_val_with_updated_field(ral.op_status.err, data, 0); + csr_wr(.ptr(ral.op_status), .value(data)); + end + endtask : wait_flash_op_err + + // Wait for prog fifo to not be full. + virtual task wait_flash_ctrl_prog_fifo_not_full(); + // if intr enabled, 'flash_ctrl_intr_write' task is used. + bit prog_full; + csr_spinwait(.ptr(ral.status.prog_full), + .compare_op(CompareOpNe), + .exp_data(1)); + endtask : wait_flash_ctrl_prog_fifo_not_full + + // Wait for rd fifo to not be empty. + virtual task wait_flash_ctrl_rd_fifo_not_empty(); + // if intr enabled, 'flash_ctrl_intr_read' task is used. + bit read_empty; + csr_spinwait(.ptr(ral.status.rd_empty), + .compare_op(CompareOpNe), + .exp_data(1)); + endtask : wait_flash_ctrl_rd_fifo_not_empty + + // Starts an Operation on the Flash Controller + virtual task flash_ctrl_start_op(flash_op_t flash_op); + uvm_reg_data_t data; + flash_part_e partition_sel; + bit [InfoTypesWidth-1:0] info_sel; + + print_flash_op(flash_op, UVM_MEDIUM); + csr_wr(.ptr(ral.addr), .value(flash_op.addr)); + + // flash_op.partition -> partition_sel , info_sel | + // (flash_dv_part_e) | (flash_part_e) | bit[InfoTypesWidth] | + // --------------------------|-----------------|---------------------| + // FlashPartData = 0 | FlashPartData=0 | 0 | + // FlashPartInfo = 1 | FlashPartInfo=1 | 0 | + // FlashPartInfo1 = 2 | FlashPartInfo=1 | 1 | + // FlashPartInfo2 = 4 | FlashPartInfo=1 | 2 | + + partition_sel = flash_part_e'(|flash_op.partition); + info_sel = flash_op.partition >> 1; + data = get_csr_val_with_updated_field(ral.control.start, data, 1'b1); + data = data | get_csr_val_with_updated_field(ral.control.op, data, flash_op.op); + data = data | get_csr_val_with_updated_field(ral.control.prog_sel, data, flash_op.prog_sel); + data = data | get_csr_val_with_updated_field(ral.control.erase_sel, data, flash_op.erase_type); + data = data | get_csr_val_with_updated_field(ral.control.partition_sel, data, partition_sel); + data = data | get_csr_val_with_updated_field(ral.control.info_sel, data, info_sel); + data = data | get_csr_val_with_updated_field(ral.control.num, data, flash_op.num_words - 1); + csr_wr(.ptr(ral.control), .value(data)); + endtask : flash_ctrl_start_op + + // Program data into flash, stopping whenever full. + // The flash op is assumed to have already commenced. + virtual task flash_ctrl_write(data_q_t data, bit poll_fifo_status); + foreach (data[i]) begin + // Check if prog fifo is full. If yes, then wait for space to become available. + // Note that this polling is not needed since the interface is backpressure enabled. + if (poll_fifo_status) begin + wait_flash_ctrl_prog_fifo_not_full(); + end + mem_wr(.ptr(ral.prog_fifo), .offset(0), .data(data[i])); + `uvm_info(`gfn, $sformatf("flash_ctrl_write: 0x%0h", data[i]), UVM_HIGH) + end + endtask : flash_ctrl_write + + // Read data from flash, stopping whenever empty. + // The flash op is assumed to have already commenced. + virtual task flash_ctrl_read(uint num_words, ref data_q_t data, + input bit poll_fifo_status, bit dis = 0); + for (int i = 0; i < num_words; i++) begin + // Check if rd fifo is empty. If yes, then wait for data to become available. + // Note that this polling is not needed since the interface is backpressure enabled. + if (poll_fifo_status) begin + wait_flash_ctrl_rd_fifo_not_empty(); + end + mem_rd(.ptr(ral.rd_fifo), .offset(0), .data(data[i])); + `uvm_info(`gfn, $sformatf("flash_ctrl_read: 0x%0h", data[i]), UVM_HIGH) + if (dis) begin + `uvm_info(`gfn, $sformatf("dis:flash_ctrl_read: 0x%0h", data[i]), UVM_MEDIUM) + end + end + endtask : flash_ctrl_read + + virtual task clear_intr_state(uvm_reg_data_t data); + csr_wr(.ptr(ral.intr_state), .value(data)); + endtask + + virtual task flash_ctrl_intr_read(flash_op_t flash_op, ref data_q_t rdata); + uvm_reg_data_t data; + bit[31:0] intr_st; + int rd_timeout_ns = 1000000; // 1 ms + int curr_rd, rd_idx = 0; + + `uvm_info("flash_ctrl_intr_read", $sformatf("num_rd:%0d", + flash_op.num_words), UVM_MEDIUM) + print_flash_op(flash_op, UVM_MEDIUM); + + `DV_SPINWAIT(wait(cfg.rd_crd - flash_op.num_words >= 0);, + "wait for rd_crd timeout", + rd_timeout_ns, "flash_ctrl_intr_read") + flash_ctrl_start_op(flash_op); + cfg.rd_crd -= flash_op.num_words; + while (rd_idx < flash_op.num_words) begin + // If read data comes slow, use FlashCtrlIntrRdLvl as non-empty + // and read out then clear this interrupt until + // read all 'flash_op.num_words' + `DV_SPINWAIT(wait(cfg.intr_vif.pins[FlashCtrlIntrRdLvl] == 1 || + cfg.intr_vif.pins[FlashCtrlIntrRdFull] == 1 || + cfg.intr_vif.pins[FlashCtrlIntrOpDone] == 1);, + "wait read intr timeout", + rd_timeout_ns, "flash_ctrl_intr_read") + // read interrupt status reg + csr_rd(.ptr(ral.intr_state), .value(data)); + intr_st = data; + clear_intr_state(data); + csr_rd(.ptr(ral.curr_fifo_lvl.rd), .value(curr_rd)); + `uvm_info("intr_read", $sformatf("intr_state: %x", intr_st), UVM_MEDIUM) + + // the comparison below is done because when the flash reads "too fast", it can fill up + // the FIFO before more entries are read out. This creates a situation where we may have + // multiple level or full interrupts even though it is not really the case. + // Imagine the level is set to 5, and we get the first interrupt when are 5 entries. + // While reading the 5 entries out, the flash fills so fast that the hardware sees another + // 4->5 transition, causing a second interrupt. However, there has not actually been 10 + // entries deposited, this is just an artifact of one side moving much faster than + // anticipated. This kind of level interrupt scheme works better when one side is + // much slower, which is not guaranteed based on the parameters of the test. + if (intr_st[FlashCtrlIntrOpDone]) begin + // just read whatever the current read level is + end else if (intr_st[FlashCtrlIntrRdFull]) begin + // fifo size is 16 + curr_rd = curr_rd >= 16 ? 16 : curr_rd; + end else if (intr_st[FlashCtrlIntrRdLvl]) begin + curr_rd = curr_rd >= cfg.rd_lvl ? cfg.rd_lvl : curr_rd; + end + repeat(curr_rd) begin + mem_rd(.ptr(ral.rd_fifo), .offset(0), .data(rdata[rd_idx++])); + cfg.rd_crd++; + end + end + endtask // flash_ctrl_intr_read + + virtual task flash_ctrl_intr_write(flash_op_t flash_op, data_q_t wdata); + int wr_idx = 0; + uvm_reg_data_t data; + bit [31:0] intr_st; + + `uvm_info("flash_ctrl_intr_write", $sformatf("num_wd: %0d", flash_op.num_words), + UVM_MEDIUM) + // Enable ProgLvl interrupt + csr_rd(.ptr(ral.intr_enable), .value(data)); + data[FlashCtrlIntrProgLvl] = 1; + csr_wr(.ptr(ral.intr_enable), .value(data)); + + // Make sure prog_fifo is available before start program. + `DV_SPINWAIT(wait(cfg.intr_vif.pins[FlashCtrlIntrProgLvl] == 1);, + "wait initial prog intr timeout", + // Defined in the seq_cfg, default is 10ms. + cfg.seq_cfg.prog_timeout_ns, "flash_ctrl_intr_write") + + flash_ctrl_start_op(flash_op); + + while (wr_idx < flash_op.num_words) begin + `DV_SPINWAIT(wait(cfg.intr_vif.pins[FlashCtrlIntrProgLvl] == 1);, + "wait prog intr timeout", + // Defined in the seq_cfg, default is 10ms. + cfg.seq_cfg.prog_timeout_ns, "flash_ctrl_intr_write") + mem_wr(.ptr(ral.prog_fifo), .offset(0), .data(wdata[wr_idx++])); + end + + `DV_SPINWAIT(wait(cfg.intr_vif.pins[FlashCtrlIntrOpDone] == 1);, + "wait intr op done timeout", + // Defined in the seq_cfg, default is 10ms. + cfg.seq_cfg.prog_timeout_ns, "flash_ctrl_intr_write") + + // Disable and clear the interrupt + csr_rd(.ptr(ral.intr_enable), .value(data)); + data[FlashCtrlIntrProgLvl] = 0; + csr_wr(.ptr(ral.intr_enable), .value(data)); + + csr_rd(.ptr(ral.intr_state), .value(data)); + intr_st = data; + clear_intr_state(data); + endtask // flash_ctrl_intr_write + + // Task to perform a direct Flash read at the specified location + // Used timeout is to match the longest waiting timeout possible for the host, which will happen + // when the host is waiting for the controller to finish bank-erase + virtual task do_direct_read( + input addr_t addr, input bit [TL_DBW-1:0] mask = get_rand_contiguous_mask(), + input bit blocking = $urandom_range(0, 1), input bit check_rdata = 0, + input data_t exp_rdata = '0, input mubi4_t instr_type = MuBi4False, + output data_4s_t rdata, output bit completed, + input bit exp_err_rsp = 1'b0); + + bit saw_err; + + tl_access_w_abort(.addr(addr), .write(1'b0), .completed(completed), .saw_err(saw_err), + .tl_access_timeout_ns(cfg.seq_cfg.erase_timeout_ns), .mask(mask), + .data(rdata), .exp_err_rsp(exp_err_rsp), .exp_data(exp_rdata), + .compare_mask(mask), .check_exp_data(check_rdata), .blocking(blocking), + .instr_type(instr_type), + .tl_sequencer_h(p_sequencer.tl_sequencer_hs[cfg.flash_ral_name])); + endtask : do_direct_read + + // Task to Read/Erase/Program the Two Secret Seed Partitions (Creator and Owner) + virtual task do_flash_op_secret_part(input flash_sec_part_e secret_part, input flash_op_e op, + output data_q_t flash_op_data); + // Note: + // Secret partition 0 (used for creator): Bank 0, information partition 0, page 1 + // Secret partition 1 (used for owner): Bank 0, information partition 0, page 2 + + // Local Signals + bit poll_fifo_status; + data_q_t exp_data; + flash_op_t flash_op; + bit scr_en; + + scr_en = (flash_ctrl_pkg::CfgAllowRead.scramble_en == MuBi4True); + // Flash Operation Assignments + flash_op.op = op; + flash_op.partition = FlashPartInfo; + flash_op.erase_type = FlashErasePage; + flash_op.num_words = FlashSecretPartWords; + poll_fifo_status = 1; + + // Disable HW Access to Secret Partition from Life Cycle Controller Interface (Write/Read/Erase) + cfg.flash_ctrl_vif.lc_seed_hw_rd_en = + get_rand_lc_tx_val(.t_weight(0), .f_weight(1), .other_weight(9)); + + unique case (secret_part) + FlashCreatorPart: begin + flash_op.addr = FlashCreatorPartStartAddr; + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + end + FlashOwnerPart: begin + flash_op.addr = FlashOwnerPartStartAddr; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + end + default: `uvm_error(`gfn, "Secret Partition Unrecognised, FAIL") + endcase + + // Perform Flash Opeation via Host Interface + unique case (flash_op.op) + flash_ctrl_pkg::FlashOpErase: begin + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); + end + flash_ctrl_pkg::FlashOpProgram: begin + // Write Frontdoor, Read Backdoor + // Generate Random Key + for (int i = 0; i < flash_op.num_words; i++) begin + flash_op_data[i] = $urandom_range(0, 2 ** (TL_DW) - 1); + end + // Calculate expected data for post-transaction checks + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + if (cfg.seq_cfg.check_mem_post_tran) begin + cfg.flash_mem_bkdr_read_check(flash_op, exp_data, , scr_en); + end + end + flash_ctrl_pkg::FlashOpRead: begin + // Read Frontdoor, Compare Backdoor + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + if (cfg.seq_cfg.check_mem_post_tran) begin + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data, 1, scr_en); + end + end + default: `uvm_error(`gfn, "Flash Operation Unrecognised, FAIL") + endcase + + // Disable Secret Partitions from Life Cycle Controller Interface (Write/Read/Erase) + unique case (secret_part) + FlashCreatorPart: begin + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::Off; + end + FlashOwnerPart: begin + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::Off; + end + default: `uvm_error(`gfn, "Secret Partition Unrecognised, FAIL") + endcase + endtask : do_flash_op_secret_part + + // Task to compare a Secret Seed sent to the Key Manager with the Value in the FLASH + virtual task compare_secret_seed(input flash_sec_part_e secret_part, + input data_q_t flash_op_data); + + // Local Variables + data_q_t key_data; + + // Check for the Key being 'x + foreach (cfg.flash_ctrl_vif.keymgr.seeds[bit'(secret_part)][i]) begin + if (cfg.flash_ctrl_vif.keymgr.seeds[bit'(secret_part)][i] === 'x) begin + `uvm_error(`gfn, "Key Manager Keys Sampled : 'x', FAIL") + end + end + + // Read Key Manager Interface + foreach (flash_op_data[i]) begin + key_data[i] = cfg.flash_ctrl_vif.keymgr.seeds[bit'(secret_part)][i*32+:32]; + end + + // Display Keys + `uvm_info(`gfn, $sformatf("Secret Partition : %s", secret_part.name()), UVM_LOW) + `uvm_info(`gfn, $sformatf("Data Read : %p", flash_op_data), UVM_LOW) + `uvm_info(`gfn, $sformatf("KeyMgr Read : %p", key_data), UVM_LOW) + + // Compare Seeds + foreach (key_data[i]) begin + `DV_CHECK_EQ(key_data[i], flash_op_data[i], $sformatf( + "(Read) Secret Partition : %s : Keys Mismatch, FAIL", secret_part.name())) + end + + endtask : compare_secret_seed + + // Task to restore the stimulus from the Life Cycle Controller to its Reset State + virtual task lc_ctrl_if_rst(); + + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.lc_seed_hw_rd_en = lc_ctrl_pkg::On; + + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = + get_rand_lc_tx_val(.t_weight(0), .f_weight(1), .other_weight(4)); + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = + get_rand_lc_tx_val(.t_weight(0), .f_weight(1), .other_weight(4)); + + cfg.flash_ctrl_vif.lc_nvm_debug_en = + get_rand_lc_tx_val(.t_weight(0), .f_weight(1), .other_weight(4)); + cfg.flash_ctrl_vif.lc_escalate_en = lc_ctrl_pkg::Off; + + cfg.flash_ctrl_vif.rma_req = lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.rma_seed = '0; + + endtask : lc_ctrl_if_rst + + // Simple Model For The OTP Key Seeds + virtual task otp_model(); + + `uvm_info(`gfn, "Starting OTP Model ...", UVM_LOW) + + // Initial Values + cfg.flash_ctrl_vif.otp_rsp.addr_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.data_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.key = '0; + cfg.flash_ctrl_vif.otp_rsp.rand_key = '0; + otp_key_init_done = 'h0; + // Note 'some values' appear in both branches of this fork, this is OK because the + // branches never run together by design. + // The order is always 'addr' followed by 'data'. + fork + forever begin // addr + @(posedge cfg.clk_rst_vif.rst_n); + @(posedge cfg.flash_ctrl_vif.otp_req.addr_req); + otp_key_init_done[1] = 0; + `uvm_info(`gfn, $sformatf("OTP Addr Key Applied to DUT : otp_addr_key : %0x", + otp_addr_key), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("OTP Addr Rand Key Applied to DUT : otp_addr_rand_key : %0x", + otp_addr_rand_key), UVM_MEDIUM) + cfg.flash_ctrl_vif.otp_rsp.key = otp_addr_key; + cfg.flash_ctrl_vif.otp_rsp.rand_key = otp_addr_rand_key; + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b1; + #1ns; // Positive Hold + cfg.flash_ctrl_vif.otp_rsp.addr_ack = 1'b1; + @(negedge cfg.flash_ctrl_vif.otp_req.addr_req); + #1ns; // Positive Hold + cfg.flash_ctrl_vif.otp_rsp.addr_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b0; + otp_key_init_done[1] = 1; + end + forever begin // data + @(posedge cfg.clk_rst_vif.rst_n); + @(posedge cfg.flash_ctrl_vif.otp_req.data_req); + otp_key_init_done[0] = 0; + cfg.flash_ctrl_vif.otp_rsp.key = otp_data_key; + cfg.flash_ctrl_vif.otp_rsp.rand_key = otp_data_rand_key; + `uvm_info(`gfn, $sformatf("OTP Data Key Applied to DUT : otp_data_key : %0x", + otp_data_key), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("OTP Data Rand Key Applied to DUT : otp_data_rand_key : %0x", + otp_data_rand_key), UVM_MEDIUM) + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b1; + #1ns; // Positive Hold + cfg.flash_ctrl_vif.otp_rsp.data_ack = 1'b1; + @(negedge cfg.flash_ctrl_vif.otp_req.data_req); + #1ns; // Positive Hold + cfg.flash_ctrl_vif.otp_rsp.data_ack = 1'b0; + cfg.flash_ctrl_vif.otp_rsp.seed_valid = 1'b0; + otp_key_init_done[0] = 1; + end + join_none + + endtask : otp_model + + // Compares Two Queues Of Data + virtual function void check_data_match(ref data_q_t data, ref data_q_t exp_data); + foreach (exp_data[i]) begin + `DV_CHECK_EQ(data[i], exp_data[i], $sformatf( + "Expected : 0x%0x, Read : 0x%0x, FAIL", exp_data[i], data[i])) + end + endfunction : check_data_match + + // Wait for Flash Operation, or Timeout ... Timeout Expected + virtual task wait_flash_op_done_expect_timeout(input time timeout_ns = 10_000_000, + output bit result); + + // Looks for Status Returning in the Timeout Period + + // Expect a Timeout, with No Status Returned + // Result 0 - Response Returned (timeout = 0, status = 1) - FAIL + // 1 - Timeout, No Response Returned (timeout = 1, status = 0) - PASS + + // Local Variables + uvm_reg_data_t data; + bit timeout; + bit status; + bit finished; + + finished = 0; + timeout = 0; + fork + fork + + begin // Poll Status Bit + `uvm_info(`gfn, "Polling Flash Status ...", UVM_LOW) + while (finished == 0) begin + csr_rd(.ptr(ral.op_status), .value(data)); + status = get_field_val(ral.op_status.done, data); + if (status == 1) finished = 1; + end + end + + begin // Timeout - Expected + #(timeout_ns); + `uvm_info(`gfn, "Exiting Timeout Check ... Timeout Occured, Expected", UVM_LOW) + timeout = 1; + finished = 1; + end + + join + join + // Exit Gracefully + + // Decide Result + if ((timeout == 1'b1) && (status == 1'b0)) result = 1'b1; + else result = 1'b0; + + endtask : wait_flash_op_done_expect_timeout + + // Task to Read/Erase/Program the RMA Partitions Creator, Owner, Isolated, Data0 and Data1 + virtual task do_flash_op_rma(input flash_sec_part_e part, input flash_op_e op, + ref data_q_t flash_op_wdata, input bit cmp = READ_CHECK_NORM, + input uint data_part_addr, input uint data_part_num_words); + + // Note: + // Special Partition (used for Creator) : Bank 0, Information Partition 0, Page 1 + // Special Partition (used for Owner) : Bank 0, Information Partition 0, Page 2 + // Special Partition (used for Isolated) : Bank 0, Information Partition 0, Page 3 + + // Local Variables + bit poll_fifo_status; + data_q_t exp_data; + flash_op_t flash_op; + data_q_t flash_op_rdata; + int match_cnt; + string msg; + + // Assign + flash_op.op = op; + poll_fifo_status = 1; + + `uvm_info(`gfn, $sformatf("Operation : %s, Partition : %s ", op.name(), part.name()), + UVM_MEDIUM) + + // Disable HW Access to Secret Partition from Life Cycle Controller Interface (Write/Read/Erase) + cfg.flash_ctrl_vif.lc_seed_hw_rd_en = + get_rand_lc_tx_val(.t_weight(0), .f_weight(1), .other_weight(4)); + + // Select Options + unique case (part) + FlashCreatorPart: begin + flash_op.addr = FlashCreatorPartStartAddr; // Fixed Val + flash_op.num_words = FullPageNumWords; // Fixed Val + flash_op.partition = FlashPartInfo; + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + end + FlashOwnerPart: begin + flash_op.addr = FlashOwnerPartStartAddr; // Fixed Val + flash_op.num_words = FullPageNumWords; // Fixed Val + flash_op.partition = FlashPartInfo; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + end + FlashIsolPart: begin + flash_op.addr = FlashIsolPartStartAddr; // Fixed Val + flash_op.num_words = FullPageNumWords; // Fixed Val + flash_op.partition = FlashPartInfo; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + end + FlashData0Part, FlashData1Part: begin + flash_op.addr = data_part_addr; // Variable Val + flash_op.num_words = data_part_num_words; // Fixed Val + flash_op.partition = FlashPartData; + end + default: `uvm_error(`gfn, "Unrecognised Partiton, FAIL") + endcase + + // Perform Flash Operations via the Host Interface + case (flash_op.op) + + flash_ctrl_pkg::FlashOpErase: begin + if (part inside {FlashCreatorPart, FlashOwnerPart, FlashIsolPart}) + flash_op.erase_type = flash_ctrl_pkg::FlashErasePage; + else flash_op.erase_type = flash_ctrl_pkg::FlashEraseBank; + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); + end + + flash_ctrl_pkg::FlashOpProgram: begin + // Write Frontdoor, Read/Compare Backdoor + // Random Data + for (int i = 0; i < flash_op.num_words; i++) + flash_op_wdata[i] = $urandom_range(0, 2 ** (TL_DW) - 1); + flash_ctrl_write_extra(flash_op, flash_op_wdata); + end + + flash_ctrl_pkg::FlashOpRead: begin + flash_ctrl_read_extra(flash_op, flash_op_rdata); + // Compare + if (cfg.seq_cfg.check_mem_post_tran) begin + + if (cmp == ReadCheckNorm) begin + `uvm_info(`gfn, "Read : Compare Backdoor with Frontdoor", UVM_MEDIUM) + cfg.flash_mem_bkdr_read_check(flash_op, + flash_op_rdata); // Compare Backdoor with Frontdoor + end else if (cmp == ReadCheckErased) begin + `uvm_info(`gfn, "Read : Compare Backdoor with Erased Status", UVM_MEDIUM) + match_cnt = 0; + foreach (flash_op_rdata[i]) begin + if (flash_op_rdata[i] === '1) begin + // Data Match - Unexpected, but theoretically possible + // Theoretically if locations are all '1 then + // RMA Erase Worked but RMA Program did not + `uvm_info(`gfn, "Read : Data Match (Erased), EXPECTED", UVM_MEDIUM) + match_cnt++; + end + end + end else begin + `uvm_info(`gfn, "Read : Compare Backdoor with Erased Status", UVM_MEDIUM) + match_cnt = 0; + foreach (flash_op_rdata[i]) begin + if (flash_op_rdata[i] === '1) begin + // Data Match - Unexpected, but theoretically possible + // Theoretically if locations are all '1 then + // RMA Erase Worked but RMA Program did not + `uvm_info(`gfn, "Read : Data Match (Erased), UNEXPECTED", UVM_MEDIUM) + match_cnt++; + end + end + + // Decide Pass/Fail Based on Match Count + if (match_cnt > 1) + `uvm_error(`gfn, {"Read : Data Matches Seen (Erase), UNEXPECTED", + $sformatf("Flash Content Should Be Random (RMA Wipe) (Matches : %0d)", match_cnt)}) + + `uvm_info(`gfn, "Read : Compare Backdoor with Data Previously Written", UVM_MEDIUM) + match_cnt = 0; + foreach (flash_op_rdata[i]) begin + if (flash_op_rdata[i] === flash_op_wdata[i]) begin + // Data Match - Unlikely, but theoretically possible + `uvm_info(`gfn, "Read : Data Match, UNEXPECTED", UVM_MEDIUM) + match_cnt++; + end + end + // Decide Pass/Fail Based on Match Count + if (match_cnt > 1) + `uvm_error(`gfn, { + "Read : Data Matches Seen, UNEXPECTED, Flash Content Should Be ", + $sformatf("Random (RMA Wipe) (Matches : %0d)", match_cnt)}) + end + end + end + default: `uvm_error(`gfn, "Unrecognised Partiton, FAIL") + endcase + + // Deselect Life Cycle Controller HW Options + unique case (part) + FlashCreatorPart: begin + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::Off; + end + FlashOwnerPart: begin + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::Off; + end + FlashIsolPart: begin + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::Off; + end + FlashData0Part, FlashData1Part: ; // No Operation + default: `uvm_error(`gfn, "Unrecognised Partiton, FAIL") + endcase + + endtask : do_flash_op_rma + + // Task to Program the Entire Flash Memory + virtual task flash_ctrl_write_extra(flash_op_t flash_op, data_q_t data, + bit check_match = 1, bit scr_en = 0, + bit ecc_en = 0); + + // Local Signals + uvm_reg_data_t reg_data; + flash_part_e partition_sel; + bit [InfoTypesWidth-1:0] info_sel; + int num; + int num_full; + int num_part; + data_4s_t fifo_data; + addr_t flash_addr; + data_q_t exp_data; + flash_op_t flash_op_copy; + data_q_t data_copy; + + // Calculate Number of Complete Cycles and Partial Cycle Words + num = data.size(); + num_full = num / FIFO_DEPTH; + num_part = num % FIFO_DEPTH; + + // Other + partition_sel = flash_part_e'(|flash_op.partition); + info_sel = flash_op.partition >> 1; + flash_addr = flash_op.addr; + + `uvm_info(`gfn, $sformatf( + "Flash Write Summary : Words : %0d, Full Cycles : %0d, Partial Cycle Words : %0d", + num, + num_full, + num_part + ), UVM_LOW) + + // Copies + flash_op_copy = flash_op; + data_copy = data; + + // If num_full > 0 + for (int cycle = 0; cycle < num_full; cycle++) begin + + `uvm_info(`gfn, $sformatf("Write Cycle : %0d, flash_addr = 0x%0x", cycle, flash_addr), + UVM_MEDIUM) + csr_wr(.ptr(ral.addr), .value(flash_addr)); + + reg_data = '0; + reg_data = get_csr_val_with_updated_field(ral.control.start, reg_data, 1'b1) | + get_csr_val_with_updated_field(ral.control.op, reg_data, flash_op.op) | + get_csr_val_with_updated_field(ral.control.erase_sel, reg_data, flash_op.erase_type) | + get_csr_val_with_updated_field(ral.control.partition_sel, reg_data, partition_sel) | + get_csr_val_with_updated_field(ral.control.info_sel, reg_data, info_sel) | + get_csr_val_with_updated_field(ral.control.num, reg_data, FIFO_DEPTH - 1); + csr_wr(.ptr(ral.control), .value(reg_data)); + + for (int i = 0; i < FIFO_DEPTH; i++) begin + fifo_data = data.pop_front(); + mem_wr(.ptr(ral.prog_fifo), .offset(0), .data(fifo_data)); + end + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + + flash_addr += FIFO_DEPTH * 4; + + end + + // If there is a partial cycle + if (num_part > 0) begin + if (num_full == 0) flash_addr = flash_op.addr; + `uvm_info(`gfn, $sformatf("Last Write : flash_addr = 0x%0x", flash_addr), UVM_MEDIUM) + + csr_wr(.ptr(ral.addr), .value(flash_addr)); + + reg_data = '0; + reg_data = get_csr_val_with_updated_field(ral.control.start, reg_data, 1'b1) | + get_csr_val_with_updated_field(ral.control.op, reg_data, flash_op.op) | + get_csr_val_with_updated_field(ral.control.erase_sel, reg_data, flash_op.erase_type) | + get_csr_val_with_updated_field(ral.control.partition_sel, reg_data, partition_sel) | + get_csr_val_with_updated_field(ral.control.info_sel, reg_data, info_sel) | + get_csr_val_with_updated_field(ral.control.num, reg_data, num_part - 1); + csr_wr(.ptr(ral.control), .value(reg_data)); + for (int i = 0; i < num_part; i++) begin + fifo_data = data.pop_front(); + mem_wr(.ptr(ral.prog_fifo), .offset(0), .data(fifo_data)); + end + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + + end + + exp_data = cfg.calculate_expected_data(flash_op_copy, data_copy); + + if (cfg.seq_cfg.check_mem_post_tran) begin + flash_op_copy.otf_addr = flash_op_copy.addr; + flash_op_copy.otf_addr[BusAddrByteW-2:OTFHostId] = 'h0; + cfg.flash_mem_bkdr_read_check(flash_op_copy, exp_data, check_match, scr_en, ecc_en); + end + endtask : flash_ctrl_write_extra + + // Task to Read the Entire Flash Memory + virtual task flash_ctrl_read_extra(flash_op_t flash_op, ref data_q_t data); + + // Local Signals + uvm_reg_data_t reg_data; + flash_part_e partition_sel; + bit [InfoTypesWidth-1:0] info_sel; + logic [TL_AW:0] flash_addr; + int num; + int num_full; + int num_part; + int num_words; + int idx; + + // Calculate Number of Complete Cycles and Partial Cycle Words + num = flash_op.num_words; + num_full = num / FIFO_DEPTH; + num_part = num % FIFO_DEPTH; + + `uvm_info(`gfn, $sformatf( + "Flash Read Summary : Words : %0d, Full Cycles : %0d, Partial Cycle Words : %0d", + num, + num_full, + num_part + ), UVM_LOW) + + // Other + partition_sel = flash_part_e'(|flash_op.partition); + info_sel = flash_op.partition >> 1; + num_words = flash_op.num_words; + flash_addr = flash_op.addr; + + // If num_full > 0 + idx = 0; + for (int cycle = 0; cycle < num_full; cycle++) begin + + `uvm_info(`gfn, $sformatf("Read Cycle : %0d, flash_addr = 0x%0x", cycle, flash_addr), + UVM_MEDIUM) + + csr_wr(.ptr(ral.addr), .value(flash_addr)); // Read Address + + reg_data = '0; + reg_data = get_csr_val_with_updated_field(ral.control.start, reg_data, 1'b1) | + get_csr_val_with_updated_field(ral.control.op, reg_data, flash_op.op) | + get_csr_val_with_updated_field(ral.control.erase_sel, reg_data, flash_op.erase_type) | + get_csr_val_with_updated_field(ral.control.partition_sel, reg_data, partition_sel) | + get_csr_val_with_updated_field(ral.control.info_sel, reg_data, info_sel) | + get_csr_val_with_updated_field(ral.control.num, reg_data, FIFO_DEPTH - 1); + csr_wr(.ptr(ral.control), .value(reg_data)); + + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + + // Read from FIFO + for (int i = 0; i < FIFO_DEPTH; i++) begin + mem_rd(.ptr(ral.rd_fifo), .offset(0), .data(data[idx])); + idx++; + end + flash_addr += FIFO_DEPTH * 4; + + end + + // If there is a partial Cycle + if (num_part > 0) begin + if (num_full == 0) flash_addr = flash_op.addr; + `uvm_info(`gfn, $sformatf("Last Read Cycle : flash_addr = 0x%0x", flash_addr), UVM_MEDIUM) + + csr_wr(.ptr(ral.addr), .value(flash_addr)); // Write Address + + reg_data = '0; + reg_data = get_csr_val_with_updated_field(ral.control.start, reg_data, 1'b1) | + get_csr_val_with_updated_field(ral.control.op, reg_data, flash_op.op) | + get_csr_val_with_updated_field(ral.control.erase_sel, reg_data, flash_op.erase_type) | + get_csr_val_with_updated_field(ral.control.partition_sel, reg_data, partition_sel) | + get_csr_val_with_updated_field(ral.control.info_sel, reg_data, info_sel) | + get_csr_val_with_updated_field(ral.control.num, reg_data, FIFO_DEPTH - 1); + csr_wr(.ptr(ral.control), .value(reg_data)); + + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + + // Read from FIFO + for (int i = 0; i < FIFO_DEPTH; i++) begin + mem_rd(.ptr(ral.rd_fifo), .offset(0), .data(data[idx++])); + end + + end + + endtask : flash_ctrl_read_extra + + // This task can be called, when rma is requested by lc_ctrl. + // Before rma wipe for data partition started (256 pages), + // this task force total page to 9 pages. So rma process is completed faster. + virtual task enable_small_rma(); + string path = "tb.dut.u_flash_hw_if"; + string mypath; + logic [2:0] rma_wipe_idx; + logic [3:0] rma_ack; + // Wait for data partition rma. + mypath = {path, ".rma_wipe_idx"}; + + `DV_SPINWAIT( + do begin + @(cfg.clk_rst_vif.cb); + uvm_hdl_read(mypath, rma_wipe_idx); + end while (rma_wipe_idx != 3'h3);, + "waiting for rma index = 3", 50_000_000 + ) + + // Reduce page size to 'd2 + mypath = {path, ".end_page"}; + `DV_CHECK(uvm_hdl_force(mypath, 'h2)); + + // Wait for rma complete + mypath = {path, ".rma_ack_q"}; + `DV_SPINWAIT( + do begin + @(cfg.clk_rst_vif.cb); + uvm_hdl_read(mypath, rma_ack); + end while (rma_ack != lc_ctrl_pkg::On);, + "waiting for rma ack == On", 100_000_000 + ) + mypath = {path, ".end_page"}; + `DV_CHECK(uvm_hdl_release(mypath)); + endtask : enable_small_rma + + // Task to send an RMA Request (with a given seed) to the Flash Controller + virtual task send_rma_req(lc_flash_rma_seed_t rma_seed = LC_FLASH_RMA_SEED_DEFAULT, + bit ignore_short_rma = 0); + + // Local Variables + bit done; + time timeout = 15s; + time start_time; + bit rma_ack_seen; + + `uvm_info(`gfn, $sformatf("RMA Seed : 0x%08x", rma_seed), UVM_LOW) + + // Set Seed and Send Req + cfg.flash_ctrl_vif.rma_seed <= rma_seed; + cfg.flash_ctrl_vif.rma_req <= lc_ctrl_pkg::On; + + // RMA Start Time + start_time = $time(); + + // Wait for RMA Ack to Rise (NOTE LONG DURATION) + `uvm_info(`gfn, "Waiting for RMA to complete ... ", UVM_LOW) + + done = 0; + rma_ack_seen = 0; + fork + begin + // If small_rma enabled + if (cfg.en_small_rma & !ignore_short_rma) begin + `uvm_info(`gfn, "small_rma mode is enabled", UVM_LOW) + enable_small_rma(); + end + end + begin + fork + begin // Poll RMA ACK + do begin + `uvm_info(`gfn, "Polling RMA ACK ...", UVM_LOW) + #10ms; // Jump Ahead (Not Sampling Clocks) + @(posedge cfg.clk_rst_vif.clk); // Align to Clock + if (cfg.flash_ctrl_vif.rma_ack == lc_ctrl_pkg::On || + cfg.rma_ack_polling_stop == 1) done = 1; + end while (done == 0); + if (cfg.rma_ack_polling_stop) begin + `uvm_info(`gfn, "Polling is stopped by external task", UVM_LOW) + end + end + begin // Timeout - Unexpected + `uvm_info(`gfn, "Starting RMA Timeout Check ...", UVM_LOW) + #(timeout); + `uvm_error(`gfn, { + "RMA ACK NOT seen within the expected time frame, Timeout - FAIL", + $sformatf(" (%0t)", timeout)}) + end + join_any + disable fork; + end + join + + // Note: After a valid RMA Ack is sent, the RMA State Machine remains in its last state, + // until reset + + // RMA End Time + `uvm_info(`gfn, "RMA complete", UVM_LOW) + `uvm_info(`gfn, $sformatf("RMA Duration : %t", $time() - start_time), UVM_LOW); + + endtask : send_rma_req + + // Task to Enable/Disable the 'Info' Partitions, Creator, Owner and Isolated, via the Lifetime + // Controller Interface + virtual task en_sw_rw_part_info(input flash_op_t flash_op, input lc_ctrl_pkg::lc_tx_t val); + if (flash_op.partition == FlashPartInfo) begin + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = val; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = val; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = val; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = val; + end + endtask : en_sw_rw_part_info + + // Controller read page. + virtual task controller_read_page(flash_op_t flash_op_r); + data_q_t flash_read_data; + bit poll_fifo_status = 1; + flash_op_r.op = flash_ctrl_pkg::FlashOpRead; + flash_op_r.num_words = 16; + flash_op_r.addr = {flash_op_r.addr[19:11], {11{1'b0}}}; + for (int i = 0; i < 32; i++) begin + flash_ctrl_start_op(flash_op_r); + flash_ctrl_read(flash_op_r.num_words, flash_read_data, poll_fifo_status); + wait_flash_op_done(); + flash_op_r.addr = flash_op_r.addr + 64; //64B was read, 16 words + end + endtask : controller_read_page + + // Controller program page. + virtual task controller_program_page(flash_op_t flash_op_p); + bit poll_fifo_status = 1; + flash_op_p.op = flash_ctrl_pkg::FlashOpProgram; + flash_op_p.num_words = 16; + flash_op_p.addr = {flash_op_p.addr[19:11], {11{1'b0}}}; + for (int i = 0; i < 32; i++) begin + `uvm_info(`gfn, $sformatf("PROGRAM ADDRESS: 0x%0h", flash_op_p.addr), UVM_HIGH) + // Randomize Write Data + for (int j = 0; j < 16; j++) begin + flash_program_data[j] = $urandom(); + end + cfg.flash_mem_bkdr_write(.flash_op(flash_op_p), .scheme(FlashMemInitSet)); + flash_ctrl_start_op(flash_op_p); + flash_ctrl_write(flash_program_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + flash_op_p.addr = flash_op_p.addr + 64; //64B was written, 16 words + end + endtask : controller_program_page + + // Check Expected Alert for prog_type_err and prog_win_err + virtual task check_exp_alert_status(input bit exp_alert, input string alert_name, + input flash_op_t flash_op, input data_q_t flash_op_data); + + // Local Variables + uvm_reg_data_t reg_data; + + // Read Status Bits + case (alert_name) + "prog_type_err" : csr_rd_check(.ptr(ral.err_code.prog_type_err), .compare_value(exp_alert)); + "prog_win_err" : csr_rd_check(.ptr(ral.err_code.prog_win_err), .compare_value(exp_alert)); + "mp_err" : csr_rd_check(.ptr(ral.err_code.mp_err), .compare_value(exp_alert)); + "op_err" : csr_rd_check(.ptr(ral.err_code.op_err), .compare_value(exp_alert)); + default : `uvm_fatal(`gfn, "Unrecognized alert_name, FAIL") + endcase + csr_rd_check(.ptr(ral.op_status.err), .compare_value(exp_alert)); + + // For 'prog_type_err' and 'prog_win_err' check via backdoor if Pass, + // 'mp_err' is Backdoor checked directly within its own test. + if ((alert_name inside {"prog_type_err", "prog_win_err"}) && (exp_alert == 0)) begin + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + end + + // Clear Status Bits + case (alert_name) + "prog_type_err" : reg_data = get_csr_val_with_updated_field(ral.err_code.prog_type_err, + reg_data, 1); + "prog_win_err" : reg_data = get_csr_val_with_updated_field(ral.err_code.prog_win_err, + reg_data, 1); + "mp_err" : reg_data = get_csr_val_with_updated_field(ral.err_code.mp_err, + reg_data, 1); + "op_err" : reg_data = get_csr_val_with_updated_field(ral.err_code.op_err, + reg_data, 1); + default : `uvm_fatal(`gfn, "Unrecognized alert_name") + endcase + csr_wr(.ptr(ral.err_code), .value(reg_data)); + reg_data = get_csr_val_with_updated_field(ral.op_status.err, reg_data, 0); + csr_wr(.ptr(ral.op_status), .value(reg_data)); + + endtask : check_exp_alert_status + + // Refill table with all default value. + function void init_p2r_map(); + foreach (cfg.p2r_map[i]) cfg.p2r_map[i] = 8; + endfunction + + // p2r_map needs to be in sync with rtl config. + // Same as RTL, lower index has priority when + // regions are content. + function void update_p2r_map(flash_mp_region_cfg_t mp[]); + int num = mp.size() - 1; + int base, size; + // Lower region has priority. + `uvm_info("update_p2r_map", $sformatf("default : %p", cfg.default_region_cfg), UVM_MEDIUM) + for (int i = num; i >= 0; --i) begin + // Check the region is enabled. + if (mp[i].en == MuBi4True) begin + `uvm_info("update_p2r_map", $sformatf("region %0d : %p", i, mp[i]), UVM_MEDIUM) + base = mp[i].start_page; + size = mp[i].num_pages; + for (int j = base; j < (base + size); ++j) begin + if (cfg.p2r_map[j] > i) cfg.p2r_map[j] = i; + end + end + end + + `uvm_info("update_p2r_map", $sformatf("after p2r_map update, %p", cfg.p2r_map), UVM_HIGH) + endfunction // update_p2r_map + + // Takes flash_op and region profile and check if the flash_op is legal or not. + // return 1 : illegal transaction + // return 0 : legal transaction + function bit validate_flash_op(flash_op_t flash_op, flash_mp_region_cfg_t my_region); + if (my_region.en != MuBi4True) return 1; + case(flash_op.op) + FlashOpRead:begin + return (my_region.read_en != MuBi4True); + end + FlashOpProgram:begin + return (my_region.program_en != MuBi4True); + end + FlashOpErase:begin + return (my_region.erase_en != MuBi4True); + end + FlashOpInvalid:begin + return 1; + end + default:begin + `uvm_error("update_flash_op", $sformatf("got %s command", flash_op.op.name())) + return 1; + end + endcase + endfunction // validate_flash_op + + // Takes flash_op and info profile and check if the flash_op is legal or not. + // return 1 : illegal transaction + // return 0 : legal transaction + // Bank erase doesn't follow rules in this function. + function bit validate_flash_info(flash_op_t flash_op, flash_bank_mp_info_page_cfg_t my_info); + if(my_info.en != MuBi4True) return 1; + case(flash_op.op) + FlashOpRead:begin + return (my_info.read_en != MuBi4True); + end + FlashOpProgram:begin + return (my_info.program_en != MuBi4True); + end + FlashOpErase:begin + return (my_info.erase_en != MuBi4True); + end + FlashOpInvalid:begin + return 1; + end + default:begin + `uvm_error("update_flash_op", $sformatf("got %s command", flash_op.op.name())) + return 1; + end + endcase + endfunction // validate_flash_info + + function void set_otf_exp_alert(string str); + cfg.scb_h.exp_alert_ff[str].push_back(1); + cfg.scb_h.expected_alert[str].max_delay = 2000; + `uvm_info("set_otf_exp_alert", + $sformatf("exp_alert_ff[%s] size: %0d", + str, cfg.scb_h.exp_alert_ff[str].size()), UVM_MEDIUM) + endfunction // set_otf_exp_alert + + // This function checks wheter input 'sig' is lc_ctrl_pkg::On or lc_ctrl_pkg::Off + function bit is_lc_ctrl_valid(lc_ctrl_pkg::lc_tx_t sig, bit is_true_valid = 1); + + return ((sig == lc_ctrl_pkg::On && is_true_valid == 1) || + (sig == lc_ctrl_pkg::Off && is_true_valid == 0)); + endfunction // is_lc_ctrl_valid + + function void all_sw_rw_en(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + endfunction // all_sw_rw_en + + // Collect cover poiint by reading csr + // ral.std_fault_status + // ral.fault_status + // ral.err_code + task collect_err_cov_status(dv_base_reg ptr); + uvm_reg_data_t rdata; + if (cfg.en_cov) begin + csr_rd(.ptr(ptr), .value(rdata), .backdoor(1)); + if (ptr.get_name == "std_fault_status") begin + cfg.scb_h.cov.std_fault_cg.sample(rdata); + end else if (ptr.get_name == "err_code") begin + cfg.scb_h.cov.sw_error_cg.sample(rdata); + end else begin + cfg.scb_h.cov.hw_error_cg.sample(rdata); + end + end + endtask + + task init_controller(bit non_blocking = 0); + int wait_timeout_ns = 200_000; // 200 us + + csr_wr(.ptr(ral.init), .value(1)); + `uvm_info(`gfn,"init_controller: OTP",UVM_LOW) + otp_model(); + if (non_blocking == 0) begin + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);, + "Timed out waiting for rd_buf_en", + wait_timeout_ns) + cfg.clk_rst_vif.wait_clks(10); + end + endtask + + // Use uvm_hdl_read / force flip 2 bits out of 32 bit bus + // Assuming the input path should be 32bit bus + function void flip_2bits(string path); + bit [31:0] rdata; + int idx[32]; + foreach (idx[i]) idx[i] = i; + `DV_CHECK(uvm_hdl_read(path, rdata)); + idx.shuffle(); + rdata[idx[0]] = ~rdata[idx[0]]; + rdata[idx[1]] = ~rdata[idx[1]]; + `DV_CHECK(uvm_hdl_force(path, rdata)); + endfunction + + // Identify secret partition from flash_op. + function bit is_secret_part(flash_op_t op); + return ( op.partition == FlashPartInfo && + op.addr inside {[FlashCreatorPartStartAddr:FlashIsolPartEndAddr]}); + endfunction // is_secret_part + + // Update secret partition with scrambled and ecc enabled data. + function void update_secret_partition(bit dis = 0); + uvm_hdl_data_t data; + flash_otf_item item; + bit [BankAddrW-1:0] mem_addr; + int start_page = 1; + int number_of_secret_pages = 3; + `uvm_info(`gfn, $sformatf("Updating secret partition with addr_key:%x, data_key:%x", + otp_addr_key, otp_data_key), UVM_MEDIUM) + + for (int page = start_page; page < start_page + number_of_secret_pages; ++page) begin + mubi4_t scramble_en; + mubi4_t ecc_en; + int page_st_addr = page * BytesPerPage; + int page_en_addr = page_st_addr + BytesPerPage - 1; + // Only scr/ecc enable matter; cfg.ovrd_src_dis can be randomized in directed test, + // but otherwise it has the same default value as HW_INFO_CFG_OVERRIDE. + if (page != 3) begin + scramble_en = prim_mubi_pkg::mubi4_and_hi(flash_ctrl_pkg::CfgAllowRead.scramble_en, + mubi4_t'(~cfg.ovrd_scr_dis)); + ecc_en = prim_mubi_pkg::mubi4_and_hi(flash_ctrl_pkg::CfgAllowRead.ecc_en, + mubi4_t'(~cfg.ovrd_ecc_dis)); + end else begin + scramble_en = flash_ctrl_pkg::CfgAllowRead.scramble_en; + ecc_en = flash_ctrl_pkg::CfgAllowRead.ecc_en; + end + `uvm_info(`gfn, $sformatf( + "info page %0d [0x%x : 0x%x] scr_en:%x, ecc_en:%x", + page, page_st_addr, page_st_addr + BytesPerPage - 1, scramble_en, ecc_en), + UVM_MEDIUM) + for (int addr = page_st_addr; addr <= page_en_addr; addr += 8) begin + `uvm_create_obj(flash_otf_item, item) + data = cfg.mem_bkdr_util_h[FlashPartInfo][0].read(addr); + item.dq.push_back(data[31:0]); + item.dq.push_back(data[63:32]); + item.region.scramble_en = scramble_en; + item.region.ecc_en = ecc_en; + item.scramble(otp_addr_key, otp_data_key, addr, dis); + cfg.mem_bkdr_util_h[FlashPartInfo][0].write(addr, item.fq[0]); + mem_addr = addr >> 3; + cfg.otf_scb_h.info_mem[0][0][mem_addr] = item.fq[0]; + cfg.scb_flash_info[addr] = item.fq[0][31:0]; + cfg.scb_flash_info[addr+4] = item.fq[0][63:32]; + end + end + add_address_range(0, FlashPartInfo, start_page * BytesPerPage, + (start_page + number_of_secret_pages) * BytesPerPage - 1); + sort_all_address_ranges(); + endfunction // update_secret_partition + + function void update_mp_region_cfg_mubifalse(ref flash_mp_region_cfg_t cfg); + if (cfg.en != MuBi4True) cfg.en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.read_en != MuBi4True) cfg.read_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.program_en != MuBi4True) cfg.program_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.erase_en != MuBi4True) cfg.erase_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.scramble_en != MuBi4True) cfg.scramble_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.ecc_en != MuBi4True) cfg.ecc_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.he_en != MuBi4True) cfg.he_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + endfunction + + function void update_mp_info_cfg_mubifalse(ref flash_bank_mp_info_page_cfg_t cfg); + if (cfg.en != MuBi4True) cfg.en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.read_en != MuBi4True) cfg.read_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.program_en != MuBi4True) cfg.program_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.erase_en != MuBi4True) cfg.erase_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.scramble_en != MuBi4True) cfg.scramble_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.ecc_en != MuBi4True) cfg.ecc_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + if (cfg.he_en != MuBi4True) cfg.he_en = + get_rand_mubi4_val(.t_weight(0), .f_weight(1), .other_weight(9)); + endfunction + +endclass : flash_ctrl_base_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_callback_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_callback_vseq.sv new file mode 100644 index 0000000000000..5f5ea6a6b8133 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_callback_vseq.sv @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// A sequence hook to attach to flash_ctrl_base_vseq. +class flash_ctrl_callback_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_callback_vseq) + `uvm_object_new + + virtual task apply_reset_callback(); + // Do nothing but can be overridden in closed source environment. + endtask + + virtual task update_env_mp_info(); + // Do nothing but can be overridden in closed source environment. + endtask +endclass : flash_ctrl_callback_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_common_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_common_vseq.sv new file mode 100644 index 0000000000000..562ed195d4513 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_common_vseq.sv @@ -0,0 +1,257 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_common_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_common_vseq) + + `uvm_object_new + + virtual function void configure_vseq(); + cfg.seq_cfg.max_num_trans = 2; + endfunction + + virtual task pre_start(); + super.pre_start(); + // After reset, scoreboard need to wait until wip process is done. + // Since common reset test is not aware of it, remove check from sb and + // have each test check read response. + if (common_seq_type inside {"stress_all_with_rand_reset", "csr_mem_rw_with_rand_reset"}) begin + cfg.scb_h.skip_read_check = 1'b1; + end + // Remove prim from following test until alert issue is resolved + if (common_seq_type inside {"same_csr_outstanding"}) begin + foreach (all_csrs[i]) begin + csr_excl_item csr_excl = get_excl_item(all_csrs[i]); + if (!uvm_re_match("*prim_reg_block*", all_csrs[i].get_full_name)) begin + csr_excl.add_excl(all_csrs[i].get_full_name, CsrExclAll, CsrRwTest); + end + + end + end else begin + csr_excl_item csr_excl = ral.get_excl_item(); + csr_excl.add_excl("flash_ctrl_core_reg_block.init", CsrExclAll, CsrAllTests); + end + endtask // pre_start + + function void disable_fi_for_prim_count(string path); + sec_cm_pkg::find_sec_cm_if_proxy(.path({path, "*u_rptr"}), .is_regex(1)).disable_fi(); + sec_cm_pkg::find_sec_cm_if_proxy(.path({path, "*u_wptr"}), .is_regex(1)).disable_fi(); + endfunction + + task dut_init(string reset_kind = "HARD"); + // Disable fault injection on the prim_count module associated with the TL-UL + // adapter SRAM request and sramreqfifo fifo. + // + // This is because injecting a fault causes a spurious TL transaction whose response + // eventually causes a fatal alert (good). Unfortunately, the FIFOs might actually have + // been empty, so lots of signals in the design become X. This includes FLASH_CTRL's + // bus_integ_error signal than then cannot be reliably sensed in the DV environment. + // The code here disables fault injection at that location. + disable_fi_for_prim_count("*u_tl_adapter_eflash*u_rspfifo*u_fifo_cnt"); + disable_fi_for_prim_count("*u_tl_adapter_eflash*u_reqfifo*u_fifo_cnt"); + disable_fi_for_prim_count("*u_tl_adapter_eflash*u_sramreqfifo*u_fifo_cnt"); + + super.dut_init(reset_kind); + endtask // dut_init + + virtual task body(); + string path[] = { + {"tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd", + ".u_rd_storage.gen_normal_fifo.storage_rdata[74:0]"}, + {"tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd", + ".u_rd_storage.gen_normal_fifo.storage_rdata[74:0]"}, + "tb.dut.u_to_rd_fifo.u_rspfifo.gen_normal_fifo.storage_rdata[39:0]" + }; + if (common_seq_type == "") void'($value$plusargs("run_%0s", common_seq_type)); + if (common_seq_type == "sec_cm_fi") begin + for (int i = 0; i < path.size(); i++) begin + `DV_CHECK(uvm_hdl_deposit(path[i], 0)) + end + // Each run of sec_cm takes about 10 min. + // Limit num_trans of sec_cm to 10. + run_sec_cm_fi_vseq(10); + end else run_common_vseq_wrapper(num_trans); + endtask : body + + bit prim_tl_intg_error; + + task run_tl_intg_err_vseq_sub(string ral_name); + if (!uvm_re_match("*prim_reg_block*", ral_name)) prim_tl_intg_error = 1; + else prim_tl_intg_error = 0; + super.run_tl_intg_err_vseq_sub(ral_name); + endtask + + // Override from hw/dv/sv/cip_lib/seq_lib/cip_base_vseq__sec_cm_fi.svh + task test_sec_cm_fi(); + sec_cm_base_if_proxy if_proxy_q[$] = sec_cm_pkg::sec_cm_if_proxy_q; + + if_proxy_q.shuffle(); + while (if_proxy_q.size) begin + sec_cm_base_if_proxy if_proxy = if_proxy_q.pop_front(); + + // If fault injection is disabled at this instance of the interface, skip it (and don't inject + // anything) + if (if_proxy.fi_disabled) continue; + + sec_cm_fi_ctrl_svas(if_proxy, .enable(0)); + sec_cm_inject_fault(if_proxy); + + // Randomly force the cnt to normal value (error will be cleared) to make sure design latches + // the error + if ($urandom_range(0, 1)) begin + sec_cm_restore_fault(if_proxy); + end + + if (cfg.seq_cfg.use_vendor_flash == 1 && + cfg.seq_cfg.vendor_flash_path != "" && + !uvm_re_match(cfg.seq_cfg.vendor_flash_path, if_proxy.path) == 1) begin + wait_alert_trigger("fatal_prim_flash_alert", .wait_complete(1)); + end else begin + // when a fault occurs at the reg_we_check, it's treated as a TL intg error + if (if_proxy.sec_cm_type == SecCmPrimOnehot && + !uvm_re_match("*u_prim_reg_we_check*", if_proxy.path)) begin + if (!uvm_re_match("*u_eflash*", if_proxy.path)) prim_tl_intg_error = 1; + check_tl_intg_error_response(); + end else begin + check_sec_cm_fi_resp(if_proxy); + end + end + sec_cm_fi_ctrl_svas(if_proxy, .enable(1)); + // issue hard reset for fatal alert to recover + prim_tl_intg_error = 0; + dut_init("HARD"); + end + endtask : test_sec_cm_fi + + virtual task check_tl_intg_error_response(); + if (prim_tl_intg_error) begin + repeat ($urandom_range(5, 10)) + wait_alert_trigger("fatal_prim_flash_alert"); + end else begin + super.check_tl_intg_error_response(); + end + endtask // check_tl_intg_error_response + + virtual task check_sec_cm_fi_resp(sec_cm_base_if_proxy if_proxy); + bit flash_dis = 1; + `uvm_info(`gfn, $sformatf("path: %s", if_proxy.path), UVM_MEDIUM) + + if (!uvm_re_match("*.u_host_outstanding_cnt*", if_proxy.path)) begin + collect_err_cov_status(ral.fault_status); + csr_rd_check(.ptr(ral.fault_status.host_gnt_err), .compare_value(1)); + flash_dis = 0; + end else begin + super.check_sec_cm_fi_resp(if_proxy); + end + if (!uvm_re_match("*.u_flash_hw_if.*", if_proxy.path)) begin + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.lcmgr_err), .compare_value(1)); + // skip debug_state check because state is corrupted. + flash_dis = 0; + end + if (cfg.seq_cfg.use_vendor_flash == 1 && + cfg.seq_cfg.vendor_flash_path != "" && + !uvm_re_match(cfg.seq_cfg.vendor_flash_path, if_proxy.path) == 1) begin + flash_dis = 0; + end + case (if_proxy.sec_cm_type) + SecCmPrimCount: begin + if (!uvm_re_match("*.u_host_rsp_fifo.*", if_proxy.path) | + !uvm_re_match("*.u_to_rd_fifo.*", if_proxy.path) | + !uvm_re_match("*.u_rd_storage.*", if_proxy.path)) begin + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.fifo_err), .compare_value(1)); + end + if (!uvm_re_match("*.u_flash_ctrl_rd.u_cnt*", if_proxy.path) | + !uvm_re_match("*.u_flash_ctrl_prog.u_cnt*", if_proxy.path)) begin + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.ctrl_cnt_err), .compare_value(1)); + end + end + SecCmPrimSparseFsmFlop: begin + if (!uvm_re_match("*.gen_flash_cores*", if_proxy.path)) begin + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.phy_fsm_err), .compare_value(1)); + end + if (!uvm_re_match("*.u_ctrl_arb.*", if_proxy.path)) begin + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.arb_fsm_err), .compare_value(1)); + end + if (!uvm_re_match("*_tl_gate.*", if_proxy.path)) begin + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.reg_intg_err), .compare_value(1)); + end + end + SecCmPrimOnehot: begin + // Do nothing. + end + default: begin + `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name)) + end + endcase + + if (flash_dis) begin + csr_rd_check(.ptr(ral.debug_state), + .compare_value(flash_ctrl_env_pkg::FlashLcDisabled)); + flash_access_after_disabled(); + end + endtask // check_sec_cm_fi_resp + + virtual function void sec_cm_fi_ctrl_svas(sec_cm_base_if_proxy if_proxy, bit enable); + case (if_proxy.sec_cm_type) + SecCmPrimCount: begin + if (enable) begin + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd.u_rd_storage"); + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd.u_rd_storage"); + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[0].u_host_rsp_fifo"); + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[1].u_host_rsp_fifo"); + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd.u_rsp_order_fifo"); + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd.u_rsp_order_fifo"); + $asserton(0, "tb.dut.u_to_rd_fifo.u_rspfifo.DataKnown_A"); + $asserton(0, "tb.dut.tlul_assert_device.gen_device.dDataKnown_A"); + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[0].u_core.RdTxnCheck_A"); + $asserton(0, "tb.dut.u_eflash.gen_flash_cores[1].u_core.RdTxnCheck_A"); + $asserton(0, "tb.dut.RspPayLoad_A"); + end else begin + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd.u_rd_storage"); + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd.u_rd_storage"); + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[0].u_host_rsp_fifo"); + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[1].u_host_rsp_fifo"); + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd.u_rsp_order_fifo"); + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd.u_rsp_order_fifo"); + $assertoff(0, "tb.dut.u_to_rd_fifo.u_rspfifo.DataKnown_A"); + $assertoff(0, "tb.dut.tlul_assert_device.gen_device.dDataKnown_A"); + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[0].u_core.RdTxnCheck_A"); + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[1].u_core.RdTxnCheck_A"); + $assertoff(0, "tb.dut.u_to_rd_fifo.rvalidHighWhenRspFifoFull"); + $assertoff(0, "tb.dut.RspPayLoad_A"); + end + end + SecCmPrimSparseFsmFlop: begin + if (enable) begin + $asserton(0, "tb.dut.u_flash_hw_if.DisableChk_A"); + end else begin + $assertoff(0, "tb.dut.u_flash_hw_if.DisableChk_A"); + end + end + SecCmPrimOnehot: begin + // Do nothing. + end + default: begin + `uvm_fatal(`gfn, $sformatf("unexpected sec_cm_type %s", if_proxy.sec_cm_type.name)) + end + endcase + endfunction + + virtual task write_and_check_update_error(dv_base_reg shadowed_csr); + super.write_and_check_update_error(shadowed_csr); + collect_err_cov_status(ral.err_code); + endtask // write_and_check_update_error + + virtual task poke_and_check_storage_error(dv_base_reg shadowed_csr); + super.poke_and_check_storage_error(shadowed_csr); + collect_err_cov_status(ral.std_fault_status); + endtask + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_config_regwen_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_config_regwen_vseq.sv new file mode 100644 index 0000000000000..571bd6f36f483 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_config_regwen_vseq.sv @@ -0,0 +1,88 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Designated sequence to test "RO" type regwen +// The sequence does write and read back check for flash_ctrl.control register. +// Then it launches long operation. +// While operation is on going, try write random data but register value should not be changed. +// Finally, release flash_ctrl.ctrl_regwen and does write and readback check +// with a random data. +// This test does not include any flash data transaction. +class flash_ctrl_config_regwen_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_config_regwen_vseq) + `uvm_object_new + + rand bit[31:0] ctrl_data; + + // Make rsvd field '0' + constraint ctrl_data_c { + ctrl_data[3:1] == 0; + ctrl_data[15:11] == 0; + ctrl_data[31:28] == 0; + } + + task body(); + uvm_reg_data_t exp_data, dumb_data; + + // Randomized program of control register can trigger + // unintended or illegal transactions. + // Since the purpose of this test is to check regwen function, + // turn off scoreboard to avoid spurious transaction error. + // Also cover csr read, write check in this sequence. + cfg.scb_h.skip_read_check = 1; + cfg.scb_check = 0; + // Write and read back control register + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(ctrl_data) + // Capture for expected data after regwen force '0' + // set op_start to 0 to avoid spurious error + ctrl_data[0] = 0; + exp_data = ctrl_data; + `uvm_info(`gfn, $sformatf("TEST: exp_data: %x", exp_data), UVM_MEDIUM) + write_readback_ctrl(.wr_data(exp_data), .exp_data(exp_data)); + + // Launch long operation + flash_program_data_c.constraint_mode(0); + + // Added to avoid contradiction and to follow the constraint ctrl_num_c in + // flash_ctrl_otf_base_vseq line 95 (at 5/6/2024): + // if (rand_op.partition == FlashPartData) ctrl_num == ctrl_data_num; + ctrl_num = ctrl_data_num; + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL( + rand_op, + rand_op.op == FlashOpProgram; + rand_op.partition == FlashPartData;) + rand_op.addr[8:0] = 0; + rand_op.num_words = 16; + flash_ctrl_start_op(rand_op); + csr_rd(.ptr(ral.control), .value(exp_data)); + + `uvm_info(`gfn, $sformatf("TEST after op start: exp_data: %x", exp_data), UVM_MEDIUM) + repeat (5) begin + // Read back value should not be change + // because regwen is '0' + dumb_data = $urandom(); + write_readback_ctrl(.wr_data(dumb_data), .exp_data(exp_data)); + cfg.clk_rst_vif.wait_clks($urandom_range(0,10)); + end + flash_program_data = '{}; + for (int i = 0; i < 16; i++) begin + flash_program_data.push_back($urandom()); + end + flash_ctrl_write(flash_program_data, 1); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + + rand_op_c.constraint_mode(0); + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(ctrl_data) + ctrl_data[0] = 0; + write_readback_ctrl(.wr_data(ctrl_data), .exp_data(ctrl_data)); + + endtask // body + + task write_readback_ctrl(uvm_reg_data_t wr_data, + uvm_reg_data_t exp_data); + csr_wr(.ptr(ral.control), .value(wr_data)); + csr_rd_check(.ptr(ral.control), .compare_value(exp_data)); + endtask // write_readback_ctrl + +endclass // flash_ctrl_config_regwen_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_connect_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_connect_vseq.sv new file mode 100644 index 0000000000000..786a116399ed4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_connect_vseq.sv @@ -0,0 +1,86 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// misc ports connectivity check +class flash_ctrl_connect_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_connect_vseq) + `uvm_object_new + + task body(); + jtag_pkg::jtag_req_t jtag_src_req, jtag_dst_req; + jtag_pkg::jtag_rsp_t jtag_src_rsp, jtag_dst_rsp; + string dut_path = "tb.dut"; + bit lc_nvm_debug_en; + ast_pkg::ast_obs_ctrl_t obs_src, obs_dst; + bit [7:0] fla_src, fla_dst; + + string mystr; + uvm_hdl_data_t data; + `uvm_info("seq", "connectivity test starts...", UVM_MEDIUM) + + // jtag + `DV_CHECK_STD_RANDOMIZE_FATAL(jtag_src_req) + `DV_CHECK_STD_RANDOMIZE_FATAL(jtag_src_rsp) + `uvm_info("seq", $sformatf("src_req:%p src_rsp:%p", jtag_src_req, jtag_src_rsp), UVM_HIGH) + mystr = {dut_path, ".cio_tck_i"}; + `DV_CHECK(uvm_hdl_force(mystr, jtag_src_req.tck)) + mystr = {dut_path, ".cio_tms_i"}; + `DV_CHECK(uvm_hdl_force(mystr, jtag_src_req.tms)) + mystr = {dut_path, ".cio_tdi_i"}; + `DV_CHECK(uvm_hdl_force(mystr, jtag_src_req.tdi)) + mystr = {cfg.seq_cfg.flash_path_str, ".tdo_o"}; + `DV_CHECK(uvm_hdl_force(mystr, jtag_src_rsp.tdo)) + // tdo_oe : dut.eflash + $assertoff(0, "prim_lc_sync"); + lc_nvm_debug_en = $urandom_range(0, 1); + cfg.flash_ctrl_vif.lc_nvm_debug_en = (lc_nvm_debug_en)? + lc_ctrl_pkg::On : get_rand_lc_tx_val(.t_weight(0), .f_weight(1), .other_weight(4)); + + // takes delay to propagate lc_nvm_debug_en + cfg.clk_rst_vif.wait_clks(5); + mystr = {cfg.seq_cfg.flash_path_str, ".tck_i"}; + `DV_CHECK(uvm_hdl_read(mystr, jtag_dst_req.tck)) + mystr = {cfg.seq_cfg.flash_path_str, ".tms_i"}; + `DV_CHECK(uvm_hdl_read(mystr, jtag_dst_req.tms)) + mystr = {cfg.seq_cfg.flash_path_str, ".tdi_i"}; + `DV_CHECK(uvm_hdl_read(mystr, jtag_dst_req.tdi)) + mystr = {dut_path, ".cio_tdo_o"}; + `DV_CHECK(uvm_hdl_read(mystr, jtag_dst_rsp.tdo)) + + // Make non-declared port don't care. + jtag_dst_req.trst_n = jtag_src_req.trst_n & lc_nvm_debug_en; + jtag_dst_rsp.tdo_oe = jtag_src_rsp.tdo_oe & lc_nvm_debug_en; + + `DV_CHECK_EQ(jtag_dst_req, jtag_src_req & {4{lc_nvm_debug_en}}) + `DV_CHECK_EQ(jtag_dst_rsp, jtag_src_rsp & {2{lc_nvm_debug_en}}) + + `uvm_info("seq", "jtag port check complete", UVM_MEDIUM) + `uvm_info("seq", "Observability port check start", UVM_MEDIUM) + `DV_CHECK_STD_RANDOMIZE_FATAL(obs_src) + `DV_CHECK_STD_RANDOMIZE_FATAL(fla_src) + mystr = {dut_path, ".obs_ctrl_i.obgsl"}; + `DV_CHECK(uvm_hdl_force(mystr, obs_src.obgsl)) + mystr = {dut_path, ".obs_ctrl_i.obmsl"}; + `DV_CHECK(uvm_hdl_force(mystr, obs_src.obmsl)) + mystr = {dut_path, ".obs_ctrl_i.obmen"}; + `DV_CHECK(uvm_hdl_force(mystr, obs_src.obmen)) + mystr = {cfg.seq_cfg.flash_path_str, ".fla_obs_o"}; + `DV_CHECK(uvm_hdl_force(mystr, fla_src)) + + cfg.clk_rst_vif.wait_clks(1); + mystr = {cfg.seq_cfg.flash_path_str, ".obs_ctrl_i.obgsl"}; + `DV_CHECK(uvm_hdl_read(mystr, obs_dst.obgsl)) + mystr = {cfg.seq_cfg.flash_path_str, ".obs_ctrl_i.obmsl"}; + `DV_CHECK(uvm_hdl_read(mystr, data)) + obs_dst.obmsl = ast_pkg::ast_omdl_e'(data); + mystr = {cfg.seq_cfg.flash_path_str, ".obs_ctrl_i.obmen"}; + `DV_CHECK(uvm_hdl_read(mystr, data)) + obs_dst.obmen = mubi4_t'(data); + mystr = {dut_path, ".fla_obs_o"}; + `DV_CHECK(uvm_hdl_read(mystr, fla_dst)) + `DV_CHECK_EQ(obs_dst, obs_src) + `DV_CHECK_EQ(fla_dst, fla_src) + `uvm_info("seq", "Observability port check complete", UVM_MEDIUM) + endtask +endclass // flash_ctrl_connect_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv new file mode 100644 index 0000000000000..24ce30570fcde --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_derr_detect_vseq.sv @@ -0,0 +1,70 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Directed test to detect double bit error. +class flash_ctrl_derr_detect_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_derr_detect_vseq) + `uvm_object_new + + constraint ctrl_info_num_c {ctrl_info_num == ctrl_data_num;} + + virtual task body(); + flash_op_t ctrl; + int num, bank; + uvm_reg_data_t addr0, addr1; + cfg.derr_once = 1; + cfg.scb_h.do_alert_check = 1; + cfg.m_tl_agent_cfg.check_tl_errs = 0; + cfg.m_tl_agent_cfgs["flash_ctrl_eflash_reg_block"].check_tl_errs = 0; + cfg.otf_scb_h.stop = 0; + cfg.clk_rst_vif.wait_clks(5); + + fork begin : isolation_fork + fork + begin + repeat(cfg.otf_num_rw) begin + randcase + cfg.otf_wr_pct:begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + prog_flash(ctrl, bank, num, fractions); + end + 1: begin + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + read_flash(ctrl, bank, num, fractions); + end + endcase + end + end + begin + for (int i = 0; i < cfg.otf_num_hr; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + begin + while (cfg.scb_h.alert_count["fatal_err"] == 0) begin + cfg.clk_rst_vif.wait_clks(1); + end + dut_init(); + end + join_any + disable fork; + end : isolation_fork + join + + // Add drain time + #10us; + if (cfg.derr_count(ReadTaskCtrl) > 0 || cfg.derr_count(ReadTaskHost) > 0) begin + int fatal_cnt = cfg.scb_h.alert_count["fatal_err"]; + `DV_CHECK_NE(fatal_cnt, 0, "fatal alert is not detected", error, "SEQ") + end + `uvm_info("SEQ", $sformatf("seqend derr_created: %p", cfg.derr_created), UVM_LOW) + otf_tb_clean_up(); + endtask : body +endclass : flash_ctrl_derr_detect_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_disable_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_disable_vseq.sv new file mode 100644 index 0000000000000..70b6b926ffcaa --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_disable_vseq.sv @@ -0,0 +1,55 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Test flash access disable feature by +// Global escalation : Set lc_escalate_en to On +// sw command (flash_ctrl.DIS) +class flash_ctrl_disable_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_disable_vseq) + `uvm_object_new + + + virtual task body(); + bit exp_err; + + $assertoff(0, "tb.dut.u_lc_escalation_en_sync"); + send_rand_ops(); + set_flash_disable(exp_err); + + if (exp_err) begin + `uvm_info("SEQ", $sformatf("disable is set"), UVM_MEDIUM) + csr_utils_pkg::wait_no_outstanding_access(); + cfg.m_tl_agent_cfg.check_tl_errs = 0; + end + `uvm_info("SEQ", $sformatf("disable txn start"), UVM_MEDIUM) + // mp error or tlul error expected + + // Wait until disable is set. + cfg.clk_rst_vif.wait_clks(10); + send_rand_ops(1, exp_err); + + `DV_CHECK_EQ(cfg.tlul_core_obs_cnt, cfg.tlul_core_exp_cnt) + endtask // body + + task set_flash_disable(ref bit exp_err); + bit is_disable = 0; + randcase + 1: begin + cfg.flash_ctrl_vif.lc_escalate_en = + get_rand_lc_tx_val(.t_weight(1), .f_weight(1), .other_weight(4)); + is_disable = (cfg.flash_ctrl_vif.lc_escalate_en != lc_ctrl_pkg::Off); + end + 1: begin + mubi4_t dis_val; + dis_val = get_rand_mubi4_val(.t_weight(1), .f_weight(1), .other_weight(4)); + csr_wr(.ptr(ral.dis), .value(dis_val)); + // DIS acts as true if program value is not 4b0xxx or xxx0. + // However, there is additional routine in flash_ctrl_lcmgr makes + // disable flash when dis_val is not mubi_false. + is_disable = (dis_val != prim_mubi_pkg::MuBi4False); + end + endcase // randcase + exp_err = is_disable; + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv new file mode 100644 index 0000000000000..16915a502f128 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_erase_suspend_vseq.sv @@ -0,0 +1,300 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Erase suspend test. Activate Erase suspend in following cases: +// 1. Scenario - Erase is not active +// 2. Scenario - Erase is in progress +class flash_ctrl_erase_suspend_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_erase_suspend_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + // number of transactions + cfg.seq_cfg.max_num_trans = 15; + + // no overlap mp regions + cfg.seq_cfg.allow_mp_region_overlap = 0; + + // enable scramble + cfg.seq_cfg.mp_region_scramble_en_pc = 50; + cfg.seq_cfg.default_region_scramble_en_pc = 50; + + // enable high endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + // randomize memory + cfg.seq_cfg.flash_init_set_pc = 0; + endfunction + + // Flash ctrl operation data queue - used for programing or reading the flash. + data_q_t flash_op_data; + + // Randomized flash ctrl operation. + rand flash_op_t flash_op; + + // Constraint address to be in relevant range for the selected partition. + constraint addr_c { + if (flash_op.partition != FlashPartData) { + flash_op.addr inside + {[0:InfoTypeBytes[flash_op.partition>>1]-1], + [BytesPerBank:BytesPerBank+InfoTypeBytes[flash_op.partition>>1]-1]}; + } + } + + constraint flash_op_c { + flash_op.addr inside {[0 : FlashSizeBytes - 1]}; + flash_op.op == flash_ctrl_pkg::FlashOpErase; + + // Bank erase is supported only for data & 1st info partitions + flash_op.partition != FlashPartData && flash_op.partition != FlashPartInfo -> + flash_op.erase_type == flash_ctrl_pkg::FlashErasePage; + + flash_op.erase_type dist { + flash_ctrl_pkg::FlashErasePage :/ (100 - cfg.seq_cfg.op_erase_type_bank_pc), + flash_ctrl_pkg::FlashEraseBank :/ cfg.seq_cfg.op_erase_type_bank_pc + }; + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + } + + // Bit vector representing which of the mp region cfg CSRs to enable. + rand bit [flash_ctrl_pkg::MpRegions-1:0] en_mp_regions; + + constraint en_mp_regions_c {$countones(en_mp_regions) == cfg.seq_cfg.num_en_mp_regions;} + + // Memory protection regions settings. + rand flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + constraint mp_regions_c { + solve en_mp_regions before mp_regions; + + foreach (mp_regions[i]) { + mp_regions[i].en == mubi4_bool_to_mubi(en_mp_regions[i]); + + mp_regions[i].read_en == MuBi4True; + + mp_regions[i].program_en == MuBi4True; + + mp_regions[i].erase_en == MuBi4True; + + mp_regions[i].scramble_en == MuBi4False; + + mp_regions[i].ecc_en == MuBi4False; + + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + + mp_regions[i].start_page inside {[0 : FlashNumPages - 1]}; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + + // If overlap not allowed, then each configured region is uniquified. + // This creates an ascending order of mp_regions that are configured, so we shuffle it in + // post_randomize. + if (!cfg.seq_cfg.allow_mp_region_overlap) { + foreach (mp_regions[j]) { + if (i != j) { + !mp_regions[i].start_page inside { + [mp_regions[j].start_page:mp_regions[j].start_page + mp_regions[j].num_pages] + }; + } + } + } + } + } + + // Information partitions memory protection pages settings. + rand flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + + foreach (mp_info_pages[i, j]) { + + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + + foreach (mp_info_pages[i][j][k]) { + + mp_info_pages[i][j][k].en == MuBi4True; + + mp_info_pages[i][j][k].read_en == MuBi4True; + + mp_info_pages[i][j][k].program_en == MuBi4True; + + mp_info_pages[i][j][k].erase_en == MuBi4True; + + mp_info_pages[i][j][k].ecc_en == MuBi4False; + + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_he_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_he_en_pc[i][j] + }; + } + } + } + + // Default flash ctrl region settings. + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + rand mubi4_t default_region_scramble_en; + rand mubi4_t default_region_he_en; + mubi4_t default_region_ecc_en; + + constraint default_scramble_he_en_c { + default_region_scramble_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_scramble_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_scramble_en_pc) + }; + } + + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + // Bank erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint bank_erase_en_c { + foreach (bank_erase_en[i]) { + bank_erase_en[i] == 1; + } + } + + data_q_t flash_rd_data; + uvm_reg_data_t data; + + virtual task body(); + repeat (cfg.seq_cfg.max_num_trans) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + reset_flash(); + do_erase(); + // Check that the erase suspended by initiating a read to another page of the flash and make + // sure it completes in a reasonable time relevant for read - cfg.seq_cfg.read_timeout_ns. + check_erase_suspended(); + // Check recovery by initiating an additional erase to the affected page and backdoor + // verify it. + // After an erase is suspended, the page must be erased before any other transaction can be + // initiated to the selected page. + check_recovery(); + end + endtask : body + + virtual task do_erase(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + // Default region settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_ecc_en = MuBi4False; + + // Configure the flash with scramble disable. + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + //Enable Bank erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // 1. Scenario - erase is not active + `uvm_info(`gfn, $sformatf("Scenario 1: Erase is not active"), UVM_HIGH) + + // Read data before writing + csr_rd(.ptr(ral.erase_suspend), .value(data)); + `uvm_info(`gfn, $sformatf("ERASE SUSPEND DATA BEFORE WR: %0p", data), UVM_HIGH) + + // Invoke erase suspend request + csr_wr(.ptr(ral.erase_suspend), .value(1)); + `uvm_info(`gfn, $sformatf("ERASE SUSPEND DATA AFTER WR: %0p", data), UVM_HIGH) + + // value of error suspend request should be imediatelly cleared when + // erase is not in progress + csr_rd_check(.ptr(ral.erase_suspend.req), .compare_value(0)); + + // 2. Scneario - Erase is in progress + `uvm_info(`gfn, $sformatf("Scenario 2: Erase is in progress"), UVM_HIGH) + + `uvm_info(`gfn, $sformatf("FLASH OP ERASE START OP: %0p", flash_op), UVM_HIGH) + flash_ctrl_start_op(flash_op); + + `uvm_info(`gfn, $sformatf("START COUNTING BEFORE ES REQ"), UVM_HIGH) + cfg.clk_rst_vif.wait_clks($urandom_range(50, 100)); + csr_wr(.ptr(ral.erase_suspend), .value(1)); + `uvm_info(`gfn, $sformatf("ERASE SUSPEND REQUESTED"), UVM_HIGH) + + // WAITING THAT ERASE SUSPEND REQ IS DONE AND REQ RETURNED TO ZERO + `DV_SPINWAIT(do begin + csr_rd(.ptr(ral.erase_suspend), .value(data)); + `uvm_info(`gfn, $sformatf("ERASE SUSPEND REQ: %0p", data), UVM_HIGH) + end while (data == 1);, + "ERASE SUSPEND TIMEOUT OCCURED!", cfg.seq_cfg.erase_timeout_ns) + + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_suspend_expected_time_ns)); + + endtask : do_erase + + // Check that the erase suspended by initiating a read to another page of the flash and make + // sure it completes in a reasonable time relevant for read - cfg.seq_cfg.read_timeout_ns. + // If the erase that suspended was bank-erase, make sure to read from the other bank. + task check_erase_suspended(); + flash_op_t flash_op_erase = flash_op; + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(flash_op, + flash_op.partition != flash_op_erase.partition || + flash_op.addr[FlashMemAddrBankMsbBit-:(FlashBankWidth+FlashPageWidth)] != + flash_op_erase.addr[FlashMemAddrBankMsbBit-:(FlashBankWidth+FlashPageWidth)]; + if (flash_op_erase.erase_type == flash_ctrl_pkg::FlashEraseBank) { + flash_op.addr[FlashMemAddrBankMsbBit] != + flash_op_erase.addr[FlashMemAddrBankMsbBit]; + }) + flash_op.op = FlashOpRead; + `uvm_info(`gfn, $sformatf("START READ DIFFERENT PAGE TO CHECK THE ERASE IS SUSPENDED, op: %p", + flash_op), UVM_HIGH) + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, 1'b0); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.read_timeout_ns)); + flash_op = flash_op_erase; + endtask : check_erase_suspended + + // Task to run another erase on the page in which the erase-suspend done and check it complete + // successfully. + // After an erase is suspended, the page must be erased before any other transaction can be + // initiated to the selected page. + task check_recovery(); + // Expected data. + data_q_t exp_data; + + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(flash_op_data, flash_op_data.size() == 0;) + + `uvm_info(`gfn, $sformatf("START ERASE THE SAME PAGE TO CHECK RECOVERY flash_ctrl op: %p", + flash_op), UVM_HIGH) + flash_ctrl_start_op(flash_op); + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); + + endtask : check_recovery + +endclass : flash_ctrl_erase_suspend_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_err_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_err_base_vseq.sv new file mode 100644 index 0000000000000..87119453f98c1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_err_base_vseq.sv @@ -0,0 +1,56 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Base sequence for fault tests +class flash_ctrl_err_base_vseq extends flash_ctrl_rw_vseq; + `uvm_object_utils(flash_ctrl_err_base_vseq) + `uvm_object_new + + task body(); + fork + begin + run_main_event(); + end + begin + run_error_event(); + end + join + clean_up(); + + endtask + + virtual task run_main_event(); + super.body(); + endtask + virtual task run_error_event(); endtask + + task check_fault(input uvm_object ptr, + input uvm_reg_data_t exp_data = 1, + input bit back_door = 0); + `uvm_info(`gfn, "err assert is done", UVM_MEDIUM) + csr_spinwait(.ptr(ptr), .exp_data(exp_data), .backdoor(back_door)); + `uvm_info(`gfn, "csr wait is done is done", UVM_MEDIUM) + endtask + + // After fatal error event, we need to reset dut + // for clean finish. + // This task assert reset and wait for buffer enable comes back. + virtual task clean_up(); + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + apply_reset(); + init_controller(); + endtask // clean_up + + // Call this task from 'run_error_event' if 'run_main_event' cannot be stopped gracefully. + virtual task drain_n_finish_err_event(); + cfg.tlul_core_exp_cnt = cfg.tlul_core_obs_cnt; + cfg.en_scb = 0; + // Give some drain time + cfg.clk_rst_vif.wait_n_clks(100); + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + apply_reset(); + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_mp_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_mp_vseq.sv new file mode 100644 index 0000000000000..76dbfbe770968 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_mp_vseq.sv @@ -0,0 +1,510 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Perform accesses in order to provoke memory permission errors. Test the Software +// interface (Erase, Program, Read). + +// flash_ctrl_error_mp Test + +// Pseudo Code +// Initialize Random Flash MP Regions, Enable All Default Regions +// Loop (x) +// Randomize a Flash Program Operation (any Partition) +// Predict if the selected operation will cause an MP violation, or not +// Set scoreboard to accept alert, if predicted +// Perform selected Flash Operation +// If no violation is expected, check data integrity (via backdoor) +// Check Status Registers +// End + +class flash_ctrl_error_mp_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_error_mp_vseq) + + `uvm_object_new + + // Class Members + bit poll_fifo_status = 1; + uint num_iter; + rand flash_op_t flash_op; + rand data_q_t flash_op_data; + rand uint bank; + uint prog_err_cnt = 0; + uint read_err_cnt = 0; + uint erase_err_cnt = 0; + + // Copies of the MP Region Settings (Data and Info Partitions) + flash_mp_region_cfg_t mp_data_regions[flash_ctrl_pkg::MpRegions]; + flash_bank_mp_info_page_cfg_t + mp_info_regions[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + // Constraint for Bank. + constraint bank_c {bank inside {[0 : flash_ctrl_pkg::NumBanks - 1]};} + + // Constraint for controller address to be in the relevant range for + // the selected partition. + constraint addr_c { + solve bank before flash_op; + flash_op.addr inside {[BytesPerBank * bank : BytesPerBank * (bank + 1)]}; + if (flash_op.partition != FlashPartData) { + flash_op.addr inside + {[0:InfoTypeBytes[flash_op.partition>>1]-1], + [BytesPerBank:BytesPerBank+InfoTypeBytes[flash_op.partition>>1]-1]}; + } + } + + // Constraint for the Flash Operation + constraint flash_op_c { + + // Bank Erase is only supported for Data & 1st Info Partitions + flash_op.partition != FlashPartData && flash_op.partition != FlashPartInfo -> + flash_op.erase_type == flash_ctrl_pkg::FlashErasePage; + + if (cfg.seq_cfg.op_readonly_on_info_partition) { + flash_op.partition == FlashPartInfo -> flash_op.op == flash_ctrl_pkg::FlashOpRead; + } + + if (cfg.seq_cfg.op_readonly_on_info1_partition) { + flash_op.partition == FlashPartInfo1 -> flash_op.op == flash_ctrl_pkg::FlashOpRead; + } + + if (cfg.seq_cfg.op_readonly_on_info2_partition) { + if (flash_op.partition == FlashPartInfo2) {flash_op.op == flash_ctrl_pkg::FlashOpRead;} + } + + flash_op.op inside {flash_ctrl_pkg::FlashOpRead, flash_ctrl_pkg::FlashOpProgram, + flash_ctrl_pkg::FlashOpErase}; + + flash_op.erase_type dist { + flash_ctrl_pkg::FlashErasePage :/ (100 - cfg.seq_cfg.op_erase_type_bank_pc), + flash_ctrl_pkg::FlashEraseBank :/ cfg.seq_cfg.op_erase_type_bank_pc + }; + + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + } + + // Flash ctrl operation data queue - used for programing or reading the flash. + constraint flash_op_data_c { + solve flash_op before flash_op_data; + if (flash_op.op inside {flash_ctrl_pkg::FlashOpRead, flash_ctrl_pkg::FlashOpProgram}) { + flash_op_data.size() == flash_op.num_words; + } else { + flash_op_data.size() == 0; + } + } + + rand flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + constraint mp_regions_c { + + foreach (mp_regions[i]) { + + mp_regions[i].en dist { + MuBi4False := 1, + MuBi4True := 4 + }; + mp_regions[i].program_en dist { + MuBi4False := 4, + MuBi4True := 1 + }; + mp_regions[i].erase_en dist { + MuBi4False := 4, + MuBi4True := 1 + }; + mp_regions[i].read_en dist { + MuBi4False := 4, + MuBi4True := 1 + }; + mp_regions[i].scramble_en == MuBi4False; + mp_regions[i].ecc_en == MuBi4False; + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + + mp_regions[i].start_page inside {[0 : FlashNumPages - 1]}; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + + // If overlap is not allowed, then each configured region is uniquified. + // This creates an ascending order of mp_regions that are configured, so we shuffle it in + // post_randomize. + if (!cfg.seq_cfg.allow_mp_region_overlap) { + foreach (mp_regions[j]) { + if (i != j) { + !(mp_regions[i].start_page inside { + [mp_regions[j].start_page:mp_regions[j].start_page + mp_regions[j].num_pages] + }); + } + } + } + } + } + + // Information partitions memory protection settings. + rand flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + + foreach (mp_info_pages[i, j]) { + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + foreach (mp_info_pages[i][j][k]) { + mp_info_pages[i][j][k].scramble_en == MuBi4False; + mp_info_pages[i][j][k].ecc_en == MuBi4False; + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_he_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_he_en_pc[i][j] + }; + } + } + } + + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + mubi4_t default_region_ecc_en; + mubi4_t default_region_scramble_en; + rand mubi4_t default_region_he_en; + + // Bank Erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint bank_erase_en_c { + foreach (bank_erase_en[i]) { + bank_erase_en[i] == 1; + } + } + + // High Endurance + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + // Configure sequence knobs to tailor it to seq. + virtual function void configure_vseq(); + + // Do no more than 16 words per op (by default) + cfg.seq_cfg.op_max_words = 16; + + // Configure High Endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + // Configure MP Region Enable Prob + cfg.seq_cfg.mp_region_en_pc = 70; + + // Scoreboard knob for blocking host reads + cfg.block_host_rd = 1; + + endfunction : configure_vseq + + // Body + virtual task body(); + + // Local Variables + data_q_t exp_data; + bit exp_alert; + + `uvm_info(`gfn, "TEST : error_mp", UVM_LOW) + + // Enable/Disable Flash Regions + init_flash_regions(); + + // Iteration Loop + num_iter = 200; + for (int iter = 0; iter < num_iter; iter++) begin + `uvm_info(`gfn, $sformatf("Iteration : %0d : %0d", iter+1, num_iter), UVM_LOW) + + // Randomize the Members of the Class + `DV_CHECK_RANDOMIZE_FATAL(this) + + // Model Expected Response + exp_alert = predict_expected_mp_err_rsp(flash_op); + + // Control HW Access to Info Partitions if Selected + control_hw_access(flash_op); + + // Initialise Flash Content + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + if (flash_op.op == flash_ctrl_pkg::FlashOpProgram) begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + end else begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + end + + // Model Expected Response (Error Expected / Pass) + if (exp_alert) set_otf_exp_alert("recov_err"); + + // Do FLASH Operation + case (flash_op.op) + + // ERASE + flash_ctrl_pkg::FlashOpErase : begin + `uvm_info(`gfn, $sformatf("Flash : ERASE exp_alert:%0d", exp_alert), UVM_LOW) + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.clear_op_status(0), .timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + if (exp_alert == MP_PASS) + cfg.flash_mem_bkdr_erase_check(flash_op); + else + erase_err_cnt++; + end + + // PROGRAM + flash_ctrl_pkg::FlashOpProgram : begin + `uvm_info(`gfn, $sformatf("Flash : PROGRAM exp_alert:%0d", exp_alert), UVM_LOW) + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.clear_op_status(0), .timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + if (exp_alert == MP_PASS) + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + else + prog_err_cnt++; + end + + // READ + flash_ctrl_pkg::FlashOpRead : begin + `uvm_info(`gfn, $sformatf("Flash : READ exp_alert:%0d", exp_alert), UVM_LOW) + flash_op_data.delete(); + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(.clear_op_status(0), .timeout_ns(cfg.seq_cfg.read_timeout_ns)); + if (exp_alert == MP_PASS) + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + else + read_err_cnt++; + end + + default : `uvm_fatal(`gfn, "Unrecognized Flash Operation, FAIL") + + endcase + + // Predict Status (for RAL) + ral.err_code.mp_err.predict(exp_alert); + + // Check Alert Status + check_exp_alert_status(exp_alert, "mp_err", flash_op, flash_op_data); + end + + // Final Statistics for Information + display_test_stats(); + endtask : body + + // Task to initialize the Flash Access (Enable All Regions) + virtual task init_flash_regions(); + + // Default Region Settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_scramble_en = MuBi4False; + default_region_ecc_en = MuBi4False; + + // Configure Bank Erasability + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // Copy mp_regions settings, so we only apply one configuration per test. + mp_data_regions = mp_regions; + + // Initialize MP Region Settings + foreach (mp_data_regions[i]) begin + flash_ctrl_mp_region_cfg(i, mp_data_regions[i]); + `uvm_info(`gfn, $sformatf("MP DATA Region [%0d] : %p", i, mp_data_regions[i]), UVM_MEDIUM) + end + + // Initialize Default Regions (other than set above) + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // Initialize Info MP Regions + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO Region [%0d, %0d, %0d] : %p", i, j, k, + mp_info_pages[i][j][k]), UVM_MEDIUM) + end + + // Copy mp_info_pages settings, so we only apply one configuration per test. + mp_info_regions = mp_info_pages; + + endtask : init_flash_regions + + // Predict the expected MP Error Response (Model) + virtual function bit predict_expected_mp_err_rsp(input flash_op_t flash_op); + + // Local Variables + bit rsp; + + /// Flash Operation + `uvm_info(`gfn, $sformatf("Flash Operation : flash_op : %p", flash_op), UVM_MEDIUM) + + unique case (flash_op.partition) + FlashPartData : rsp = do_data_part(flash_op); + FlashPartInfo, FlashPartInfo1, FlashPartInfo2 : rsp = do_info_part(flash_op); + default : `uvm_fatal(`gfn, "Unrecognised Flash Operation, FAIL") + endcase + + // Display Expected Response + if (rsp == MP_PASS) + `uvm_info(`gfn, "Expect : MP_PASS", UVM_INFO) + else + `uvm_info(`gfn, "Expect : MP_VIOLATION", UVM_INFO) + + return (rsp); // Return Status + + endfunction : predict_expected_mp_err_rsp + + virtual function void control_hw_access(flash_op_t flash_op); + lc_tx_t hw_access; + hw_access = (flash_op.partition inside {FlashPartInfo, FlashPartInfo1, FlashPartInfo2}) ? + lc_ctrl_pkg::On : lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = hw_access; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = hw_access; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = hw_access; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = hw_access; + endfunction : control_hw_access + + // Model Flash Data Partition Behaviour + virtual function do_data_part(flash_op_t flash_op); + + // Local Variables + string op_msg; + uint region_start; + uint region_end; + bit [MpRegions-1:0] rsp_vec = (MpRegions)'(MP_PASS); + + display_mp_region_info(); + + // Assign op_msg to Op Type (used below) + unique case (flash_op.op) + flash_ctrl_pkg::FlashOpErase : op_msg = "Erase"; + flash_ctrl_pkg::FlashOpProgram : op_msg = "Program"; + flash_ctrl_pkg::FlashOpRead : op_msg = "Read"; + default : `uvm_fatal(`gfn, "Unrecognised Flash Operation, FAIL") + endcase + + // Look for MP Area Violations + foreach (mp_data_regions[i]) begin + // Start and End Regions for the Flash Operation + region_start = mp_data_regions[i].start_page*(FullPageNumWords*4); + region_end = + (mp_data_regions[i].start_page+mp_data_regions[i].num_pages)*(FullPageNumWords*4); + if (flash_op.addr inside {[region_start : region_end - 1]}) begin + `uvm_info(`gfn, $sformatf("%s : MP Region : Address : HIT : MPR%0d", op_msg, i), + UVM_MEDIUM) + if (mp_data_regions[i].en == MuBi4True) begin + unique case (flash_op.op) + flash_ctrl_pkg::FlashOpErase : begin + // Bank Erase Defeats the MP Settings + if (flash_op.erase_type == flash_ctrl_pkg::FlashEraseBank) + rsp_vec[i] = MP_PASS; + else + rsp_vec[i] = (mp_data_regions[i].erase_en == MuBi4False); + end + flash_ctrl_pkg::FlashOpProgram : rsp_vec[i] = + (mp_data_regions[i].program_en == MuBi4False); + flash_ctrl_pkg::FlashOpRead : rsp_vec[i] = + (mp_data_regions[i].read_en == MuBi4False); + default : `uvm_fatal(`gfn, "Unrecognised Flash Operation, FAIL") + endcase + end else + rsp_vec[i] = MP_PASS; + end else begin + `uvm_info(`gfn, $sformatf("%s : MP Region : Address : MISS : MPR%0d", op_msg, i), + UVM_MEDIUM) + rsp_vec[i] = MP_PASS; + end + end + + return (|(rsp_vec)); + + endfunction : do_data_part + + // Model Flash Info Partition Behaviour + virtual function do_info_part(flash_op_t flash_op); + + // Local Variables + uint info_bank; + uint info_page; + uint info_part; + bit rsp; + + unique case (flash_op.partition) + FlashPartInfo : info_part = 0; + FlashPartInfo1 : info_part = 1; + FlashPartInfo2 : info_part = 2; + default : `uvm_fatal(`gfn, "Unrecognised Info Partition, FAIL") + endcase + + // Info Partition Bank and Page + info_bank = flash_op.addr[19]; + info_page = flash_op.addr[18:11]; + `uvm_info(`gfn, $sformatf("Info Partition Selected : Info%0d", info_part), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("Bank : %0d, Page : %0d", flash_op.addr[19], + flash_op.addr[18:11]), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("MP INFO Regions [%0d, %0d, %0d] : %p", info_bank, info_part, + info_page, mp_info_regions[info_bank][info_part][info_page]), UVM_MEDIUM) + + // Look for MP Area Violations + if (mp_info_regions[info_bank][info_part][info_page].en == MuBi4True) begin + unique case (flash_op.op) + flash_ctrl_pkg::FlashOpErase : begin + // Bank Erase Defeats the MP Settings, Only valid for Info Partition (not Info1 or info2) + if ((info_part == 0) && (flash_op.erase_type == flash_ctrl_pkg::FlashEraseBank)) + rsp = MP_PASS; + else + rsp = (mp_info_regions[info_bank][info_part][info_page].erase_en == MuBi4False); + end + flash_ctrl_pkg::FlashOpProgram : + rsp = (mp_info_regions[info_bank][info_part][info_page].program_en == MuBi4False); + flash_ctrl_pkg::FlashOpRead : + rsp = (mp_info_regions[info_bank][info_part][info_page].read_en == MuBi4False); + default : `uvm_fatal(`gfn, "Unrecognised Flash Operation, FAIL") + endcase + end + else + begin + // Bank Erase Defeats the MP Settings, Only valid for Info Partition (not Info1 or info2) + if ((info_part == 0) && (flash_op.op == flash_ctrl_pkg::FlashOpErase) && + (flash_op.erase_type == flash_ctrl_pkg::FlashEraseBank)) + rsp = MP_PASS; + else + rsp = MP_VIOLATION; + end + + return (rsp); + + endfunction : do_info_part + + virtual function void display_mp_region_info(); + string en_msg; + `uvm_info(`gfn, "MP REGION INFORMATION (DATA PARTITIONS)", UVM_MEDIUM) + foreach (mp_data_regions[i]) begin + en_msg = (mp_data_regions[i].en == MuBi4True) ? "Enabled": "Disabled"; + `uvm_info(`gfn, + $sformatf("MPR%0d : From : 0x%03x, To : 0x%03x : From : 0x%08x, To : 0x%08x, %s", i, + mp_data_regions[i].start_page, mp_data_regions[i].start_page+mp_data_regions[i].num_pages, + mp_data_regions[i].start_page*(FullPageNumWords*4), + (mp_data_regions[i].start_page+mp_data_regions[i].num_pages)*(FullPageNumWords*4), + en_msg), UVM_MEDIUM) + end + endfunction : display_mp_region_info + + // Display Test Statistics, Error/Pass Counts + virtual task display_test_stats(); + uint pass_cnt = num_iter - (prog_err_cnt + read_err_cnt + erase_err_cnt); + `uvm_info(`gfn, "Test Statistics", UVM_LOW) + `uvm_info(`gfn, $sformatf("Program Error : %0d", prog_err_cnt), UVM_LOW) + `uvm_info(`gfn, $sformatf("Read Errors : %0d", read_err_cnt), UVM_LOW) + `uvm_info(`gfn, $sformatf("Erase Errors : %0d", erase_err_cnt), UVM_LOW) + `uvm_info(`gfn, $sformatf("Passes : %0d", pass_cnt), UVM_LOW) + endtask : display_test_stats + +endclass : flash_ctrl_error_mp_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_type_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_type_vseq.sv new file mode 100644 index 0000000000000..e02e67c6b35d1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_type_vseq.sv @@ -0,0 +1,279 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// flash_ctrl_error_prog_type Test + +// Pseudo Code +// Outer Loop (x) +// Initialize +// Choose a random Program Type Scheme (Normal and/or Program Repair) +// Select Scheme via CSR +// Inner Loop (y) +// Randomize a Flash Program Operation (Data Partition) +// Predict whether access will accepted or denied (random prog_sel) +// Do Flash Op +// Check prediction above, Pass/Fail +// End +// Reset DUT +// End + +class flash_ctrl_error_prog_type_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_error_prog_type_vseq) + + `uvm_object_new + + // Class Members + bit poll_fifo_status = 1; + rand flash_op_t flash_op; + rand data_q_t flash_op_data; + rand uint bank; + rand bit [1:0] prog_type_en; + + // Iteration Limits + rand uint x_max; + constraint x_max_c { x_max inside {[8:16]}; } // Outer Loop - Num Schemes + rand uint y_max; + constraint y_max_c { y_max inside {[16:32]}; } // Inner Loop - Num Transactions + + // Constraint for Bank. + constraint bank_c {bank inside {[0 : flash_ctrl_pkg::NumBanks - 1]};} + + // Constraint for controller address to be in relevant range the for the selected partition. + constraint addr_c { + solve bank before flash_op; + flash_op.addr inside {[BytesPerBank * bank : BytesPerBank * (bank + 1)]}; + } + + // Constraint for the Flash Operation + constraint flash_op_c { + flash_op.op == flash_ctrl_pkg::FlashOpProgram; // Only Flash Program Used in this test + flash_op.partition == FlashPartData; // Ony Data Partitions Used in this test + + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + + flash_op.prog_sel inside {FlashProgSelNormal, FlashProgSelRepair}; + } + + // Flash ctrl operation data queue - used for programing in this test + constraint flash_op_data_c { + flash_op_data.size() == flash_op.num_words; + } + + rand flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + constraint mp_regions_c { + + foreach (mp_regions[i]) { + mp_regions[i].en == MuBi4False; + mp_regions[i].read_en == MuBi4True; + mp_regions[i].program_en == MuBi4True; + mp_regions[i].erase_en == MuBi4True; + mp_regions[i].scramble_en == MuBi4False; + mp_regions[i].ecc_en == MuBi4False; + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + + mp_regions[i].start_page inside {[0 : FlashNumPages - 1]}; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + + // If overlap is not allowed, then each configured region is uniquified. + // This creates an ascending order of mp_regions that are configured, so we shuffle it in + // post_randomize. + if (!cfg.seq_cfg.allow_mp_region_overlap) { + foreach (mp_regions[j]) { + if (i != j) { + !(mp_regions[i].start_page inside { + [mp_regions[j].start_page:mp_regions[j].start_page + mp_regions[j].num_pages] + }); + } + } + } + } + } + + // Information partitions memory protection settings. + rand flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + + foreach (mp_info_pages[i, j]) { + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + foreach (mp_info_pages[i][j][k]) { + mp_info_pages[i][j][k].en == MuBi4True; + mp_info_pages[i][j][k].read_en == MuBi4True; + mp_info_pages[i][j][k].program_en == MuBi4True; + mp_info_pages[i][j][k].erase_en == MuBi4True; + mp_info_pages[i][j][k].scramble_en == MuBi4False; + mp_info_pages[i][j][k].ecc_en == MuBi4False; + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_he_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_he_en_pc[i][j] + }; + } + } + } + + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + mubi4_t default_region_scramble_en; + rand mubi4_t default_region_he_en; + rand mubi4_t default_region_ecc_en; + + // Bank Erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint bank_erase_en_c { + foreach (bank_erase_en[i]) { + bank_erase_en[i] == 1; + } + } + + // High Endurance + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + constraint default_region_ecc_en_c {default_region_ecc_en == MuBi4False;} + + // Configure sequence knobs to tailor it to seq. + virtual function void configure_vseq(); + + // Do no more than 16 words per op (by default) + cfg.seq_cfg.op_max_words = 16; + + // Enable NO memory protection regions + cfg.seq_cfg.num_en_mp_regions = 0; + + // Enable High Endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + // MAX Delay for an Expected Alert + cfg.alert_max_delay = cfg.seq_cfg.prog_timeout_ns; + + endfunction : configure_vseq + + // Body + virtual task body(); + + // Local Variables + bit [1:0] prog_type_en; + bit exp_alert; + + `uvm_info(`gfn, "TEST : error_prog_type", UVM_LOW) + + // Outer Loop + for (int x = 0; x < x_max; x++) begin + + // Enable All Regions + init_flash_regions(); + + // Choose a Flash Program Scheme (Normal and/or Program Repair) + prog_type_en = $urandom_range(0, 3); + + csr_wr(.ptr(ral.prog_type_en), .value(prog_type_en)); + csr_rd_check(.ptr(ral.prog_type_en), .compare_vs_ral(1)); + display_prog_scheme(prog_type_en); + + // Inner Loop + for (int y = 0; y < y_max; y++) begin + `uvm_info(`gfn, $sformatf("Iteration : %0d:%0d", x, y), UVM_LOW) + + // Randomize the Members of the Class (Uses Flash Program, and a Data Partition) + `DV_CHECK_RANDOMIZE_FATAL(this) + + // Model Expected Response (Violation Expected / Pass) + exp_alert = predict_expected_err_rsp(prog_type_en, flash_op.prog_sel); + + // Initialise Flash Content + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + + if (exp_alert) set_otf_exp_alert("recov_err"); + // FLASH PROGRAM + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.clear_op_status(0), .timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + `uvm_info(`gfn, $sformatf("Program Data : %0p", flash_op_data), UVM_LOW) + + // Predict Status (for RAL) + ral.err_code.prog_type_err.predict(exp_alert); + + // Check Status + check_exp_alert_status(exp_alert, "prog_type_err", flash_op, flash_op_data); + end + + // RESET DUT + `uvm_info(`gfn, ">>> RESET <<<", UVM_LOW) + apply_reset(); + end + endtask : body + + // Task to initialize the Flash Access (Enable All Regions) + virtual task init_flash_regions(); + + // Default Region Settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_scramble_en = MuBi4False; + + // Enable Bank Erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // Initialize MP Regions + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + // Initialize Default Regions + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // Initialize Info MP Regions + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + + endtask : init_flash_regions + + // Display The Chosen Program Scheme + virtual function void display_prog_scheme(input bit [1:0] prog_type_en); + string flash_program_scheme; + unique case (prog_type_en) + 2'b00 : flash_program_scheme = "NO SCHEME"; + 2'b01 : flash_program_scheme = "NORMAL"; + 2'b10 : flash_program_scheme = "REPAIR"; + 2'b11 : flash_program_scheme = "NORMAL and REPAIR"; + default : `uvm_fatal(`gfn, "Unrecognised Flash Program Scheme") + endcase + `uvm_info(`gfn, $sformatf("FLASH PROGRAM SCHEME : %s", flash_program_scheme), UVM_LOW) + endfunction : display_prog_scheme + + // Predict the expected Pass/Error Response (Model) + virtual function bit predict_expected_err_rsp(input bit [1:0] prog_type_en, input bit prog_sel); + bit rsp; + string rsp_str; + rsp = ~prog_type_en[prog_sel]; + rsp_str = rsp ? "MP_VIOLATION" : "MP_PASS"; + `uvm_info(`gfn, $sformatf("prog_type : %02b, prog_sel : %0b : Expect : %s", prog_type_en, + prog_sel, rsp_str), UVM_LOW) + return (rsp); + endfunction : predict_expected_err_rsp + +endclass : flash_ctrl_error_prog_type_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_win_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_win_vseq.sv new file mode 100644 index 0000000000000..25384997ace2f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_error_prog_win_vseq.sv @@ -0,0 +1,159 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// flash_ctrl_error_prog_win Test + +// Pseudo Code +// Loop (x) +// Initialize +// Choose whether to violate a programming window, or not +// Randomize a Flash Program Operation (Data Partition) +// If a violation is selected, adjust Flash Op to give a window violation +// else, leave it as it was correctly randomized +// Do Flash Op +// Model expected response +// Check prediction above, Pass/Fail +// End + +class flash_ctrl_error_prog_win_vseq extends flash_ctrl_fetch_code_vseq; + `uvm_object_utils(flash_ctrl_error_prog_win_vseq) + + `uvm_object_new + + // Class Members + rand bit exp_alert; + rand uint extended_num_words; + rand data_q_t extended_data; + + // Iteration Limits + rand uint x_max; + constraint x_max_c { x_max inside {[64:256]}; } // Loop - Num Iterations + + // Expect Alert Violation + constraint exp_alert_c { exp_alert dist {MP_PASS:=3, MP_VIOLATION:=1}; } + + // Extended Num Words (for the Violation Case) + constraint extended_num_words_c { extended_num_words + inside {[cfg.seq_cfg.op_max_words+1:cfg.seq_cfg.op_max_words+32]}; } + + // Extended Data Words (for the Violation case) + constraint extended_data_c { + solve extended_num_words before extended_data; + extended_data.size() == extended_num_words; + } + + // Constraint for the Flash Operation + constraint flash_op_c { + + flash_op.op == flash_ctrl_pkg::FlashOpProgram; // Only Flash Program Used in this test + flash_op.partition == FlashPartData; // Ony Data Partitions Used in this test + + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + + flash_op.prog_sel inside {FlashProgSelNormal, FlashProgSelRepair}; + } + + // Configure sequence knobs to tailor it to seq. + virtual function void configure_vseq(); + + // Do no more than 16 words per op (by default) + cfg.seq_cfg.op_max_words = 16; + + // Enable NO memory protection regions + cfg.seq_cfg.num_en_mp_regions = 0; + + // Enable High Endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + endfunction : configure_vseq + + // Body + virtual task body(); + + // Local Variables + flash_op_t flash_op_prog_win; + data_q_t flash_op_data_prog_win; + string alert_str; + + `uvm_info(`gfn, "TEST : error_prog_win", UVM_LOW) + + // Loop + for (int x = 0; x < x_max; x++) begin + + // Enable All Regions + init_flash_regions(); + + // Randomize Class (flash_op uses Flash Program, and a Data Partition) + `DV_CHECK_RANDOMIZE_FATAL(this) + + `uvm_info(`gfn, $sformatf("extended_num_words : %0d", extended_num_words), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("extended_data : %p ", extended_data), UVM_MEDIUM) + + // Display Alert Chosen + alert_str = exp_alert ? "MP_VIOLATION" : "MP_PASS"; + `uvm_info(`gfn, $sformatf("Expect Alert : %s", alert_str), UVM_LOW) + + // Choose given Flash Op, or Extend Program Window + flash_op_prog_win = flash_op; // Copy Op + if (exp_alert == MP_PASS) // Normal Window - PASS + flash_op_data_prog_win = flash_op_data; // Copy Data + else begin // Extended Program Window - VIOLATION + flash_op_prog_win.num_words = extended_num_words; // Extended Window + flash_op_data_prog_win = extended_data; + `uvm_info(`gfn, $sformatf("--> flash_op_data_prog_win : %p", + flash_op_data_prog_win), UVM_MEDIUM) + end + + // Initialise Flash Content + cfg.flash_mem_bkdr_init(flash_op_prog_win.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op_prog_win), .scheme(FlashMemInitSet)); + + // Model Expected Response (Error Expected / Pass) + if (exp_alert) set_otf_exp_alert("recov_err"); + + // FLASH PROGRAM + flash_ctrl_start_op(flash_op_prog_win); + flash_ctrl_write(flash_op_data_prog_win, poll_fifo_status); + wait_flash_op_done(.clear_op_status(0), .timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + `uvm_info(`gfn, $sformatf("Program Data : %0p", flash_op_data_prog_win), UVM_MEDIUM) + + // Predict Alert Status (for RAL) + ral.err_code.prog_win_err.predict(exp_alert); + + // Check Alert Status + check_exp_alert_status(exp_alert, "prog_win_err", flash_op, flash_op_data); + + end + + endtask : body + + // Task to initialize the Flash Access (Enable All Regions) + virtual task init_flash_regions(); + // Enable Bank Erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // Initialize MP Regions + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + // Initialize Default Regions + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // Initialize Info MP Regions + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + + endtask : init_flash_regions + +endclass : flash_ctrl_error_prog_win_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv new file mode 100644 index 0000000000000..5e57da5b6580f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_fetch_code_vseq.sv @@ -0,0 +1,345 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// flash_ctrl_fetch_code Test + +// Pseudo Code +// Initialise (All) +// Loop { 32 .. 64 +// Randomize (Read Cycle, Data Partition, Exec Key, Instruction Type) +// Model and Verify Expected Functionality +// Do Flash Read, expect code access Allowed/Denied +// Uses Modeling in the Scorboard to expect TLUL Error when denied +// Checks Data via Frontdoor/Backdoor and Equal to Zero as required +// } +// +// exec_key==CODE_EXEC_KEY, instr_type=MuBi4False - Allowed, Data Match, No TL Error - Data Access +// exec_key==CODE_EXEC_KEY, instr_type=MuBi4True - Allowed, Data Match, No TL Error - Code Access +// exec_key!=CODE_EXEC_KEY, instr_type=MuBi4False - Allowed, Data Match, No TL Error - Data Access +// exec_key!=CODE_EXEC_KEY, instr_type=MuBi4True - Denied, Data 0, TL Error - Code Access +// x (Don't care) , instr_type=None - Denied, TL Error + + +class flash_ctrl_fetch_code_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_fetch_code_vseq) + + `uvm_object_new + + // Code Allowed/Denied Flags + typedef enum bit [1:0] { + CODE_FETCH_ALLOWED, + CODE_FETCH_DENIED, + CODE_FETCH_ERR + } code_fetch_type_e; + + // Class Members + bit poll_fifo_status = 1; + rand data_q_t flash_op_data; + rand flash_op_t flash_op; + rand uint bank; + rand mubi4_t instr_type; + rand bit [CODE_EXEC_KEY_W-1:0] exec_key; + + constraint exec_key_c { + exec_key dist { + [32'h00000000 : 32'hFFFFFFFF] :/ 2, // All Keys except CODE_EXEC_KEY Deny Code Access + CODE_EXEC_KEY :/ 1 // CODE_EXEC_KEY Correct 1 in 3, otherwise too Random + }; + } + + constraint bank_c {bank inside {[0 : flash_ctrl_pkg::NumBanks - 1]};} + + // Constraint for controller address to be in relevant range for the selected partition. + constraint addr_c { + solve bank before flash_op; + flash_op.addr inside {[BytesPerBank * bank : BytesPerBank * (bank + 1)]}; + if (flash_op.partition != FlashPartData) { + flash_op.addr inside + {[0:InfoTypeBytes[flash_op.partition>>1]-1], + [BytesPerBank:BytesPerBank+InfoTypeBytes[flash_op.partition>>1]-1]}; + } + } + + constraint flash_op_c { + // Bank Erase is only supported for Data & 1st Info Partitions + flash_op.partition != FlashPartData && flash_op.partition != FlashPartInfo -> + flash_op.erase_type == flash_ctrl_pkg::FlashErasePage; + + if (cfg.seq_cfg.op_readonly_on_info_partition) { + flash_op.partition == FlashPartInfo -> flash_op.op == flash_ctrl_pkg::FlashOpRead; + } + + if (cfg.seq_cfg.op_readonly_on_info1_partition) { + flash_op.partition == FlashPartInfo1 -> flash_op.op == flash_ctrl_pkg::FlashOpRead; + } + + if (flash_op.partition == FlashPartInfo2) {flash_op.op == flash_ctrl_pkg::FlashOpRead;} + + flash_op.op inside {flash_ctrl_pkg::FlashOpRead, flash_ctrl_pkg::FlashOpProgram, + flash_ctrl_pkg::FlashOpErase}; + + flash_op.erase_type dist { + flash_ctrl_pkg::FlashErasePage :/ (100 - cfg.seq_cfg.op_erase_type_bank_pc), + flash_ctrl_pkg::FlashEraseBank :/ cfg.seq_cfg.op_erase_type_bank_pc + }; + + flash_op.num_words >= 10; + flash_op.num_words <= (FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]); + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < (FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]); + } + + // Flash ctrl operation data queue - used for programing or reading the flash. + constraint flash_op_data_c { + solve flash_op before flash_op_data; + if (flash_op.op inside {flash_ctrl_pkg::FlashOpRead, flash_ctrl_pkg::FlashOpProgram}) { + flash_op_data.size() == flash_op.num_words; + } else { + flash_op_data.size() == 0; + } + } + + // Bit vector representing which of the mp region cfg CSRs to enable. + rand bit [flash_ctrl_pkg::MpRegions-1:0] en_mp_regions; + + // Memory Protection Regions + constraint en_mp_regions_c {$countones(en_mp_regions) == cfg.seq_cfg.num_en_mp_regions;} + + rand flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + constraint mp_regions_c { + solve en_mp_regions before mp_regions; + + foreach (mp_regions[i]) { + mp_regions[i].en == mubi4_bool_to_mubi(en_mp_regions[i]); + mp_regions[i].read_en == MuBi4True; + mp_regions[i].program_en == MuBi4True; + mp_regions[i].erase_en == MuBi4True; + mp_regions[i].scramble_en == MuBi4False; + mp_regions[i].ecc_en == MuBi4False; + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + + mp_regions[i].start_page inside {[0 : FlashNumPages - 1]}; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + + // If overlap is not allowed, then each configured region is uniquified. + if (!cfg.seq_cfg.allow_mp_region_overlap) { + foreach (mp_regions[j]) { + if (i != j) { + !mp_regions[i].start_page inside { + [mp_regions[j].start_page:mp_regions[j].start_page + mp_regions[j].num_pages] + }; + } + } + } + } + } + + // Information partitions memory protection settings. + rand flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + + foreach (mp_info_pages[i, j]) { + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + foreach (mp_info_pages[i][j][k]) { + mp_info_pages[i][j][k].en == MuBi4True; + mp_info_pages[i][j][k].read_en == MuBi4True; + mp_info_pages[i][j][k].program_en == MuBi4True; + mp_info_pages[i][j][k].erase_en == MuBi4True; + mp_info_pages[i][j][k].scramble_en == MuBi4False; + mp_info_pages[i][j][k].ecc_en == MuBi4False; + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_he_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_he_en_pc[i][j] + }; + } + } + } + + // Default region values + mubi4_t default_region_read_en = MuBi4True; + mubi4_t default_region_program_en = MuBi4True; + mubi4_t default_region_erase_en = MuBi4True; + mubi4_t default_region_scramble_en = MuBi4False; + rand mubi4_t default_region_he_en; + mubi4_t default_region_ecc_en = MuBi4False; + + // Bank Erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint bank_erase_en_c { + foreach (bank_erase_en[i]) { + bank_erase_en[i] == 1; + } + } + + // High Endurance + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + + // Do no more than 16 words per op. + cfg.seq_cfg.op_max_words = 16; + + // Enable NO memory protection regions + cfg.seq_cfg.num_en_mp_regions = 0; + + // Enable High Endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + endfunction : configure_vseq + + // Body + virtual task body(); + + // Local Variables + string msg; + uint num_trans; + + `uvm_info(`gfn, $sformatf("FETCH CODE TEST"), UVM_LOW) + + // Scoreboard knob for Blocking Read Data Checking + // Checks performed in this test + cfg.block_host_rd = 0; + + // Iterate + num_trans = $urandom_range(32, 64); + + for (int i = 0; i < num_trans; i++) begin + + `uvm_info(`gfn, $sformatf("Iteration : %0d / %0d", i + 1, num_trans), UVM_LOW) + + // Enable All Regions + init_flash_regions(); + + // Randomize the Members of the Class (Use Flash Read, and a Data Partition) + `DV_CHECK_RANDOMIZE_WITH_FATAL(this, flash_op.op == FlashOpRead; + flash_op.partition == FlashPartData;) + instr_type = get_rand_mubi4_val(.t_weight(2), + .f_weight(2), + .other_weight(1)); + + `uvm_info(`gfn, $sformatf( + "Flash Op : Bank: %0d, flash_op: %0p, flash_op_data: %0p, EXEC Key: 0x%0x, instr_type: %s", + bank, flash_op, flash_op_data, exec_key, instr_type.name()), UVM_LOW) + + // Note: 'exec_key' and 'instr_type' are randomised with the rest of the class + + // Write Randomly Selected Code Execution Key + csr_wr(.ptr(ral.exec), .value(exec_key)); + + // EXEC Key Value + msg = (exec_key == CODE_EXEC_KEY) ? "(KEY MATCH)" : ""; + `uvm_info(`gfn, $sformatf("Set: FLASH_CTRL.EXEC: Fetch Code Key : 0x%08x %s", exec_key, msg), + UVM_LOW) + + // Instruction Type : MuBi4False - Data, MuBi4True - Code + if (instr_type == MuBi4False) msg = "Data"; + else msg = "Code"; + `uvm_info(`gfn, $sformatf("Code Fetch Type : %s (%s)", instr_type.name(), msg), UVM_LOW) + + // Model Expected Functionality + if (exec_key == CODE_EXEC_KEY && + instr_type inside {MuBi4True, MuBi4False}) begin + check_code_access(CODE_FETCH_ALLOWED); + end else begin + unique case (instr_type) + MuBi4False: check_code_access(CODE_FETCH_ALLOWED); + MuBi4True: check_code_access(CODE_FETCH_DENIED); + default: check_code_access(CODE_FETCH_ERR); + endcase + end + + end + endtask : body + + // Task to initialize the Flash Access (Enable All Regions) + virtual task init_flash_regions(); + + // Enable Bank Erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // Initialize MP Regions + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + // Initialize Default Regions + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // Initialize Info MP Regions + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + + endtask : init_flash_regions + + // Task to Check Code Access + virtual task check_code_access(code_fetch_type_e opt); + bit comp, exp_err; + // Local Variables + addr_t read_addr; + data_t rdata; + data_t rdata_unused; + + // Note : opt 'CODE_FETCH_ALLOWED' - Access Allowed, 'CODE_FETCH_DENIED' - Access Denied + exp_err = (opt != CODE_FETCH_ALLOWED); + + // Delete Data Queues + flash_op_data.delete(); + cfg.flash_rd_data.delete(); + + // Read Selected Data Block via SW Access (Frontdoor) and Store + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + + // Read from Memory Interface (Direct Read) + for (int i = 0; i < flash_op.num_words; i++) begin + read_addr = flash_op.addr + 4 * i; + // Note: rdata is omitted, as it cannot be directly compared with Backdoor reads + do_direct_read(.addr(read_addr), .mask('1), .blocking(cfg.block_host_rd), .check_rdata(0), + .instr_type(instr_type), .rdata(rdata_unused), .exp_err_rsp(exp_err), + .completed(comp)); + cfg.clk_rst_vif.wait_clks($urandom_range(1, 10)); + end + csr_utils_pkg::wait_no_outstanding_access(); + + // Check SW Read Data vs Host Direct Read Data (stored in cfg.flash_rd_data) + foreach (flash_op_data[i]) begin + if (opt == CODE_FETCH_ALLOWED) begin // Expect Data to Match + rdata = cfg.flash_rd_data.pop_front(); + `DV_CHECK_EQ(rdata, flash_op_data[i]) + end else if (opt == CODE_FETCH_ERR) begin + `DV_CHECK_NE(rdata, flash_op_data[i]) + end else begin // Expect Data to Read Zero + `DV_CHECK_EQ(rdata, '0) + end + + `uvm_info(`gfn, $sformatf( + "Flash SW Read Data: 0x%0h, Flash Direct Read Data: 0x%0h", flash_op_data[i], rdata + ), UVM_LOW) + end + + endtask : check_code_access + +endclass : flash_ctrl_fetch_code_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv new file mode 100644 index 0000000000000..02d57f6167b80 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_filesystem_support_vseq.sv @@ -0,0 +1,277 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Write and readback test. If write location is not erased, write 0's +// to mimic generic filesystem behavior. +class flash_ctrl_filesystem_support_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_filesystem_support_vseq) + `uvm_object_new + + typedef bit [BusBankAddrW-1:0] mem_addr_q_t[$]; + + // Written memory address ( flash_op.addr[19:3]) + bit written_addr[bit[BusBankAddrW-1:0]]; + flash_op_t wr_ent_q[$]; + flash_op_t pre_wr_ent_q[$]; + flash_op_t my_op; + data_q_t readback_data[flash_op_t]; + flash_op_t check_ent_q[$]; + mem_addr_q_t addr_q; + + constraint ctrl_num_c {ctrl_num == 1;} + + virtual task body(); + int round; + + // Don't select a partition defined as read-only + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + cfg.seq_cfg.avoid_prog_res_fault = 1'b1; + + special_info_acc_c.constraint_mode(0); + flash_program_data_c.constraint_mode(0); + + // Disable scramble, enable ECC + flash_otf_region_cfg(.scr_mode(OTFCfgFalse), .ecc_mode(OTFCfgTrue)); + + // Initial write to empty locations. + repeat (100) begin + int num; + int bank; + `DV_CHECK(try_create_prog_op(my_op, bank, num), "Could not create a prog flash op") + addr_q = {addr_q, generate_all_addr(my_op)}; + wr_ent_q.push_back(my_op); + pre_wr_ent_q.push_back(my_op); + prog_flash(.flash_op(my_op), .bank(bank), .num(num), .wd(fractions), .store_prog_data(1)); + `uvm_info(`gfn, $sformatf("round:%0d ent:%p addr:size:%0d %p", round++, my_op, + addr_q.size(), addr_q), UVM_HIGH) + end + + `uvm_info(`gfn, $sformatf("readback check stage 1"), UVM_HIGH) + // Readback check; + pre_wr_ent_q.shuffle(); + foreach(pre_wr_ent_q[i]) begin + filesys_read_check(.flash_op_r(pre_wr_ent_q[i]), .use_cfg_rdata(1)); + end + + `uvm_info(`gfn, $sformatf("readback check stage 2 with 1bit error"), UVM_HIGH) + // Readback check with 1 bit error + pre_wr_ent_q.shuffle(); + foreach(pre_wr_ent_q[i]) begin + filesys_read_check(.flash_op_r(pre_wr_ent_q[i]), .use_cfg_rdata(1), .serr(1)); + end + + wr_ent_q.shuffle(); + round = 0; + + // Mimicking file system behavior here. + // If locations are from 'wr_ent_q', write all zeros. + // Otherwise write random data. + repeat (20) begin + `uvm_info(`gfn, $sformatf("TEST: round:%0d", round++), UVM_MEDIUM) + randcase + 2: begin + my_op = wr_ent_q.pop_front(); + filesys_ctrl_prgm(.flash_op_p(my_op), .all_zero(1), + .wdata(readback_data[my_op])); + end + 1: begin + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(rand_op, + rand_op.op == FlashOpProgram;) + // make sure all address are 8 byte aligned. + rand_op.addr[2:0] = 'h0; + rand_op.otf_addr[2:0] = 'h0; + + if (rand_op.num_words % 2) rand_op.num_words++; + my_op = rand_op; + if (is_secret_part(my_op)) continue; + + filesys_ctrl_prgm(.flash_op_p(my_op), .all_zero(0), + .wdata(readback_data[my_op])); + end + endcase + check_ent_q.push_back(my_op); + end + + `uvm_info(`gfn, $sformatf("readback check stage 3"), UVM_HIGH) + // Readback check; + foreach(check_ent_q[op]) begin + filesys_read_check(.flash_op_r(check_ent_q[op])); + end + + `uvm_info(`gfn, $sformatf("readback check stage 4 with 1 bit error"), UVM_HIGH) + // Readback check with 1 bit error + foreach(check_ent_q[op]) begin + filesys_read_check(.flash_op_r(check_ent_q[op]), .serr(1)); + end + + endtask + + // Helper task to issue a flash program op. + local task issue_flash_prog(flash_op_t op, data_q_t data); + bit poll_fifo_status = 1; + `uvm_info(`gfn, "Issuing flash write op:", UVM_MEDIUM) + flash_ctrl_start_op(op); + flash_ctrl_write(data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + endtask + + // Program flash. + // Program all 0 or random data depends on 'all_zero' value. + // If program address is in global 'addr_q', program all zero + // to the address. + // After program, store write data for readback check. + task filesys_ctrl_prgm(flash_op_t flash_op_p, bit all_zero, output data_q_t wdata); + bit [BusBankAddrW-1:0] mem_addr = (flash_op_p.addr >> 3); + bit ovwr_zero = 0; + + flash_op_p.op = FlashOpProgram; + `uvm_info(`gfn, $sformatf("PROGRAM ADDRESS: 0x%0h flash_op:%p is_secret:%b", + flash_op_p.addr, flash_op_p, is_secret_part(flash_op_p)), UVM_MEDIUM) + // Randomize Write Data + for (int j = 0; j < flash_op_p.num_words; j++) begin + if (j % 2 == 0) begin + foreach (addr_q[i]) begin + if (mem_addr == addr_q[i]) begin + ovwr_zero = 1; + break; + end + end + end + + flash_program_data[j] = (all_zero | ovwr_zero)? 'h0 : $urandom(); + wdata.push_back(flash_program_data[j]); + if (j % 2 == 1) begin + ovwr_zero = 0; + mem_addr++; + end + end + // If the op spills over a program window, break it into two. + if (in_different_prog_win(flash_op_p.addr, + flash_op_p.addr + 4 * flash_op_p.num_words - 1)) begin + flash_op_t first_op, second_op; + addr_t split_addr = round_to_prog_resolution(flash_op_p.addr + 4 * flash_op_p.num_words - 1); + `DV_CHECK_LE(flash_op_p.num_words, 16) + first_op = flash_op_p; + first_op.num_words = (split_addr - flash_op_p.addr) / 4; + print_flash_op(flash_op_p, UVM_MEDIUM); + `uvm_info(`gfn, $sformatf( + "splitting at addr:%x, first wd:%x", split_addr, first_op.num_words), UVM_MEDIUM) + issue_flash_prog(first_op, flash_program_data[0:first_op.num_words-1]); + second_op = flash_op_p; + second_op.addr = split_addr; + second_op.otf_addr = split_addr; + second_op.num_words = flash_op_p.num_words - first_op.num_words; + issue_flash_prog(second_op, flash_program_data[first_op.num_words:flash_op_p.num_words - 1]); + end else begin + issue_flash_prog(flash_op_p, flash_program_data); + end + endtask : filesys_ctrl_prgm + + // Read data either from host or controller, and compare with + // readback_data[flash_op_t]. + task filesys_read_check(flash_op_t flash_op_r, bit use_cfg_rdata = 0, bit serr = 0); + data_q_t read_data, ref_data; + flash_op_r.op = FlashOpRead; + `uvm_info("read_check", $sformatf("%p", flash_op_r), UVM_MEDIUM) + if (flash_op_r.partition == FlashPartData) begin + randcase + 1: begin + `uvm_info(`gfn, "send ctrl_read", UVM_MEDIUM) + filesys_ctrl_read(flash_op_r, read_data, serr); + end + 1: begin + `uvm_info(`gfn, "send host_read", UVM_MEDIUM) + filesys_host_read(flash_op_r, read_data, serr); + end + endcase // randcase + end else begin // if (flash_op_r.partition == FlashPartData) + `uvm_info(`gfn, "send ctrl_read", UVM_MEDIUM) + filesys_ctrl_read(flash_op_r, read_data, serr); + end + + ref_data = (use_cfg_rdata)? cfg.prog_data[flash_op_r] : readback_data[flash_op_r]; + for (int i = 0; i < ref_data.size(); i++) begin + `DV_CHECK_EQ(read_data[i], ref_data[i], + $sformatf("read_check:%0d ", i)) + end + endtask : filesys_read_check + + // All addresses are 8byte aligned. + task filesys_ctrl_read(flash_op_t flash_op_r, output data_q_t rdata, input bit serr); + bit poll_fifo_status = 1; + int size; + flash_op_r.op = FlashOpRead; + `uvm_info(`gfn, $sformatf("filesys_ctrl_read: flash_op:%p is_secret:%b", + flash_op_r, is_secret_part(flash_op_r)), UVM_MEDIUM) + + rdata = '{}; + size = flash_op_r.num_words / 2; + if (serr) begin + filesystem_add_bit_err(flash_op_r.partition, flash_op_r.addr, ReadTaskCtrl, size); + end + flash_ctrl_start_op(flash_op_r); + flash_ctrl_read(flash_op_r.num_words, rdata, poll_fifo_status); + wait_flash_op_done(); + endtask : filesys_ctrl_read + + task filesys_host_read(flash_op_t flash_op_r, output data_q_t rdata, input bit serr); + bit [TL_AW-1:0] tl_addr; + bit completed; + data_4s_t unit_rdata; + tl_addr = flash_op_r.addr; + rdata = '{}; + + for (int i = 0; i < flash_op_r.num_words; i++) begin + if (serr & (i % 2 == 0)) begin + filesystem_add_bit_err(flash_op_r.partition, tl_addr, ReadTaskHost, 1); + end + do_direct_read(.addr(tl_addr), .mask('1), .blocking(1), .rdata(unit_rdata), + .completed(completed)); + rdata.push_back(unit_rdata); + tl_addr += 4; + end + endtask : filesys_host_read + + // Create all addresses for the flash_op from the start address + // in the resolution of 8 bytes + function mem_addr_q_t generate_all_addr(flash_op_t flash_op); + // For odd numbers, add one more address. + int addr_end = (flash_op.num_words + 1) / 2; + for (int i = 0; i < addr_end; i++) begin + generate_all_addr.push_back((flash_op.addr >> 3)); + flash_op.addr += 8; + end + endfunction : generate_all_addr + + function void filesystem_add_bit_err(flash_dv_part_e partition, addr_t addr, read_task_e caller, + int size); + int err_idx, bank; + addr_t per_bank_addr; + bit [flash_phy_pkg::FullDataWidth-1:0] mem_data; + + bank = addr[OTFBankId]; + for (int i = 0; i < size; i++) begin + per_bank_addr = addr; + per_bank_addr[31:OTFBankId] = 'h0; + + if (!cfg.address_has_serr(addr, partition)) begin + err_idx = $urandom_range(0, 75); + cfg.add_serr(addr, partition, caller, err_idx); + cfg.flash_bit_flip(cfg.mem_bkdr_util_h[partition][bank], per_bank_addr, err_idx); + // Flip the same bit in the reference mem model. + if (partition == FlashPartData) begin + mem_data = cfg.otf_scb_h.data_mem[bank][per_bank_addr>>3]; + mem_data[err_idx] = ~mem_data[err_idx]; + cfg.otf_scb_h.data_mem[bank][per_bank_addr>>3] = mem_data; + end else begin + mem_data = cfg.otf_scb_h.info_mem[bank][partition>>1][per_bank_addr>>3]; + mem_data[err_idx] = ~mem_data[err_idx]; + cfg.otf_scb_h.info_mem[bank][partition>>1][per_bank_addr>>3] = mem_data; + end + end + addr += 8; + end + endfunction : filesystem_add_bit_err + +endclass : flash_ctrl_filesystem_support_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_full_mem_access_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_full_mem_access_vseq.sv new file mode 100644 index 0000000000000..a4feb20992894 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_full_mem_access_vseq.sv @@ -0,0 +1,199 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Full memory access test. First flash is first programmed and than read back +// by controller. Second direct reads are invoked. +class flash_ctrl_full_mem_access_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_full_mem_access_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + + // enable high endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + endfunction + + rand flash_op_t flash_op; + rand bit selected_bank; + addr_t bank_start_addr; + + // Memory protection regions settings. + flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + // Information partitions memory protection pages settings. + rand flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + foreach (mp_info_pages[i, j]) { + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + foreach (mp_info_pages[i][j][k]) { + mp_info_pages[i][j][k].en == MuBi4True; + mp_info_pages[i][j][k].read_en == MuBi4True; + mp_info_pages[i][j][k].program_en == MuBi4True; + mp_info_pages[i][j][k].erase_en == MuBi4True; + mp_info_pages[i][j][k].scramble_en == MuBi4False; + mp_info_pages[i][j][k].ecc_en == MuBi4False; + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + } + } + } + + // Default flash ctrl region settings. + rand mubi4_t default_region_read_en; + rand mubi4_t default_region_program_en; + rand mubi4_t default_region_erase_en; + rand mubi4_t default_region_he_en; + mubi4_t default_region_scramble_en; + mubi4_t default_region_ecc_en; + + // Bank erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + virtual task body(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + cfg.scb_check = 1; + + `DV_CHECK_RANDOMIZE_FATAL(this) + bank_start_addr = selected_bank * BytesPerBank; + `uvm_info(`gfn, $sformatf("SW PROGRAM AND READ DATA FROM BANK %0d", selected_bank), UVM_LOW) + do_sw_rw(); + `uvm_info(`gfn, $sformatf("DIRECT READ DATA FROM BANK %0d", selected_bank), UVM_LOW) + do_direct_rd(); + + endtask : body + + virtual task do_sw_rw(); + flash_op_t flash_op_sw_rw; + // Default region settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_ecc_en = MuBi4False; + default_region_scramble_en = MuBi4False; + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // No Protection + foreach (mp_regions[i]) begin + mp_regions[i].en = MuBi4False; + end + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + //Enable Bank erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + flash_op_sw_rw.partition = FlashPartData; + flash_op_sw_rw.erase_type = flash_ctrl_pkg::FlashEraseBank; + flash_op_sw_rw.op = flash_ctrl_pkg::FlashOpProgram; + flash_op_sw_rw.num_words = 16; + flash_op_sw_rw.addr = bank_start_addr; + + `uvm_info(`gfn, $sformatf("PROGRAM DATA PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_DATA; i++) begin + controller_program_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + + flash_op_sw_rw.partition = FlashPartInfo; + flash_op_sw_rw.addr = bank_start_addr; + `uvm_info(`gfn, $sformatf("PROGRAM INFO PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_INFO0; i++) begin + controller_program_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + + flash_op_sw_rw.partition = FlashPartInfo1; + flash_op_sw_rw.addr = bank_start_addr; + `uvm_info(`gfn, $sformatf("PROGRAM INFO1 PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_INFO1; i++) begin + controller_program_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + + flash_op_sw_rw.partition = FlashPartInfo2; + flash_op_sw_rw.addr = bank_start_addr; + `uvm_info(`gfn, $sformatf("PROGRAM INFO2 PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_INFO2; i++) begin + controller_program_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + + flash_op_sw_rw.partition = FlashPartData; + flash_op_sw_rw.addr = bank_start_addr; + `uvm_info(`gfn, $sformatf("READ DATA PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_DATA; i++) begin + controller_read_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + + flash_op_sw_rw.partition = FlashPartInfo; + flash_op_sw_rw.addr = bank_start_addr; + `uvm_info(`gfn, $sformatf("READ INFO PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_INFO0; i++) begin + controller_read_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + + flash_op_sw_rw.partition = FlashPartInfo1; + flash_op_sw_rw.addr = bank_start_addr; + `uvm_info(`gfn, $sformatf("READ INFO1 PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_INFO1; i++) begin + controller_read_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + + flash_op_sw_rw.partition = FlashPartInfo2; + flash_op_sw_rw.addr = bank_start_addr; + `uvm_info(`gfn, $sformatf("READ INFO2 PART %p", flash_op_sw_rw), UVM_LOW) + for (int i = 0; i < NUM_PAGE_PART_INFO2; i++) begin + controller_read_page(flash_op_sw_rw); + flash_op_sw_rw.addr = flash_op_sw_rw.addr + BytesPerPage; + end + endtask : do_sw_rw + + virtual task do_direct_rd(); + bit [TL_AW-1:0] read_addr; + bit [TL_AW-1:0] start_addr; + data_4s_t rdata; + bit comp; + start_addr = bank_start_addr; + cfg.dir_rd_in_progress = 1'b1; + for (int i = 0; i < NUM_BK_DATA_WORDS; i++) begin + read_addr = start_addr + 4 * i; + `uvm_info(`gfn, $sformatf("Direct read address 0x%0h", read_addr), UVM_HIGH) + do_direct_read(.addr(read_addr), .mask('1), .blocking(1), .check_rdata(0), .rdata(rdata), + .completed(comp)); + end + csr_utils_pkg::wait_no_outstanding_access(); + cfg.dir_rd_in_progress = 1'b0; + endtask : do_direct_rd + +endclass : flash_ctrl_full_mem_access_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_addr_infection_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_addr_infection_vseq.sv new file mode 100644 index 0000000000000..b23f3bdb002b5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_addr_infection_vseq.sv @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence issues a read to the flash controller. Inside the flash controller +// a fault is injected into the address. The goal of this sequence is to check, +// whether the data XOR address infection triggers a data integrity violation. +class flash_ctrl_host_addr_infection_vseq extends flash_ctrl_legacy_base_vseq; + `uvm_object_utils(flash_ctrl_host_addr_infection_vseq) + `uvm_object_new + + task body(); + string path1, path2; + int state_timeout_ns = 100000; // 100us + + flash_op_t host; + bit [TL_AW-1:0] tl_addr; + bit [7:0] addr_glitched; + bit saw_err, completed; + data_4s_t rdata; + + flash_otf_region_cfg(.scr_mode(OTFCfgTrue), .ecc_mode(OTFCfgTrue)); + cfg.clk_rst_vif.wait_clks(10); + + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + + // We expect that the TL-UL integrity check fails because address used for + // the access gets manipulated and the data XOR address mechanism infects the + // data, resulting in an integrity error. + cfg.scb_h.exp_tl_rsp_intg_err = 1; + + // Generate random address for the read access. + tl_addr[OTFBankId] = $urandom_range(0, 1); + tl_addr[OTFHostId-2:2] = $urandom(); + tl_addr[1:0] = 'h0; + `uvm_info(`gfn, $sformatf("Original TL-UL address is 'h%0x", tl_addr), UVM_LOW) + + // Flip bits in address before the data XOR address infection is done. + path1 = "tb.dut.u_eflash.gen_flash_cores[0].u_core.u_rd.addr_xor_muxed[8:1]"; + path2 = "tb.dut.u_eflash.gen_flash_cores[1].u_core.u_rd.addr_xor_muxed[8:1]"; + addr_glitched = tl_addr[8:1] ^ (1 << $urandom_range(0, 7)); + `uvm_info(`gfn, $sformatf("Forcing %s to value 'h%0x", path1, addr_glitched), UVM_LOW) + `uvm_info(`gfn, $sformatf("Forcing %s to value 'h%0x", path2, addr_glitched), UVM_LOW) + `DV_CHECK(uvm_hdl_force(path1, addr_glitched)) + `DV_CHECK(uvm_hdl_force(path2, addr_glitched)) + + // Perform the memory access. + tl_access_w_abort(.addr(tl_addr), .write(1'b0), .completed(completed), + .saw_err(saw_err), + .tl_access_timeout_ns(cfg.seq_cfg.erase_timeout_ns), + .data(rdata), .check_rsp(0), .blocking(1), + .tl_sequencer_h(p_sequencer.tl_sequencer_hs[cfg.flash_ral_name])); + + csr_utils_pkg::wait_no_outstanding_access(); + + `uvm_info(`gfn, "Wait until all drain", UVM_LOW) + cfg.clk_rst_vif.wait_clks(100); + `DV_CHECK(uvm_hdl_release(path1)) + `DV_CHECK(uvm_hdl_release(path2)) + + // reset for the next round + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + apply_reset(); + csr_wr(.ptr(ral.init), .value(1)); + `uvm_info("Test","OTP",UVM_LOW) + otp_model(); + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);, + "Timed out waiting for rd_buf_en", + state_timeout_ns) + cfg.clk_rst_vif.wait_clks(10); + + // disable tlul_err_cnt check + cfg.tlul_core_obs_cnt = cfg.tlul_core_exp_cnt; + endtask + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_ctrl_arb_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_ctrl_arb_vseq.sv new file mode 100644 index 0000000000000..99bbf06d57e2b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_ctrl_arb_vseq.sv @@ -0,0 +1,250 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// flash_ctrl_host_ctrl_arb Test + +// Pseudo Code +// Initialise (All) +// Loop (2) { +// Initialize Flash Regions (Enable All MP Regions) +// Number of Flash Operations is set to 64 +// Select a Flash Operation when to Apply an RMA (random) +// loop (64) { +// Do SW Flash Operation (random) +// Apply RMA Request during Flash Operation (at selected point) +// SW Flash Operations should complete successfully before and during +// initial RMA Request period, after that when RMA is active, Software +// is denied access. This remains valid until the DUT is Reset +// } +// Check that the RMA FSM Remains in its final state. +// Reset DUT +// Repeat +// } + +class flash_ctrl_host_ctrl_arb_vseq extends flash_ctrl_fetch_code_vseq; + `uvm_object_utils(flash_ctrl_host_ctrl_arb_vseq) + + `uvm_object_new + + // Body + virtual task body(); + + // Local Variables + bit result; + uint apply_rma; + uint num_ops; + event ev_rma_req; + string dut_prb; + uint rd_prb; + logic [RmaSeedWidth-1:0] rma_seed; + + // Iterate fixed Number of iterations as test time is VERY LONG. + // Set to 1 always + uint num_trans = 1; + + `uvm_info(`gfn, $sformatf("HOST CONTROL ARB TEST"), UVM_LOW) + poll_fifo_status = 0; + for (int i=0; i < num_trans; i++) begin + + `uvm_info(`gfn, $sformatf("Iteration : %0d", i), UVM_LOW) + + // Enable All Regions + init_flash_regions(); + + `uvm_info(`gfn, "Start SW Flash Operations, then randomly apply an RMA Request", UVM_HIGH) + + // Define Number of Flash Operations, and when to apply the RMA Request in parallel + num_ops = 64; + apply_rma = $urandom_range((num_ops/2)-16, (num_ops/2)+16); + + `uvm_info(`gfn, $sformatf("Apply RMA at Flash Operation : %0d", apply_rma+1), UVM_LOW) + + // Perform random Flash Operations, and send an RMA Request when required + fork + begin + for (int op_cnt=0; op_cnt ev_rma_req; + do_sw_op(op_cnt, apply_rma, num_ops); + end + end + begin + @(ev_rma_req); + cfg.clk_rst_vif.wait_clks($urandom_range(5, 10)); + `uvm_info(`gfn, "RMA REQUEST", UVM_LOW) + rma_seed = $urandom; + send_rma_req(rma_seed); + end + join + + // Check the End State Of the RMA FSM - Uses Internal DUT Probing + dut_prb = PRB_RMA_FSM; + + repeat (16) + begin + #($urandom_range(1000, 5000)*1us); + if (!uvm_hdl_read(dut_prb, rd_prb)) + `uvm_error(`gfn, $sformatf("Unable to Read from DUT Probe : %s, FAIL", dut_prb)) + + if (rd_prb == RMA_FSM_STATE_ST_RMA_RSP) + `uvm_info(`gfn, "RMA FSM Remains in Final State 'StRmaRsp' - PASS", UVM_LOW) + else + `uvm_error(`gfn, "RMA FSM NOT in Final State 'StRmaRsp' - FAIL") + end + + // RESET DUT + + `uvm_info(`gfn, "RESET DUT", UVM_LOW) + lc_ctrl_if_rst(); // Restore lc_ctrl_if to Reset Values + apply_reset(); + + end + + endtask : body + + // Task to do a Software Flash Operation, checking arbitration between SW and RMA + virtual task do_sw_op(input uint op_cnt, input uint apply_rma, input uint num_ops); + + // Local Variables + data_q_t exp_data; + + // Randomize The Members of the Class + `DV_CHECK_RANDOMIZE_FATAL(this) + `uvm_info(`gfn, $sformatf( + "Flash Operation : Bank: %0d, flash_op: %0p, flash_op_data: %0p", + bank, flash_op, flash_op_data), UVM_LOW) + + // If the 'Info' Partition is Selected, Turn On the HW Access Signals + // to allow SW access to Creator, Owner and Isolation Partitions + en_sw_rw_part_info(flash_op, lc_ctrl_pkg::On); + + // Note: Once the RMA has started, these backdoor calls fail, + // so only apply them when SW has access + if (op_cnt <= apply_rma) begin + // Initialise Flash Content + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + if (flash_op.op == flash_ctrl_pkg::FlashOpProgram) begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + end else begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + end + end + + `uvm_info(`gfn, $sformatf("Flash Operation : %0d / %0d", op_cnt+1, num_ops), UVM_LOW) + + // Start Controller Read, Program or Erase + unique case (flash_op.op) + + FlashOpRead : + begin + flash_op_data.delete(); + flash_ctrl_start_op(flash_op); + if (op_cnt <= apply_rma) begin // Expect Success + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + `uvm_info(`gfn, $sformatf("Read Data : %0p", flash_op_data), UVM_LOW) + // if on the last operation before rma, only check that half the words + // are correct. This is because upon read completion, the hardware + // immediately transitions into RMA and clears the read fifos. + // Thus, even if the read completed correctly, the data likely cannot + // be read out in time. + // This is no longer valid after #14244. + // Leave this comment for sometime until a new update become matured. + if (op_cnt == apply_rma) begin + flash_op.num_words = flash_op.num_words; + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + end else begin + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + end + end else begin // Expect Fail + expect_flash_op_fail(); + end + end + + FlashOpProgram : + begin + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + flash_ctrl_start_op(flash_op); + if (op_cnt <= apply_rma) begin // Expect Success + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + `uvm_info(`gfn, $sformatf("Program Data : %0p", flash_op_data), UVM_LOW) + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + end else begin // Expect Fail + expect_flash_op_fail(); + end + end + + FlashOpErase : + begin + flash_ctrl_start_op(flash_op); + if (op_cnt <= apply_rma) begin // Expect Success + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + `uvm_info(`gfn, "Erase Data", UVM_LOW) + cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); + end else begin // Expect Fail + expect_flash_op_fail(); + end + end + + default : `uvm_fatal(`gfn, "Flash Operation Unrecognised, FAIL") + + endcase + + // If the 'Info' Partition is Selected, Turn Off the HW Access Signals + // to disallow SW access to Creator, Owner and Isolation Partitions + en_sw_rw_part_info (flash_op, lc_ctrl_pkg::Off); + + // Delay and resync to clk + #($urandom_range(100, 500)*0.01ms); + cfg.clk_rst_vif.wait_clks(1); + + endtask : do_sw_op + + // Task to initialize the Flash Access (Enable All Regions) + virtual task init_flash_regions(); + + // Default Region Settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_scramble_en = MuBi4False; + + // Enable Bank Erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // Initialize MP Regions + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + // Initialize Default Regions + flash_ctrl_default_region_cfg( + .read_en (default_region_read_en), .program_en (default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en (default_region_ecc_en), .he_en (default_region_he_en)); + + // Initialize Info MP Regions + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + + endtask : init_flash_regions + + // Task to wait for a Flash Operation Fail, and display this status + virtual task expect_flash_op_fail(); + + // Local Variables + bit result; + + wait_flash_op_done_expect_timeout(.timeout_ns(100000), .result(result)); + if (result == 1) // Expect a Timeout + `uvm_info(`gfn, "Timeout Seen - RMA is Blocking SW Access, Expected, PASS", UVM_LOW) + else + `uvm_error(`gfn, "Timeout Not Seen - RMA is NOT Blocking SW Access, Unexpected, FAIL") + + endtask : expect_flash_op_fail + +endclass : flash_ctrl_host_ctrl_arb_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_dir_rd_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_dir_rd_vseq.sv new file mode 100644 index 0000000000000..93062db35ce50 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_host_dir_rd_vseq.sv @@ -0,0 +1,208 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// host direct back to back read test. Testing pipeline architecture +// of host interface reads with and without scrambling enabled. +class flash_ctrl_host_dir_rd_vseq extends flash_ctrl_fetch_code_vseq; + `uvm_object_utils(flash_ctrl_host_dir_rd_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + // MAx number of transactions. + cfg.seq_cfg.max_num_trans = 10; + + // Do no more than 16 words per op. + cfg.seq_cfg.op_max_words = 16; + + // no overlap mp regions + cfg.seq_cfg.allow_mp_region_overlap = 0; + + // enable high endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + endfunction + + + // Constraint address to be in relevant range for the selected partition. + constraint addr_c { + solve bank before flash_op; + flash_op.addr inside {[BytesPerBank * bank : BytesPerBank * (bank + 1) - BytesPerBank / 2]}; + } + + constraint flash_op_c { + flash_op.op == flash_ctrl_pkg::FlashOpProgram; + flash_op.partition == FlashPartData; + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + } + + // Single direct read data + data_t flash_rd_one_data; + + constraint mp_regions_c { + solve en_mp_regions before mp_regions; + + foreach (mp_regions[i]) { + mp_regions[i].en == mubi4_bool_to_mubi(en_mp_regions[i]); + + mp_regions[i].read_en == MuBi4True; + + mp_regions[i].program_en == MuBi4True; + + mp_regions[i].erase_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_erase_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_erase_en_pc + }; + + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + mp_regions[i].ecc_en == MuBi4False; + mp_regions[i].scramble_en == MuBi4False; + + mp_regions[i].start_page inside {[0 : FlashNumPages - 1]}; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + + // If overlap not allowed, then each configured region is uniquified. + // This creates an ascending order of mp_regions that are configured, so we shuffle it in + // post_randomize. + if (!cfg.seq_cfg.allow_mp_region_overlap) { + foreach (mp_regions[j]) { + if (i != j) { + !mp_regions[i].start_page inside { + [mp_regions[j].start_page:mp_regions[j].start_page + mp_regions[j].num_pages] + }; + } + } + } + } + } + + // Default flash ctrl region settings. + rand mubi4_t default_region_erase_en; + + constraint default_region_erase_en_c { + default_region_erase_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_erase_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_erase_en_pc) + }; + } + + bit [TL_AW-1:0] read_addr; + data_4s_t rdata; + virtual task body(); + repeat (num_trans) begin + // Randomize self + `DV_CHECK_RANDOMIZE_FATAL(this) + do_tasks(); + end + endtask : body + + task do_tasks(); + bit comp; + //enable polling of fifo status for frontdoor write and read + poll_fifo_status = 1; + + // Scoreboard knob + cfg.block_host_rd = 1; + + // 1. Scramble disabled, read data has been checked in scoreboard by backdoor read + // Configure the flash with scramble disable. + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // Invalidate the flash mem contents. We do this because we operate on and check a specific + // chunk of space. The rest of the flash mem is essentially dont-care. If the flash ctrl + // does not work correctly, the check will result in an access from the invalidated mem + // region exposing the issue. + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + `uvm_info(`gfn, $sformatf("Starting backdoor write operation with random values"), UVM_HIGH) + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + + // Host direct read of random written value + `uvm_info(`gfn, $sformatf("Starting direct back-to-back reads without scramble enabled"), + UVM_HIGH) + + for (int j = 0; j < flash_op.num_words; j++) begin + read_addr = flash_op.addr + 4 * j; + do_direct_read(.addr(read_addr), .mask('1), .blocking(1'b0), .check_rdata(0), .rdata(rdata), + .completed(comp)); + end + csr_utils_pkg::wait_no_outstanding_access(); + + // 2. Scramble enabled, host direct read data has been checked by SW read + `uvm_info(`gfn, $sformatf("Starting direct back-to-back reads with scramble enabled"), UVM_HIGH) + + cfg.block_host_rd = 0; + + // Configure the flash with scramble disable as this particular test does not support it. + // Configurations where scrambling and ECC are enabled are tested in the *_otf environment. + foreach (mp_regions[k]) begin + mp_regions[k].scramble_en = MuBi4False; + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + default_region_scramble_en = MuBi4False; + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // Start Controller + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH OP DATA: %0p", flash_op_data), UVM_HIGH) + flash_ctrl_start_op(flash_op); + + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + + // Select FLASH Read Operation + flash_op.op = flash_ctrl_pkg::FlashOpRead; + + // Start Controller read data + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + `uvm_info(`gfn, $sformatf("READ FLASH OP DATA: %0p", flash_op_data), UVM_HIGH) + + for (int j = 0; j < flash_op.num_words; j++) begin + read_addr = flash_op.addr + 4 * j; + do_direct_read(.addr(read_addr), .mask('1), .blocking(1'b0), .check_rdata(0), .rdata(rdata), + .completed(comp)); + end + csr_utils_pkg::wait_no_outstanding_access(); + + // check SW read data and Host direct read data + foreach (flash_op_data[k]) begin + flash_rd_one_data = cfg.flash_rd_data.pop_front(); + `uvm_info(`gfn, $sformatf( + "FLASH READ DATA: 0x%0h FLASH DIRECT READ DATA: 0x%0h", + flash_op_data[k], + flash_rd_one_data + ), UVM_HIGH) + `DV_CHECK_EQ(flash_op_data[k], flash_rd_one_data) + end + + // check directly read data queue + if (cfg.flash_rd_data.size() != 0) begin + `uvm_error(`gfn, $sformatf("Queue of read data has:%0d elements!", cfg.flash_rd_data.size())) + end + + endtask : do_tasks + +endclass : flash_ctrl_host_dir_rd_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_prog_rma_wipe_err_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_prog_rma_wipe_err_vseq.sv new file mode 100644 index 0000000000000..c1a6d6da7b269 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_prog_rma_wipe_err_vseq.sv @@ -0,0 +1,95 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence assert erros during rma wipe stage targeting +// hit a couple of hw oriented fault_status errors. +// See 'check_status' tasks for what status errors are covered. +class flash_ctrl_hw_prog_rma_wipe_err_vseq extends flash_ctrl_err_base_vseq; + `uvm_object_utils(flash_ctrl_hw_prog_rma_wipe_err_vseq) + `uvm_object_new + + task run_main_event(); + logic [RmaSeedWidth-1:0] rma_seed = $urandom; + // This test needs long rma. + // In case en_small_rma is set for all tests, + // force to long rma. + send_rma_req(.rma_seed(rma_seed), .ignore_short_rma(1)); + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + endtask // run_main_event + + // fatal_std_err + task run_error_event(); + int event_idx = $urandom_range(0, 3); + + `uvm_info(`gfn, $sformatf("event_idx :%0d", event_idx), UVM_MEDIUM) + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rma_state == StRmaWordSel);, + , cfg.seq_cfg.state_wait_timeout_ns) + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + + add_glitch(event_idx); + collect_err_cov_status(ral.fault_status); + check_status(event_idx); + cfg.scb_h.do_alert_check = 0; + cfg.rma_ack_polling_stop = 1; + endtask // run_error_event + + task add_glitch(int idx); + string path = LIST_OF_PROG_RMA_WIPE_FORCE_PATHS[idx]; + case (idx) + 0, 1: begin + // This will trigger std_fault_status.prog_intg_err + // but it will be captured in the other test. + cfg.scb_h.expected_alert["fatal_std_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_std_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_std_err"] = 10000; + $assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + flip_2bits(path); + end + 2: begin + `DV_CHECK(uvm_hdl_force(path, 100)); + end + 3: begin + $assertoff(0, "tb.dut.u_flash_hw_if.ProgRdVerify_A"); + csr_wr(.ptr(ral.prog_type_en.normal), .value(0)); + end + default: `uvm_error(`gfn, $sformatf("unsupported index %0d", idx)) + endcase // case (idx) + cfg.clk_rst_vif.wait_clks(10); + + // Since idx = 3 doesn't use force, exclude it from release. + if (idx != 3) begin + `DV_CHECK(uvm_hdl_release(path)); + end + endtask + + task check_status(int idx); + uvm_object fld; + case (idx) + 0: begin + fld = ral.fault_status.prog_err; + end + 1: begin + fld = ral.fault_status.mp_err; + end + 2: begin + fld = ral.fault_status.prog_win_err; + end + 3: begin + fld = ral.fault_status.prog_type_err; + end + default: `uvm_error(`gfn, $sformatf("unsupported index %0d", idx)) + endcase + csr_rd_check(.ptr(ral.err_code), .compare_value(0)); + csr_rd_check(.ptr(fld), .compare_value(1)); + endtask // check_status + + task clean_up(); + cfg.otf_scb_h.stop = 1; + cfg.otf_scb_h.clear_fifos(); + apply_reset(); + endtask // clean_up +endclass // flash_ctrl_hw_prog_rma_wipe_err_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_read_seed_err_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_read_seed_err_vseq.sv new file mode 100644 index 0000000000000..8dbc4abfe36cc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_read_seed_err_vseq.sv @@ -0,0 +1,80 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence assert errors duing seed-reading process targeting +// some hw oriented fault status errors. +// See 'check_status' tasks for what status errors are covered. +class flash_ctrl_hw_read_seed_err_vseq extends flash_ctrl_err_base_vseq; + `uvm_object_utils(flash_ctrl_hw_read_seed_err_vseq) + `uvm_object_new + + task run_main_event(); + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + apply_reset(); + // Enable ecc for all regions + init_controller(.non_blocking(1)); + endtask // run_main_event + + // fatal_std_err + task run_error_event(); + int wait_timeout_ns = 50_000; + int event_idx = $urandom_range(0, 4); + + `uvm_info(`gfn, $sformatf("event_idx :%0d", event_idx), UVM_MEDIUM) + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.hw_rvalid == 1);, + , wait_timeout_ns) + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + + add_glitch(event_idx); + collect_err_cov_status(ral.fault_status); + check_status(event_idx); + endtask + + task add_glitch(int idx); + string path = LIST_OF_READ_SEED_FORCE_PATHS[idx]; + case (idx) + 0, 1: begin + `DV_CHECK(uvm_hdl_force(path, FlashOpInvalid)); + end + 2: begin + `DV_CHECK(uvm_hdl_force(path, 0)); + end + 3, 4: begin + flip_2bits(path); + end + default: `uvm_error(`gfn, $sformatf("unsupported index %0d", idx)) + endcase // case (idx) + cfg.clk_rst_vif.wait_clks(10); + `DV_CHECK(uvm_hdl_release(path)); + endtask + + task check_status(int idx); + uvm_object fld; + + case (idx) + 0: begin + fld = ral.fault_status.op_err; + end + 1: begin + fld = ral.fault_status.seed_err; + end + 2: begin + fld = ral.fault_status.mp_err; + end + 3: begin + fld = ral.fault_status.rd_err; + end + 4: begin + fld = ral.fault_status.phy_relbl_err; + end + default: `uvm_error(`gfn, $sformatf("unsupported index %0d", idx)) + endcase // case (idx) + csr_rd_check(.ptr(ral.err_code), .compare_value(0)); + csr_rd_check(.ptr(fld), .compare_value(1)); + endtask // check_status + +endclass // flash_ctrl_hw_read_seed_err_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_err_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_err_vseq.sv new file mode 100644 index 0000000000000..e44a505f7c01d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_err_vseq.sv @@ -0,0 +1,140 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// flash_ctrl_hw_rma Test + +import lc_ctrl_pkg::*; + +class flash_ctrl_hw_rma_err_vseq extends flash_ctrl_hw_rma_vseq; + `uvm_object_utils(flash_ctrl_hw_rma_err_vseq) + + `uvm_object_new + + // Body + task body(); + + // Local Variables + logic [RmaSeedWidth-1:0] rma_seed; + bit rma_done; + + `uvm_info(`gfn, "FLASH_CTRL_HW_RMA", UVM_LOW) + + // These are valid assertoff's. + $assertoff(0, "tb.dut.u_flash_hw_if.ProgRdVerify_A"); + $assertoff(0, "tb.dut.u_flash_hw_if.DisableChk_A"); + + // RMA TESTS + + // INITIALIZE FLASH REGIONS + init_data_part(); + init_info_part(); + + // Delay + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + // Select Data Partition Start Address an Num Words for this iteration + set_rand_data_page(FlashData0Part, data0_part_addr, data0_part_num_words); + set_rand_data_page(FlashData1Part, data1_part_addr, data1_part_num_words); + + // ERASE + + `uvm_info(`gfn, "ERASE", UVM_LOW) + do_flash_ops(flash_ctrl_pkg::FlashOpErase, ReadCheckNorm); + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + // PROGRAM + + `uvm_info(`gfn, "PROGRAM", UVM_LOW) + do_flash_ops(flash_ctrl_pkg::FlashOpProgram, ReadCheckNorm); + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + // READ (Compare Expected Data with Data Read : EXPECT DATA MATCH) + + `uvm_info(`gfn, "READ", UVM_LOW) + do_flash_ops(flash_ctrl_pkg::FlashOpRead, ReadCheckNorm); + + // SEND RMA REQUEST (Erases the Flash and Writes Random Data To All Partitions) + fork + begin + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + fork + begin + `uvm_info(`gfn, "RMA REQUEST", UVM_LOW) + rma_seed = $urandom; // Random RMA Seed + send_rma_req(rma_seed); + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + // This should not happen + if (cfg.rma_ack_polling_stop == 0) rma_done = 1; + end + begin + csr_spinwait(.ptr(ral.debug_state), + .exp_data(flash_ctrl_env_pkg::FlashLcInvalid), + .spinwait_delay_ns(500_000), + .timeout_ns(2_000_000_000)); + cfg.clk_rst_vif.wait_clks(3); + `uvm_info(`gfn, "RMA FAIL DUE TO Wipe out write data failure (expected)", UVM_LOW) + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.lcmgr_err), .compare_value(1)); + end + join_any + end + begin + // Assert flash_ctrl.INIT at the beginning of RMA or + // in the middle + int val = $urandom_range(0, 1); + `uvm_info(`gfn, $sformatf("INIT val: %0d", val), UVM_MEDIUM) + csr_wr(.ptr(ral.init), .value(val)); + + if (val == 0) begin + int my_wait = $urandom_range(1,100); + val = $urandom_range(0, 1); + #(my_wait * 1ms); + csr_wr(.ptr(ral.init), .value(val)); + end + end + begin + string path = {"tb.dut.u_eflash.gen_flash_cores[0].u_core.gen_prog_data", + ".u_prog.pack_data[31:0]"}; + + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rma_state == StRmaEraseWait);, + , cfg.seq_cfg.state_wait_timeout_ns) + flip_2bits(path); + cfg.clk_rst_vif.wait_clks(10); + `DV_CHECK(uvm_hdl_release(path)) + // Fatal alert (std_fault_status.lcmgr_err) is checked in the other thread by + // csr_rd_check + cfg.scb_h.do_alert_check = 0; + end + join + + // RESET DUT + `uvm_info("Test", "RMA END", UVM_LOW) + `DV_CHECK_NE(rma_done, 1, "rma_done shouldn't be 1") + // Stop rma polling + cfg.rma_ack_polling_stop = 1; + + `uvm_info(`gfn, "RESET", UVM_LOW) + lc_ctrl_if_rst(); // Restore lc_ctrl_if to Reset Values + cfg.seq_cfg.disable_flash_init = 1; // Disable Flash Random Initialisation + apply_reset(); + + // INITIALIZE FLASH REGIONS + + init_data_part(); + init_info_part(); + + // READ (Compare Expected Data with Data Read : EXPECT DATA MISMATCH or STATUS FAIL) + // After Reset and DUT Initialisation, Check the FLASH is written randomly and its contents + // mismatch against its contents before the RMA took place. + // This may get an occasional Hit ~ 1 in 32^2-1, per location + // Additionally check that the Flash has not just been Erased, but has been overwritten. + + `uvm_info(`gfn, "READ", UVM_LOW) + + do_flash_ops(flash_ctrl_pkg::FlashOpRead, ReadCheckRand); + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + endtask : body + +endclass : flash_ctrl_hw_rma_err_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv new file mode 100644 index 0000000000000..417b501d8a4e4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_reset_vseq.sv @@ -0,0 +1,130 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Run rma request event with random resets +class flash_ctrl_hw_rma_reset_vseq extends flash_ctrl_hw_rma_vseq; + +// Observed wait time for each state: +// DVStRmaPageSel : 0.120 us +// DVStRmaErase : 0.140 us +// DVStRmaEraseWait : 6.065 us +// DVStRmaWordSel : 6.088 us +// DVStRmaProgram : 2.776 us +// DVStRmaProgramWait: 2.797 us +// DVStRmaRdVerify : 3.464 us +// RMA : 108 msec + typedef enum {DVStRmaPageSel = 0, + DVStRmaErase = 1, + DVStRmaEraseWait = 2, + DVStRmaWordSel = 3, + DVStRmaProgram = 4, + DVStRmaProgramWait = 5, + DVStRmaRdVerify = 6} reset_state_index_e; + `uvm_object_utils(flash_ctrl_hw_rma_reset_vseq) + `uvm_object_new + + task pre_start(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + cfg.seq_cfg.en_init_keys_seeds = 1; + super.pre_start(); + endtask + + task body(); + logic [RmaSeedWidth-1:0] rma_seed; + bit rma_done = 0; + bit flash_dis = 0; + // INITIALIZE FLASH REGIONS + init_data_part(); + init_info_part(); + flash_dis = $urandom(); + + fork begin + // SEND RMA REQUEST (Erases the Flash and Writes Random Data To All Partitions) + fork + begin + `uvm_info("Test", $sformatf("RMA REQUEST flash_dis:%0d", flash_dis), UVM_LOW) + rma_seed = $urandom; // Random RMA Seed + send_rma_req(rma_seed); + rma_done = 1; + end + begin + reset_state_index_e reset_state_index = reset_state_index_e'( + $urandom_range(DVStRmaPageSel, DVStRmaRdVerify)); + // Assert reset during RMA state transition + `uvm_info("Test", $sformatf("Reset index: %s", reset_state_index.name), UVM_LOW) + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rma_state == dv2rma_st(reset_state_index));, + $sformatf("Timed out waiting for rma_state: %s", reset_state_index.name), + cfg.seq_cfg.state_wait_timeout_ns) + // Give more cycles for long stages + // to trigger reset in the middle of the state. + if (reset_state_index inside {StRmaRdVerify, StRmaErase}) cfg.clk_rst_vif.wait_clks(10); + + if (flash_dis) begin + `uvm_info("Test", "set disable_flash", UVM_MEDIUM) + cfg.scb_h.do_alert_check = 0; + update_assert(.enable(0)); + csr_wr(.ptr(ral.dis), .value(get_rand_mubi4_val(.f_weight(0)))); + cfg.clk_rst_vif.wait_clks(10); + end + `uvm_info("Test", "RESET", UVM_LOW) + lc_ctrl_if_rst(); // Restore lc_ctrl_if to Reset Values + apply_reset(); + end + join_any + disable fork; + // Since the 2nd begin/end wait for substate of RMA, + // the 2nd begin/end always finish first. + // So diable fork only terminate send_rma_req. + end join // fork begin + + `uvm_info("Test", "RMA END", UVM_LOW) + `DV_CHECK_NE(rma_done, 1, "rma_done shouldn't be 1") + if (rma_done == 0) begin + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + update_assert(.enable(1)); + // INITIALIZE FLASH REGIONS + init_data_part(); + init_info_part(); + `uvm_info("Test", "RMA REQUEST", UVM_LOW) + rma_seed = $urandom; // Random RMA Seed + send_rma_req(rma_seed); + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + // CHECK HOST SOFTWARE HAS NO ACCESS TO THE FLASH + // Attempt to Read from FLASH Controller + do_flash_ctrl_access_check(); + end // if (rma_done == 0) + endtask + + function rma_state_e dv2rma_st(reset_state_index_e idx); + case (idx) + DVStRmaPageSel: return StRmaPageSel; + DVStRmaErase: return StRmaErase; + DVStRmaEraseWait: return StRmaEraseWait; + DVStRmaWordSel: return StRmaWordSel; + DVStRmaProgram: return StRmaProgram; + DVStRmaProgramWait: return StRmaProgramWait; + DVStRmaRdVerify: return StRmaRdVerify; + default: begin + `uvm_error("dv2rma_st", $sformatf("unknown index:%0d", idx)) + end + endcase + endfunction // dv2rma_st + + function void update_assert(bit enable); + if (enable) begin + $asserton(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + $asserton(0, "tb.dut.u_flash_hw_if.u_addr_sync_reqack.SyncReqAckHoldReq"); + $asserton(0, "tb.dut.u_flash_hw_if.ProgRdVerify_A"); + end else begin + $assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + $assertoff(0, "tb.dut.u_flash_hw_if.u_addr_sync_reqack.SyncReqAckHoldReq"); + $assertoff(0, "tb.dut.u_flash_hw_if.ProgRdVerify_A"); + end + endfunction // update_assert +endclass // flash_ctrl_hw_rma_reset_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_vseq.sv new file mode 100644 index 0000000000000..84be771aec608 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_hw_rma_vseq.sv @@ -0,0 +1,338 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// flash_ctrl_hw_rma Test + +// Pseudo Code +// Initialise (All) +// Loop { +// Erase Partitions(#) +// Program Partitions(#) +// Read Partitions(#) +// RMA REQUEST (Random Seed) +// Check Software has NO Access to the FLASH +// Reset DUT (No Flash Init) +// Initialise +// Read Partitions#() Compare Data (MISMATCH Expected) +// (additionally check Data Read is not all 1's +// indicating Erase but not RMA Wipe) +// } +// #Random Order : Creator(page), Owner(page), Isolation(page), +// Data0(random page), Data1(random page) + +import lc_ctrl_pkg::*; + +class flash_ctrl_hw_rma_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_hw_rma_vseq) + + `uvm_object_new + + // Class Members + data_q_t flash_creator_data; + data_q_t flash_owner_data; + data_q_t flash_isol_data; + data_q_t flash_data0_data; + data_q_t flash_data1_data; + uint data0_part_addr; + uint data0_part_num_words; + uint data1_part_addr; + uint data1_part_num_words; + + // Configure sequence knobs to tailor it to this seq + virtual function void configure_vseq(); + + // Enable NO memory protection regions + cfg.seq_cfg.num_en_mp_regions = 0; + cfg.seq_cfg.poll_fifo_status_pc = 0; + + // Enable Checks Post Transaction + cfg.seq_cfg.check_mem_post_tran = 1; + + // Randomize the 'Keys and Seeds' Setting to prove + // this has no effect on the RMA + cfg.seq_cfg.en_init_keys_seeds = $urandom; + + endfunction : configure_vseq + + // Body + task body(); + // sw flash_init value + int sw_init_val = 0; + // Local Variables + logic [RmaSeedWidth-1:0] rma_seed; + + `uvm_info(`gfn, "FLASH_CTRL_HW_RMA", UVM_LOW) + + // RMA TESTS + + // INITIALIZE FLASH REGIONS + init_data_part(); + init_info_part(); + + // Delay + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + // Iterate fixed Number of iterations as test time is VERY LONG. + // Since this test is getting unbearably long in the closed-source, when running in the + // closed-source, this test will do only one iteration. + num_trans = `PRIM_DEFAULT_IMPL==prim_pkg::ImplGeneric ? 2 : 1; + for (int i=0; i>> RESET DUT <<<", UVM_LOW) + + lc_ctrl_if_rst(); // Restore lc_ctrl_if to Reset Values + cfg.seq_cfg.disable_flash_init = 1; // Disable Flash Random Initialisation + apply_reset(); + + // Delay + cfg.clk_rst_vif.wait_clks($urandom_range(10, 100)); + + end + + endtask : body + + virtual task init_data_part(); + + // DATA PARTITION + + flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + + // MEMORY PROTECTION REGIONS + + // No Protection Regions + foreach (mp_regions[i]) begin + mp_regions[i].en = MuBi4False; + end + + // Configure the flash based on the given settings + foreach (mp_regions[i]) begin + flash_ctrl_mp_region_cfg(i, mp_regions[i]); + end + + // DEFAULT REGIONS + + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + + // Memory Default Regions + flash_ctrl_default_region_cfg(.read_en(default_region_read_en), + .program_en(default_region_program_en), + .erase_en(default_region_erase_en)); + + endtask : init_data_part + + virtual task init_info_part(); + + // INFO REGION + + flash_bank_mp_info_page_cfg_t info_regions[flash_ctrl_reg_pkg::NumInfos0]; + + foreach (info_regions[i]) begin + // Get secret partition cfg from flash_ctrl_pkg + if ( i inside {1, 2}) begin + // Copy protection from hw_cfg0. + info_regions[i] = conv2env_mp_info(flash_ctrl_pkg::CfgAllowRead); + // Update program and erase control for the test purpose. + info_regions[i].program_en = MuBi4True; + info_regions[i].erase_en = MuBi4True; + end else begin + info_regions[i].en = MuBi4True; + info_regions[i].read_en = MuBi4True; + info_regions[i].program_en = MuBi4True; + info_regions[i].erase_en = MuBi4True; + end + flash_ctrl_mp_info_page_cfg(.bank(0), .info_part(0), .page(i), .page_cfg(info_regions[i])); + end + + endtask : init_info_part + + // Tests the connections between the Flash OTP and the Scramble Block in the Flash Ctrl + virtual task otp_scramble_key_test_connect(); + + logic [KeyWidth-1:0] prb_otp_addr_key; + logic [KeyWidth-1:0] prb_otp_data_key; + logic [KeyWidth-1:0] prb_otp_addr_rand_key; + logic [KeyWidth-1:0] prb_otp_data_rand_key; + + // OTP SCRAMBLE KEY TESTS - CONNECTIVITY TEST ONLY + + // OTP Acknowledge and Random Scramble Seeds are Provided by a model in the Base Seq + // (flash_ctrl_base_vseq), called otp_model() + + `uvm_info(`gfn, "FLASH OTP KEY - Scramble Connectivity Check", UVM_LOW) + + // Probe Internal Scramble Signals + prb_otp_addr_key = read_key_probe("tb.dut.u_eflash.u_scramble.addr_key_i"); + prb_otp_addr_rand_key = read_key_probe("tb.dut.u_eflash.u_scramble.rand_addr_key_i"); + prb_otp_data_key = read_key_probe("tb.dut.u_eflash.u_scramble.data_key_i"); + prb_otp_data_rand_key = read_key_probe("tb.dut.u_eflash.u_scramble.rand_data_key_i"); + + // Compare OTP Keys - Probed vs Expected (For This Test Scenario) + compare_key_probe("otp_addr_key", prb_otp_addr_key, otp_addr_key); + compare_key_probe("otp_addr_rand_key", prb_otp_addr_rand_key, otp_addr_rand_key); + compare_key_probe("otp_data_key", prb_otp_data_key, otp_data_key); + compare_key_probe("otp_data_rand_key", prb_otp_data_rand_key, otp_data_rand_key); + + endtask : otp_scramble_key_test_connect + + // Function Reads the OTP Key values within the Flash Ctrl, at the Scrambing Module + virtual function logic [KeyWidth-1:0] read_key_probe(input string dut_prb); + if (!uvm_hdl_read(dut_prb, read_key_probe)) + `uvm_error(`gfn, $sformatf("Unable to Read from DUT Probe : %s, FAIL", dut_prb)) + endfunction : read_key_probe + + // Task that compares an expected Key with a given key + virtual task compare_key_probe(input string dut_prb, + input logic [KeyWidth-1:0] key, + input logic [KeyWidth-1:0] expected_key); + + `uvm_info(`gfn, $sformatf("Compare OTP Key, Read : 0x%0x, Expected : 0x%0x", key, expected_key), + UVM_MEDIUM) + + `DV_CHECK_EQ(key, expected_key, $sformatf( + {"Flash OTP Scramble Key Mismatch, Key : %s, Read : ", + "0x%0x, Expected : 0x%0x, FAIL"}, + dut_prb, key, expected_key)) + + endtask : compare_key_probe + +endclass : flash_ctrl_hw_sec_otp_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_info_part_access_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_info_part_access_vseq.sv new file mode 100644 index 0000000000000..4884a5fa2735e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_info_part_access_vseq.sv @@ -0,0 +1,189 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// The sequence accesses secret info regions after randomize lc_ctrl inputs. +// lc_ctrl_inputs: +// .lc_creator_seed_sw_rw_en_i +// .lc_owner_seed_sw_rw_en_i +// .lc_iso_part_sw_rd_en_i +// .lc_iso_part_sw_wr_en_i +// The sequence randomizes hw_info_cfg_override. +// Therefore, sw_info_access needs to sync with hw_info_cfg +// to avoid unexpected fatal error +class flash_ctrl_info_part_access_vseq extends flash_ctrl_hw_sec_otp_vseq; + `uvm_object_utils(flash_ctrl_info_part_access_vseq) + `uvm_object_new + + typedef enum { + AccessTest, + ReadOnlyTest, + WriteOnlyTest + } test_type_e; + int round = 0; + + task hw_info_cfg_update(); + // Randomize hw_info_cfg_override + cfg.ovrd_scr_dis = get_rand_mubi4_val(.t_weight(2), .f_weight(1), .other_weight(1)); + cfg.ovrd_ecc_dis = get_rand_mubi4_val(.t_weight(2), .f_weight(1), .other_weight(1)); + ral.hw_info_cfg_override.scramble_dis.set(cfg.ovrd_scr_dis); + ral.hw_info_cfg_override.ecc_dis.set(cfg.ovrd_ecc_dis); + csr_update(ral.hw_info_cfg_override); + `uvm_info("hw_info_cfg_update", $sformatf("ovrd_scr_dis: %0d ovrd_ecc_dis:%0d", + cfg.ovrd_scr_dis, cfg.ovrd_ecc_dis), + UVM_MEDIUM) + // Update secret partition after hw_info_cfg update + update_secret_partition(); + endtask // hw_info_cfg_update + + virtual task body(); + // INITIALIZE FLASH REGIONS + // All on to configure secret info_page_cfg + all_sw_rw_en(); + init_sec_info_part(); + $assertoff(0, "prim_lc_sync"); + cfg.seq_cfg.check_mem_post_tran = 1; + + repeat (10) begin + `uvm_info(`gfn, $sformatf("iter:%0d", round++), UVM_LOW) + + check_lc_ctrl(cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en, FlashCreatorPart); + check_lc_ctrl(cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en, FlashOwnerPart); + + randcase + 1: check_lc_ctrl(cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en, FlashIsolPart, WriteOnlyTest); + 1: check_lc_ctrl(cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en, FlashIsolPart, ReadOnlyTest); + endcase // randcase + + // Drain between iteration + #1us; + end // repeat (10) + endtask // body + + task check_lc_ctrl(ref lc_ctrl_pkg::lc_tx_t sig, input flash_sec_part_e part, + test_type_e test = AccessTest); + flash_op_e flash_op; + bit is_valid; + `uvm_info(`gfn, $sformatf("iter%0d:info:%s test:%s begin", + round, part.name, test.name), UVM_HIGH) + if (test == AccessTest) begin + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(flash_op, + flash_op != FlashOpInvalid;) + end else if (test == ReadOnlyTest) begin + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(flash_op, + flash_op == FlashOpRead;) + end else begin + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(flash_op, + flash_op inside {FlashOpProgram, FlashOpErase};) + end + + sig = get_rand_lc_tx_val(.t_weight(1), .f_weight(1), .other_weight(8)); + is_valid = is_lc_ctrl_valid(sig); + cfg.clk_rst_vif.wait_clks(4); + `uvm_info(`gfn, $sformatf("Check sig:0x%x(is_valid:%0d) part:%s op:%s testtype:%s", + sig, is_valid, part.name, flash_op.name, test.name), UVM_LOW) + + do_flash_op_info_part(part, flash_op, is_valid); + endtask // check_lc_ctrl + + // Task to access secret info partition. + // lc control should be set from the exernal task. + task do_flash_op_info_part(flash_sec_part_e part, flash_op_e op, bit is_valid); + data_q_t flash_op_data; + flash_op_t flash_op; + bit scr_en, ecc_en; + + flash_op.op = op; + flash_op.erase_type = FlashErasePage; + + case (part) + FlashCreatorPart: begin + flash_op.addr = FlashCreatorPartStartAddr; // Fixed Val + flash_op.num_words = FullPageNumWords; // Fixed Val + flash_op.partition = FlashPartInfo; + end + FlashOwnerPart: begin + flash_op.addr = FlashOwnerPartStartAddr; // Fixed Val + flash_op.num_words = FullPageNumWords; // Fixed Val + flash_op.partition = FlashPartInfo; + end + FlashIsolPart: begin + flash_op.addr = FlashIsolPartStartAddr; // Fixed Val + flash_op.num_words = FullPageNumWords; // Fixed Val + flash_op.partition = FlashPartInfo; + end + default: `uvm_error(`gfn, $sformatf("%s partition is not supported in this task", + part.name)) + endcase + flash_op.otf_addr = flash_op.addr[OTFBankId-1:0]; + flash_op_data = '{}; + if (part == FlashIsolPart) begin + scr_en = 1; + ecc_en = 1; + end else begin + scr_en = (prim_mubi_pkg::mubi4_and_hi(flash_ctrl_pkg::CfgAllowRead.scramble_en, + mubi4_t'(~cfg.ovrd_scr_dis)) == MuBi4True); + ecc_en = (prim_mubi_pkg::mubi4_and_hi(flash_ctrl_pkg::CfgAllowRead.ecc_en, + mubi4_t'(~cfg.ovrd_ecc_dis)) == MuBi4True); + end + + `uvm_info(`gfn, $sformatf("iter%0d:info:%s is_valid:%0b op:%p scr:%0b ecc:%0b", + round, part.name, is_valid, flash_op, scr_en, ecc_en), + UVM_MEDIUM) + + case (op) + FlashOpErase: begin + if (!is_valid) set_otf_exp_alert("recov_err"); + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitRandomize); + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + cfg.flash_mem_bkdr_erase_check(.flash_op(flash_op), .check_match(is_valid)); + end + FlashOpProgram: begin + for (int i = 0; i < flash_op.num_words; i++) begin + flash_op_data[i] = $urandom_range(0, 2 ** (TL_DW) - 1); + end + if (!is_valid) begin + repeat(32) set_otf_exp_alert("recov_err"); + end + // This task issues flash_ctrl.control write 32 times + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitSet); + flash_ctrl_write_extra(flash_op, flash_op_data, is_valid, scr_en, ecc_en); + end + FlashOpRead: begin + if (!is_valid) set_otf_exp_alert("recov_err"); + + if (scr_en) begin + // scramble secret partition + update_secret_partition(); + end else begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + end + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, 1); + wait_flash_op_done(); + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data, is_valid, scr_en, ecc_en); + end + default: `uvm_error(`gfn, $sformatf("%s op is not supported in this task", + op.name)) + endcase + endtask + + task init_sec_info_part(); + flash_bank_mp_info_page_cfg_t info_regions = '{default: MuBi4True}; + for (int i = 1; i < 4; i++) begin + if (i < 3) begin + info_regions.scramble_en = prim_mubi_pkg::mubi4_and_hi( + flash_ctrl_pkg::CfgAllowRead.scramble_en, + mubi4_t'(~cfg.ovrd_scr_dis)); + info_regions.ecc_en = prim_mubi_pkg::mubi4_and_hi( + flash_ctrl_pkg::CfgAllowRead.ecc_en, + mubi4_t'(~cfg.ovrd_ecc_dis)); + end else begin + info_regions.scramble_en = flash_ctrl_pkg::CfgAllowRead.scramble_en; + info_regions.ecc_en = flash_ctrl_pkg::CfgAllowRead.ecc_en; + end + flash_ctrl_mp_info_page_cfg(0, 0, i, info_regions); + end + endtask // init_info_part +endclass // flash_ctrl_info_part_access_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_integrity_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_integrity_vseq.sv new file mode 100644 index 0000000000000..044dba2bd807e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_integrity_vseq.sv @@ -0,0 +1,66 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Directed test to check flash_ctrl.single_err_addr +// Each round test insert one single bit error and capture the address from tb. +// At the end of each round, compare the captured value with +// csr read (flash_ctrl.single_err_addr) value. +class flash_ctrl_integrity_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_integrity_vseq) + `uvm_object_new + + constraint ctrl_num_c { + ctrl_num dist { CtrlTransMin := 7, [2:31] :/ 1, CtrlTransMax := 2}; + } + constraint fractions_c { + solve ctrl_num before fractions; + if (ctrl_num == 1) + fractions dist { [1:4] := 4, [5:16] := 1}; + else + fractions == 16; + } + + constraint odd_addr_c { + solve fractions before is_addr_odd; + (fractions == 16) -> is_addr_odd == 0; + } + + virtual task body(); + flash_op_t ctrl; + int bank; + + ctrl.partition = FlashPartData; + cfg.clk_rst_vif.wait_clks(5); + + fork + begin + repeat(100) begin + if (cfg.stop_transaction_generators()) break; + randcase + 1: begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + prog_flash(ctrl, bank, num, fractions); + end + 1: begin + set_ecc_err_target(TgtRd); + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + read_flash(ctrl, bank, num, fractions); + end + endcase + end + end + begin + for (int i = 0; i < 10; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + join + endtask : body +endclass : flash_ctrl_integrity_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_rd_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_rd_vseq.sv new file mode 100644 index 0000000000000..e2720f9f9e0fa --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_rd_vseq.sv @@ -0,0 +1,48 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Send read only traffic with interrup mode. +// No protection is applied. +class flash_ctrl_intr_rd_vseq extends flash_ctrl_legacy_base_vseq; + `uvm_object_utils(flash_ctrl_intr_rd_vseq) + `uvm_object_new + + task pre_start(); + cfg.intr_mode = 1; + cfg.skip_init = 1; + + super.pre_start(); + endtask + virtual task body(); + flash_op_t ctrl; + int num, bank; + + flash_program_data_c.constraint_mode(0); + cfg.clk_rst_vif.wait_clks(5); + fork + begin + for (int i = 0; i < 1000; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + begin + repeat(100) begin + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rand_op) + ctrl = rand_op; + if (ctrl.partition == FlashPartData) begin + num = $urandom_range(1, 32); + end else begin + num = $urandom_range(1, InfoTypeSize[rand_op.partition >> 1]); + end + bank = rand_op.addr[OTFBankId]; + read_flash(ctrl, bank, num); + end + end + join + endtask +endclass // flash_ctrl_intr_rd_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv new file mode 100644 index 0000000000000..6210c6aaa8aa1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_intr_wr_vseq.sv @@ -0,0 +1,29 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Send write only traffic +class flash_ctrl_intr_wr_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_intr_wr_vseq) + `uvm_object_new + + constraint ctrl_data_num_c {ctrl_data_num inside {[1 : 32]};} + + task pre_start(); + cfg.intr_mode = 1; + super.pre_start(); + endtask + + virtual task body(); + flash_op_t ctrl; + int num, bank; + + // Don't select a partition defined as read-only + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + flash_program_data_c.constraint_mode(0); + repeat(100) begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + prog_flash(ctrl, bank, num, fractions); + end + endtask +endclass : flash_ctrl_intr_wr_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_invalid_op_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_invalid_op_vseq.sv new file mode 100644 index 0000000000000..4650487181608 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_invalid_op_vseq.sv @@ -0,0 +1,236 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Flash invalid operation test. All partitions are exercised +// with final check that invalid operation does not affect flash +// memory content. +class flash_ctrl_invalid_op_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_invalid_op_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + + // enable high endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + endfunction + + rand flash_op_t flash_op; + flash_op_t flash_op_inv; + flash_op_t flash_op_rd; + flash_op_t flash_op_er; + rand data_q_t flash_op_data; + bit poll_fifo_status; + int num_trans; + bit expect_alert; + + constraint flash_op_data_c { + solve flash_op before flash_op_data; + flash_op_data.size() == flash_op.num_words; + } + + // Constraint address to be in relevant range for the selected partition. + constraint addr_c { + if (flash_op.partition != FlashPartData) { + flash_op.addr inside + {[0:InfoTypeBytes[flash_op.partition>>1]-1], + [BytesPerBank:BytesPerBank+InfoTypeBytes[flash_op.partition>>1]-1]}; + } + } + + constraint flash_op_c { + flash_op.addr inside {[0 : FlashSizeBytes - 1]}; + // 8Byte (2 words) aligned. + // With scramble enabled, odd size of word access (or address) will cause + // ecc errors. + flash_op.addr[2:0] == 3'h0; + flash_op.erase_type == flash_ctrl_pkg::FlashErasePage; + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + flash_op.num_words % 2 == 0; + + // This added because in some extending env the info2 has special use. + if (cfg.seq_cfg.exclude_info2) { + flash_op.partition dist { FlashPartData := 1, [FlashPartInfo:FlashPartInfo1] :/ 1}; + } else { + flash_op.partition dist { FlashPartData := 1, [FlashPartInfo:FlashPartInfo2] :/ 1}; + } + + } + + // Memory protection regions settings. + flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + // Information partitions memory protection pages settings. + rand flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + foreach (mp_info_pages[i, j]) { + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + foreach (mp_info_pages[i][j][k]) { + mp_info_pages[i][j][k].en == MuBi4True; + mp_info_pages[i][j][k].read_en == MuBi4True; + mp_info_pages[i][j][k].program_en == MuBi4True; + mp_info_pages[i][j][k].erase_en == MuBi4True; + mp_info_pages[i][j][k].scramble_en == MuBi4False; + mp_info_pages[i][j][k].ecc_en == MuBi4False; + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + } + } + } + + // Default flash ctrl region settings. + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + rand mubi4_t default_region_he_en; + mubi4_t default_region_scramble_en; + mubi4_t default_region_ecc_en; + + // Bank erasability. + bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + virtual task pre_start(); + super.pre_start(); + // This test requires fast alert hand shake to avoid overlapping + // multiple alert expected / completed. + cfg.m_alert_agent_cfgs["recov_err"].ack_delay_max = 1; + cfg.m_alert_agent_cfgs["recov_err"].ack_stable_max = 1; + endtask // pre_start + + virtual task body(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + cfg.scb_check = 1; + cfg.check_full_scb_mem_model = 1; + poll_fifo_status = 1; + num_trans = 100; + + repeat (num_trans) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + do_op(); + end + + endtask : body + + virtual task do_op(); + + // Default region settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_ecc_en = MuBi4False; + default_region_scramble_en = MuBi4False; + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // No Protection + foreach (mp_regions[i]) begin + mp_regions[i].en = MuBi4False; + end + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + for (int i = 1; i < 4; i++) begin + mp_info_pages[0][0][i].ecc_en = MuBi4True; + mp_info_pages[0][0][i].scramble_en = MuBi4True; + end + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + + //Enable Bank erase + bank_erase_en = {NumBanks{1'b1}}; + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + flash_op.op = FlashOpProgram; + flash_op_inv = flash_op; + flash_op_rd = flash_op; + flash_op_er = flash_op; + // When testing RO partitions, skip the program and erase parts. + if ((cfg.seq_cfg.op_readonly_on_info_partition && flash_op.partition == FlashPartInfo) || + (cfg.seq_cfg.op_readonly_on_info1_partition && flash_op.partition == FlashPartInfo1)) begin + expect_alert = 1; + cfg.scb_h.expected_alert["recov_err"].expected = 1; + cfg.scb_h.expected_alert["recov_err"].max_delay = 1000; + flash_op_inv.op = FlashOpInvalid; + flash_ctrl_start_op(flash_op_inv); + wait_flash_op_done(); + + ral.err_code.op_err.predict(expect_alert); + check_exp_alert_status(expect_alert, "op_err", flash_op_inv, flash_op_data); + cfg.scb_h.expected_alert["recov_err"].expected = 0; + + flash_op_rd.op = FlashOpRead; + flash_op_data = {}; + flash_ctrl_start_op(flash_op_rd); + flash_ctrl_read(flash_op_rd.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + end else begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.clear_op_status(0), .timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + // Add guard time between previous alert detection complete and set the next expected alert + cfg.clk_rst_vif.wait_clks(100); + + expect_alert = 1; + cfg.scb_h.expected_alert["recov_err"].expected = 1; + cfg.scb_h.expected_alert["recov_err"].max_delay = 1000; + flash_op_inv.op = FlashOpInvalid; + flash_ctrl_start_op(flash_op_inv); + wait_flash_op_done(); + + ral.err_code.op_err.predict(expect_alert); + check_exp_alert_status(expect_alert, "op_err", flash_op_inv, flash_op_data); + cfg.scb_h.expected_alert["recov_err"].expected = 0; + + flash_op_rd.op = FlashOpRead; + flash_op_data = {}; + flash_ctrl_start_op(flash_op_rd); + flash_ctrl_read(flash_op_rd.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + flash_op_er.op = FlashOpErase; + flash_ctrl_start_op(flash_op_er); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + end + + flash_op_inv.op = FlashOpInvalid; + cfg.scb_h.expected_alert["recov_err"].expected = 1; + flash_ctrl_start_op(flash_op_inv); + wait_flash_op_done(); + ral.err_code.op_err.predict(expect_alert); + check_exp_alert_status(expect_alert, "op_err", flash_op_inv, flash_op_data); + cfg.scb_h.expected_alert["recov_err"].expected = 0; + + flash_op_rd.op = FlashOpRead; + flash_op_data = {}; + flash_ctrl_start_op(flash_op_rd); + flash_ctrl_read(flash_op_rd.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + endtask : do_op + +endclass : flash_ctrl_invalid_op_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_lcmgr_intg_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_lcmgr_intg_vseq.sv new file mode 100644 index 0000000000000..f09d7fbf1ffe5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_lcmgr_intg_vseq.sv @@ -0,0 +1,43 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence triggers std_fault_status.lcmgr_intg_err by force +class flash_ctrl_lcmgr_intg_vseq extends flash_ctrl_err_base_vseq; + `uvm_object_utils(flash_ctrl_lcmgr_intg_vseq) + `uvm_object_new + + task run_main_event; + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + apply_reset(); + init_controller(.non_blocking(1)); + endtask // init_controller + + // fatal_std_err + task run_error_event(); + int wait_timeout_ns = 50_000; + string path = "tb.dut.u_flash_hw_if.rdata_i[38:32]"; + logic [38:0] enc_data; + // Generate error intg from random data to ensure + // error to occur when test force this field. + enc_data = prim_secded_pkg::prim_secded_39_32_enc(($urandom() + 1)); + + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.hw_rvalid == 1);, + , wait_timeout_ns) + cfg.scb_h.expected_alert["fatal_std_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_std_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_std_err"] = 10000; + + $assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + #0; + @(posedge cfg.flash_ctrl_vif.hw_rvalid); + `DV_CHECK(uvm_hdl_force(path, enc_data[38:32])) + // Make sure this is not too long. + // If this is too long, it will causes other fatal errors. + cfg.clk_rst_vif.wait_clks(5); + `DV_CHECK(uvm_hdl_release(path)) + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.lcmgr_intg_err), .compare_value(1)); + endtask +endclass // flash_ctrl_lcmgr_intg_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_legacy_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_legacy_base_vseq.sv new file mode 100644 index 0000000000000..3515b5a2789e9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_legacy_base_vseq.sv @@ -0,0 +1,70 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_legacy_base_vseq extends flash_ctrl_otf_base_vseq; + + `uvm_object_utils(flash_ctrl_legacy_base_vseq) + `uvm_object_new + flash_op_t ctrl; + int num, bank; + + constraint rand_op_c { + solve fractions before rand_op.addr; + solve flash_program_data before rand_op; + solve rand_op.partition before rand_op.prog_sel, rand_op.addr; + solve rand_op.addr before rand_op.otf_addr; + solve rand_op.addr before rand_op.num_words; + if (cfg.seq_cfg.op_readonly_on_info_partition) { + if (cfg.seq_cfg.avoid_ro_partitions) { + rand_op.partition != FlashPartInfo; + } else { + rand_op.partition == FlashPartInfo -> rand_op.op == flash_ctrl_pkg::FlashOpRead; + } + } + if (cfg.seq_cfg.op_readonly_on_info1_partition) { + if (cfg.seq_cfg.avoid_ro_partitions) { + rand_op.partition != FlashPartInfo1; + } else { + rand_op.partition == FlashPartInfo1 -> rand_op.op == flash_ctrl_pkg::FlashOpRead; + } + } + // This added because in some extending env the info2 has special use. + if (cfg.seq_cfg.exclude_info2) { + rand_op.partition dist { FlashPartData := 1, [FlashPartInfo:FlashPartInfo1] :/ 1}; + } else { + rand_op.partition dist { FlashPartData := 1, [FlashPartInfo:FlashPartInfo2] :/ 1}; + } + rand_op.addr[TL_AW-1:BusAddrByteW] == 'h0; + rand_op.addr[1:0] == 'h0; + cfg.seq_cfg.addr_flash_word_aligned -> rand_op.addr[2] == 1'b0; + // If address starts from 0x4 and full prog_win size access(16), + // transaction creates prog_win error. + // To prevent that, make full size access always start from address[2:0] == 0. + if (fractions == 16) rand_op.addr[2] == 0; + if (rand_op.partition != FlashPartData) { + rand_op.addr inside + {[0:InfoTypeBytes[rand_op.partition>>1]-(FlashBankBytesPerWord*fractions)]}; + rand_op.prog_sel == 1; + } else { + rand_op.prog_sel == 0; + } + if (cfg.ecc_mode > FlashEccEnabled) { + if (rand_op.partition == FlashPartData) { + rand_op.addr[18:17] == cfg.tgt_pre[rand_op.partition][cfg.seq_cfg.ecc_err_target]; + } else { + rand_op.addr[10:9] == cfg.tgt_pre[rand_op.partition][cfg.seq_cfg.ecc_err_target]; + } + } + rand_op.otf_addr == rand_op.addr[BusAddrByteW-2:0]; + rand_op.num_words == fractions; + rand_op.addr[5:0] + ((rand_op.num_words - 1) * 4) < 64; + } + + virtual task pre_start(); + super.pre_start(); + cfg.preload_mem(); + cfg.scb_h.do_alert_check = 0; + expect_fatal_alerts = 1; + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mid_op_rst_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mid_op_rst_vseq.sv new file mode 100644 index 0000000000000..753a98db785a1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mid_op_rst_vseq.sv @@ -0,0 +1,304 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Flash middle operation reset test. Send reset via power ready signal +// in the middle of operation program, read, erase and erase suspend. +class flash_ctrl_mid_op_rst_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_mid_op_rst_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + + // enable high endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + + // num of words to program + cfg.seq_cfg.op_max_words = 4; + + endfunction + + parameter uint NUM_TRANS = 20; + + rand flash_op_t flash_op; + flash_op_t flash_op_q [NUM_TRANS]; + flash_op_t flash_op_erase; + flash_op_t flash_op_rd; + rand data_q_t flash_op_data; + bit poll_fifo_status; + bit expect_alert; + + // Constraint address to be in relevant range for the selected partition. + constraint addr_c { + if (flash_op.partition != FlashPartData) { + flash_op.addr inside + {[0:InfoTypeBytes[flash_op.partition>>1]-1], + [BytesPerBank:BytesPerBank+InfoTypeBytes[flash_op.partition>>1]-1]}; + } + } + + constraint flash_op_c { + flash_op.prog_sel == FlashProgSelNormal; + flash_op.erase_type == flash_ctrl_pkg::FlashErasePage; + flash_op.addr inside {[0 : FlashSizeBytes - 1]}; + flash_op.num_words inside {[1 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + } + + constraint flash_op_data_c { + solve flash_op before flash_op_data; + flash_op_data.size() == flash_op.num_words; + } + + // Memory protection regions settings. + flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + // Information partitions memory protection pages settings. + rand flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + foreach (mp_info_pages[i, j]) { + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + foreach (mp_info_pages[i][j][k]) { + mp_info_pages[i][j][k].en == MuBi4True; + mp_info_pages[i][j][k].read_en == MuBi4True; + mp_info_pages[i][j][k].program_en == MuBi4True; + mp_info_pages[i][j][k].erase_en == MuBi4True; + mp_info_pages[i][j][k].scramble_en == MuBi4False; + mp_info_pages[i][j][k].ecc_en == MuBi4False; + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + } + } + } + + // Default flash ctrl region settings. + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + rand mubi4_t default_region_he_en; + mubi4_t default_region_scramble_en; + mubi4_t default_region_ecc_en; + + // Bank erasability. + bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + task pre_start(); + cfg.skip_init_buf_en = 1; + super.pre_start(); + endtask // pre_start + + virtual task body(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + cfg.scb_check = 1; + cfg.check_full_scb_mem_model = 1; + poll_fifo_status = 1; + // program interrupt + for (int i = 0; i < NUM_TRANS; i++) begin + `DV_CHECK_RANDOMIZE_WITH_FATAL(this, flash_op.op == FlashOpProgram; + flash_op.partition == FlashPartData;) + flash_op_q[i] = flash_op; + do_cfg(); + do_prog(flash_op); + fork + begin : isolation_fork_prog + fork + begin + cfg.clk_rst_vif.wait_clks(100); + end + begin + cfg.clk_rst_vif.wait_clks(30); + low_ready_h(); + end + join_any; + disable fork; + end : isolation_fork_prog + join + wait_cfg_prog_rd(); + end + // erase interrupt + for (int i = 0; i < NUM_TRANS; i++) begin + do_erase(flash_op_q[i]); + fork + begin : isolation_fork_erase + fork + begin + cfg.clk_rst_vif.wait_clks(100); + end + begin + cfg.clk_rst_vif.wait_clks(30); + low_ready_h(); + end + join_any; + disable fork; + end : isolation_fork_erase + join + wait_cfg_prog_rd(); + end + + // erase suspend interrupt + fork + begin : isolation_fork_erase_suspend + fork + begin + do_erase(flash_op_q[0]); + cfg.clk_rst_vif.wait_clks(100); + end + begin + cfg.clk_rst_vif.wait_clks(30); + csr_wr(.ptr(ral.erase_suspend), .value(1)); + low_ready_h(); + end + join + end : isolation_fork_erase_suspend + join + wait_cfg_prog_rd(); + + // cleaning before full memory check + for (int i = 0; i < NUM_TRANS; i++) begin + do_erase(flash_op_q[i]); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + end + + // read interrupt + `DV_CHECK_RANDOMIZE_WITH_FATAL(this, flash_op.op == FlashOpRead; + flash_op.partition == FlashPartData; + flash_op.num_words == 1;) + do_cfg(); + fork + begin : isolation_fork_read + fork + begin + do_read(flash_op); + cfg.clk_rst_vif.wait_clks(100); + end + begin + cfg.clk_rst_vif.wait_clks(19); + low_ready_h(); + apply_reset(); + end + join + end : isolation_fork_read + join + endtask : body + + // Task to wait and then do random program and read transactions and check that they complete + // successfully (and by this making sure the flash recovered from the power-loss) + task wait_cfg_prog_rd(); + data_q_t exp_data; + flash_op_t myop; + // Wait some time to make sure flash is stable again. + cfg.clk_rst_vif.wait_clks(1_000); + // Make sure that flash initialization is complete. + csr_spinwait(.ptr(ral.status.init_wip), .exp_data(1'b0)); + // Make sure to clear the op_status register's done. + clear_outstanding_done(); + // Configure memry protection. + do_cfg(); + // Do random program transaction, then check it completed successfully. + `DV_CHECK_RANDOMIZE_WITH_FATAL(this, flash_op.op == FlashOpProgram; + flash_op.partition == FlashPartData;) + do_prog(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + cfg.flash_mem_bkdr_read_check(flash_op, exp_data); + cfg.clk_rst_vif.wait_clks(100); + // Store program op for read back. + myop = flash_op; + + // Do read back transaction, then check it completed successfully. + `DV_CHECK_RANDOMIZE_WITH_FATAL(this, flash_op.op == FlashOpRead; + flash_op.addr == myop.addr; + flash_op.partition == FlashPartData; + flash_op.num_words == 1;) + do_read(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.read_timeout_ns)); + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + endtask : wait_cfg_prog_rd + + // Task to clear the op_status register's done before starting the next transaction. + task clear_outstanding_done(); + uvm_reg_data_t data; + bit done; + csr_rd(.ptr(ral.op_status), .value(data)); + done = get_field_val(ral.op_status.done, data); + if (done) begin + data = get_csr_val_with_updated_field(ral.op_status.done, data, 0); + csr_wr(.ptr(ral.op_status), .value(data)); + end + endtask : clear_outstanding_done + + virtual task do_cfg(); + + // Default region settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_ecc_en = MuBi4False; + default_region_scramble_en = MuBi4False; + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + // No Protection + foreach (mp_regions[i]) begin + mp_regions[i].en = MuBi4False; + end + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + //Enable Bank erase + bank_erase_en = {NumBanks{1'b1}}; + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + `uvm_info(`gfn, $sformatf("FLASH OP PROGRAM START OP: %0p", flash_op), UVM_HIGH) + endtask : do_cfg + + virtual task do_erase(flash_op_t flash_op_erase); + flash_op_erase.op = FlashOpErase; + flash_ctrl_start_op(flash_op_erase); + endtask : do_erase + + virtual task do_prog(flash_op_t flash_op); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + endtask : do_prog + + virtual task do_read(flash_op_t flash_op_rd); + poll_fifo_status = 0; + cfg.flash_mem_bkdr_write(.flash_op(flash_op_rd), .scheme(FlashMemInitRandomize)); + flash_ctrl_start_op(flash_op_rd); + flash_ctrl_read(flash_op_rd.num_words, flash_op_data, poll_fifo_status); + endtask : do_read + + virtual task low_ready_h(); + cfg.flash_ctrl_vif.power_ready_h = 1'b0; + cfg.clk_rst_vif.wait_clks(1); + cfg.flash_ctrl_vif.power_ready_h = 1'b1; + endtask : low_ready_h + +endclass : flash_ctrl_mid_op_rst_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mp_regions_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mp_regions_vseq.sv new file mode 100644 index 0000000000000..6e0016a03ebfc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_mp_regions_vseq.sv @@ -0,0 +1,415 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Memory protect test. Overlapping regions with randomization. +// Send one op among program, read and erase (page) in each trans round. +// This sequence uses local mp_region db. Don't use cfg.get_region() +class flash_ctrl_mp_regions_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_mp_regions_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + + // set page erase as default + cfg.seq_cfg.op_erase_type_bank_pc = 0; + + // enable high endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + endfunction + + rand flash_op_t flash_op; + flash_op_t flash_op_pg_erase; + flash_op_t flash_op_bk_erase; + + data_b_t set_val; + + bit poll_fifo_status; + bit illegal_trans = 0; + int trans_cnt = 0; + int exp_alert_cnt = 0; + + // Memory protection regions settings. + rand flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + // Information partitions memory protection pages settings. + rand + flash_bank_mp_info_page_cfg_t + mp_info_pages[NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint solv_order_c { + solve mp_regions, mp_info_pages before flash_op; + } + // Constraint address to be in relevant range for the selected partition. + constraint addr_c { + if (flash_op.partition != FlashPartData) { + flash_op.addr inside + {[0:InfoTypeBytes[flash_op.partition>>1]-1], + [BytesPerBank:BytesPerBank+InfoTypeBytes[flash_op.partition>>1]-1]}; + } + } + + constraint flash_op_c { + flash_op.op inside {FlashOpRead, FlashOpProgram, FlashOpErase}; + flash_op.addr inside {[0 : FlashSizeBytes - 1]}; + flash_op.otf_addr == flash_op.addr[OTFHostId-1:0]; + // Bank erase is supported only for data & 1st info partitions + flash_op.partition != FlashPartData && flash_op.partition != FlashPartInfo -> + flash_op.erase_type == flash_ctrl_pkg::FlashErasePage; + + flash_op.erase_type dist { + flash_ctrl_pkg::FlashErasePage :/ (100 - cfg.seq_cfg.op_erase_type_bank_pc), + flash_ctrl_pkg::FlashEraseBank :/ cfg.seq_cfg.op_erase_type_bank_pc + }; + + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + } + + constraint mp_regions_c { + + foreach (mp_regions[i]) { + + mp_regions[i].scramble_en == MuBi4False; + + mp_regions[i].ecc_en == MuBi4False; + + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + + mp_regions[i].start_page dist { + 0 :/ 10, + [1 : FlashNumPages - 2] :/ 80, + FlashNumPages - 1 :/ 10 + }; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + } + } + + constraint mp_info_pages_c { + + foreach (mp_info_pages[i]) { + if (cfg.seq_cfg.op_readonly_on_info_partition) { + foreach (mp_info_pages[i][0][k]) { + mp_info_pages[i][0][k].program_en == MuBi4False; + mp_info_pages[i][0][k].erase_en == MuBi4False; + } + } + if (cfg.seq_cfg.op_readonly_on_info1_partition) { + foreach (mp_info_pages[i][1][k]) { + mp_info_pages[i][1][k].program_en == MuBi4False; + mp_info_pages[i][1][k].erase_en == MuBi4False; + } + } + } + + foreach (mp_info_pages[i, j]) { + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + + foreach (mp_info_pages[i][j][k]) { + mp_info_pages[i][j][k].en dist { + MuBi4True := 4, + MuBi4False := 1 + }; + + mp_info_pages[i][j][k].scramble_en == MuBi4False; + + mp_info_pages[i][j][k].ecc_en == MuBi4False; + + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_he_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_he_en_pc[i][j] + }; + } + } + } + + // Default flash ctrl region settings. + rand mubi4_t default_region_read_en; + rand mubi4_t default_region_program_en; + rand mubi4_t default_region_erase_en; + rand mubi4_t default_region_he_en; + mubi4_t default_region_scramble_en; + mubi4_t default_region_ecc_en; + + // Bank erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + rand data_q_t flash_op_data; + uvm_reg_data_t data; + // number of randomized transactions + int num_trans = 100; + int iter = 0; + + virtual task pre_start(); + super.pre_start(); + // Flash operations can create multiple recov_err alerts. + // With default ack_*_max values, sometimes, alert agent missed catching + // every recov_err. So reduce max value to get finer detect resolution. + cfg.m_alert_agent_cfgs["recov_err"].ack_delay_max = 5; + cfg.m_alert_agent_cfgs["recov_err"].ack_stable_max = 5; + endtask // pre_start + + virtual task body(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + cfg.scb_check = 1; + + repeat (num_trans) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + cfg.default_region_cfg.read_en = default_region_read_en; + cfg.default_region_cfg.program_en = default_region_program_en; + cfg.default_region_cfg.erase_en = default_region_erase_en; + cfg.default_region_cfg.he_en = default_region_he_en; + init_p2r_map(); + update_p2r_map(mp_regions); + + do_mp_reg(); + if (illegal_trans) begin + exp_alert_cnt++; + end + illegal_trans = 0; + + // This 'wait' will be terminated by expected_alert's max_delay from scoreboard + `uvm_info("seq", $sformatf("wait for recov_err alert exp:%0d obs:%0d max_delay:%0d", + exp_alert_cnt, cfg.scb_h.alert_count["recov_err"], + cfg.scb_h.expected_alert["recov_err"].max_delay), UVM_MEDIUM) + + `DV_SPINWAIT(wait(cfg.scb_h.alert_count["recov_err"] == exp_alert_cnt);, + $sformatf({"wait timeout for alert_count == exp_alertcnt after do_mp_reg() ", + "alert_cnt:%0d exp_alert_cnt:%0d"}, + cfg.scb_h.alert_count["recov_err"], exp_alert_cnt), + cfg.alert_max_delay_in_ns) + + cfg.scb_h.expected_alert["recov_err"].expected = 0; + end + // Send info region access and bank erase + exp_alert_cnt = 0; + cfg.scb_h.alert_count["recov_err"] = 0; + + `DV_CHECK_RANDOMIZE_FATAL(this) + + configure_flash_protection(); + `uvm_info("seq", $sformatf("info / bank op start... "), UVM_MEDIUM) + repeat(50) begin + `uvm_info("seq", $sformatf("iter : %0d", iter++), UVM_MEDIUM) + //clean scb mem + cfg.reset_scb_mem(); + + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(flash_op, + flash_op.partition == FlashPartInfo;) + `uvm_info(`gfn, $sformatf("BANK ERASE PART %0p", flash_op), UVM_LOW) + do_info_bank(); + illegal_trans = 0; + `uvm_info("do_info_bank", $sformatf("done: alert_cnt exp:%0d obs:%0d", + exp_alert_cnt, cfg.scb_h.alert_count["recov_err"]), + UVM_MEDIUM) + + `DV_SPINWAIT(wait(cfg.scb_h.alert_count["recov_err"] == exp_alert_cnt);, + $sformatf({"wait timeout for alert_count == exp_alertcnt after do_info_bank() ", + "alert_cnt:%0d exp_alert_cnt:%0d"}, + cfg.scb_h.alert_count["recov_err"], exp_alert_cnt), + cfg.alert_max_delay_in_ns) + + `DV_SPINWAIT(wait(cfg.scb_h.hs_state == AlertAckComplete);, + "wait timeout for hs_state == AlertAckComplete", + cfg.alert_max_delay_in_ns) + + cfg.scb_h.expected_alert["recov_err"].expected = 0; + end + endtask : body + + virtual task do_mp_reg(); + int page ,bank; + flash_mp_region_cfg_t my_region; + poll_fifo_status = 1; + // Default region settings + default_region_ecc_en = MuBi4False; + default_region_scramble_en = MuBi4False; + cfg.allow_spec_info_acc = 3'b111; + configure_flash_protection(); + // Randomize Write Data + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(flash_op_data, + flash_op_data.size == flash_op.num_words;) + `uvm_info("do_mp_reg", $sformatf("flash_op: %p", flash_op), UVM_MEDIUM) + bank = flash_op.addr[OTFBankId]; + if (flash_op.partition != FlashPartData) begin + illegal_trans |= check_info_part(flash_op, "check_info_tran"); + end + // For ctrl read, you have to validate per Qword + if (flash_op.op == FlashOpRead) begin + int is_odd = flash_op.addr[2]; + int size = (flash_op.num_words + is_odd) / 2; + int tail = (flash_op.num_words + is_odd) % 2; + addr_t tmp_addr = flash_op.addr; + flash_op.addr[2:0] = 0; + + `uvm_info("do_mp_reg", $sformatf("size:%0d tail:%0d bank:%0d addr:%x", + size, tail, bank, tmp_addr), UVM_MEDIUM) + for (int i = 0; i < size; i++) begin + flash_op.otf_addr = flash_op.addr[OTFBankId-1:0]; + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = get_region_from_page(page); + end else begin + page = cfg.addr2page(flash_op.addr[OTFBankId-1:0]); + my_region = cfg.get_region_from_info(mp_info_pages[bank][flash_op.partition>>1][page]); + end + illegal_trans |= validate_flash_op(flash_op, my_region); + flash_op.addr += 8; + end // for (int i = 0; i < size; i++) + if (tail) begin + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = get_region_from_page(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(mp_info_pages[bank][flash_op.partition>>1][page]); + end + illegal_trans |= validate_flash_op(flash_op, my_region); + end // if (tail) + flash_op.addr = tmp_addr; + end else begin // if (flash_op.op == FlashOpRead) + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = get_region_from_page(page); + end else begin + page = cfg.addr2page(flash_op.addr[OTFBankId-1:0]); + my_region = cfg.get_region_from_info(mp_info_pages[bank][flash_op.partition>>1][page]); + end + illegal_trans = validate_flash_op(flash_op, my_region); + end + + if(illegal_trans) begin + set_otf_exp_alert("recov_err"); + end + + `uvm_info("do_mp_reg", $sformatf("trans:%0d page:%x region:%0d illegal_trans:%0d", + ++trans_cnt, page, cfg.p2r_map[page], illegal_trans), + UVM_MEDIUM) + + if (flash_op.op == FlashOpProgram) begin + //prepare for program op + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + end else if (flash_op.op == FlashOpRead) begin + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + end else begin + flash_op.addr[10:0] = 'h0; + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + end + endtask : do_mp_reg + + virtual task do_info_bank(); + int info_page_addr, num_info_pages; + int info_sel, bank; + + flash_bank_mp_info_page_cfg_t my_info; + + poll_fifo_status = 1; + + flash_op.erase_type = flash_ctrl_pkg::FlashEraseBank; + flash_op.num_words = 16; + info_sel = flash_op.partition >> 1; + bank = flash_op.addr[19]; + num_info_pages = InfoTypeSize[info_sel]; + info_page_addr = $urandom_range(1, num_info_pages) - 1; + flash_op.addr[18:0] = 'h0; + flash_op.addr += (BytesPerPage * info_page_addr); + my_info = mp_info_pages[flash_op.addr[19]][info_sel][info_page_addr]; + + // Bank erase + if (flash_op.op == FlashOpErase) begin + illegal_trans = (bank_erase_en[bank] == 0); + end else begin + illegal_trans = validate_flash_info(flash_op, my_info); + end + + if(illegal_trans) begin + if (flash_op.op != FlashOpErase) begin + cfg.scb_h.expected_alert["recov_err"].expected = 1; + cfg.scb_h.exp_alert_contd["recov_err"] = 31; + exp_alert_cnt += 32; + end else begin + cfg.scb_h.expected_alert["recov_err"].expected = 1; + exp_alert_cnt +=1; + end + cfg.scb_h.expected_alert["recov_err"].max_delay = 2000; // cycles + end + `uvm_info("do_info_bank", $sformatf("flash_op: %p", flash_op), UVM_MEDIUM) + `uvm_info("do_info_bank", $sformatf("INFO_TBL[%0d][%0d][%0d] = %p", flash_op.addr[19], + info_sel, info_page_addr, my_info), UVM_MEDIUM) + `uvm_info("do_info_bank", $sformatf("trans:%0d illegal_trans:%0d exp_alert:%0d op:%s", + ++trans_cnt, illegal_trans, + cfg.scb_h.expected_alert["recov_err"].expected, + flash_op.op.name), + UVM_MEDIUM) + + if (flash_op.op == FlashOpProgram) begin + controller_program_page(flash_op); + end else if (flash_op.op == FlashOpRead) begin // if (flash_op.op == FlashOpProgram) + controller_read_page(flash_op); + end else begin // if (flash_op.op == FlashOpRead) + `uvm_info("do_info_bank", $sformatf("bank_erase_en[%0d]=%0d", + bank,bank_erase_en[bank]), UVM_MEDIUM) + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + end + endtask : do_info_bank + + task configure_flash_protection(); + // Configure the flash with scramble disable. + foreach (mp_regions[k]) begin + mp_regions[k].scramble_en = MuBi4False; + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + end + //Enable Bank erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + endtask // configure_flash_protection + + function flash_mp_region_cfg_t get_region_from_page(int page, bit dis = 1); + flash_mp_region_cfg_t my_region; + if (cfg.p2r_map[page] == 8) begin + my_region = cfg.default_region_cfg; + end else begin + my_region = this.mp_regions[cfg.p2r_map[page]]; + if (my_region.en != MuBi4True) my_region = cfg.default_region_cfg; + end + if (dis) begin + `uvm_info("get_region_from_page", $sformatf("page:%0d --> region:%0d", + page, cfg.p2r_map[page]), UVM_MEDIUM) + end + return my_region; + endfunction // get_region_from_page + +endclass : flash_ctrl_mp_regions_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv new file mode 100644 index 0000000000000..13ff4e2fb98d4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otf_base_vseq.sv @@ -0,0 +1,1555 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This is base class for on the fly mode test sequence. +// On the fly mode test checks data integrity per transaction (program or read), +// and doesn't rely on reference memory model in the test bench. +class flash_ctrl_otf_base_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_otf_base_vseq) + `uvm_object_new + + // The maximum number of attempts to get an address that has not been previously written. + localparam int MaxProgAttempts = 20; + + // Used for tracing programmed data + bit [15:0] global_pat_cnt = 16'hA000; + + // Double bit err is created + bit global_derr_is_set = 0; + + // Trace host read ountstanding + int d_cnt1, d_cnt2; + + // Number of controller transactions per a single task + // Min: 1 Max:32 + rand int ctrl_data_num; + rand int ctrl_info_num; + rand int ctrl_num; + + rand bit is_addr_odd; + rand int fractions; + + // flash op + // WIP. not all field is valid. + rand flash_op_t rand_op; + + // Permission to access special partition + rand bit [2:0] allow_spec_info_acc; + rand bit all_entry_en; + + // scramble and ecc config mode + rand otf_cfg_mode_e scr_ecc_cfg; + + rand flash_mp_region_cfg_t rand_regions[MpRegions]; + rand flash_bank_mp_info_page_cfg_t rand_info[NumBanks][InfoTypes][$]; + flash_mem_init_e otf_flash_init = FlashMemInitEccMode; + + constraint all_ent_c { + solve all_entry_en before rand_regions, rand_info; + if (cfg.en_always_any) all_entry_en == 1; + else all_entry_en dist { 1 := 1, 0 := 4}; + } + constraint scr_ecc_c { + scr_ecc_cfg dist { OTFCfgRand := 5, OTFCfgTrue := 4}; + } + constraint rand_regions_c { + foreach (rand_regions[i]) { + if (all_entry_en) rand_regions[i].en == MuBi4True; + rand_regions[i].start_page dist { + 0 := 1, + [1 : FlashNumPages - 2] :/ 8, + FlashNumPages - 1 := 1 + }; + rand_regions[i].num_pages inside {[1 : FlashNumPages - rand_regions[i].start_page]}; + rand_regions[i].num_pages <= 32; + rand_regions[i].scramble_en dist { MuBi4True := 4, MuBi4False := 1}; + rand_regions[i].ecc_en dist { MuBi4True := 4, MuBi4False := 1}; + } + } + constraint rand_info_c { + foreach (rand_info[i, j]) { + rand_info[i][j].size() == InfoTypeSize[j]; + foreach (rand_info[i][j][k]) { + if (all_entry_en) rand_info[i][j][k].en == MuBi4True; + rand_info[i][j][k].en dist { MuBi4True := 4, MuBi4False :=1}; + if (cfg.en_always_read) rand_info[i][j][k].read_en == MuBi4True; + rand_info[i][j][k].scramble_en dist { MuBi4True := 4, MuBi4False :=1}; + rand_info[i][j][k].ecc_en dist { MuBi4True := 4, MuBi4False :=1}; + } + } + } + constraint ctrl_data_num_c { + ctrl_data_num dist { CtrlTransMin := 2, [2:31] :/ 1, CtrlTransMax := 2}; + } + constraint fractions_c { + if (cfg.seq_cfg.trigger_prog_res_fault) fractions inside {[17:32]}; + else fractions dist { [1:4] := 4, [5:15] := 1, 16 := 1}; + cfg.seq_cfg.addr_flash_word_aligned -> fractions[0] == 1'b0; + } + constraint ctrl_info_num_c { + solve rand_op before ctrl_info_num; + ctrl_info_num inside {[1 : InfoTypeSize[rand_op.partition >> 1]]}; + if (cfg.ecc_mode > FlashEccEnabled) ctrl_info_num * fractions <= 128; + } + constraint ctrl_num_c { + solve ctrl_data_num, ctrl_info_num, rand_op before ctrl_num; + if (rand_op.partition == FlashPartData) ctrl_num == ctrl_data_num; + else ctrl_num == ctrl_info_num; + } + + constraint rand_op_c { + solve fractions before rand_op.addr; + solve flash_program_data before rand_op; + solve rand_op.partition before rand_op.prog_sel, rand_op.addr; + solve rand_op.addr before rand_op.otf_addr; + solve rand_op.addr before rand_op.num_words; + + if (cfg.seq_cfg.op_readonly_on_info_partition) { + if (cfg.seq_cfg.avoid_ro_partitions) { + rand_op.partition != FlashPartInfo; + } else { + rand_op.partition == FlashPartInfo -> rand_op.op == flash_ctrl_pkg::FlashOpRead; + } + } + if (cfg.seq_cfg.op_readonly_on_info1_partition) { + if (cfg.seq_cfg.avoid_ro_partitions) { + rand_op.partition != FlashPartInfo1; + } else { + rand_op.partition == FlashPartInfo1 -> rand_op.op == flash_ctrl_pkg::FlashOpRead; + } + } + rand_op.partition dist { FlashPartData := 1, [FlashPartInfo:FlashPartInfo2] :/ 1}; + rand_op.addr[TL_AW-1:BusAddrByteW] == 'h0; + rand_op.addr[1:0] == 'h0; + cfg.seq_cfg.addr_flash_word_aligned -> rand_op.addr[2] == 1'b0; + // If address starts from 0x4 and full prog_win size access(16), + // transaction creates prog_win error. + // To prevent that, make full size access always start from address[2:0] == 0. + if (fractions == 16) rand_op.addr[2] == 0; + // Make sure that the operation will not cross the selected partition boundries. + if (rand_op.partition != FlashPartData) { + rand_op.addr inside + {[0:InfoTypeBytes[rand_op.partition>>1]-(FlashBankBytesPerWord*fractions)]}; + rand_op.prog_sel == 1; + } else { + rand_op.prog_sel == 0; + } + if (cfg.ecc_mode > FlashEccEnabled) { + if (rand_op.partition == FlashPartData) { + rand_op.addr[18:17] == cfg.tgt_pre[rand_op.partition][cfg.seq_cfg.ecc_err_target]; + } else { + rand_op.addr[10:9] == cfg.tgt_pre[rand_op.partition][cfg.seq_cfg.ecc_err_target]; + } + } + rand_op.otf_addr == rand_op.addr[BusAddrByteW-2:0]; + // Maybe remove this to avoid constraint complexity? + rand_op.num_words == fractions; + } + constraint special_info_acc_c { + allow_spec_info_acc dist { 3'h7 := 1, 3'h0 := 1, [1:6] :/ 2}; + } + + // If the partition that selected configured as read-only, set otf_wr_pct to 0 to make sure to + // not program those partitions. + int otf_wr_pct_temp, otf_bwr_pct_temp; + function void sync_otf_wr_ro_part(); + if ((cfg.seq_cfg.op_readonly_on_info_partition && + rand_op.partition == FlashPartInfo) || + (cfg.seq_cfg.op_readonly_on_info1_partition && + rand_op.partition == FlashPartInfo1)) begin + otf_wr_pct_temp = cfg.otf_wr_pct; + otf_bwr_pct_temp = cfg.otf_bwr_pct; + cfg.otf_wr_pct = 0; + cfg.otf_bwr_pct = 0; + end else begin + cfg.otf_wr_pct = otf_wr_pct_temp; + cfg.otf_bwr_pct = otf_bwr_pct_temp; + end + endfunction : sync_otf_wr_ro_part + + function void post_randomize(); + super.post_randomize(); + foreach (rand_regions[i]) begin + if (cfg.en_always_read) rand_regions[i].read_en = MuBi4True; + if (cfg.en_always_prog) rand_regions[i].program_en = MuBi4True; + if (cfg.en_always_erase) rand_regions[i].erase_en = MuBi4True; + end + foreach (rand_info[i, j, k]) begin + if (cfg.en_always_read) rand_info[i][j][k].read_en = MuBi4True; + if (cfg.en_always_prog) rand_info[i][j][k].program_en = MuBi4True; + if (cfg.en_always_erase) rand_info[i][j][k].erase_en = MuBi4True; + end + if (cfg.en_all_info_acc) allow_spec_info_acc = 3'h7; + + // overwrite secret_partition cfg with hw_cfg0 + rand_info[0][0][1] = conv2env_mp_info(flash_ctrl_pkg::CfgAllowRead); + rand_info[0][0][2] = conv2env_mp_info(flash_ctrl_pkg::CfgAllowRead); + endfunction : post_randomize + + virtual task pre_start(); + bit csr_test_mode = 0; + string run_seq_name = ""; + // Erased page doesn't go through descramble. + // To maintain high stress rate, + // keep flash_init to FlashMemInitRandomize + + void'($value$plusargs("csr_test_mode=%0b", csr_test_mode)); + void'($value$plusargs("run_%0s", run_seq_name)); + if (csr_test_mode == 1 || + run_seq_name inside{"tl_intg_err", "sec_cm_fi"}) begin + cfg.skip_init = 1; + + super.pre_start(); + end else begin + flash_init_c.constraint_mode(0); + if (cfg.ecc_mode > FlashEccEnabled) begin + foreach (cfg.tgt_pre[partition]) begin + cfg.tgt_pre[partition].shuffle(); + `uvm_info("cfg_summary", + $sformatf("prefix:%s:rd:%2b dr:%2b wr:%2b er:%2b", + partition.name, cfg.tgt_pre[partition][TgtRd], + cfg.tgt_pre[partition][TgtDr], cfg.tgt_pre[partition][TgtWr], + cfg.tgt_pre[partition][TgtEr]), + UVM_MEDIUM) + end + end + flash_init = otf_flash_init; + + init_p2r_map(); + `uvm_info("cfg_summary", + $sformatf({"flash_init:%s ecc_mode %s allow_spec_info_acc:%3b", + " scr_ecc_cfg:%s always_read:%0d"}, + flash_init.name, cfg.ecc_mode.name, allow_spec_info_acc, + scr_ecc_cfg.name, cfg.en_always_read), + UVM_MEDIUM) + + configure_otf_mode(); + super.pre_start(); + if (cfg.seq_cfg.en_init_keys_seeds == 1) begin + `DV_SPINWAIT(while (otp_key_init_done != 2'b11) cfg.clk_rst_vif.wait_clks(1);, + "timeout waiting otp_key_init_done", 100_000) + end + + // Need additional flash update after key init is done + case (cfg.ecc_mode) + FlashEccDisabled: begin + // In this mode, write and read are not separated. + // When write and read happen at the same address, + // unexpected ecc error can be created. + flash_otf_region_cfg(); + end + FlashEccEnabled: begin + // This mode use tb memory model. + flash_otf_region_cfg(.scr_mode(scr_ecc_cfg), .ecc_mode(scr_ecc_cfg)); + end + default: begin + flash_otf_region_cfg(.scr_mode(scr_ecc_cfg), .ecc_mode(OTFCfgTrue)); + // update_secret_partition program random data to all secret partition. + // revert change and keep update only for read zone. + flash_otf_set_secret_part(); + flash_otf_mem_read_zone_init(); + end + endcase // case (cfg.ecc_mode) + if (cfg.ecc_mode > FlashSerrTestMode) begin + cfg.scb_h.do_alert_check = 0; + end + + cfg.allow_spec_info_acc = allow_spec_info_acc; + update_partition_access(cfg.allow_spec_info_acc); + // Polling init wip is done + csr_spinwait(.ptr(ral.status.init_wip), .exp_data(1'b0)); + cfg.m_fpp_agent_cfg.mon_start = 1; + `uvm_info("pre_start", "TEST PARAM SUMMARY", UVM_MEDIUM) + `uvm_info("pre_start", " ** sequence param", UVM_MEDIUM) + `uvm_info("pre_start", $sformatf({" otf_num_rw:%0d otf_num_hr:%0d", + " otf_wr_pct:%0d otf_rd_pct:%0d"}, + cfg.otf_num_rw, + cfg.otf_num_hr, + cfg.otf_wr_pct, + cfg.otf_rd_pct), UVM_MEDIUM) + + if (cfg.intr_mode == 1) begin + cfg.rd_lvl = $urandom_range(1,15); + cfg.wr_lvl = $urandom_range(1,3); + `uvm_info("pre_start", $sformatf("interrupt testmode. rd_lvl:%0d wr_lvl:%0d", + cfg.rd_lvl, cfg.wr_lvl), UVM_MEDIUM) + + flash_ctrl_fifo_levels_cfg_intr(cfg.rd_lvl, cfg.wr_lvl); + flash_ctrl_intr_enable(6'h3c); + end + end + otf_wr_pct_temp = cfg.otf_wr_pct; + otf_bwr_pct_temp = cfg.otf_bwr_pct; + endtask : pre_start + + // On the fly scoreboard mode + // This will disable reference memory check in the end of the test + // as well as all intermediate transaction update for memory model. + function void configure_otf_mode(); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + cfg.seq_cfg.en_init_keys_seeds = 1; + cfg.scb_check = 0; + cfg.check_full_scb_mem_model = 0; + cfg.scb_otf_en = 1; + foreach (cfg.m_tl_agent_cfgs[i]) begin + cfg.m_tl_agent_cfgs[i].a_valid_delay_min = 0; + cfg.m_tl_agent_cfgs[i].a_valid_delay_max = 0; + cfg.m_tl_agent_cfgs[i].d_valid_delay_min = 0; + cfg.m_tl_agent_cfgs[i].d_valid_delay_max = 0; + cfg.m_tl_agent_cfgs[i].a_ready_delay_min = 0; + cfg.m_tl_agent_cfgs[i].a_ready_delay_max = 0; + cfg.m_tl_agent_cfgs[i].d_ready_delay_min = 0; + cfg.m_tl_agent_cfgs[i].d_ready_delay_max = 0; + end + endfunction + + // This is to configure the target prefixes for ecc errors. + protected function void set_ecc_err_target(flash_tgt_prefix_e target); + cfg.seq_cfg.ecc_err_target = target; + endfunction + + protected function void get_bank_and_num(input flash_op_t flash_op, ref int bank, ref int num); + bank = flash_op.addr[OTFBankId]; + num = ctrl_num; + endfunction + + // Randomizes until a flash operation satisfies the constraints and its address was not + // previously written. It issues an error when failing after MaxProgAttempts attempts. + protected function bit try_create_prog_op(ref flash_op_t ctrl, ref int bank, ref int num); + int attempts = 0; + bit prev_addr_flash_word_aligned = cfg.seq_cfg.addr_flash_word_aligned; + bit prev_avoid_ro_partitions = cfg.seq_cfg.avoid_ro_partitions; + flash_tgt_prefix_e prev_err_target = cfg.seq_cfg.ecc_err_target; + + // Set the config to avoid half-word writes and readonly partitions. + cfg.seq_cfg.addr_flash_word_aligned = 1'b1; + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + set_ecc_err_target(TgtWr); + while (attempts < MaxProgAttempts) begin + otf_addr_t end_addr; + `DV_CHECK_RANDOMIZE_FATAL(this) + // This should not happen since cfg.seq_cfg.addr_flash_word_aligned is set, + // but perhaps the constraint solver is not working as expected. + `DV_CHECK_EQ(rand_op.addr[2], 1'b0, "Constraint solver should set rand_op.addr[2] = 0") + `DV_CHECK_EQ(rand_op.otf_addr[2], 1'b0, + "Constraint solver should set rand_op.otf_addr[2] = 0") + `DV_CHECK_EQ(fractions[0], 1'b0, "Constraint solver should set fractions[0] = 0") + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + end_addr = ctrl.otf_addr + (num * fractions * 4) - 1; + `uvm_info(`gfn, $sformatf( + "Address start=%x end=%x num=%x fractions=%x", ctrl.otf_addr, end_addr, num, + fractions), UVM_MEDIUM) + if (!address_range_was_written(bank, ctrl.partition, ctrl.otf_addr, end_addr)) begin + `uvm_info(`gfn, $sformatf( + "Found unwritten address range bank:%0d %s [0x%x : 0x%x]", + bank, ctrl.partition.name, ctrl.otf_addr, end_addr), UVM_MEDIUM) + cfg.seq_cfg.addr_flash_word_aligned = prev_addr_flash_word_aligned; + cfg.seq_cfg.avoid_ro_partitions = prev_avoid_ro_partitions; + set_ecc_err_target(prev_err_target); + return 1'b1; + end + ++attempts; + end + `DV_CHECK(0, "Too many unsuccessful attempts to create a prog_op") + cfg.seq_cfg.addr_flash_word_aligned = prev_addr_flash_word_aligned; + cfg.seq_cfg.avoid_ro_partitions = prev_avoid_ro_partitions; + set_ecc_err_target(prev_err_target); + return 1'b0; + endfunction : try_create_prog_op + + // This detects if two addresses are in different program resolution window. + protected function bit in_different_prog_win(input otf_addr_t a, input otf_addr_t b); + return (a >> (FlashPgmResWidth + BusByteWidth)) != (b >> (FlashPgmResWidth + BusByteWidth)); + endfunction + + // This is a helper function for prog_flash. It performs a write operation, places the data + // in the fifo, checks protection, and checks for program window resolution errors. If the + // write will proceed it creates an item with the expected results for the scoreboard. + local task issue_prog_request(input flash_op_t flash_op, ref shortint lcnt, input bit in_err, + input bit store_prog_data); + flash_mp_region_cfg_t region; + bit expect_prog_win_error = 1'b0; + bit drop = 1'b0; + int bank = flash_op.addr[TL_AW-1:OTFBankId]; + otf_addr_t end_addr; + + `uvm_info("prog_flash", $sformatf( + "addr:%x, otf_addr:%x wd:%0d, ", flash_op.addr, flash_op.otf_addr, + flash_op.num_words), UVM_MEDIUM) + flash_program_data = '{}; + // Each flash_program_data[] entry : 4B + // {global_cnt(16bits), lcnt(16bits)} + for (int j = 0; j < flash_op.num_words; j++) begin + if (cfg.wr_rnd_data) begin + flash_program_data.push_back($urandom); + end else begin + flash_program_data.push_back({global_pat_cnt, lcnt++}); + end + end + // Check permissions. + if (flash_op.partition == FlashPartData) begin + int page = cfg.addr2page(flash_op.addr); + region = cfg.get_region(page); + end else begin + // for region, use per bank page number + int page = cfg.addr2page(flash_op.otf_addr); + region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + drop |= check_info_part(flash_op, "prog_flash"); + end + drop |= validate_flash_op(flash_op, region); + if (drop) begin + `uvm_info("prog_flash", $sformatf("op:%s is not allowed in this region %p", + flash_op.op.name, region), UVM_MEDIUM) + end + + // Check program window resolution error. + end_addr = flash_op.otf_addr + flash_op.num_words * 4 - 1; + if (in_different_prog_win(flash_op.otf_addr, end_addr)) begin + `uvm_info("prog_flash", $sformatf("prog_window violation, start_addr:0x%x end_addr:0x%x", + flash_op.otf_addr, end_addr), UVM_MEDIUM) + expect_prog_win_error = 1; + drop = 1; + end + if (drop) set_otf_exp_alert("recov_err"); + + // Start the operation. + if (cfg.intr_mode) begin + flash_ctrl_intr_write(flash_op, flash_program_data); + end else begin + flash_ctrl_start_op(flash_op); + if (in_err) begin + cfg.tlul_core_exp_cnt += flash_op.num_words; + end + flash_ctrl_write(flash_program_data, !in_err); + + if (!in_err) wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + end + + if (expect_prog_win_error) begin + csr_rd_check(.ptr(ral.err_code.prog_win_err), .compare_value(1)); + drop = 1; + end + + `uvm_info("prog_flash", $sformatf("bank:%0d addr:%x otf_addr:%x part:%s wd:%0d", + bank, flash_op.addr, flash_op.otf_addr, + flash_op.partition.name, flash_op.num_words), UVM_MEDIUM) + if (drop) begin + uvm_reg_data_t ldata; + csr_rd(.ptr(ral.err_code), .value(ldata), .backdoor(1)); + `uvm_info("prog_flash", $sformatf("skip sb path due to err_code:%x", ldata), UVM_MEDIUM) + end else begin + flash_otf_item exp_item; + if (store_prog_data) cfg.prog_data[flash_op] = flash_program_data; + + flash_otf_print_data64(flash_program_data, "wdata"); + `uvm_create_obj(flash_otf_item, exp_item) + + `uvm_info("prog_flash", $sformatf("Creating exp_item for addr:0x%x", flash_op.addr), + UVM_MEDIUM) + exp_item.cmd = flash_op; + exp_item.dq = flash_program_data; + exp_item.region = region; + // Scramble data + exp_item.scramble(otp_addr_key, otp_data_key, flash_op.otf_addr, 1); + + p_sequencer.eg_exp_ctrl_port[bank].write(exp_item); + flash_phy_prim_agent_pkg::print_flash_data(exp_item.fq, + $sformatf("fdata_%0d bank %0d", cfg.otf_ctrl_wr_sent, bank)); + end + global_pat_cnt++; + cfg.otf_ctrl_wr_sent++; + endtask + + // Program flash in the unit of minimum resolution (4Byte) + // If data is not aligned to 8Byte, rtl pads all F to + // upper or lower 4Byte. + // @arg: flash_op_p : command struct return updated address after write + // @arg: bank: bank index to access flash + // @arg: num : number of 8 words range: [1 : 32] + // @arg: wd : number of 4byte (TL bus unit) : default : 16 + // @arg: in_err : inject fatal error causes flash access disable + virtual task prog_flash(ref flash_op_t flash_op, input int bank, int num, int wd = 16, + bit in_err = 0, bit store_prog_data = 0); + data_q_t flash_data_chunk; + bit poll_fifo_status = ~in_err; + shortint lcnt = 0; + otf_addr_t start_addr, end_addr; + data_4s_t tmp_data; + int tot_wd; + bit overflow = 0; + + `DV_CHECK_EQ(flash_op.otf_addr[2], 1'b0, + "prog_flash gets unexpected address not 8 byte aligned") + `DV_CHECK(wd % 2 == 0, "prog_flash gets unexpected odd bus word count") + tot_wd = wd * num; + + flash_op.op = FlashOpProgram; + flash_op.num_words = wd; + start_addr = flash_op.addr; + // last byte address in each program + end_addr = start_addr + (tot_wd * 4) - 1; + update_range_addresses_written(bank, flash_op.partition, start_addr, end_addr); + + `uvm_info("prog_flash", $sformatf("begin start_addr:%x part:%s num:%0d wd:%0d end_addr:%x", + flash_op.addr, flash_op.partition.name, num, wd, end_addr), + UVM_MEDIUM) + // Roll over start address if this is the case. + `uvm_info("prog_flash", $sformatf("bank:%0d otf_addr:0x%0h, part:%s size:%0d x %0d x 4B", + bank, flash_op.otf_addr, flash_op.partition.name, num, wd), + UVM_MEDIUM) + + flash_op.otf_addr = start_addr; + + for (int i = 0; i < num; i++) begin : num_loop + end_addr = flash_op.otf_addr + (wd * 4) - 1; + + flash_op.addr = flash_op.otf_addr; + flash_op.addr[TL_AW-1:OTFBankId] = bank; + + `DV_CHECK_EQ(flash_op.addr[2], 1'b0, "Unexpected address not 8-byte aligned for flash_prog") + `uvm_info("prog_flash", $sformatf("in loop tl_addr:%x start_addr:%x end_addr:%x", + flash_op.addr, flash_op.otf_addr, end_addr), UVM_MEDIUM) + + // Check resolution error + // Current resolution : 0x40. + // If address[6] differ between start and end addr a prog_win error will be raised and the + // transaction will be dropped. But if cfg.seq_cfg.avoid_prog_res_fault is set this breaks + // off a transaction up to the window's end, issues it, and adjusts the transactions to + // come to start past the window's end. + if (in_different_prog_win(flash_op.otf_addr, end_addr) && + cfg.seq_cfg.avoid_prog_res_fault) begin + flash_op_t tmp_op = flash_op; + flash_op_t split_op; + int split_wd; + otf_addr_t next_addr; + do begin + // The next address needs to be at the next window resolution start. + next_addr = round_to_prog_resolution( + tmp_op.otf_addr + flash_ctrl_reg_pkg::RegBusPgmResBytes); + `DV_CHECK_NE(next_addr - 1, end_addr, "Should not break up to end_addr") + split_wd = (next_addr - tmp_op.otf_addr) >> 2; + split_op = tmp_op; + split_op.num_words = split_wd; + `uvm_info("prog_flash", $sformatf( + "Broke request below into one up to 0x%x with %0d bus words", + next_addr, split_wd), UVM_MEDIUM) + print_flash_op(tmp_op, UVM_MEDIUM); + `uvm_info("prog_flash", "Broken request first", UVM_MEDIUM) + print_flash_op(split_op, UVM_MEDIUM); + tmp_op.addr = {bank, next_addr}; + tmp_op.otf_addr = tmp_op.addr; + tmp_op.num_words -= split_wd; + `uvm_info("prog_flash", "Broken request second", UVM_MEDIUM) + print_flash_op(tmp_op, UVM_MEDIUM); + issue_prog_request(split_op, lcnt, in_err, store_prog_data); + end while (in_different_prog_win(tmp_op.otf_addr, end_addr)); + issue_prog_request(tmp_op, lcnt, in_err, store_prog_data); + end else begin + issue_prog_request(flash_op, lcnt, in_err, store_prog_data); + end + flash_op.addr += wd * 4; + flash_op.otf_addr += wd * 4; + end : num_loop + endtask : prog_flash + + // Read flash in the unit of minimum resolution (4 Byte). + // 1 word : 8Byte + // @arg: flash_op_p : command struct return updated address after write + // @arg: bank: bank index to access flash + // @arg: num : number of 8 words range: [1 : 32] + // @arg: wd : number of 4byte (TL bus unit) : default : 16 + // @arg: overrd : invoke oversize read + // @arg: in_err : inject fatal error causes flash access disable + virtual task read_flash(ref flash_op_t flash_op, input int bank, int num, int wd = 16, + int overrd = 0, bit in_err = 0); + data_q_t flash_read_data; + flash_otf_item exp_item; + bit poll_fifo_status = ~in_err; + bit [flash_ctrl_pkg::BusAddrByteW-1:0] start_addr, end_addr; + int page; + bit overflow = 0; + uvm_reg_data_t reg_data; + bit derr_is_set; + bit drop; + int size, is_odd, tail; + addr_t tmp_addr; + flash_mp_region_cfg_t my_region; + rd_cache_t rd_entry; + + // Exclude secret partition from non scrambled / ecc mode + if (cfg.ecc_mode == FlashEccDisabled && + flash_op.partition == FlashPartInfo) return; + + flash_op.op = FlashOpRead; + flash_op.num_words = wd; + start_addr = flash_op.otf_addr; + end_addr = start_addr + (wd * 4 * num) - 1; + + if (cfg.ecc_mode > FlashEccEnabled) begin + if (flash_op.partition == FlashPartData) begin + overflow = (end_addr[18:17] != start_addr[18:17] || + end_addr[16:0] > 17'h1_FE00); + end else begin + overflow = (end_addr[10:9] != start_addr[10:9]); + end + end else begin + // Ctrl read takes lower half of each bank + // and host read takes upper half. + overflow = end_addr[OTFHostId]; + end + + if (overflow) begin + if (flash_op.partition == FlashPartData) begin + flash_op.addr[16:0] = 'h0; + end else begin + flash_op.addr[8:0] = 'h0; + end + flash_op.otf_addr = flash_op.addr; + `uvm_info("read_flash", $sformatf("overflow!, roll over start address to 0x%x", + flash_op.otf_addr), UVM_MEDIUM) + end + + `uvm_info(`gfn, $sformatf( + "read_flash start_addr:0x%x, num:%0d, wd:%0d, end_addr:0x%x", + flash_op.addr, num, wd, flash_op.addr + (wd * 4 * num) - 1), + UVM_MEDIUM) + + for (int i = 0; i < num; i++) begin + drop = 0; + flash_op.addr = flash_op.otf_addr; + flash_op.addr[TL_AW-1:OTFBankId] = bank; + rd_entry.bank = bank; + is_odd = flash_op.addr[2]; + size = (flash_op.num_words + is_odd) / 2; + tail = (flash_op.num_words + is_odd) % 2; + tmp_addr = flash_op.addr; + flash_op.addr[2:0] = 0; + + // Per Qword loop + `uvm_create_obj(flash_otf_item, exp_item) + for (int i = 0; i < size; i++) begin + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = cfg.get_region(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + `uvm_info(`gfn, $sformatf( + "For addr:%x, bank:%0d, page:%0d, region scr_en:%b ecc_en:%b", + flash_op.otf_addr, bank, page, my_region.scramble_en == MuBi4True, + my_region.ecc_en == MuBi4True), UVM_MEDIUM) + drop |= check_info_part(flash_op, "read_flash"); + end + drop |= validate_flash_op(flash_op, my_region); + flash_op.addr += 8; + flash_op.otf_addr += 8; + exp_item.ctrl_rd_region_q.push_back(my_region); + end // for (int i = 0; i < size; i++) + if (tail) begin + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = cfg.get_region(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + drop |= check_info_part(flash_op, "read_flash"); + end + drop |= validate_flash_op(flash_op, my_region); + exp_item.ctrl_rd_region_q.push_back(my_region); + end + flash_op.addr = tmp_addr; + // Bank id truncated by otf_addr size + flash_op.otf_addr = tmp_addr; + // recalculate page and region based on start address + // for the debug print + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = cfg.get_region(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + end + if (drop) begin + `uvm_info("read_flash", $sformatf("op:%s is not allowed in the region:%p", + flash_op.op.name, my_region), UVM_MEDIUM) + set_otf_exp_alert("recov_err"); + end + `uvm_info("read_flash", + $sformatf({"bank:%0d page:%0d otf_addr:0x%0h,", + " part:%s size:%0d x %0d x 4B start_addr:%x end_addr:%x", + " overrd:%0d"}, + bank, page, flash_op.otf_addr, + flash_op.partition.name, num, wd, start_addr, end_addr, overrd), + UVM_MEDIUM) + exp_item.cmd = flash_op; + // per bank address is used for decryption in sbx + exp_item.start_addr = flash_op.otf_addr; + exp_item.addr_key = otp_addr_key; + exp_item.data_key = otp_data_key; + + rd_entry.addr = flash_op.otf_addr; + // Address has to be 8byte aligned + rd_entry.addr[2:0] = 'h0; + rd_entry.part = flash_op.partition; + if (cfg.ecc_mode > FlashEccEnabled) begin + if (drop == 0) begin + if (cfg.ecc_mode == FlashSerrTestMode || flash_op.addr[2] == 0) begin + cfg.add_bit_err(flash_op.addr, ReadTaskCtrl, exp_item); + derr_is_set = cfg.address_has_derr(flash_op.addr, flash_op.partition); + `uvm_info(`gfn, $sformatf("derr_is_set:%b, addr:0x%x", derr_is_set, flash_op.addr), + UVM_MEDIUM) + end + end + end + + cfg.otf_read_entry.insert(rd_entry, flash_op); + if (derr_is_set) begin + `uvm_info("read_flash", $sformatf("assert_derr 0x%x", align_to_flash_word(flash_op.addr)), + UVM_MEDIUM) + global_derr_is_set = 1; + if (cfg.scb_h.do_alert_check == 1) begin + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + + cfg.scb_h.expected_alert["recov_err"].expected = 1; + cfg.scb_h.expected_alert["recov_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["recov_err"] = 10000; + end + end + + `uvm_info("read_flash", $sformatf("intr_mode=%b", cfg.intr_mode), UVM_MEDIUM) + if (cfg.intr_mode) begin + flash_ctrl_intr_read(flash_op, flash_read_data); + end else begin + flash_ctrl_start_op(flash_op); + if (in_err) begin + cfg.tlul_core_exp_cnt += flash_op.num_words; + end + flash_ctrl_read(flash_op.num_words, flash_read_data, poll_fifo_status); + + if (overrd > 0) begin + overread(flash_op, bank, num, overrd); + end + if (!in_err) wait_flash_op_done(); + end + + if (derr_is_set | cfg.ierr_created[ReadTaskCtrl]) begin + `uvm_info("read_flash", $sformatf( + "bank:%0d addr: %x(otf:%x) derr_is_set:%0d ierr_created[ReadTaskCtrl]:%0d", + bank, flash_op.addr, flash_op.otf_addr, derr_is_set, + cfg.ierr_created[ReadTaskCtrl]), + UVM_MEDIUM) + csr_rd_check(.ptr(ral.op_status.err), .compare_value(1)); + csr_rd_check(.ptr(ral.err_code.rd_err), .compare_value(1)); + reg_data = get_csr_val_with_updated_field(ral.err_code.rd_err, reg_data, 1); + csr_wr(.ptr(ral.err_code), .value(reg_data)); + reg_data = get_csr_val_with_updated_field(ral.op_status.err, reg_data, 0); + csr_wr(.ptr(ral.op_status), .value(reg_data)); + if (cfg.derr_once == 0) cfg.derr_created[ReadTaskCtrl] = 0; + cfg.ierr_created[ReadTaskCtrl] = 0; + end + + exp_item.exp_err |= in_err; + exp_item.dq = flash_read_data; + exp_item.fq = exp_item.dq2fq(flash_read_data); + + if (drop) begin + `uvm_info("read_flash", "skip sb path due to err", UVM_MEDIUM) + end else begin + p_sequencer.eg_exp_ctrl_port[bank].write(exp_item); + end + cfg.otf_ctrl_rd_rcvd++; + flash_op.addr += 4 * wd; + flash_op.otf_addr += 4 * wd; + end // for (int i = 0; i < num; i++) + endtask // read_flash + + // Read error behavior task + // This task issue rd_fifo read without setting stat_op. + // Expected output is to received errored response from core_tl interface. + task overread(flash_op_t flash_op, int bank, int num, int wd); + data_q_t flash_read_data; + bit poll_fifo_status = 0; + addr_t addr = ral.rd_fifo.get_address(); + + repeat (wd) cfg.scb_h.over_rd_err[addr]++; + cfg.m_tl_agent_cfg.check_tl_errs = 0; + `uvm_info("overread", $sformatf("addr is set 0x%x wd:%0d", addr, wd), + UVM_MEDIUM) + flash_ctrl_read(wd, flash_read_data, poll_fifo_status, 1); + cfg.m_tl_agent_cfg.check_tl_errs = 1; + endtask // overread + + // Direct access from the host. It returns multiple of + // 4bytes of data. + // @arg : addr : Direct access address. + // At the phy interface, address_phy = addr >> 3, + // because phy returns data in 8byte. + // At the host interface, addr[2] is used for + // word selector s.t. + // addr[2]? upper 4byte : lower 4byte of phy data. + // @arg : bank : bank index to access flash. + // @arg : num : number of 4byte data to read countinuously + // by 4 byte apart. + // @arg: in_err : inject fatal error causes flash access disable + virtual task otf_direct_read(bit [OTFHostId-2:0] addr, int bank, int num, bit in_err); + bit[TL_AW-1:0] tl_addr, st_addr, end_addr; + data_4s_t rdata; + flash_otf_item exp_item; + int page; + flash_op_t flash_op; + bit completed; + bit derr_is_set; + bit ierr_is_set; + bit derr, drop; + bit overflow = 0; + flash_mp_region_cfg_t my_region; + rd_cache_t rd_entry; + + end_addr = addr + num * 4 - 1; + if (cfg.ecc_mode > FlashEccEnabled) begin + overflow = (end_addr[OTFHostId:0] > 18'h1_FE00); + tl_addr[OTFHostId-:2] = cfg.tgt_pre[FlashPartData][TgtDr]; + end else begin + tl_addr[OTFHostId] = 1; + overflow = end_addr[OTFHostId]; + end + `uvm_info("direct_read", $sformatf("addr: %x end_addr: %x overflow: %x", + addr, end_addr, overflow), UVM_HIGH) + rd_entry.bank = bank; + tl_addr[TL_AW-1:OTFBankId] = bank; + if (overflow) begin + addr = num * 4; + end + tl_addr[OTFHostId-2:2] = addr[OTFHostId-2:2]; + + `uvm_info("direct_read", $sformatf("bank:%0d tl_addr:0x%0h, num: %0d", + bank, tl_addr, num), UVM_MEDIUM) + // Capture for the print in sb. + st_addr = tl_addr; + for (int i = 0; i < num ; i++) begin + drop = 0; + derr = 0; + // force address wrap around + if (cfg.ecc_mode > FlashEccEnabled) tl_addr[18:17] = cfg.tgt_pre[FlashPartData][TgtDr]; + + `uvm_create_obj(flash_otf_item, exp_item) + page = cfg.addr2page(tl_addr[OTFBankId:0]); + my_region = cfg.get_region(page); + flash_op.op = FlashOpRead; + + exp_item.page = page; + exp_item.region = my_region; + exp_item.start_addr = tl_addr; + exp_item.addr_key = otp_addr_key; + exp_item.data_key = otp_data_key; + + // Address should be per bank addr + rd_entry.addr = tl_addr; + rd_entry.addr[TL_AW-1:OTFBankId] = 0; + + // Address has to be 8byte aligned + rd_entry.addr[2:0] = 'h0; + rd_entry.part = FlashPartData; + + if (cfg.ecc_mode > FlashEccEnabled) begin + if (exp_item.region.ecc_en == MuBi4True) begin + flash_op.addr = tl_addr; + // host can only access data partitions. + flash_op.partition = FlashPartData; + flash_op.num_words = 1; + if (cfg.ecc_mode == FlashSerrTestMode || tl_addr[2] == 0) begin + cfg.add_bit_err(flash_op, ReadTaskHost, exp_item); + end + derr_is_set = cfg.address_has_derr(align_to_flash_word(flash_op.addr), + flash_op.partition); + ierr_is_set = cfg.address_has_ierr(align_to_flash_word(flash_op.addr), + flash_op.partition); + if (derr_is_set) begin + `uvm_info("direct_read", $sformatf("assert_derr 0x%x", tl_addr), UVM_MEDIUM) + cfg.scb_h.ecc_error_addr[align_to_flash_word(tl_addr)] = 1; + global_derr_is_set = 1; + end + if (ierr_is_set) begin + `uvm_info("direct_read", $sformatf("assert_ierr 0x%x", tl_addr), UVM_MEDIUM) + end + if (cfg.derr_once == 0) cfg.derr_created[ReadTaskHost] = 0; + `uvm_info("direct_read", $sformatf( + "ierr_created[ReadTaskHost]:%0d derr_is_set:%0d exists:%0d", + cfg.ierr_created[ReadTaskHost], derr_is_set, + cfg.scb_h.ecc_error_addr.exists(align_to_flash_word(tl_addr))), + UVM_MEDIUM) + cfg.ierr_created[ReadTaskHost] = 0; + end + if (cfg.scb_h.ecc_error_addr.exists(align_to_flash_word(tl_addr)) || + derr_is_set) begin + derr = 1; + end + end + cfg.otf_read_entry.insert(rd_entry, flash_op); + `uvm_info("direct_read", $sformatf({"num_i:%0d bank:%0d exec: page:%0d(%0d)", + " 0x%x derr:%0d in_err:%0d"}, + i, bank, tl_addr, page, (page % 256), + derr, in_err), UVM_MEDIUM) + if (in_err) cfg.scb_h.in_error_addr[align_to_flash_word(tl_addr)] = 1; + + derr |= in_err; + + if (cfg.ecc_mode > FlashSerrTestMode) begin + if ((derr || derr_is_set) && cfg.scb_h.do_alert_check) begin + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = cfg.seq_cfg.long_fatal_err_delay; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + end + end + + // in_err is currently used to address error caused by disable flash. + if (in_err) begin + set_otf_exp_alert("fatal_err"); + end + + cfg.inc_otd_tbl(bank, tl_addr, FlashPartData); + d_cnt1++; + do_direct_read(.addr(tl_addr), .mask('1), .blocking(1), .rdata(rdata), + .completed(completed), .exp_err_rsp(derr || ierr_is_set)); + d_cnt2++; + `uvm_info(`gfn, $sformatf("direct_read_trace: sent:%0d rcvd:%0d", d_cnt1, d_cnt2), + UVM_HIGH) + // issue csr rd to capture coverpoint at sb. + if (derr) begin + uvm_reg_data_t ldata; + csr_rd(.ptr(ral.err_code), .value(ldata)); + end + if (completed) begin + exp_item.dq.push_back(rdata); + exp_item.exp_err |= in_err; + + p_sequencer.eg_exp_host_port[bank].write(exp_item); + `uvm_info("direct_read", + $sformatf("SEQ:st_addr:%x addr:%x rcvd:%0d rdata:%x derr:%0d", + st_addr, tl_addr, cfg.otf_host_rd_rcvd, rdata, derr), + UVM_MEDIUM) + end else begin + `uvm_info("direct_read", + $sformatf("SEQ:st_addr:%x addr:%x rcvd:%0d aborted derr:%0d", + st_addr, tl_addr, cfg.otf_host_rd_rcvd, derr), + UVM_MEDIUM) + end + cfg.dec_otd_tbl(bank, tl_addr, FlashPartData); + cfg.otf_host_rd_rcvd++; + tl_addr += 4; + end + endtask // otf_direct_read + + // Read flash in the unit of minimum resolution (4 Byte). + // This task has following difference from 'task read_flash' + // - This task doesn't use target prefix (tgt_pre). + // - If same address write happens, the address marked as error and + // set expected alert + // - num and wd is controlled by test sequence to keep read within + // 'loaded zone' + // + // @arg: flash_op_p : command struct return updated address after write + // @arg: bank: bank index to access flash + // @arg: num : number of 8 words range: [1 : 32] + // @arg: wd : number of 4byte (TL bus unit) : default : 16 + task readback_flash(flash_op_t flash_op, int bank, int num, int wd = 16); + data_q_t flash_read_data; + flash_otf_item exp_item; + bit poll_fifo_status = 1; + int page; + + uvm_reg_data_t reg_data; + bit derr_is_set; + bit drop; + int size, is_odd, tail; + addr_t tmp_addr; + flash_mp_region_cfg_t my_region; + rd_cache_t rd_entry; + + flash_op.op = FlashOpRead; + flash_op.num_words = wd; + + for (int i = 0; i < num; i++) begin + drop = 0; + flash_op.addr = flash_op.otf_addr; + flash_op.addr[TL_AW-1:OTFBankId] = bank; + rd_entry.bank = bank; + is_odd = flash_op.addr[2]; + size = (flash_op.num_words + is_odd) / 2; + tail = (flash_op.num_words + is_odd) % 2; + tmp_addr = flash_op.addr; + flash_op.addr[2:0] = 0; + + // Per Qword loop + `uvm_create_obj(flash_otf_item, exp_item) + exp_item.addr_key = otp_addr_key; + exp_item.data_key = otp_data_key; + + for (int i = 0; i < size; i++) begin + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = cfg.get_region(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + drop |= check_info_part(flash_op, "readback_flash"); + end + drop |= validate_flash_op(flash_op, my_region); + exp_item.ctrl_rd_region_q.push_back(my_region); + + rd_entry.addr = flash_op.otf_addr; + // Address has to be 8byte aligned + rd_entry.addr[2:0] = 'h0; + rd_entry.part = flash_op.partition; + if (drop == 0 && + my_region.ecc_en == MuBi4True && + cfg.otf_scb_h.corrupt_entry.exists(rd_entry) == 1) begin + `uvm_info("readback_flash", $sformatf("read corrupted entry 0x%x", + align_to_flash_word(flash_op.addr)), UVM_MEDIUM) + derr_is_set |= 1; + end + + flash_op.addr += 8; + flash_op.otf_addr += 8; + end // for (int i = 0; i < size; i++) + if (tail) begin + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = cfg.get_region(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + drop |= check_info_part(flash_op, "readback_flash"); + end + drop |= validate_flash_op(flash_op, my_region); + exp_item.ctrl_rd_region_q.push_back(my_region); + + rd_entry.addr = flash_op.otf_addr; + // Address has to be 8byte aligned + rd_entry.addr[2:0] = 'h0; + rd_entry.part = flash_op.partition; + if (drop == 0 && + my_region.ecc_en == MuBi4True && + cfg.otf_scb_h.corrupt_entry.exists(rd_entry) == 1) begin + `uvm_info("readback_flash", $sformatf("read corrupted entry 0x%x", + align_to_flash_word(flash_op.addr)), UVM_MEDIUM) + derr_is_set |= 1; + end + end + flash_op.addr = tmp_addr; + // Bank id truncaded by otf_addr size + flash_op.otf_addr = tmp_addr; + + // recalculate page and region based on start address + // for the debug print + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = cfg.get_region(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + end + if (drop) begin + `uvm_info("readback_flash", $sformatf("op:%s is not allowed in the region:%p", + flash_op.op.name, my_region), UVM_MEDIUM) + set_otf_exp_alert("recov_err"); + end + `uvm_info("readback_flash", + $sformatf({"bank:%0d page:%0d otf_addr:0x%0h,", + " part:%s size:%0d x %0d x 4B"}, + bank, page, flash_op.otf_addr, + flash_op.partition.name, num, wd), + UVM_MEDIUM) + + exp_item.cmd = flash_op; + // per bank address is used for decryption in sbx + exp_item.start_addr = flash_op.otf_addr; + + rd_entry.addr = flash_op.otf_addr; + // Address has to be 8byte aligned + rd_entry.addr[2:0] = 'h0; + rd_entry.part = flash_op.partition; + + if (cfg.ecc_mode > FlashEccEnabled) begin + if (exp_item.region.ecc_en == MuBi4True && drop == 0) begin + if (cfg.ecc_mode == FlashSerrTestMode || flash_op.addr[2] == 0) begin + cfg.add_bit_err(flash_op, ReadTaskCtrl, exp_item); + derr_is_set = cfg.address_has_derr(flash_op.addr, flash_op.partition); + end + end + end + + cfg.otf_read_entry.insert(rd_entry, flash_op); + + if (derr_is_set) begin + `uvm_info("readback_flash", $sformatf("read corrupted entry 0x%x", + align_to_flash_word(flash_op.addr)), UVM_MEDIUM) + global_derr_is_set = 1; + exp_item.derr = 1; + + if (cfg.scb_h.do_alert_check == 1) begin + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + + cfg.scb_h.expected_alert["recov_err"].expected = 1; + cfg.scb_h.expected_alert["recov_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["recov_err"] = 10000; + end + end + if (cfg.intr_mode) begin + flash_ctrl_intr_read(flash_op, flash_read_data); + end else begin + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_read_data, poll_fifo_status); + wait_flash_op_done(); + end + + if (derr_is_set | cfg.ierr_created[ReadTaskCtrl]) begin + uvm_reg_data_t ldata; + csr_rd(.ptr(ral.err_code), .value(ldata), .backdoor(1)); + `uvm_info("readback_flash", $sformatf( + "bank:%0d addr: %x(otf:%x) derr_is_set:%0d ierr_created[ReadTaskCtrl]:%0d", + bank, flash_op.addr, flash_op.otf_addr, derr_is_set, + cfg.ierr_created[ReadTaskCtrl]), + UVM_MEDIUM) + csr_rd_check(.ptr(ral.op_status.err), .compare_value(1)); + csr_rd_check(.ptr(ral.err_code.rd_err), .compare_value(1)); + reg_data = get_csr_val_with_updated_field(ral.err_code.rd_err, reg_data, 1); + csr_wr(.ptr(ral.err_code), .value(reg_data)); + reg_data = get_csr_val_with_updated_field(ral.op_status.err, reg_data, 0); + csr_wr(.ptr(ral.op_status), .value(reg_data)); + if (cfg.derr_once == 0) cfg.derr_created[ReadTaskCtrl] = 0; + cfg.ierr_created[ReadTaskCtrl] = 0; + end + + exp_item.dq = flash_read_data; + exp_item.fq = exp_item.dq2fq(flash_read_data); + if (drop) begin + `uvm_info("read_flash", "skip sb path due to err", UVM_MEDIUM) + csr_wr(.ptr(ral.op_status), .value(0)); + + end else begin + p_sequencer.eg_exp_ctrl_port[bank].write(exp_item); + end + cfg.otf_ctrl_rd_rcvd++; + flash_op.otf_addr = flash_op.otf_addr + (4 * wd); + end // for (int i = 0; i < num; i++) + endtask + + task direct_readback(bit [OTFBankId-1:0] addr, int bank, int num); + bit[TL_AW-1:0] tl_addr, st_addr, end_addr; + data_4s_t rdata; + flash_otf_item exp_item; + int page; + flash_op_t flash_op; + bit completed; + bit derr_is_set; + bit derr, drop; + bit overflow = 0; + flash_mp_region_cfg_t my_region; + rd_cache_t rd_entry; + + rd_entry.bank = bank; + tl_addr[TL_AW-1:OTFBankId] = bank; + tl_addr[OTFHostId:2] = addr[OTFHostId:2]; + + `uvm_info("direct_readback", $sformatf("bank:%0d tl_addr:0x%0h, num: %0d", + bank, tl_addr, num), UVM_MEDIUM) + // Capture for the print in sb. + st_addr = tl_addr; + + for (int i = 0; i < num ; i++) begin + drop = 0; + derr = 0; + + `uvm_create_obj(flash_otf_item, exp_item) + page = cfg.addr2page(tl_addr[OTFBankId:0]); + `uvm_info("direct_readback", $sformatf("direct page: %0d", page), UVM_MEDIUM) + my_region = cfg.get_region(page); + flash_op.op = FlashOpRead; + + exp_item.page = page; + exp_item.region = my_region; + exp_item.start_addr = tl_addr; + exp_item.addr_key = otp_addr_key; + exp_item.data_key = otp_data_key; + + rd_entry.addr = tl_addr; + rd_entry.addr[TL_AW-1:OTFBankId] = 0; + // Address has to be 8byte aligned + rd_entry.addr[2:0] = 'h0; + rd_entry.part = FlashPartData; + + if (cfg.ecc_mode > FlashEccEnabled) begin + if (exp_item.region.ecc_en == MuBi4True) begin + flash_op.addr = tl_addr; + // host can only access data partitions. + flash_op.partition = FlashPartData; + flash_op.num_words = 1; + if (cfg.ecc_mode == FlashSerrTestMode || tl_addr[2] == 0) begin + cfg.add_bit_err(flash_op, ReadTaskHost, exp_item); + derr_is_set = cfg.address_has_derr(flash_op.addr, flash_op.partition); + end + if (derr_is_set) begin + `uvm_info("direct_readback", $sformatf("assert_derr 0x%x", tl_addr), UVM_MEDIUM) + cfg.scb_h.ecc_error_addr[align_to_flash_word(tl_addr)] = 1; + global_derr_is_set = 1; + end + if (cfg.derr_once == 0) cfg.derr_created[ReadTaskHost] = 0; + `uvm_info("direct_readback", + $sformatf("ierr_created[ReadTaskHost]:%0d derr_is_set:%0d exists:%0d", + cfg.ierr_created[ReadTaskHost], derr_is_set, + cfg.scb_h.ecc_error_addr.exists(align_to_flash_word(tl_addr))), + UVM_MEDIUM) + cfg.ierr_created[ReadTaskHost] = 0; + end + if (cfg.scb_h.ecc_error_addr.exists(align_to_flash_word(tl_addr)) | + derr_is_set) begin + derr = 1; + end + end // if (cfg.ecc_mode > FlashEccEnabled) + + cfg.otf_read_entry.insert(rd_entry, flash_op); + if (my_region.ecc_en == MuBi4True && cfg.otf_scb_h.corrupt_entry.exists(rd_entry) == 1) begin + bit local_derr = 0; + check_mem_intg(exp_item, bank, local_derr); + if (local_derr) begin + exp_item.derr = 1; + derr = 1; + cfg.scb_h.ecc_error_addr[align_to_flash_word(tl_addr)] = 1; + if (derr & cfg.scb_h.do_alert_check) begin + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + end + end + end + + `uvm_info("direct_readback", $sformatf("idx:%0d: bank:%0d exec: 0x%x page:%0d derr:%0d", + i, bank, tl_addr, page, derr), UVM_MEDIUM) + cfg.inc_otd_tbl(bank, tl_addr, FlashPartData); + do_direct_read(.addr(tl_addr), .mask('1), .blocking(1), .rdata(rdata), + .completed(completed), .exp_err_rsp(derr)); + + if (completed) begin + exp_item.dq.push_back(rdata); + p_sequencer.eg_exp_host_port[bank].write(exp_item); + `uvm_info("direct_readback", + $sformatf("SEQ:st_addr:%x addr:%x rcvd:%0d rdata:%x derr:%0d", + st_addr, tl_addr, cfg.otf_host_rd_rcvd, rdata, derr), + UVM_MEDIUM) + end else begin + `uvm_info("direct_readback", + $sformatf("SEQ:st_addr:%x addr:%x rcvd:%0d aborted derr:%0d", + st_addr, tl_addr, cfg.otf_host_rd_rcvd, derr), + UVM_MEDIUM) + end + cfg.dec_otd_tbl(bank, tl_addr, FlashPartData); + cfg.otf_host_rd_rcvd++; + tl_addr += 4; + end // for (int i = 0; i < num ; i++) + endtask + + task erase_flash(flash_op_t flash_op, int bank, bit in_err = 0); + bit drop = 0; + int page; + flash_mp_region_cfg_t my_region; + + flash_op.op = FlashOpErase; + flash_op.addr[TL_AW-1:OTFBankId] = bank; + flash_op.otf_addr = flash_op.addr; + flash_op.erase_type = FlashErasePage; + + if (cfg.ecc_mode > FlashEccEnabled) begin + if (flash_op.partition == FlashPartData) begin + flash_op.otf_addr[18:17] = cfg.tgt_pre[flash_op.partition][TgtEr]; + end else begin + flash_op.otf_addr[10:9] = cfg.tgt_pre[flash_op.partition][TgtEr]; + end + end + `uvm_info("erase_flash", $sformatf("{bank:%0d otf_addr:0x%0h, page:%0d part:%s erase_type:%s", + bank, flash_op.otf_addr, cfg.addr2page(flash_op.addr), + flash_op.partition.name, flash_op.erase_type.name), + UVM_MEDIUM) + if (flash_op.partition == FlashPartData) begin + page = cfg.addr2page(flash_op.addr); + my_region = cfg.get_region(page); + end else begin + page = cfg.addr2page(flash_op.otf_addr); + my_region = cfg.get_region_from_info(cfg.mp_info[bank][flash_op.partition>>1][page]); + drop = check_info_part(flash_op, "erase_flash"); + end + drop |= validate_flash_op(flash_op, my_region); + if (drop) begin + `uvm_info("erase_flash", $sformatf("op:%s is not allowed in this region %p", + flash_op.op.name, my_region), UVM_MEDIUM) + set_otf_exp_alert("recov_err"); + end + flash_ctrl_start_op(flash_op); + if (!in_err) wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + endtask + + // Update rd / dr tgt of the memory with their page profile + virtual function void flash_otf_mem_read_zone_init(); + for (int i = 0; i < NumBanks; i++) begin :banks + flash_dv_part_e part; + // read tgt region : cfg.tgt_pre[0] + // direct rd tgt region: cfg.tgt_pre[1] + part = part.first; + do begin : parts + if (part == FlashPartData) begin + // Allocate a quarter of each bank to each read target. + int byte_size = BytesPerBank / 4; + for (flash_tgt_prefix_e j = TgtRd; j <= TgtDr; j = j.next()) begin : targets + // 8byte aligned + addr_t st_addr, ed_addr; + st_addr = 'h0; + st_addr[18:17] = cfg.tgt_pre[part][j]; + ed_addr = st_addr + byte_size - 1; + cfg.update_otf_mem_read_zone(part, i, st_addr, ed_addr); + add_address_range(i, part, st_addr, ed_addr); + `uvm_info("flash_otf_init", + $sformatf("part:%s pre:%s bank:%0d st:%x ed:%x", + part.name, j.name, i, st_addr, ed_addr), UVM_MEDIUM) + end : targets + end else begin // part != FlashPartData + // While data part can be divided by pages, info part + // need finer resolution due to number of pages in each info + // is relatively small. + // So every page in info part will be divided into 4 parts. + int byte_size = BytesPerPage / 4; + for (flash_tgt_prefix_e j = TgtRd; j <= TgtDr; j = j.next()) begin : targets + // 8byte aligned + addr_t st_addr, ed_addr; + st_addr = 'h0; + st_addr[10:9] = cfg.tgt_pre[part][j]; + for (int k = 0; k < InfoTypeSize[part>>1]; k++) begin : pages + st_addr[DVPageMSB:DVPageLSB] = k; // page + ed_addr = st_addr + byte_size - 1; + cfg.update_otf_mem_read_zone(part, i, st_addr, ed_addr); + add_address_range(i, part, st_addr, ed_addr); + `uvm_info("flash_otf_init", + $sformatf("part:%s pre:%s bank:%0d page:%0d st:%x ed:%x", + part.name, j.name, i, k, st_addr, ed_addr), UVM_MEDIUM) + end : pages + end : targets + end + part = part.next; + end :parts + while (part != part.first); + end : banks + sort_all_address_ranges(); + endfunction // flash_otf_init + + // Send direct host read to both banks 'host_num' times. + virtual task send_rand_host_rd(int num = -1, bit in_err = 0); + flash_op_t host; + int host_num, host_bank; + + host.otf_addr[OTFHostId-2:0] = $urandom(); + host.otf_addr[1:0] = 'h0; + if (num >= 0) host_num = num; + else host_num = $urandom_range(1,32); + host_bank = $urandom_range(0,1); + + `uvm_info(`gfn, $sformatf( + "send_rand_host_rd addr=0x%x bank=%0d host_num=%0d, in_err=%b", + host.otf_addr, host_bank, host_num, in_err), UVM_MEDIUM) + otf_direct_read(host.otf_addr, host_bank, host_num, in_err); + endtask // send_rand_host_rd + + // Clean up tb vars. Used for multiple sequence run. + task otf_tb_clean_up(); + global_derr_is_set = 0; + cfg.otf_clean_up(); + endtask + + // Populate cfg.mp_info with default_info_page_cfg except scr, ecc. + // Then program each info region. + virtual task flash_ctrl_default_info_cfg(otf_cfg_mode_e scr_mode = OTFCfgFalse, + otf_cfg_mode_e ecc_mode = OTFCfgFalse); + mubi4_t scr_en, ecc_en; + // If scr/ecc mode is random, + // follow rand_info_c + scr_en = get_mubi_val(scr_mode); + ecc_en = get_mubi_val(ecc_mode); + + foreach (cfg.mp_info[i, j, k]) begin + if (cfg.ecc_mode == FlashEccDisabled) cfg.mp_info[i][j][k] = cfg.default_info_page_cfg; + else cfg.mp_info[i][j][k] = rand_info[i][j][k]; + if (scr_mode != OTFCfgRand) cfg.mp_info[i][j][k].scramble_en = scr_en; + if (ecc_mode != OTFCfgRand) cfg.mp_info[i][j][k].ecc_en = ecc_en; + + // overwrite secret_partition cfg with hw_cfg0 + cfg.mp_info[0][0][1] = conv2env_mp_info(flash_ctrl_pkg::CfgAllowRead); + cfg.mp_info[0][0][2] = conv2env_mp_info(flash_ctrl_pkg::CfgAllowRead); + + flash_ctrl_mp_info_page_cfg(i, j, k, cfg.mp_info[i][j][k]); + `uvm_info("otf_info_cfg", $sformatf("bank:type:page:[%0d][%0d][%0d] = %p", + i, j, k, cfg.mp_info[i][j][k]), UVM_MEDIUM) + end + // Add callback to customize mp info + callback_vseq.update_env_mp_info(); + endtask // flash_ctrl_default_info_cfg + + virtual task flash_otf_region_cfg(otf_cfg_mode_e scr_mode = OTFCfgFalse, + otf_cfg_mode_e ecc_mode = OTFCfgFalse); + mubi4_t scr_en, ecc_en; + // If scr/ecc mode is random, + // follow rand_regions_c + scr_en = get_mubi_val(scr_mode); + ecc_en = get_mubi_val(ecc_mode); + + flash_ctrl_default_region_cfg(,,,scr_en, ecc_en); + foreach (cfg.mp_regions[i]) begin + cfg.mp_regions[i] = rand_regions[i]; + // use default region in FlashEccDisabled mode. + if (cfg.ecc_mode == FlashEccDisabled) cfg.mp_regions[i].en = MuBi4False; + if (scr_mode != OTFCfgRand) cfg.mp_regions[i].scramble_en = scr_en; + if (ecc_mode != OTFCfgRand) cfg.mp_regions[i].ecc_en = ecc_en; + + flash_ctrl_mp_region_cfg(i, cfg.mp_regions[i]); + `uvm_info("otf_region_cfg", $sformatf("region[%0d] = %p", i, cfg.mp_regions[i]), UVM_MEDIUM) + end + `uvm_info("otf_region_cfg", $sformatf("default = %p", cfg.default_region_cfg), UVM_MEDIUM) + flash_ctrl_default_info_cfg(scr_mode, ecc_mode); + update_p2r_map(cfg.mp_regions); + endtask // flash_otf_region_cfg + + task send_rand_ops(int iter = 1, bit exp_err = 0, bit ctrl_only = 0); + flash_op_t ctrl; + int num, bank; + int host_pct = (ctrl_only)? 0 : 1; + + repeat (iter) begin + randcase + 1: begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + prog_flash(ctrl, bank, 1, fractions, exp_err); + end + 1: begin + set_ecc_err_target(TgtRd); + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + read_flash(ctrl, bank, 1, fractions, 0, exp_err); + end + host_pct: send_rand_host_rd(.in_err(exp_err)); + 1: begin + set_ecc_err_target(TgtEr); + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + erase_flash(ctrl, bank, exp_err); + end + endcase // randcase + end + endtask + + // Use this task only after flash is disabled. + task flash_access_after_disabled(); + `uvm_info(`gfn, "Flash Access after disabled", UVM_LOW) + cfg.m_tl_agent_cfg.check_tl_errs = 0; + send_rand_ops(.iter(5), .exp_err(1), .ctrl_only(1)); + + // Disable tlul_err_cnt check + cfg.tlul_core_obs_cnt = cfg.tlul_core_exp_cnt; + endtask // flash_access_after_disabled + + function void update_partition_access(bit[2:0] acc); + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::Off; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::Off; + + if (acc[0]) cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + if (acc[1]) cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + if (acc[2]) begin + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + end + endfunction // update_partition_access + + function mubi4_t get_mubi_val(otf_cfg_mode_e mode); + case (mode) + OTFCfgRand: begin + // return true or false with 1:1 ratio + return get_rand_mubi4_val(.other_weight(0)); + end + OTFCfgTrue: return MuBi4True; + default: return MuBi4False; + endcase + endfunction // get_mubi_val + + function flash_dv_part_e get_dv_part_from_int(int page); + if (page < 1000) return FlashPartData; + else begin + if (page < 1010) begin + return FlashPartInfo; + end else if (page < 1011) begin + return FlashPartInfo1; + end + end + return FlashPartInfo2; + endfunction // get_dv_part_from_int + + // return right page number from 1000+ number + function int get_info_page(flash_dv_part_e info, int num); + int page; + case (info) + FlashPartInfo: page = num - 1000; + FlashPartInfo1: page = num - 1010; + FlashPartInfo2: page = num - 1011; + default: `uvm_error("get_info_page", $sformatf("%s is not valid info page", + info.name)) + endcase // case (info) + return page; + endfunction // get_info_page + + // Write all 1 to secret partition for some write tests. + function void flash_otf_set_secret_part(); + int page = 1; + repeat(2) begin + int page_st_addr = page*2048; + uvm_hdl_data_t data = '{default:1}; + for (int addr = page_st_addr; addr < (page_st_addr + 8*256); addr += 8) begin + cfg.mem_bkdr_util_h[FlashPartInfo][0].write(addr, data); + end + page++; + end + endfunction + + // Do backdoor read and check if double error exists. + task check_mem_intg(flash_otf_item exp, int bank, ref bit err); + flash_otf_item obs; + `uvm_create_obj(flash_otf_item, obs) + + obs.cmd.partition = FlashPartData; + obs.cmd.op = FlashOpRead; + obs.cmd.addr = exp.start_addr; // tl_addr + // for debug print + obs.start_addr = exp.start_addr; + obs.cmd.num_words = 1; + obs.mem_addr = exp.start_addr >> 3; + + cfg.flash_mem_otf_read(obs.cmd, obs.fq); + + obs.print("chk_mem_intg: before"); + obs.region = exp.region; + obs.skip_err_chk = 1; + + // descramble needs 2 buswords + obs.cmd.num_words = 2; + obs.descramble(exp.addr_key, exp.data_key); + obs.print("chk_mem_intg: after"); + err = obs.derr; + endtask +endclass // flash_ctrl_otf_base_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv new file mode 100644 index 0000000000000..bb9f76905e47a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_otp_reset_vseq.sv @@ -0,0 +1,184 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Run OTP with reset and other misbehavior to stretch coverage +class flash_ctrl_otp_reset_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_otp_reset_vseq) + `uvm_object_new + typedef enum logic [10:0] { + StIdle = 11'b10001000001, // + StReqAddrKey = 11'b01110101100, // 0.615 us + StReqDataKey = 11'b01110010001, // 0.775 + StReadSeeds = 11'b11011111110, // 0.934 + StReadEval = 11'b01000100111, // 3.032 + StWait = 11'b00100111011, // 4.856 + StEntropyReseed = 11'b00011000110, // 4.947 + StRmaWipe = 11'b10010110101, // 4.97 + StRmaRsp = 11'b10110001010, // 3093.344 + StDisabled = 11'b11111100011, // + StInvalid = 11'b11101011000 // + } lc_ctrl_state_e; + + typedef enum { + DVWaitAddrKey = 0, + DVWaitDataKey = 1, + DVWaitReadSeeds = 2, + DVWaitReadEval = 3, + DVWait = 4, + DVWaitEntropyReseed = 5, + DVWaitRmaWipe = 6, + DVWaitRmaRsp = 7 + } reset_index_e; + + + task pre_start(); + cfg.skip_init = 1; + super.pre_start(); + endtask + + task body(); + int long_wait_timeout_ns = 5000000; // 5ms + int wait_time; + string path; + logic [RmaSeedWidth-1:0] rma_seed; + cfg.scb_h.do_alert_check = 0; + + repeat(4) begin + update_assert(.enable(0)); + fork begin + fork + begin + csr_wr(.ptr(ral.init), .value(1)); + `uvm_info("Test","OTP",UVM_LOW) + otp_model(); + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);, + "Timed out waiting for rd_buf_en", + cfg.seq_cfg.state_wait_timeout_ns) + `uvm_info("Test", "RMA REQUEST START", UVM_LOW) + rma_seed = $urandom; // Random RMA Seed + send_rma_req(rma_seed); + `uvm_info("Test", "RMA REQUEST DONE", UVM_LOW) + + cfg.flash_ctrl_vif.rma_req <= lc_ctrl_pkg::Off; + end + begin + // exceptions + // 0. none + // 1. add disable to each state + // 2. rma_req[1] == true at StReqAddrKey, StReqDataKey + // 3. StReqDataKey, data_key_ack_q = 1, provision_en_i = 0 + bit[1:0] exception_mode; + reset_index_e reset_index = reset_index_e'($urandom_range(DVWaitAddrKey, + DVWaitEntropyReseed)); + `DV_CHECK_STD_RANDOMIZE_FATAL(exception_mode) + + `uvm_info("Test", $sformatf("index: %s exception_mode: %0d", + reset_index.name, exception_mode), UVM_LOW) + if (reset_index == DVWaitRmaRsp) wait_time = long_wait_timeout_ns; + else wait_time = cfg.seq_cfg.state_wait_timeout_ns; + + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.lcmgr_state == dv2rtl_st(reset_index));, + $sformatf("Timed out waiting for %s", reset_index.name), + wait_time) + // Since these are single cycle state, + // use force for disable or reset + if (reset_index == DVWaitReadEval || reset_index == DVWaitEntropyReseed)begin + @(negedge cfg.clk_rst_vif.clk); + + if (exception_mode[0]) begin + // disable + path = "tb.dut.u_flash_hw_if.disable_i"; + `DV_CHECK(uvm_hdl_force(path, MuBi4True)) + end else begin + // reset + path = "tb.dut.u_flash_hw_if.rst_ni"; + `DV_CHECK(uvm_hdl_force(path, 0)) + end + cfg.clk_rst_vif.wait_clks(2); + `DV_CHECK(uvm_hdl_release(path)) + end else begin + // Add extra cycles for longer states + // to trigger reset in the middle of the state. + if (reset_index == DVWaitAddrKey || reset_index == DVWaitDataKey) begin + cfg.clk_rst_vif.wait_clks(2); + end else if (reset_index == DVWaitReadSeeds || reset_index == DVWait) begin + cfg.clk_rst_vif.wait_clks(10); + end + case(exception_mode) + 2'b01: begin + csr_wr(.ptr(ral.dis), .value(get_rand_mubi4_val(.f_weight(0)))); + end + 2'b10: begin + if (reset_index inside {DVWaitAddrKey, DVWaitDataKey}) begin + cfg.flash_ctrl_vif.rma_req <= lc_ctrl_pkg::On; + cfg.clk_rst_vif.wait_clks(2); + cfg.flash_ctrl_vif.rma_req <= lc_ctrl_pkg::Off; + end + end + 2'b11: begin + if (reset_index == DVWaitDataKey) begin + cfg.flash_ctrl_vif.lc_seed_hw_rd_en = + get_rand_lc_tx_val(.t_weight(0), .f_weight(1), .other_weight(9)); + end + end + default: begin + // Add no disturbance. + end + endcase + cfg.clk_rst_vif.wait_clks(10); + end + `uvm_info(`gfn, "RESET", UVM_LOW) + // Enable secret seed at the beginning of the loop + cfg.seq_cfg.en_init_keys_seeds = 0; + cfg.flash_ctrl_vif.rma_req = lc_ctrl_pkg::Off; + apply_reset(); + end + join_any + disable fork; + // Since the 2nd begin/end wait for substate of OTP, + // the 2nd begin/end always finish first. + // So diable fork only terminate first begin/end. + end join // fork begin + + update_assert(.enable(1)); + csr_wr(.ptr(ral.init), .value(1)); + cfg.clk_rst_vif.wait_clks(2); + `uvm_info("Test","OTP after loop",UVM_LOW) + otp_model(); + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);, + "Timed out waiting for rd_buf_en", + cfg.seq_cfg.state_wait_timeout_ns) + + apply_reset(); + cfg.flash_ctrl_vif.lc_seed_hw_rd_en = lc_ctrl_pkg::On; + end + endtask // body + + function lc_ctrl_state_e dv2rtl_st(reset_index_e idx); + case (idx) + DVWaitAddrKey: return StReqAddrKey; + DVWaitDataKey: return StReqDataKey; + DVWaitReadSeeds: return StReadSeeds; + DVWait: return StWait; + DVWaitReadEval: return StReadEval; + DVWaitEntropyReseed: return StEntropyReseed; + DVWaitRmaWipe: return StRmaWipe; + DVWaitRmaRsp: return StRmaRsp; + default: begin + `uvm_error("dv2rma_st", $sformatf("unknown index:%0d", idx)) + end + endcase + endfunction + function void update_assert(bit enable); + if (enable) begin + $asserton(0, "tb.dut.u_flash_hw_if.u_addr_sync_reqack.SyncReqAckHoldReq"); + $asserton(0, "tb.dut.u_flash_hw_if.u_data_sync_reqack.SyncReqAckHoldReq"); + $asserton(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + end else begin + $assertoff(0, "tb.dut.u_flash_hw_if.u_addr_sync_reqack.SyncReqAckHoldReq"); + $assertoff(0, "tb.dut.u_flash_hw_if.u_data_sync_reqack.SyncReqAckHoldReq"); + $assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + end + endfunction +endclass // flash_ctrl_otp_reset_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv new file mode 100644 index 0000000000000..5d9c91664e85b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_oversize_error_vseq.sv @@ -0,0 +1,82 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Send errored traffic with normal traffic. +// Asserted error traffics are three kinds +// 1. Oversized (more than 16 bus words) program traffic +// 2. Oversized Read traffic: issue rd_fifo read more than +// it is supposed to. +// 3. Issue rd_fifo read without starting op. + +class flash_ctrl_oversize_error_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_oversize_error_vseq) + `uvm_object_new + flash_op_t ctrl; + int num, bank; + + virtual task body(); + cfg.scb_h.do_alert_check = 0; + cfg.otf_scb_h.comp_off = 0; + cfg.seq_cfg.avoid_prog_res_fault = 1'b0; + + fork + begin + repeat(cfg.otf_num_rw) begin + if (cfg.stop_transaction_generators()) break; + randcase + cfg.otf_wr_pct: begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + `uvm_info(`gfn, "Regular prog_flash", UVM_MEDIUM) + prog_flash(ctrl, bank, num, fractions); + end + cfg.otf_rd_pct: begin + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + read_flash(ctrl, bank, num, fractions); + end + cfg.otf_bwr_pct: begin + `uvm_info("seq", $sformatf("inj:prog_err: %0d", fractions + 16), UVM_MEDIUM) + cfg.seq_cfg.trigger_prog_res_fault = 1'b1; + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + `uvm_info(`gfn, $sformatf("Bad write prog_flash: fractions=%d", fractions + 16), + UVM_MEDIUM) + cfg.seq_cfg.trigger_prog_res_fault = 1'b0; + cfg.seq_cfg.avoid_prog_res_fault = 1'b0; + `DV_CHECK_GT(fractions, 16) + prog_flash(ctrl, bank, 1, fractions); + cfg.seq_cfg.avoid_prog_res_fault = 1'b1; + end + cfg.otf_brd_pct: begin + int sz = $urandom_range(1, 16); + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + randcase + 1: begin + `uvm_info("seq", $sformatf("inj:overread %0d",sz), UVM_MEDIUM) + overread(ctrl, bank, 1, sz); + end + 4: begin + `uvm_info("seq", $sformatf("inj:read_err %0d", fractions + sz), UVM_MEDIUM) + read_flash(ctrl, bank, .num(1), .wd(fractions), .overrd(sz)); + end + endcase + end + endcase + end + end + begin + for (int i = 0; i < cfg.otf_num_hr; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + join + endtask + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_ack_consistency_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_ack_consistency_vseq.sv new file mode 100644 index 0000000000000..c79001619fa45 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_ack_consistency_vseq.sv @@ -0,0 +1,73 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Test triggers tb.dut.u_eflash.gen_flash_cores[0].u_core.spurious_ack_o +// by force. +class flash_ctrl_phy_ack_consistency_vseq extends flash_ctrl_phy_host_grant_err_vseq; + `uvm_object_utils(flash_ctrl_phy_ack_consistency_vseq) + `uvm_object_new + + task run_error_event(); + int delay; + bit add_err1, add_err2; + string path1 = "tb.dut.u_eflash.gen_flash_cores[0].u_core.ctrl_rsp_vld"; + string path2 = "tb.dut.u_eflash.gen_flash_cores[0].u_core.host_req_done_o"; + + // Once error event is triggered, corrupted data propagate all the way down to flash phy interface and terminated. + // This can causes unexpected errors. + // Therefore, ignore potential unexpected err and check + // expected error only. + cfg.scb_h.skip_alert_chk["recov_err"] = 1; + + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2_000_000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + $assertoff(0, "tb.dut.u_eflash.gen_flash_cores[0].u_host_rsp_fifo.gen_normal_fifo.u_fifo_cnt"); + + repeat (2) begin + // unit 100 ns; + delay = $urandom_range(1, 10); + #(delay * 100ns); + + if (add_err1) begin + `DV_CHECK(uvm_hdl_release(path1)) + end + if (add_err2) begin + `DV_CHECK(uvm_hdl_release(path2)) + end + + if (add_err1 == 0 && add_err2 == 0) begin + $assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + randcase + 1: begin + // This error injection can cause catastrophic event + // Set fatal_std_err and stop tl response check + cfg.scb_h.expected_alert["fatal_std_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_std_err"].max_delay = 20000; + cfg.scb_h.exp_alert_contd["fatal_std_err"] = 10000; + cfg.scb_h.stop_tl_err_chk = 1; + cfg.m_tl_agent_cfg.check_tl_errs = 0; + add_err1 = 1; + @(posedge cfg.flash_ctrl_vif.ctrl_fsm_idle); + `DV_CHECK(uvm_hdl_force(path1, 1)) + end + 1: begin + add_err2 = 1; + wait(cfg.flash_ctrl_vif.host_outstanding == 0); + `DV_CHECK(uvm_hdl_force(path2, 1)) + end + endcase // randcase + cfg.otf_scb_h.comp_off = 1; + cfg.otf_scb_h.mem_mon_off = 1; + end + end // repeat (2) + check_fault(ral.fault_status.spurious_ack); + collect_err_cov_status(ral.fault_status); + // sw error can be unpredictably triggered. (err_code.prog_err) + // In stead of checking err_code == 0, + // make sure hw_fault.prog_err doesn't happen. + csr_rd_check(.ptr(ral.fault_status.prog_err), .compare_value(0)); + drain_n_finish_err_event(); + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_redun_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_redun_vseq.sv new file mode 100644 index 0000000000000..adaeba1efeab1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_redun_vseq.sv @@ -0,0 +1,172 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This injects arbitration faults in any of 4 arbiters with either copy grounded. +// The scrambler arbiters use prim_arbiter_tree, but the host arbiters in flash_phy_core +// use prim_arbiter_fixed, which has different assertions. For the scrambler arbiters we +// also need to disable some assertions that are violated by fault injection. +// +// Notice the $asserton/off directives need to get a string literal, which explains +// why they are done in a case statement. + +class flash_ctrl_phy_arb_redun_vseq extends flash_ctrl_err_base_vseq; + `uvm_object_utils(flash_ctrl_phy_arb_redun_vseq) + `uvm_object_new + + localparam int NumArbiters = 4; + + rand int unsigned which_arbiter; + constraint which_arbiter_c { which_arbiter < NumArbiters; } + + rand bit which_copy; + + constraint ctrl_num_c { + ctrl_num dist { CtrlTransMin := 2, [2:16] :/ 1}; + } + + typedef struct { + string name; + string copy_0_req; + string copy_1_req; + } arb_t; + +`define HOST_ARB_0_PREFIX tb.dut.u_eflash.gen_flash_cores[0].u_core.u_host_arb +`define HOST_ARB_1_PREFIX tb.dut.u_eflash.gen_flash_cores[1].u_core.u_host_arb +`define CALC_ARB_PREFIX tb.dut.u_eflash.u_scramble.u_prim_arbiter_tree_calc +`define OP_ARB_PREFIX tb.dut.u_eflash.u_scramble.u_prim_arbiter_tree_op + +`define COPY_0 gen_input_bufs[0] +`define COPY_1 gen_input_bufs[1] +`define REQ_SUFFIX u_req_buf.out_o[1:0] +`define FIXED_SVA_STAY_HIGH_SUFFIX gen_fixed_arbiter.u_arb.ReqStaysHighUntilGranted0_M +`define RR_SVA_STAY_HIGH_SUFFIX gen_rr_arbiter.u_arb.ReqStaysHighUntilGranted0_M +`define RR_SVA_LOCK_ARB_DEC_SUFFIX gen_rr_arbiter.u_arb.LockArbDecision_A + +`define HIER_PATH(prefix, copy, suffix) `"prefix.copy.suffix`" + + arb_t arbs[NumArbiters] = '{ + '{ + name: "host_arb[0]", + copy_0_req: `HIER_PATH(`HOST_ARB_0_PREFIX, `COPY_0, `REQ_SUFFIX), + copy_1_req: `HIER_PATH(`HOST_ARB_0_PREFIX, `COPY_1, `REQ_SUFFIX) + }, + '{ + name: "host_arb[1]", + copy_0_req: `HIER_PATH(`HOST_ARB_1_PREFIX, `COPY_0, `REQ_SUFFIX), + copy_1_req: `HIER_PATH(`HOST_ARB_1_PREFIX, `COPY_1, `REQ_SUFFIX) + }, + '{ + name: "scrambler_calc", + copy_0_req: `HIER_PATH(`CALC_ARB_PREFIX, `COPY_0, `REQ_SUFFIX), + copy_1_req: `HIER_PATH(`CALC_ARB_PREFIX, `COPY_1, `REQ_SUFFIX) + }, + '{ + name: "scrambler_op", + copy_0_req: `HIER_PATH(`OP_ARB_PREFIX, `COPY_0, `REQ_SUFFIX), + copy_1_req: `HIER_PATH(`OP_ARB_PREFIX, `COPY_1, `REQ_SUFFIX) + } + }; + + task run_error_event(); + int delay; + arb_t arb; + logic [1:0] req_0 = which_copy == 1'b0 ? 2'h0 : 2'h3; + logic [1:0] req_1 = which_copy == 1'b0 ? 2'h3 : 2'h0; + // unit 100 ns; + delay = $urandom_range(1, 10); + #(delay * 100ns); + cfg.otf_scb_h.comp_off = 1; + cfg.otf_scb_h.mem_mon_off = 1; + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = cfg.seq_cfg.long_fatal_err_delay; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + + arb = arbs[which_arbiter]; + `uvm_info(`gfn, $sformatf( + "Faulting arbiter %0d %s: %s=%x and %s=%x", + which_arbiter, arb.name, arb.copy_0_req, req_0, arb.copy_1_req, req_1), + UVM_MEDIUM) + case (which_arbiter) + // The host arbiters assertions (arbiters 0 and 1) are not impacted. + 0: begin + end + 1: begin + end + 2: begin + $assertoff(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_0, `RR_SVA_STAY_HIGH_SUFFIX)); + $assertoff(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_0, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + $assertoff(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_1, `RR_SVA_STAY_HIGH_SUFFIX)); + $assertoff(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_1, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + end + 3: begin + $assertoff(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_0, `RR_SVA_STAY_HIGH_SUFFIX)); + $assertoff(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_0, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + $assertoff(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_1, `RR_SVA_STAY_HIGH_SUFFIX)); + $assertoff(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_1, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + end + default: + `uvm_error(`gfn, $sformatf("Illegal arbiter index %0d, expected 0..3", which_arbiter)) + endcase + // Wait a couple cycles to have any prior SVA attempts complete, and they all last at + // most two cycles. + cfg.clk_rst_vif.wait_clks(2); + + `DV_CHECK(uvm_hdl_force(arb.copy_0_req, req_0)) + `DV_CHECK(uvm_hdl_force(arb.copy_1_req, req_1)) + cfg.clk_rst_vif.wait_clks($urandom_range(60, 90)); + `DV_CHECK(uvm_hdl_release(arb.copy_0_req)) + `DV_CHECK(uvm_hdl_release(arb.copy_1_req)) + // Wait a cycle to start attempts once the state should straighten up. + cfg.clk_rst_vif.wait_clks(1); + case (which_arbiter) + // The host arbiters assertions (arbiters 0 and 1) are not impacted. + 0: begin + end + 1: begin + end + 2: begin + $asserton(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_0, `FIXED_SVA_STAY_HIGH_SUFFIX)); + $asserton(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_0, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + $asserton(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_1, `FIXED_SVA_STAY_HIGH_SUFFIX)); + $asserton(0, `HIER_PATH(`CALC_ARB_PREFIX, `COPY_1, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + end + 3: begin + $asserton(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_0, `FIXED_SVA_STAY_HIGH_SUFFIX)); + $asserton(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_0, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + $asserton(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_1, `FIXED_SVA_STAY_HIGH_SUFFIX)); + $asserton(0, `HIER_PATH(`OP_ARB_PREFIX, `COPY_1, `RR_SVA_LOCK_ARB_DEC_SUFFIX)); + end + default: + `uvm_error(`gfn, $sformatf("Illegal arbiter index %0d, expected 0..3", which_arbiter)) + endcase + + `uvm_info(`gfn, "Calling check_fault", UVM_MEDIUM) + check_fault(ral.fault_status.arb_err); + `uvm_info(`gfn, "Calling collect_err_cov_status", UVM_MEDIUM) + collect_err_cov_status(ral.fault_status); + // host transaction unpredictably triggers err_code.mp_err. + // Instead of checking err_code == 0, make sure hw_fault.mp_err doesn't happen. + delay = $urandom_range(60, 90); + #(delay * 10us); + csr_rd_check(.ptr(ral.fault_status.mp_err), .compare_value(0)); + drain_n_finish_err_event(); + endtask + task clean_up(); + init_controller(); + endtask // clean_up + +`undef HOST_ARB_0_PREFIX +`undef HOST_ARB_1_PREFIX +`undef CALC_ARB_PREFIX +`undef OP_ARB_PREFIX + +`undef COPY_0 +`undef COPY_1 +`undef REQ_SUFFIX +`undef FIXED_SVA_STAY_HIGH_SUFFIX +`undef RR_SVA_STAY_HIGH_SUFFIX +`undef RR_SVA_LOCK_ARB_DEC_SUFFIX + +`undef HIER_PATH +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_vseq.sv new file mode 100644 index 0000000000000..0307ed38e2e4a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_arb_vseq.sv @@ -0,0 +1,299 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Flash Physical Controller Arbitration between host reads and controller operations +// 1.Scenario tests on the different banks arbitration +// 2.Scenario tests on the same bank arbitration +// 3.Scenario tests lost of priority of host read on the same bank +class flash_ctrl_phy_arb_vseq extends flash_ctrl_fetch_code_vseq; + `uvm_object_utils(flash_ctrl_phy_arb_vseq) + + `uvm_object_new + + // Randomized flash ctrl operation. + rand flash_op_t flash_op_host_rd; + data_q_t flash_rd_data; + + rand uint bank_rd; + + // knob for testing arbitration on same or different banks + logic bank_same = 0; + + // Constraint for banks. + constraint bank_c { + solve bank before bank_rd; + if (bank_same == 1) {bank == bank_rd;} else {bank != bank_rd;} + bank inside {[0 : flash_ctrl_pkg::NumBanks - 1]}; + bank_rd inside {[0 : flash_ctrl_pkg::NumBanks - 1]}; + } + + // Constraint host read address to be in relevant range for the selected partition. + constraint addr_rd_c { + solve bank_rd before flash_op_host_rd; + flash_op_host_rd.addr inside {[BytesPerBank * bank_rd : + BytesPerBank * (bank_rd + 1) - BytesPerBank / 2]}; + } + + constraint flash_op_host_rd_c { + flash_op_host_rd.partition == FlashPartData; + flash_op_host_rd.num_words inside {[10 : FlashNumBusWords - + flash_op_host_rd.addr[TL_AW-1:TL_SZW]]}; + flash_op_host_rd.num_words <= cfg.seq_cfg.op_max_words; + flash_op_host_rd.num_words < FlashPgmRes - flash_op_host_rd.addr[TL_SZW+:FlashPgmResWidth]; + } + + + addr_t read_addr; + + // Single direct read data + data_t flash_rd_one_data; + + localparam data_t AllOnes = {TL_DW{1'b1}}; + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + // MAx number of transactions. + cfg.seq_cfg.max_num_trans = 10; + + super.configure_vseq(); + endfunction + + virtual task body(); + + // enable sw rw access + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + + //disable polling of fifo status for frontdoor write and read + poll_fifo_status = 0; + + // Scoreboard knob for blocking host reads + cfg.block_host_rd = 1; + + // Scramble disable + default_region_scramble_en = MuBi4False; + + //Enable Bank erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // 1.Scenario tests on the different banks arbitration + `uvm_info(`gfn, $sformatf("1.Scenario tests on the different banks arbitration"), UVM_HIGH) + repeat (num_trans) begin + // Randomize self + bank_same = 0; + `DV_CHECK_RANDOMIZE_FATAL(this) + `uvm_info(`gfn, $sformatf( + "RAND FLASH OP bank:%0d bank_rd:%0d num_trans:%0d flash_op:%0p flash_op_data:%0p", + bank, + bank_rd, + num_trans, + flash_op, + flash_op_data + ), UVM_HIGH) + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_init(flash_op_host_rd.partition, FlashMemInitInvalidate); + if (flash_op.op == flash_ctrl_pkg::FlashOpProgram) begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + end else if (flash_op.op == flash_ctrl_pkg::FlashOpRead) begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + end + cfg.flash_mem_bkdr_write(.flash_op(flash_op_host_rd), .scheme(FlashMemInitRandomize)); + do_operations(); + end + + // 2.Scenario tests on the same bank arbitration + `uvm_info(`gfn, $sformatf("2.Scenario tests on the same bank arbitration"), UVM_HIGH) + repeat (num_trans) begin + // Randomize self + bank_same = 1; + `DV_CHECK_RANDOMIZE_FATAL(this) + `uvm_info(`gfn, $sformatf( + "RAND FLASH OP bank:%0d bank_rd:%0d num_trans:%0d flash_op:%0p flash_op_data:%0p", + bank, + bank_rd, + num_trans, + flash_op, + flash_op_data + ), UVM_HIGH) + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_init(flash_op_host_rd.partition, FlashMemInitInvalidate); + if (flash_op.op == flash_ctrl_pkg::FlashOpProgram) begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + end else if (flash_op.op == flash_ctrl_pkg::FlashOpRead) begin + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + end + cfg.flash_mem_bkdr_write(.flash_op(flash_op_host_rd), .scheme(FlashMemInitRandomize)); + do_operations(); + end + + // 3.Scenario tests lost of priority of host read on same bank + `uvm_info(`gfn, $sformatf("3.Scenario tests lost of priority of host read on same bank"), + UVM_HIGH) + + // start host reads and controller program + `DV_CHECK_RANDOMIZE_FATAL(this) + flash_op.partition = FlashPartData; + flash_op_host_rd.addr = 0; + flash_op_host_rd.num_words = 30; + flash_op.op = flash_ctrl_pkg::FlashOpProgram; + flash_op.addr = 'h14; + flash_op.num_words = 10; + cfg.flash_mem_bkdr_init(flash_op_host_rd.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op_host_rd), .scheme(FlashMemInitSet)); + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(flash_op_data, flash_op_data.size() == flash_op.num_words;) + `uvm_info(`gfn, $sformatf("FLASH OP PROGRAM:%0p DATA:%0p", flash_op, flash_op_data), UVM_HIGH) + do_arb(); + endtask : body + + virtual task do_operations(); + // Configure the flash + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + + // Host direct read of random written value + `uvm_info(`gfn, $sformatf("Starting direct back-to-back reads and controller operations"), + UVM_HIGH) + fork + begin + // host read data and init of selected chunk of memory + host_read_data(flash_op_host_rd); + end + begin + // controller read, program or erase + if (flash_op.op == flash_ctrl_pkg::FlashOpRead) begin + controller_read_data(flash_op); + end else if (flash_op.op == flash_ctrl_pkg::FlashOpProgram) begin + controller_program_data(flash_op, flash_op_data); + end else begin //flash_op.op == flash_ctrl_pkg::FlashOpErase + controller_erase_data(flash_op); + end + end + join; + endtask : do_operations + + // host read data. + virtual task host_read_data(flash_op_t flash_op); + data_4s_t rdata; + bit comp; + for (int j = 0; j < flash_op.num_words; j++) begin + read_addr = flash_op.addr + 4 * j; + do_direct_read(.addr(read_addr), .mask('1), .blocking(cfg.block_host_rd), .check_rdata(0), + .rdata(rdata), .completed(comp)); + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + end + endtask : host_read_data + + // Controller read data. + virtual task controller_read_data(flash_op_t flash_op); + flash_rd_data.delete(); + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_rd_data, poll_fifo_status); + wait_flash_op_done(); + `uvm_info(`gfn, $sformatf("FLASH OP READ DATA: %0p", flash_rd_data), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, flash_rd_data); + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + endtask : controller_read_data + + // Controller program data. + virtual task controller_program_data(flash_op_t flash_op, data_q_t flash_op_data); + data_q_t exp_data; + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + `uvm_info(`gfn, $sformatf("FLASH OP PROGRAM DATA: %0p", flash_op_data), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, exp_data); + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + endtask : controller_program_data + + // Controller erase data. + virtual task controller_erase_data(flash_op_t flash_op); + data_q_t exp_data; + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + `uvm_info(`gfn, $sformatf("FLASH OP ERASE DATA DONE"), UVM_HIGH) + cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); + endtask : controller_erase_data + + virtual task do_arb(); + data_4s_t rdata; + data_q_t exp_data; + + // setting non blocking host reads + cfg.block_host_rd = 0; + + // Configure the flash + foreach (mp_regions[k]) begin + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + `uvm_info(`gfn, $sformatf("MP INFO regions values %p", mp_info_pages[i][j][k]), UVM_HIGH) + end + + `uvm_info(`gfn, $sformatf("Starting arbitration"), UVM_HIGH) + + fork + begin // host read data + bit comp; + `uvm_info(`gfn, $sformatf("FLASH OP HOST RD ARB: %0p", flash_op_host_rd), UVM_HIGH) + cfg.clk_rst_vif.wait_clks(32); + for (int j = 0; j < flash_op_host_rd.num_words; j++) begin + read_addr = flash_op_host_rd.addr + 4 * j; + do_direct_read(.addr(read_addr), .mask('1), .blocking(cfg.block_host_rd), + .check_rdata(0), .rdata(rdata), .completed(comp)); + `uvm_info(`gfn, $sformatf("FINISH SENDING HOST ADD: %0d", read_addr), UVM_HIGH) + end + csr_utils_pkg::wait_no_outstanding_access(); + end + begin // controller program data + `uvm_info(`gfn, $sformatf("FLASH OP PROGRAM ARB: %0p DATA: %0p", flash_op, flash_op_data), + UVM_HIGH) + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + `uvm_info(`gfn, $sformatf("FINISH PROGRAM ADD: %0d expected:", flash_op.addr), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, exp_data); + end + join; + + // check 6th host direct read data after losing priority + for (int j = 0; j < flash_op_host_rd.num_words; j++) begin + flash_rd_one_data = cfg.flash_rd_data.pop_front(); + `uvm_info(`gfn, $sformatf("FLASH DIRECT READ DATA: 0x%0h", flash_rd_one_data), UVM_HIGH) + //first 5 data have init value while 6th value is overwritten by ctrl due to priority lost + if (j < 5) begin + `DV_CHECK_EQ(flash_rd_one_data, AllOnes) + end + if (j == 5) begin + `DV_CHECK_EQ(flash_rd_one_data, flash_op_data[0]) + end + end + + endtask : do_arb + +endclass : flash_ctrl_phy_arb_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_host_grant_err_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_host_grant_err_vseq.sv new file mode 100644 index 0000000000000..c6033fed955e4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_phy_host_grant_err_vseq.sv @@ -0,0 +1,90 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence force host read to non data partition +// to trigger fatal error. +class flash_ctrl_phy_host_grant_err_vseq extends flash_ctrl_err_base_vseq; + `uvm_object_utils(flash_ctrl_phy_host_grant_err_vseq) + `uvm_object_new + + task run_error_event(); + int delay; + string path = "tb.dut.u_eflash.gen_flash_cores[0].u_core.muxed_part"; + + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = cfg.seq_cfg.long_fatal_err_delay; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + cfg.scb_h.check_alert_sig_int_err = 0; + + // unit 100 ns; + delay = $urandom_range(1, 10); + #(delay * 100ns); + + // set error counter high number to skip unpredictable error + cfg.scb_h.exp_tl_rsp_intg_err = 1; + cfg.tlul_eflash_exp_cnt = 1; + cfg.tlul_core_exp_cnt = 1; + cfg.otf_scb_h.comp_off = 1; + cfg.otf_scb_h.mem_mon_off = 1; + + // This can happen when host_read is sent to info partition (by force). + // After that, fatal error happen. So turning off these assertion + // just to make sure test run to complete. + $assertoff(1, "tb.dut"); + $assertoff(0, "tb.dut.gen_alert_senders[0].u_alert_sender"); + $assertoff(0, "tb.dut.gen_alert_senders[1].u_alert_sender"); + $assertoff(0, "tb.dut.u_tl_adapter_eflash"); + $assertoff(0, "tb.dut.u_eflash"); + $assertoff(0, "tb.dut.u_disable_buf"); + $assertoff(0, "tb.dut.tlul_assert_device"); + $assertoff(0, "tb.dut.u_reg_core.u_socket"); + $assertoff(0, "tb.dut.u_prog_tl_gate"); + $assertoff(0, "tb.dut.u_to_prog_fifo"); + $assertoff(0, "tb.dut.u_tl_gate"); + $assertoff(0, "tb.dut.u_to_rd_fifo"); + $assertoff(0, "tb.dut.u_lfsr"); + $assertoff(0, "tb.dut.u_sw_rd_fifo"); + $assertoff(0, "tb.dut.u_prog_fifo"); + + @(posedge cfg.flash_ctrl_vif.host_gnt); + `DV_CHECK(uvm_hdl_force(path, 1)) + + check_fault(.ptr(ral.fault_status.host_gnt_err), .back_door(1)); + `DV_CHECK(uvm_hdl_release(path)) + + collect_err_cov_status(ral.fault_status); + // Kill all on-going assertion under dut + // Once host_grant_err is detected, whole datapath can be corrupted by x's. + // So shutdown after detect fatal error + $assertkill(0, "tb.dut"); + + drain_n_finish_err_event(); + endtask + + task launch_host_rd(); + bit [TL_AW-1:0] tl_addr; + bit saw_err, completed; + data_4s_t rdata; + + for (int i = 0; i < cfg.otf_num_hr; ++i) begin + tl_addr[OTFHostId-2:0] = $urandom(); + tl_addr[OTFBankId] = $urandom_range(0, 1); + fork + tl_access_w_abort( + .addr(tl_addr), .write(1'b0), .completed(completed), + .saw_err(saw_err), + .tl_access_timeout_ns(cfg.seq_cfg.erase_timeout_ns), + .data(rdata), .check_rsp(1'b0), .blocking(1), + .tl_sequencer_h(p_sequencer.tl_sequencer_hs[cfg.flash_ral_name])); + + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + endtask // launch_host_rd + + task clean_up(); + init_controller(); + endtask // clean_up +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv new file mode 100644 index 0000000000000..c694138a4871b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_prog_reset_vseq.sv @@ -0,0 +1,113 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_prog_reset_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_prog_reset_vseq) + `uvm_object_new + typedef enum logic [10:0] { + StIdle = 11'b11111111110, + StPrePack = 11'b00001110111, // 53.648 us + StPackData = 11'b10100100011, // 5.586 us + StPostPack = 11'b11010000101, // 53.922 + StCalcPlainEcc = 11'b01101011011, // 5.677 + StReqFlash = 11'b01010110010, // 5.814 + StWaitFlash = 11'b00100111000, // 13.246 + StCalcMask = 11'b00000001110, // 5.7 + StScrambleData = 11'b00011101001, // 5.745 + StCalcEcc = 11'b00111010100, // 5.791 + StDisabled = 11'b10001000000, + StInvalid = 11'b10010011011 + } reset_state_e; + + typedef enum { + DVStIdle = 0, + DVStPrePack = 1, // + DVStPackData = 2, // + DVStPostPack = 3, // + DVStCalcPlainEcc = 4, // + DVStReqFlash = 5, + DVStWaitFlash = 6, + DVStCalcMask = 7, // + DVStScrambleData = 8, // + DVStCalcEcc = 9, // + DVStDisabled = 10, + DVStInvalid = 11 + } reset_index_e; + + constraint ctrl_data_num_c {ctrl_data_num inside {[1:32]};} + + virtual task body(); + flash_op_t ctrl; + int num, bank, iter; + int state_long_timeout_ns = 500_000_000; // 500ms + int state_timeout_ns = 100000; // 100us + + // Don't select a partition defined as read-only + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + + cfg.m_tl_agent_cfg.check_tl_errs = 0; + cfg.m_tl_agent_cfgs["flash_ctrl_eflash_reg_block"].check_tl_errs = 0; + + flash_program_data_c.constraint_mode(0); + iter = 0; + fork begin + fork + begin + while (iter < 100) begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + prog_flash(ctrl, bank, num, fractions); + iter++; + end // while (iter < 100) + end + begin + string path1, path2; + reset_index_e reset_index = reset_index_e'($urandom_range(DVStPrePack, DVStCalcEcc)); + `uvm_info("Test", $sformatf("reset_idx: %s", reset_index.name), UVM_MEDIUM) + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.prog_state0 == dv2rtl_st(reset_index) || + cfg.flash_ctrl_vif.prog_state1 == dv2rtl_st(reset_index));, + $sformatf("Timed out waiting for %s", reset_index.name), + // Use long time out. + // Some unique state does not always guarantee to reach. + // In that case, let test finish gracefully. + state_long_timeout_ns) + end + join_any + disable fork; + end join + `uvm_info(`gfn, "RESET", UVM_LOW) + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + // Clean up scoreboard before the next round. + cfg.otf_scb_h.clear_fifos(); + cfg.otf_scb_h.stop = 1; + apply_reset(); + csr_wr(.ptr(ral.init), .value(1)); + `uvm_info("Test","OTP",UVM_LOW) + otp_model(); + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);, + "Timed out waiting for rd_buf_en", + state_timeout_ns) + + endtask + + function reset_state_e dv2rtl_st(reset_index_e idx); + case(idx) + DVStIdle : return StIdle; + DVStPrePack : return StPrePack; + DVStPackData : return StPackData; + DVStPostPack : return StPostPack; + DVStCalcPlainEcc: return StCalcPlainEcc; + DVStReqFlash : return StReqFlash; + DVStWaitFlash : return StWaitFlash; + DVStCalcMask : return StCalcMask; + DVStScrambleData: return StScrambleData; + DVStCalcEcc : return StCalcEcc; + DVStDisabled : return StDisabled; + DVStInvalid : return StInvalid; + default: begin + `uvm_error("dv2rma_st", $sformatf("unknown index:%0d", idx)) + end + endcase + endfunction +endclass // flash_ctrl_prog_reset_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_base_vseq.sv new file mode 100644 index 0000000000000..8fc50fb609b16 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_base_vseq.sv @@ -0,0 +1,409 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This vseq randomly programs memory protection and performs a bunch of read / program / erase +// operations. It is encouraged to extend this vseq to a custom vseq that constrains the +// randomization by overriding the `configure_vseq()` function. See `flash_ctrl_smoke_vseq` for +// example. +class flash_ctrl_rand_ops_base_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_rand_ops_base_vseq) + + // Number of times we run a random flash operation with a fully configured flash ctrl. + rand uint num_flash_ops_per_cfg; + + constraint num_flash_ops_per_cfg_c { + num_flash_ops_per_cfg inside {[1 : cfg.seq_cfg.max_flash_ops_per_cfg]}; + } + + // A single randomized flash ctrl operation. + rand flash_op_t flash_op; + + // Constraint address to be in relevant range for the selected partition. + constraint addr_c { + if (flash_op.partition != FlashPartData) { + flash_op.addr inside + {[0:InfoTypeBytes[flash_op.partition>>1]-1], + [BytesPerBank:BytesPerBank+InfoTypeBytes[flash_op.partition>>1]-1]}; + } + } + + constraint flash_op_c { + flash_op.op inside {FlashOpRead, FlashOpProgram, FlashOpErase}; + flash_op.addr inside {[0 : FlashSizeBytes - 1]}; + + if (!cfg.seq_cfg.op_allow_invalid) {flash_op.op != flash_ctrl_pkg::FlashOpInvalid;} + + if (cfg.seq_cfg.flash_only_op != flash_ctrl_pkg::FlashOpInvalid) { + flash_op.op == cfg.seq_cfg.flash_only_op; + } + + (flash_op.op == flash_ctrl_pkg::FlashOpErase) -> + flash_op.erase_type dist { + flash_ctrl_pkg::FlashErasePage :/ (100 - cfg.seq_cfg.op_erase_type_bank_pc), + flash_ctrl_pkg::FlashEraseBank :/ cfg.seq_cfg.op_erase_type_bank_pc + }; + + flash_op.prog_sel dist { + FlashProgSelNormal :/ (100 - cfg.seq_cfg.op_prog_type_repair_pc), + FlashProgSelRepair :/ cfg.seq_cfg.op_prog_type_repair_pc + }; + + flash_op.partition dist { + FlashPartData :/ cfg.seq_cfg.op_on_data_partition_pc, + FlashPartInfo :/ cfg.seq_cfg.op_on_info_partition_pc, + FlashPartInfo1 :/ cfg.seq_cfg.op_on_info1_partition_pc, + FlashPartInfo2 :/ cfg.seq_cfg.op_on_info2_partition_pc + }; + + // Bank erase is supported only for data & 1st info partitions + flash_op.partition != FlashPartData && flash_op.partition != FlashPartInfo -> + flash_op.erase_type == flash_ctrl_pkg::FlashErasePage; + + if (cfg.seq_cfg.op_readonly_on_info_partition) { + flash_op.partition == FlashPartInfo -> flash_op.op == flash_ctrl_pkg::FlashOpRead; + } + if (cfg.seq_cfg.op_readonly_on_info1_partition) { + flash_op.partition == FlashPartInfo1 -> flash_op.op == flash_ctrl_pkg::FlashOpRead; + } + + if (flash_op.op inside {flash_ctrl_pkg::FlashOpRead, flash_ctrl_pkg::FlashOpProgram}) { + flash_op.num_words inside {[1 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + // end of transaction must be within the program resolution + // units words bytes + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + } + + } + + // Flash ctrl operation data queue - used for programing or reading the flash. + rand data_q_t flash_op_data; + constraint flash_op_data_c { + solve flash_op before flash_op_data; + if (flash_op.op inside {flash_ctrl_pkg::FlashOpRead, flash_ctrl_pkg::FlashOpProgram}) { + flash_op_data.size() == flash_op.num_words; + } else { + flash_op_data.size() == 0; + } + } + + // Bit vector representing which of the mp region cfg CSRs to enable. + rand bit [flash_ctrl_pkg::MpRegions-1:0] en_mp_regions; + + constraint en_mp_regions_c {$countones(en_mp_regions) == cfg.seq_cfg.num_en_mp_regions;} + + // Memory protection regions settings. + rand flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + constraint mp_regions_c { + solve en_mp_regions before mp_regions; + + foreach (mp_regions[i]) { + mp_regions[i].en == mubi4_bool_to_mubi(en_mp_regions[i]); + + mp_regions[i].read_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_read_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_read_en_pc + }; + + mp_regions[i].program_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_program_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_program_en_pc + }; + + mp_regions[i].erase_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_erase_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_erase_en_pc + }; + + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + + mp_regions[i].start_page inside {[0 : FlashNumPages - 1]}; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + + // If overlap not allowed, then each configured region is uniquified. + // This creates an ascending order of mp_regions that are configured, so we shuffle it in + // post_randomize. + if (!cfg.seq_cfg.allow_mp_region_overlap) { + foreach (mp_regions[j]) { + if (i != j) { + !mp_regions[i].start_page inside { + [mp_regions[j].start_page:mp_regions[j].start_page + mp_regions[j].num_pages] + }; + } + } + } + + } + } + + // Default flash ctrl region settings. + rand mubi4_t default_region_read_en; + rand mubi4_t default_region_program_en; + rand mubi4_t default_region_erase_en; + + constraint default_region_read_en_c { + default_region_read_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_read_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_read_en_pc) + }; + } + + constraint default_region_program_en_c { + default_region_program_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_program_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_program_en_pc) + }; + } + + constraint default_region_erase_en_c { + default_region_erase_en dist { + MuBi4True :/ cfg.seq_cfg.default_region_erase_en_pc, + MuBi4False :/ (100 - cfg.seq_cfg.default_region_erase_en_pc) + }; + } + + // Information partitions memory protection rpages settings. + rand + flash_bank_mp_info_page_cfg_t + mp_info_pages[flash_ctrl_pkg::NumBanks][flash_ctrl_pkg::InfoTypes][$]; + + constraint mp_info_pages_c { + + foreach (mp_info_pages[i, j]) { + + mp_info_pages[i][j].size() == flash_ctrl_pkg::InfoTypeSize[j]; + + foreach (mp_info_pages[i][j][k]) { + + mp_info_pages[i][j][k].en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_en_pc[i][j] + }; + + mp_info_pages[i][j][k].read_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_read_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_read_en_pc[i][j] + }; + + mp_info_pages[i][j][k].program_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_program_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_program_en_pc[i][j] + }; + + mp_info_pages[i][j][k].erase_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_erase_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_erase_en_pc[i][j] + }; + + mp_info_pages[i][j][k].scramble_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_scramble_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_scramble_en_pc[i][j] + }; + + mp_info_pages[i][j][k].ecc_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_ecc_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_ecc_en_pc[i][j] + }; + + mp_info_pages[i][j][k].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_info_page_he_en_pc[i][j]), + MuBi4True :/ cfg.seq_cfg.mp_info_page_he_en_pc[i][j] + }; + + } + } + } + + // Bank erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint bank_erase_en_c { + foreach (bank_erase_en[i]) { + bank_erase_en[i] dist { + 0 :/ (100 - cfg.seq_cfg.bank_erase_en_pc), + 1 :/ cfg.seq_cfg.bank_erase_en_pc + }; + } + } + + // Fifo levels. + rand uint program_fifo_intr_level; + rand uint read_fifo_intr_level; + + constraint program_fifo_intr_level_c { + program_fifo_intr_level dist { + 0 :/ 1, + [1:4] :/ 1, + [5:10] :/ 1, + [11:ProgFifoDepth-2] :/ 1, + ProgFifoDepth-1 :/ 1 + }; + } + + constraint program_fifo_intr_level_max_c { + program_fifo_intr_level < ProgFifoDepth; + } + + constraint read_fifo_intr_level_c { + read_fifo_intr_level dist { + 0 :/ 1, + [1:4] :/ 1, + [5:10] :/ 1, + [11:ReadFifoDepth-2] :/ 1, + ReadFifoDepth-1 :/ 1 + }; + } + + constraint read_fifo_intr_level_max_c { + read_fifo_intr_level < ReadFifoDepth; + } + + // Indicates whether to poll before writing to prog_fifo or reading from rd_fifo. If interupts are + // enabled, the interrupt signals will be used instead. When set to 0, it will continuously write + // to prog_fifo / read from rd_fifo, relying on their natural backpressure mechanism. + rand bit poll_fifo_status; + + constraint poll_fifo_status_c { + poll_fifo_status dist { + 0 :/ (100 - cfg.seq_cfg.poll_fifo_status_pc), + 1 :/ cfg.seq_cfg.poll_fifo_status_pc + }; + } + + `uvm_object_new + + task body(); + rd_cache_t rd_entry; + bit op_ok = 0; + cfg.flash_ctrl_vif.lc_creator_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_owner_seed_sw_rw_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_rd_en = lc_ctrl_pkg::On; + cfg.flash_ctrl_vif.lc_iso_part_sw_wr_en = lc_ctrl_pkg::On; + cfg.scb_check = 1; + for (int i = 1; i <= num_trans; i++) begin + `uvm_info(`gfn, $sformatf("Configuring flash_ctrl %0d/%0d", i, num_trans), UVM_MEDIUM) + + // If external_cfg=1 it means this sequence is being randomized by another sequence and this + // randomization will possibly override the upper randomization (Added specifically for + // partner sequences using this one). + if (!cfg.seq_cfg.external_cfg) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + end + + // Configure the flash based on the randomized settings. + foreach (mp_regions[i]) begin + flash_ctrl_mp_region_cfg(i, mp_regions[i]); + end + + flash_ctrl_default_region_cfg(.read_en(default_region_read_en), + .program_en(default_region_program_en), + .erase_en(default_region_erase_en)); + + foreach (mp_info_pages[i, j, k]) begin + flash_ctrl_mp_info_page_cfg(i, j, k, mp_info_pages[i][j][k]); + end + + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // Send num_flash_ops_per_cfg number of ops with this configuration. + for (int j = 1; j <= num_flash_ops_per_cfg; j++) begin + data_q_t exp_data; + int retry_cnt = 0; + // Those 2 has to be randomized simultaneously, otherwise the value of flash_op_data from + // the previous iteration will affect the randomization of flash_op. + while (op_ok == 0 && retry_cnt < 100) begin + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + rd_entry.bank = flash_op.addr[OTFBankId]; + flash_op.otf_addr = flash_op.addr[OTFBankId-1:0]; + rd_entry.addr = flash_op.otf_addr; + rd_entry.addr[2:0] = 'h0; + rd_entry.part = flash_op.partition; + + if (flash_op.op == FlashOpRead) begin + if (!cfg.otf_read_entry.check(rd_entry, flash_op)) begin + cfg.otf_read_entry.insert(rd_entry, flash_op); + op_ok = 1; + end + end else begin + op_ok = 1; + cfg.otf_read_entry.update(rd_entry, flash_op); + end + retry_cnt++; + end + op_ok = 0; + `uvm_info(`gfn, $sformatf( + "Starting flash_ctrl op: %0d/%0d: %p", j, num_flash_ops_per_cfg, flash_op), + UVM_LOW) + + // Bkdr initialize the flash mem based on op. + // If you wish to do the transaction without the backdoor preperation + // (when you want transaction to affect each other), set do_tran_prep_mem to 0. + if (cfg.seq_cfg.do_tran_prep_mem) flash_ctrl_prep_mem(flash_op); + + flash_ctrl_start_op(flash_op); + `uvm_info(`gfn, $sformatf( + "Wait for operation to be done, then %s (check_mem_post_tran=%0d)", + (cfg.seq_cfg.check_mem_post_tran ? "backdoor check the flash" : + "skip to next transaction"), + cfg.seq_cfg.check_mem_post_tran + ), UVM_HIGH) + // Calculate expected data for post-transaction checks + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + case (flash_op.op) + flash_ctrl_pkg::FlashOpRead: begin + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(poll_fifo_status) + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + if (cfg.seq_cfg.check_mem_post_tran) + cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + end + flash_ctrl_pkg::FlashOpProgram: begin + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(poll_fifo_status) + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_read_check(flash_op, exp_data); + end + flash_ctrl_pkg::FlashOpErase: begin + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); + end + default: begin + // FlashOpInvalid + // covered by flash_ctrl_invalid_op_vseq + end + endcase + end + end + endtask : body + + // Prep the flash mem via bkdr before an op for enhanced checks. + virtual task flash_ctrl_prep_mem(flash_op_t flash_op); + // Invalidate the flash mem contents. We do this because we operate on and check a specific + // chunk of space. The rest of the flash mem is essentially dont-care. If the flash ctrl + // does not work correctly, the check will result in an access from the invalidated mem + // region exposing the issue. + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + case (flash_op.op) + flash_ctrl_pkg::FlashOpRead: begin + // Initialize the targeted mem region with random data. + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + cfg.clk_rst_vif.wait_clks(1); + end + flash_ctrl_pkg::FlashOpProgram: begin + // Initialize the targeted mem region with all 1s. This is required because the flash + // needs to be erased to all 1s between each successive programming. + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + end + default: ; // Do nothing + endcase + endtask + +endclass : flash_ctrl_rand_ops_base_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv new file mode 100644 index 0000000000000..66d7da4dce252 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv @@ -0,0 +1,47 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_rand_ops_vseq extends flash_ctrl_rand_ops_base_vseq; + `uvm_object_utils(flash_ctrl_rand_ops_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + cfg.seq_cfg.max_num_trans = 8; + + // Do fewer flash ops in each rerun for the smoke test. + cfg.seq_cfg.max_flash_ops_per_cfg = 20; + + // Do no more than 128 words per op. + cfg.seq_cfg.op_max_words = 128; + + // Don't enable any memory protection. + cfg.seq_cfg.num_en_mp_regions = 0; + + cfg.seq_cfg.set_partition_pc(.sel_data_part_pc(50), + .sel_info_part_pc(25), + .sel_info1_part_pc(15), + .sel_info2_part_pc(10)); + + // Enable access to all information partitions. + foreach (cfg.seq_cfg.mp_info_page_en_pc[i, j]) begin + cfg.seq_cfg.mp_info_page_en_pc[i][j] = 100; + cfg.seq_cfg.mp_info_page_read_en_pc[i][j] = 100; + cfg.seq_cfg.mp_info_page_program_en_pc[i][j] = 100; + cfg.seq_cfg.mp_info_page_erase_en_pc[i][j] = 100; + end + + // Enable default region read/program and erasability. + cfg.seq_cfg.default_region_read_en_pc = 100; + cfg.seq_cfg.default_region_program_en_pc = 100; + cfg.seq_cfg.default_region_erase_en_pc = 100; + + // Allow banks to be erased. + cfg.seq_cfg.bank_erase_en_pc = 100; + + cfg.seq_cfg.poll_fifo_status_pc = 0; + endfunction + +endclass : flash_ctrl_rand_ops_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_buff_evict_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_buff_evict_vseq.sv new file mode 100644 index 0000000000000..8106cf90e31aa --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_buff_evict_vseq.sv @@ -0,0 +1,477 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// fifo eviction test: read/program/read, read/erase/read +class flash_ctrl_rd_buff_evict_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_rd_buff_evict_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + + // Do no more than 16 words per op. + cfg.seq_cfg.op_max_words = 16; + + // no overlap mp regions + cfg.seq_cfg.allow_mp_region_overlap = 0; + + // enable high endurance + cfg.seq_cfg.mp_region_he_en_pc = 50; + cfg.seq_cfg.default_region_he_en_pc = 50; + endfunction + + // Randomized flash ctrl operation. + rand flash_op_t flash_op; + + rand uint bank; + + bit poll_fifo_status; + + // Constraint address to be in relevant range for the selected partition. + constraint addr_c { + solve bank before flash_op; + bank inside {[0 : flash_ctrl_pkg::NumBanks - 1]}; + flash_op.addr inside {[BytesPerBank * bank : BytesPerBank * (bank + 1) - BytesPerBank / 2]}; + } + + constraint flash_op_c { + flash_op.erase_type dist { + flash_ctrl_pkg::FlashErasePage :/ (100 - cfg.seq_cfg.op_erase_type_bank_pc), + flash_ctrl_pkg::FlashEraseBank :/ cfg.seq_cfg.op_erase_type_bank_pc + }; + + flash_op.partition == FlashPartData; + flash_op.num_words inside {[10 : FlashNumBusWords - flash_op.addr[TL_AW-1:TL_SZW]]}; + flash_op.num_words <= cfg.seq_cfg.op_max_words; + flash_op.num_words < FlashPgmRes - flash_op.addr[TL_SZW+:FlashPgmResWidth]; + } + + // Flash ctrl operation data queue - used for programming or reading. + rand data_q_t flash_op_data; + data_q_t flash_rd_data; + + // Single host read data + data_t flash_rd_one_data; + + constraint flash_op_data_c { + solve flash_op before flash_op_data; + flash_op_data.size() == flash_op.num_words; + } + + // Bit vector representing which of the mp region cfg CSRs to enable. + rand bit [flash_ctrl_pkg::MpRegions-1:0] en_mp_regions; + + constraint en_mp_regions_c {$countones(en_mp_regions) == cfg.seq_cfg.num_en_mp_regions;} + + // Memory protection regions settings. + rand flash_mp_region_cfg_t mp_regions[flash_ctrl_pkg::MpRegions]; + + constraint mp_regions_c { + solve en_mp_regions before mp_regions; + + foreach (mp_regions[i]) { + mp_regions[i].en == mubi4_bool_to_mubi(en_mp_regions[i]); + + mp_regions[i].read_en == MuBi4True; + + mp_regions[i].program_en == MuBi4True; + + mp_regions[i].erase_en == MuBi4True; + + mp_regions[i].he_en dist { + MuBi4False :/ (100 - cfg.seq_cfg.mp_region_he_en_pc), + MuBi4True :/ cfg.seq_cfg.mp_region_he_en_pc + }; + mp_regions[i].ecc_en == MuBi4False; + + mp_regions[i].start_page inside {[0 : FlashNumPages - 1]}; + mp_regions[i].num_pages inside {[1 : FlashNumPages - mp_regions[i].start_page]}; + mp_regions[i].num_pages <= cfg.seq_cfg.mp_region_max_pages; + + // If overlap not allowed, then each configured region is uniquified. + // This creates an ascending order of mp_regions that are configured, so we shuffle it in + // post_randomize. + if (!cfg.seq_cfg.allow_mp_region_overlap) { + foreach (mp_regions[j]) { + if (i != j) { + !mp_regions[i].start_page inside { + [mp_regions[j].start_page:mp_regions[j].start_page + mp_regions[j].num_pages] + }; + } + } + } + } + } + + // Bank erasability. + rand bit [flash_ctrl_pkg::NumBanks-1:0] bank_erase_en; + + constraint bank_erase_en_c { + foreach (bank_erase_en[i]) { + bank_erase_en[i] == 1; + } + } + + // Default flash ctrl region settings. + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + mubi4_t default_region_scramble_en; + mubi4_t default_region_ecc_en; + rand mubi4_t default_region_he_en; + + constraint default_region_he_en_c { + default_region_he_en dist { + MuBi4False :/ cfg.seq_cfg.default_region_he_en_pc, + MuBi4True :/ (100 - cfg.seq_cfg.default_region_he_en_pc) + }; + } + + addr_t read_addr; + data_q_t exp_data; + data_4s_t all_ones = {TL_DW{1'b1}}; + + task body(); + int func_cov_op; + //enable polling of fifo status for frontdoor write and read + poll_fifo_status = 1; + + // Default region settings + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + default_region_ecc_en = MuBi4False; + default_region_scramble_en = MuBi4False; + + // Scoreboard knob + cfg.block_host_rd = 1; + + // Configure the flash with scramble disable. + foreach (mp_regions[k]) begin + mp_regions[k].scramble_en = MuBi4False; + flash_ctrl_mp_region_cfg(k, mp_regions[k]); + `uvm_info(`gfn, $sformatf("MP regions values %p", mp_regions[k]), UVM_HIGH) + end + + flash_ctrl_default_region_cfg( + .read_en(default_region_read_en), .program_en(default_region_program_en), + .erase_en(default_region_erase_en), .scramble_en(default_region_scramble_en), + .ecc_en(default_region_ecc_en), .he_en(default_region_he_en)); + + //Enable Bank erase + flash_ctrl_bank_erase_cfg(.bank_erase_en(bank_erase_en)); + + // 1. host read, program and host read + `uvm_info(`gfn, $sformatf("Scenario 1: host read, program and host read"), UVM_HIGH) + + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // Invalidate the flash mem contents. We do this because we operate on and check a specific + // chunk of space. The rest of the flash mem is essentially dont-care. If the flash ctrl + // does not work correctly, the check will result in an access from the invalidated mem + // region exposing the issue. + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + `uvm_info(`gfn, $sformatf("Starting backdoor write operation with random values"), UVM_HIGH) + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + + // host read data + host_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", exp_data), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH PROGRAM DATA: %0p", flash_op_data), UVM_HIGH) + + // make sure that program data are different then previously read data + check_diff(flash_op_data); + + // program data + controller_program_data(flash_op, flash_op_data); + + // host read data has been checked in scoreboard by backdoor read for scramble disabled + `uvm_info(`gfn, $sformatf("Starting host read after program"), UVM_HIGH) + host_read_op_data(flash_op); + + // 2. Controller read, program and Controller read + `uvm_info(`gfn, $sformatf("Scenario 2: Controller read, program and Controller read"), UVM_HIGH) + + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // controller read data and init of selected chunk of memory + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + controller_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", flash_rd_data), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH PROGRAM DATA: %0p", flash_op_data), UVM_HIGH) + + // make sure that program data are different then previously read data + check_diff(flash_op_data); + + // program data + controller_program_data(flash_op, flash_op_data); + + // controller read data + controller_read_op_data(flash_op); + + // check Controller read data via backdoor read + `uvm_info(`gfn, $sformatf("READ FLASH OP PROGRAM/READ DATA: %0p", flash_rd_data), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, flash_rd_data); + + // 3. Controller read, program and host read + `uvm_info(`gfn, $sformatf("Scenario 3: Controller read, program and host read"), UVM_HIGH) + + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // controller read data and init of selected chunk of memory + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + controller_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", flash_rd_data), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH PROGRAM DATA: %0p", flash_op_data), UVM_HIGH) + + // make sure that program data are different then previously read data + check_diff(flash_op_data); + + // program data + controller_program_data(flash_op, flash_op_data); + + // host read data + `uvm_info(`gfn, $sformatf("Starting host read after program"), UVM_HIGH) + host_read_op_data(flash_op); + + // 4. host read, program and Controller read + `uvm_info(`gfn, $sformatf("Scenario 4: host read, program and Controller read"), UVM_HIGH) + + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // host read data and init of selected chunk of memory + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + host_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", exp_data), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH PROGRAM DATA: %0p", flash_op_data), UVM_HIGH) + + // make sure that program data are different then previously read data + check_diff(flash_op_data); + + // program data + controller_program_data(flash_op, flash_op_data); + + // controller read data + controller_read_op_data(flash_op); + + // check Controller read data via backdoor read + `uvm_info(`gfn, $sformatf("READ FLASH OP PROGRAM/READ DATA: %0p", flash_rd_data), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, flash_rd_data); + + // 5. host read, erase and host read + `uvm_info(`gfn, $sformatf("Scenario 5: host read, erase and host read"), UVM_HIGH) + + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // host read data and init of selected chunk of memory + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + host_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", exp_data), UVM_HIGH) + + // erase data + erase_data(flash_op); + + // host data + `uvm_info(`gfn, $sformatf("Starting host read after program"), UVM_HIGH) + host_read_op_data(flash_op); + + // make sure that host read data is all ones + check_all_ones_host(); + + // 6. Controller read, erase and Controller read + `uvm_info(`gfn, $sformatf("Scenario 6: Controller read, erase and Controller read"), UVM_HIGH) + + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // controller read data and init of selected chunk of memory + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + controller_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", flash_rd_data), UVM_HIGH) + + // erase data + erase_data(flash_op); + + // controller read data + controller_read_op_data(flash_op); + + // check Controller read data via backdoor read + `uvm_info(`gfn, $sformatf("READ FLASH OP PROGRAM/READ DATA: %0p", flash_rd_data), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, flash_rd_data); + + // make sure that controller read data is all ones + check_all_ones_ctrl(); + + // 7. Controller read, erase and host read + `uvm_info(`gfn, $sformatf("Scenario 7: Controller read, erase and host read"), UVM_HIGH) + + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // controller read data and init of selected chunk of memory + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + controller_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", flash_rd_data), UVM_HIGH) + + // erase data + erase_data(flash_op); + + // host data + `uvm_info(`gfn, $sformatf("Starting host read after program"), UVM_HIGH) + host_read_op_data(flash_op); + + // make sure that host read data is all ones + check_all_ones_host(); + + // 8. host read, erase and Controller read + `uvm_info(`gfn, $sformatf("Scenario 8: host read, erase and Controller read"), UVM_HIGH) + if (!randomize(flash_op, flash_op_data)) begin + `uvm_fatal(`gfn, "Randomization failed for flash_op & flash_op_data!") + end + + // host read data and init of selected chunk of memory + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + host_read_op_data(flash_op); + + `uvm_info(`gfn, $sformatf("FLASH OP: %0p, BANK %0d", flash_op, bank), UVM_HIGH) + `uvm_info(`gfn, $sformatf("FLASH READ DATA: %0p", exp_data), UVM_HIGH) + + // erase data + erase_data(flash_op); + + // controller read data + controller_read_op_data(flash_op); + + // check Controller read data via backdoor read + `uvm_info(`gfn, $sformatf("READ FLASH OP PROGRAM/READ DATA: %0p", flash_rd_data), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, flash_rd_data); + + // make sure that controller read data is all ones + check_all_ones_ctrl(); + + // checking coverpoints for state transitions + if (cfg.en_cov) begin + func_cov_op = cov.control_cg.op_evict_cp.get_coverage(); + if (func_cov_op == 100) begin + `uvm_info(`gfn, $sformatf("Coverage READ/PROGRAM(ERASE)/READ reached!"), UVM_LOW) + end else begin + `uvm_error(`gfn, $sformatf("Coverage READ/PROGRAM(ERASE)/READ not reached!")) + end + end + + endtask : body + + // host read data. + virtual task host_read_op_data(flash_op_t flash_op); + data_4s_t rdata; + bit completed; + exp_data.delete(); + for (int j = 0; j < flash_op.num_words; j++) begin + read_addr = flash_op.addr + 4 * j; + do_direct_read(.addr(read_addr), .mask('1), .blocking(1), .check_rdata(0), .rdata(rdata), + .completed(completed)); + exp_data.push_back(rdata); + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + end + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + endtask : host_read_op_data + + // Controller read data. + virtual task controller_read_op_data(ref flash_op_t flash_op); + flash_op.op = flash_ctrl_pkg::FlashOpRead; + flash_rd_data.delete(); + flash_ctrl_start_op(flash_op); + flash_ctrl_read(flash_op.num_words, flash_rd_data, poll_fifo_status); + wait_flash_op_done(); + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + endtask : controller_read_op_data + + // Controller program data. + virtual task controller_program_data(ref flash_op_t flash_op, data_q_t flash_op_data); + flash_op.op = flash_ctrl_pkg::FlashOpProgram; + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitSet)); + flash_ctrl_start_op(flash_op); + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + endtask : controller_program_data + + // Erase data. + virtual task erase_data(ref flash_op_t flash_op); + flash_op.op = flash_ctrl_pkg::FlashOpErase; + flash_ctrl_start_op(flash_op); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + cfg.clk_rst_vif.wait_clks($urandom_range(0, 10)); + endtask : erase_data + + // make sure that program data are different then previously read data + virtual task check_diff(data_q_t flash_op_data); + foreach (flash_op_data[k]) begin + `uvm_info(`gfn, $sformatf( + "FLASH WRITE DATA: 0x%0h FLASH HOST READ DATA: 0x%0h", flash_op_data[k], exp_data[k] + ), UVM_HIGH) + if (flash_op_data[k] == exp_data[k]) begin + `uvm_error(`gfn, $sformatf( + "write_data: 0x%0h == read_data: 0x%0h", flash_op_data[k], exp_data[k])) + end + end + endtask : check_diff + + // make sure that host read data is all ones + virtual task check_all_ones_host(); + foreach (exp_data[k]) begin + `uvm_info(`gfn, $sformatf("FLASH HOST READ DATA: 0x%0h", exp_data[k]), UVM_HIGH) + if (exp_data[k] != all_ones) begin + `uvm_error(`gfn, $sformatf( + "Erased data different than ones: 0x%0h 0x%0h", exp_data[k], all_ones)) + end + end + endtask : check_all_ones_host + + // make sure that controller read data is all ones + virtual task check_all_ones_ctrl(); + foreach (flash_rd_data[k]) begin + `uvm_info(`gfn, $sformatf("FLASH READ DATA: 0x%0h", flash_rd_data[k]), UVM_HIGH) + if (flash_rd_data[k] != all_ones) begin + `uvm_error(`gfn, $sformatf( + "Erased data different than ones: 0x%0h 0x%0h", flash_rd_data[k], all_ones)) + end + end + endtask : check_all_ones_ctrl + +endclass : flash_ctrl_rd_buff_evict_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_ooo_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_ooo_vseq.sv new file mode 100644 index 0000000000000..d3dba1912dbc0 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_ooo_vseq.sv @@ -0,0 +1,91 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Test sends 'host read' over 'slow' and 'fast' return data path. +// 'slow' and 'fast' return data path is created by +// enabling and disabling scramble for each region. +// In this test, scramble is enabled all pages in bank 0 while +// scramble is disabled in all pages in bank 1. +// Data from bank 1 return earlier than bank 0 but that should +// be re-arranged in request order at the end of read data pipe line. + +class flash_ctrl_rd_ooo_vseq extends flash_ctrl_legacy_base_vseq; + `uvm_object_utils(flash_ctrl_rd_ooo_vseq) + `uvm_object_new + + virtual task body(); + flash_op_t ctrl; + int num, bank; + + flash_program_data_c.constraint_mode(0); + cfg.clk_rst_vif.wait_clks(5); + fork + begin + for (int i = 0; i < cfg.otf_num_hr; ++i) begin + fork + send_host_rd(i); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + begin + repeat(cfg.otf_num_rw) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + bank = rand_op.addr[OTFBankId]; + read_flash(ctrl, bank, ctrl_num, fractions); + end + end + join + endtask + + task send_host_rd(int idx); + flash_op_t host; + int host_num, host_bank; + + host.otf_addr[OTFHostId-2:0] = $urandom(); + host.otf_addr[1:0] = 'h0; + `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(host_num, + host_num dist {1 := 5, + [2:4] := 1};) + host_bank = $urandom_range(0,1); + + otf_direct_read(host.otf_addr, host_bank, host_num, 0); + endtask + + task flash_otf_region_cfg(otf_cfg_mode_e scr_mode = OTFCfgFalse, + otf_cfg_mode_e ecc_mode = OTFCfgFalse); + + // Make default config scramble disable, ecc enable. + flash_ctrl_default_region_cfg(.scramble_en(MuBi4False), + .ecc_en(MuBi4True)); + // Scramble enable in Bank 0 only + foreach (cfg.mp_regions[i]) begin + cfg.mp_regions[i] = rand_regions[i]; + if (i < 2) cfg.mp_regions[i].en = MuBi4True; + else cfg.mp_regions[i].en = MuBi4False; + if (i == 0) begin + cfg.mp_regions[i].scramble_en = MuBi4True; + cfg.mp_regions[i].start_page = 0; + cfg.mp_regions[i].num_pages = 256; + end + if (i == 1) begin + cfg.mp_regions[i].scramble_en = MuBi4False; + cfg.mp_regions[i].start_page = 256; + cfg.mp_regions[i].num_pages = 256; + end + cfg.mp_regions[i].ecc_en = MuBi4True; + flash_ctrl_mp_region_cfg(i, cfg.mp_regions[i]); + `uvm_info("otf_region_cfg", $sformatf("region[%0d] = %p", i, cfg.mp_regions[i]), UVM_MEDIUM) + end + `uvm_info("otf_region_cfg", $sformatf("default = %p", cfg.default_region_cfg), UVM_MEDIUM) + flash_ctrl_default_info_cfg(scr_mode, ecc_mode); + update_p2r_map(cfg.mp_regions); + endtask // flash_otf_region_cfg + task post_start(); + flash_init = otf_flash_init; + super.post_start(); + endtask +endclass // flash_ctrl_rd_ooo_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_path_intg_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_path_intg_vseq.sv new file mode 100644 index 0000000000000..c1b5a33e435fd --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rd_path_intg_vseq.sv @@ -0,0 +1,89 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence sends read traffic with error injection at the output of read_buffer, +// and checks the read response will trigger fatal_err.storage_err. +// It enables scrambling since it is possible to skip the read buffer when it is disabled, +// see rtl/flash_phy_rd.sv for details. +class flash_ctrl_rd_path_intg_vseq extends flash_ctrl_legacy_base_vseq; + `uvm_object_utils(flash_ctrl_rd_path_intg_vseq) + `uvm_object_new + + task body(); + string path1, path2; + int state_timeout_ns = 100000; // 100us + + repeat(5) begin + flash_op_t host; + bit [TL_AW-1:0] tl_addr; + bit saw_err, completed; + data_4s_t rdata; + + // Read buffer can be skipped if descramble is not enabled and there is + // no backlog at the read response pipeline. + // Enable ecc for all regions + flash_otf_region_cfg(.scr_mode(OTFCfgTrue), .ecc_mode(OTFCfgTrue)); + cfg.clk_rst_vif.wait_clks(10); + for (int k = 0; k < 4; k++) begin + path1 = $sformatf({"tb.dut.u_eflash.gen_flash_cores[0].u_core", + ".u_rd.gen_bufs[%0d].u_rd_buf.data_i[35:28]"}, k); + path2 = $sformatf({"tb.dut.u_eflash.gen_flash_cores[1].u_core", + ".u_rd.gen_bufs[%0d].u_rd_buf.data_i[35:28]"}, k); + `DV_CHECK(uvm_hdl_force(path1, $urandom())) + `DV_CHECK(uvm_hdl_force(path2, $urandom())) + end + cfg.scb_h.expected_alert["fatal_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_err"].max_delay = 2000; + cfg.scb_h.exp_alert_contd["fatal_err"] = 10000; + + cfg.scb_h.exp_tl_rsp_intg_err = 1; + tl_addr[OTFHostId-2:0] = $urandom(); + tl_addr[1:0] = 'h0; + tl_addr[OTFBankId] = $urandom_range(0, 1); + + for (int i = 0; i < cfg.otf_num_hr; ++i) begin + bit local_saw_err; + // fatal_err.phy_storage_err + tl_access_w_abort( + .addr(tl_addr), .write(1'b0), .completed(completed), + .saw_err(local_saw_err), + .tl_access_timeout_ns(cfg.seq_cfg.erase_timeout_ns), + .data(rdata), .check_rsp(1'b0), .blocking(1), + .tl_sequencer_h(p_sequencer.tl_sequencer_hs[cfg.flash_ral_name])); + saw_err |= local_saw_err; + + if ((i % 2)== 1) tl_addr += 4; + end + csr_utils_pkg::wait_no_outstanding_access(); + `DV_CHECK_EQ(saw_err, 1) + + // Check fault_status register and err_code register to make sure + // host read only triggers fault_status.phy_storage_err + collect_err_cov_status(ral.fault_status); + csr_rd_check(.ptr(ral.fault_status.phy_storage_err), .compare_value(1)); + csr_rd_check(.ptr(ral.err_code), .compare_value(0)); + + `uvm_info(`gfn, "Wait until all drain", UVM_LOW) + cfg.clk_rst_vif.wait_clks(100); + `DV_CHECK(uvm_hdl_release(path1)) + `DV_CHECK(uvm_hdl_release(path2)) + + // reset for the next round + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + apply_reset(); + csr_wr(.ptr(ral.init), .value(1)); + `uvm_info("Test","OTP",UVM_LOW) + otp_model(); + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);, + "Timed out waiting for rd_buf_en", + state_timeout_ns) + cfg.clk_rst_vif.wait_clks(10); + end + + // disable tlul_err_cnt check + cfg.tlul_core_obs_cnt = cfg.tlul_core_exp_cnt; + endtask + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_re_evict_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_re_evict_vseq.sv new file mode 100644 index 0000000000000..e9dde5bde627c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_re_evict_vseq.sv @@ -0,0 +1,13 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This test creates read buffer eviction by erase operation. +class flash_ctrl_re_evict_vseq extends flash_ctrl_rw_evict_vseq; + `uvm_object_utils(flash_ctrl_re_evict_vseq) + `uvm_object_new + + task send_evict(flash_op_t ctrl, int bank); + erase_flash(ctrl, bank); + endtask +endclass // flash_ctrl_re_evict_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_rnd_wd_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_rnd_wd_vseq.sv new file mode 100644 index 0000000000000..68ed716c77865 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_rnd_wd_vseq.sv @@ -0,0 +1,27 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Read random size of fraction the page. +// fraction size : [1:16] buswords (4byte). +// Start address is 4byte aligned. +class flash_ctrl_read_rnd_wd_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_read_rnd_wd_vseq) + `uvm_object_new + + virtual task body(); + flash_op_t ctrl; + int num, bank; + int mywd; + + num = 1; + flash_program_data_c.constraint_mode(0); + repeat(100) begin + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rand_op) + ctrl = rand_op; + bank = rand_op.addr[OTFBankId]; + mywd = fractions; + read_flash(ctrl, bank, num, mywd); + end + endtask +endclass // flash_ctrl_read_rnd_wd_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_word_sweep_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_word_sweep_vseq.sv new file mode 100644 index 0000000000000..a8393c8609f68 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_read_word_sweep_vseq.sv @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Read fraction of the page. +// fraction size starts from 1 word (4byte) and increased by 1 word in each round. +// For error injection to work the data must be initialized, done via mem_bkdr. +// +// There are two enhancements needed here: +// - Initialize the data right before each read +// - Detect addresses out of partition bounds and terminate within the loop. +class flash_ctrl_read_word_sweep_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_read_word_sweep_vseq) + `uvm_object_new + + // This is to avoid errors due to the address ending up out-of-bounds as they are incremented. + // It begs a better way to handle this, like just stopping the loop below. + constraint partition_c {rand_op.partition == FlashPartData;} + + localparam int InitializedMemBytes = 1024; + + local function void initialize_memory(flash_dv_part_e partition, int bank, + otf_addr_t start_addr, otf_addr_t end_addr); + `uvm_info("read_word_sweep", $sformatf( + "Initializing bank:%0d %s from addr:0x%x to:0x%x", + bank, partition.name, start_addr, end_addr), + UVM_MEDIUM) + cfg.update_otf_mem_read_zone(partition, bank, start_addr, end_addr); + endfunction + + virtual task body(); + flash_op_t ctrl; + addr_t start_addr, max_addr; + addr_t addr; + + int num, bank; + int mywd; + + `DV_CHECK_RANDOMIZE_FATAL(this) + + bank = rand_op.addr[OTFBankId]; + start_addr = rand_op.addr; + max_addr = start_addr + InitializedMemBytes - 1; + + // It may be better to initialize the data right before each individual read. + initialize_memory(rand_op.partition, bank, start_addr, max_addr); + + ctrl = rand_op; + num = 1; + mywd = 1; + addr = start_addr; + repeat(20) begin + addr_t end_addr = addr + num * mywd * 4 - 1; + // Don't read uninitialized memory to avoid trouble. + if (end_addr > max_addr) break; + ctrl.addr = addr; + ctrl.otf_addr = addr; + print_flash_op(ctrl, UVM_MEDIUM); + `uvm_info("read_word_sweep", $sformatf( + "Reading from addr:0x%x, otf_addr:0x%x, num:%0d, wd:%0d", + ctrl.addr, ctrl.otf_addr, num, mywd), + UVM_MEDIUM) + read_flash(ctrl, bank, num, mywd); + addr += num * mywd * 4; + mywd = (mywd % 16) + 1; + end + endtask + +endclass : flash_ctrl_read_word_sweep_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_ro_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_ro_vseq.sv new file mode 100644 index 0000000000000..2bf17e23b1bd9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_ro_vseq.sv @@ -0,0 +1,48 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Send read only traffic +// No protection is applied. +class flash_ctrl_ro_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_ro_vseq) + `uvm_object_new + + virtual task body(); + flash_op_t ctrl; + int num, bank; + + flash_program_data_c.constraint_mode(0); + cfg.clk_rst_vif.wait_clks(5); + + fork + begin + for (int i = 0; i < 1000; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + begin + repeat(100) begin + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rand_op) + ctrl = rand_op; + if (ctrl.partition == FlashPartData) begin + num = $urandom_range(1, 32); + end else begin + num = $urandom_range(1, InfoTypeSize[rand_op.partition >> 1]); + // Max transfer size of info is 512Byte. + if (num * fractions > 128) begin + num = 128 / fractions; + end + end + bank = rand_op.addr[OTFBankId]; + read_flash(ctrl, bank, num); + end + end + join + endtask + +endclass // flash_ctrl_ro_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv new file mode 100644 index 0000000000000..7acd29c211a74 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_evict_vseq.sv @@ -0,0 +1,130 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This test creates read buffer eviction by program_flash operation, +// careful not to reuse evict addresses since they would cause a +// double write, leading to integrity errors. This means the items in +// addr_q are always popped, and addr_q needs to be replenished. +class flash_ctrl_rw_evict_vseq extends flash_ctrl_legacy_base_vseq; + `uvm_object_utils(flash_ctrl_rw_evict_vseq) + `uvm_object_new + + // We keep up to this many items in addr_q. + parameter int TargetAddrQSize = 4; + + // This holds the collection of addresses that are candidates for eviction. + rd_cache_t addr_q[$]; + + local function void add_to_addr_q(rd_cache_t entry); + addr_q.push_back(entry); + if (addr_q.size > TargetAddrQSize) begin + rd_cache_t old_ent = addr_q.pop_front(); + end + endfunction + + virtual task body(); + int page; + int evict_trans, idx = 0; + int evict_start = 0; + + flash_op_t init_ctrl; + flash_dv_part_e part; + + // Enable interrupt for more visibility + flash_ctrl_intr_enable(6'h3f); + + bank = $urandom_range(0, 1); + + fork + begin + rd_cache_t entry; + + while (idx < 50 && cfg.flash_ctrl_vif.fatal_err == 0) begin + int num; + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + ctrl.num_words = fractions; + if (evict_start && addr_q.size >= TargetAddrQSize) begin + string entries = $sformatf("%p", addr_q); + addr_q.shuffle(); + entry = addr_q.pop_front(); + ctrl.addr = entry.addr; + ctrl.otf_addr = entry.addr; + `uvm_info(`gfn, $sformatf( + "The address to evict is 0x%x, chosen from %s", entry.addr, entries), + UVM_MEDIUM) + ctrl.partition = entry.part; + init_ctrl = ctrl; + send_evict(ctrl, bank); + ctrl = init_ctrl; + if (ctrl.partition == FlashPartData) begin + randcase + 1: readback_flash(ctrl, bank, 1, fractions); + 1: direct_readback(ctrl.otf_addr, bank, 1); + endcase + end else begin + readback_flash(ctrl, bank, 1, fractions); + end + + end else begin + entry.bank = bank; + entry.addr = ctrl.otf_addr; + entry.part = ctrl.partition; + + if (ctrl.partition == FlashPartData) begin + randcase + 1: begin + int size; + `DV_CHECK(!ctrl.addr[2], "Unexpected addr[2] set") + size = fractions / 2; + repeat (size) begin + add_to_addr_q(entry); + entry.addr += 8; + end + readback_flash(ctrl, bank, 1, fractions); + end + 3: begin + add_to_addr_q(entry); + direct_readback(ctrl.otf_addr, bank, 1); + end + endcase + end else begin + int size; + size = fractions / 2; + `DV_CHECK(!ctrl.addr[2] && !fractions[0], "Odd address or fractions") + repeat (size) begin + add_to_addr_q(entry); + entry.addr += 8; + end + readback_flash(ctrl, bank, 1, fractions); + end + `uvm_info("seq", $sformatf("idx:%0d done",idx), UVM_HIGH) + end // else: !if(evct_start) + idx++; + end // while (idx < 30 && cfg.flash_ctrl_vif.fatal_err == 0) + `uvm_info("seq", + $sformatf("read complete fatal:%0d", cfg.flash_ctrl_vif.fatal_err), UVM_HIGH) + end // fork begin + begin + time timeout_ns = 100_000_000; + evict_trans = $urandom_range(10, 20); + `uvm_info("seq", $sformatf("wait evict start %0d", evict_trans), UVM_MEDIUM) + `DV_SPINWAIT( wait(idx == evict_trans);, + $sformatf("Timed out waiting for evict trans %0d idx:%0d", + evict_trans, idx), timeout_ns, + "seq") + evict_start = 1; + end + join + cfg.seq_cfg.disable_flash_init = 1; + endtask : body + + // We evict two bus words (one flash word). + virtual task send_evict(flash_op_t ctrl, int bank); + `uvm_info(`gfn, $sformatf( + "Sending eviction write bank:%0d %s addr:0x%x", + bank, ctrl.partition.name, ctrl.addr), UVM_MEDIUM) + prog_flash(ctrl, bank, /*num=*/1, /*wd=*/2); + endtask : send_evict + +endclass : flash_ctrl_rw_evict_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv new file mode 100644 index 0000000000000..5ed19ee643103 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_rnd_wd_vseq.sv @@ -0,0 +1,59 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Random read write with access resolution of 1 word (4byte). +class flash_ctrl_rw_rnd_wd_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_rw_rnd_wd_vseq) + `uvm_object_new + + constraint ctrl_data_num_c {ctrl_num inside {[1:32]};} + constraint fractions_c { + solve ctrl_num before fractions; + if (ctrl_num == 1) + fractions dist { [1:4] := 4, [5:16] := 1}; + else + fractions == 16; + } + + constraint odd_addr_c { + solve fractions before is_addr_odd; + (fractions == 16) -> is_addr_odd == 0; + } + + virtual task body(); + flash_op_t ctrl; + int num, bank; + + cfg.clk_rst_vif.wait_clks(5); + + fork + begin + repeat(500) begin + bit is_prog = 0; + randcase + cfg.otf_wr_pct: begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + is_prog = 1; + end + 1: begin + `DV_CHECK_RANDOMIZE_FATAL(this) + get_bank_and_num(ctrl, bank, num); + end + endcase + if (is_prog) prog_flash(ctrl, bank, num, fractions); + else read_flash(ctrl, bank, num, fractions); + end + end + begin + for (int i = 0; i < 100; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + join + endtask +endclass : flash_ctrl_rw_rnd_wd_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv new file mode 100644 index 0000000000000..109467557f5d9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_rw_vseq.sv @@ -0,0 +1,56 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Generates random mix of reads and writes. Writes are somewhat delicate: when scrambling or ECC +// are enabled we can only write full flash words (8 bytes), so the number of bus words needs to +// be even and the starting address needs to be 8-byte aligned. This is ensured by the consraints. +// +// In addition, overwrites will almost surely cause ecc errors to be injected because bits cannot +// flip from 0 to 1, so this makes sure addresses don't overlap previously written ones. +class flash_ctrl_rw_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_rw_vseq) + `uvm_object_new + + flash_op_t ctrl; + int num, bank; + + virtual task body(); + bit prev_addr_flash_word_aligned = cfg.seq_cfg.addr_flash_word_aligned; + bit prev_avoid_ro_partitions = cfg.seq_cfg.avoid_ro_partitions; + + cfg.clk_rst_vif.wait_clks(5); + fork + begin + repeat(cfg.otf_num_rw) begin + randcase + cfg.otf_wr_pct: begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + prog_flash(ctrl, bank, num, fractions); + end + cfg.otf_rd_pct: begin + set_ecc_err_target(TgtRd); + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + read_flash(ctrl, bank, num, fractions); + end + endcase + end + end + begin + launch_host_rd(); + end + join + endtask : body + + virtual task launch_host_rd(); + for (int i = 0; i < cfg.otf_num_hr; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + endtask : launch_host_rd +endclass : flash_ctrl_rw_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_address_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_address_vseq.sv new file mode 100644 index 0000000000000..459082d0e2b92 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_address_vseq.sv @@ -0,0 +1,32 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Directed test to check flash_ctrl.single_err_addr +// Each round test insert one single bit error and capture the address from tb. +// At the end of each round, compare the captured value with +// csr read (flash_ctrl.single_err_addr) value. +class flash_ctrl_serr_address_vseq extends flash_ctrl_rw_vseq; + `uvm_object_utils(flash_ctrl_serr_address_vseq) + `uvm_object_new + + virtual task body(); + uvm_reg_data_t addr0, addr1; + super.body(); + cfg.serr_once = 1; + + repeat(10) begin + cfg.serr_created = 0; + super.body(); + + // Give some slacks to address is stored. + #1us; + + csr_rd(.ptr(ral.ecc_single_err_addr[0]), .value(addr0)); + csr_rd(.ptr(ral.ecc_single_err_addr[1]), .value(addr1)); + + `DV_CHECK_EQ(addr0, cfg.serr_addr[0]) + `DV_CHECK_EQ(addr1, cfg.serr_addr[1]) + end + endtask // body +endclass // flash_ctrl_serr_address_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_counter_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_counter_vseq.sv new file mode 100644 index 0000000000000..24893c8e63cad --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_serr_counter_vseq.sv @@ -0,0 +1,18 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Directed test to check flash_ctrl.single_err_cnt +// Use low error injection pct to avoid counter saturation. +// Counter can be saturated but not all the time. +class flash_ctrl_serr_counter_vseq extends flash_ctrl_rw_vseq; + `uvm_object_utils(flash_ctrl_serr_counter_vseq) + `uvm_object_new + + task post_body(); + uvm_reg_data_t data; + csr_rd(.ptr(ral.ecc_single_err_cnt[0]), .value(data)); + `DV_CHECK_EQ(data[7:0], cfg.serr_cnt[0]) + `DV_CHECK_EQ(data[15:8], cfg.serr_cnt[1]) + endtask +endclass // flash_ctrl_serr_counter_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_hw_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_hw_vseq.sv new file mode 100644 index 0000000000000..19ed82a5d52f8 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_hw_vseq.sv @@ -0,0 +1,104 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// smoke hardware interface test for direct reading +class flash_ctrl_smoke_hw_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_smoke_hw_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + // Enable one memory protection region. + cfg.seq_cfg.num_en_mp_regions = 1; + + // Don't enable access to any of information partitions. + foreach (cfg.seq_cfg.mp_info_page_en_pc[i, j]) begin + cfg.seq_cfg.mp_info_page_en_pc[i][j] = 0; + end + endfunction + + task body(); + data_4s_t rdata; + data_q_t exp_data; + + int flash_depth = flash_ctrl_reg_pkg::BytesPerBank / 4; + + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + + // Bank 0 is used + uint bank; + + // A single PROGRAM flash ctrl operation. + flash_op_t flash_op; + + // Bit vector representing which of the mp region cfg CSRs to enable. + bit [flash_ctrl_pkg::MpRegions-1:0] en_mp_regions; + + // Memory protection regions settings. One MP region, Single Page + flash_mp_region_cfg_t mp_region; + bit comp; + + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + + bank = 0; + + flash_op.addr = 0; + flash_op.op = flash_ctrl_pkg::FlashOpProgram; + flash_op.partition = FlashPartData; + flash_op.num_words = 10; + + en_mp_regions = cfg.seq_cfg.num_en_mp_regions; + + mp_region.en = mubi4_bool_to_mubi(en_mp_regions); + mp_region.read_en = MuBi4True; + mp_region.program_en = MuBi4True; + mp_region.erase_en = MuBi4True; + mp_region.start_page = 0; + mp_region.num_pages = 1; + + `uvm_info(`gfn, $sformatf("Configuring flash_ctrl, flash_depth %0d", flash_depth), UVM_MEDIUM) + + // If external_cfg=1 it means this sequence is being randomized by another sequence and this + // randomization will possibly override the upper randomization (Added specifically for + // partner sequences using this one). + if (!cfg.seq_cfg.external_cfg) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + end + + // Configure the flash based on the settings. + flash_ctrl_mp_region_cfg(0, mp_region); + + flash_ctrl_default_region_cfg(.read_en(default_region_read_en), + .program_en(default_region_program_en), + .erase_en(default_region_erase_en)); + + // Invalidate the flash mem contents. We do this because we operate on and check a specific + // chunk of space. The rest of the flash mem is essentially dont-care. If the flash ctrl + // does not work correctly, the check will result in an access from the invalidated mem + // region exposing the issue. + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + + `uvm_info(`gfn, $sformatf("Starting backdoor write operation with random values"), UVM_HIGH) + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + + // Host direct read of random written value + `uvm_info(`gfn, $sformatf("Starting direct read"), UVM_HIGH) + for (int j = 0; j < 10; j++) begin + do_direct_read(.addr(j * 4), .mask('1), .blocking(1), .check_rdata(0), .rdata(rdata), + .completed(comp)); + exp_data.push_back(rdata); + end + + // Backdoor read of random written values and comparing with previously read values + `uvm_info(`gfn, $sformatf("Starting backdoor read for checking data"), UVM_HIGH) + cfg.flash_mem_bkdr_read_check(flash_op, exp_data); + + endtask : body + +endclass : flash_ctrl_smoke_hw_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_vseq.sv new file mode 100644 index 0000000000000..0baf42f1d1561 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_smoke_vseq.sv @@ -0,0 +1,46 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// basic smoke test vseq +class flash_ctrl_smoke_vseq extends flash_ctrl_rand_ops_base_vseq; + `uvm_object_utils(flash_ctrl_smoke_vseq) + + `uvm_object_new + + // Configure sequence knobs to tailor it to smoke seq. + virtual function void configure_vseq(); + // Do fewer reruns for the smoke test. + cfg.seq_cfg.max_num_trans = 2; + + // Do fewer flash ops in each rerun for the smoke test. + cfg.seq_cfg.max_flash_ops_per_cfg = 4; + + // Do no more than 128 words per op. + cfg.seq_cfg.op_max_words = 128; + + // Don't enable any memory protection. + cfg.seq_cfg.num_en_mp_regions = 0; + + cfg.seq_cfg.set_partition_pc(.sel_data_part_pc(100), + .sel_info_part_pc(0), + .sel_info1_part_pc(0), + .sel_info2_part_pc(0)); + + // Don't enable access to any of information partitions. + foreach (cfg.seq_cfg.mp_info_page_en_pc[i, j]) begin + cfg.seq_cfg.mp_info_page_en_pc[i][j] = 0; + end + + // Enable default region read/program and erasability. + cfg.seq_cfg.default_region_read_en_pc = 100; + cfg.seq_cfg.default_region_program_en_pc = 100; + cfg.seq_cfg.default_region_erase_en_pc = 100; + + // Allow banks to be erased. + cfg.seq_cfg.bank_erase_en_pc = 100; + + cfg.seq_cfg.poll_fifo_status_pc = 0; + endfunction + +endclass : flash_ctrl_smoke_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_stress_all_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_stress_all_vseq.sv new file mode 100644 index 0000000000000..96d5a392a873f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_stress_all_vseq.sv @@ -0,0 +1,36 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_stress_all_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_stress_all_vseq) + `uvm_object_new + + task body(); + string seq_names[] = { + "flash_ctrl_smoke_vseq", + "flash_ctrl_smoke_hw_vseq" + }; + + for (int i = 1; i <= num_trans; i++) begin + uvm_sequence seq; + flash_ctrl_base_vseq flash_ctrl_vseq; + uint seq_idx = $urandom_range(0, seq_names.size - 1); + + seq = create_seq_by_name(seq_names[seq_idx]); + `downcast(flash_ctrl_vseq, seq) + + flash_ctrl_vseq.do_apply_reset = 1; + flash_ctrl_vseq.set_sequencer(p_sequencer); + `DV_CHECK_RANDOMIZE_FATAL(flash_ctrl_vseq) + `uvm_info(`gfn, $sformatf("seq_idx = %0d, sequence is %0s", seq_idx, + flash_ctrl_vseq.get_name()), UVM_MEDIUM) + + flash_ctrl_vseq.start(p_sequencer); + `uvm_info(`gfn, $sformatf( + "End of sequence %0s with seq_idx = %0d", + flash_ctrl_vseq.get_name(), seq_idx), UVM_MEDIUM) + end + endtask // body + +endclass // flash_ctrl_stress_all_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_sw_op_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_sw_op_vseq.sv new file mode 100644 index 0000000000000..d05460e29cd3b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_sw_op_vseq.sv @@ -0,0 +1,166 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Pseudo Code +// Backdoor Write to FLASH (Initialize) +// FLASH Read - Compare Frontdoor +// FLASH Erase (Includes Backdoor Erase Check) +// FLASH Program +// FLASH Read - Compare Frontdoor + +// Simple sw_op test +class flash_ctrl_sw_op_vseq extends flash_ctrl_base_vseq; + `uvm_object_utils(flash_ctrl_sw_op_vseq) + + // Class Members + + flash_op_t flash_op; + uint bank; + + // Bit vector representing which of the mp region cfg CSRs to enable. + bit [flash_ctrl_pkg::MpRegions-1:0] en_mp_regions; + + // Indicates whether to poll before writing to the prog_fifo or reading from the rd_fifo. If interupts are + // enabled, the interrupt signals will be used instead. When set to 0, it will continuously write + // to prog_fifo / read from rd_fifo, relying on their natural backpressure mechanism. + bit poll_fifo_status; + + // Flash Data Queue + rand data_q_t flash_op_data; + + `uvm_object_new + + // Configure sequence knobs to tailor it to this seq. + virtual function void configure_vseq(); + // Enable NO memory protection regions. + cfg.seq_cfg.num_en_mp_regions = 0; + cfg.seq_cfg.poll_fifo_status_pc = 0; + cfg.seq_cfg.check_mem_post_tran = 1; + + // Do Not enable access to any of the information partitions. + foreach (cfg.seq_cfg.mp_info_page_en_pc[i, j]) begin + cfg.seq_cfg.mp_info_page_en_pc[i][j] = 0; + end + endfunction + + // Body + task body(); + + logic [TL_DW-1:0] rdata; + logic [TL_DW-1:0] exp_data [$]; + mubi4_t default_region_read_en; + mubi4_t default_region_program_en; + mubi4_t default_region_erase_en; + + // Configure the FLASH Controller + + // Memory protection regions settings. One MP region, Single Page + flash_mp_region_cfg_t mp_regions [flash_ctrl_pkg::MpRegions]; + + foreach (mp_regions[i]) begin + mp_regions[i].en = mubi4_bool_to_mubi(en_mp_regions[i]); + mp_regions[i].read_en = MuBi4True; + mp_regions[i].program_en = MuBi4True; + mp_regions[i].erase_en = MuBi4True; + mp_regions[i].start_page = MuBi4False; + mp_regions[i].num_pages = MuBi4True; + end + + default_region_read_en = MuBi4True; + default_region_program_en = MuBi4True; + default_region_erase_en = MuBi4True; + + // Configure the flash based on the given settings + foreach (mp_regions[i]) begin + flash_ctrl_mp_region_cfg(i, mp_regions[i]); + end + + flash_ctrl_default_region_cfg(.read_en(default_region_read_en), + .program_en(default_region_program_en), + .erase_en(default_region_erase_en)); + + // TEST SETUP + + bank = 0; // Bank 0 + flash_op.addr = 0; // Start Address + flash_op.partition = FlashPartData; // Data Partition + flash_op.num_words = 10; // Number Of Words + poll_fifo_status = 0; // FIFO Poll Status + + // INITIALIZE FLASH + + // Randomize Write Data + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(flash_op_data, flash_op_data.size == flash_op.num_words;) + + // Invalidate the flash mem contents. We do this because we operate on and check a specific + // chunk of space. The rest of the flash mem is essentially dont-care. If the flash ctrl + // does not work correctly, the check will result in an access from the invalidated mem + // region exposing the issue. + cfg.flash_mem_bkdr_init(flash_op.partition, FlashMemInitInvalidate); + + `uvm_info(`gfn, $sformatf("Starting backdoor write operation with random values"), UVM_LOW) + cfg.flash_mem_bkdr_write(.flash_op(flash_op), .scheme(FlashMemInitRandomize)); + + // FLASH READ 1 + // Read Frontdoor, Compare Backdoor + + // Select FLASH Read Operation + flash_op.op = flash_ctrl_pkg::FlashOpRead; + + // Start Controller + flash_ctrl_start_op(flash_op); + + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + + // FLASH ERASE + + // Select FLASH Read Operation + flash_op.op = flash_ctrl_pkg::FlashOpErase; + + // Select Page Erase + flash_op.erase_type = flash_ctrl_pkg::FlashErasePage; + + // Start Controller + flash_ctrl_start_op(flash_op); + + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.erase_timeout_ns)); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_erase_check(flash_op, exp_data); + + // FLASH PROGRAM + // Write Frontdoor, Read backdoor + + // Select FLASH Operation + flash_op.op = flash_ctrl_pkg::FlashOpProgram; + + // Randomize Write Data + `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(flash_op_data, flash_op_data.size == flash_op.num_words;) + + // Calculate expected data for post-transaction checks + exp_data = cfg.calculate_expected_data(flash_op, flash_op_data); + + // Start Controller + flash_ctrl_start_op(flash_op); + + flash_ctrl_write(flash_op_data, poll_fifo_status); + wait_flash_op_done(.timeout_ns(cfg.seq_cfg.prog_timeout_ns)); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_read_check(flash_op, exp_data); + + // FLASH READ 2 + // Read Frontdoor, Compare Backdoor + + // Select FLASH Read Operation + flash_op.op = flash_ctrl_pkg::FlashOpRead; + + // Start Controller + flash_ctrl_start_op(flash_op); + + flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status); + wait_flash_op_done(); + if (cfg.seq_cfg.check_mem_post_tran) cfg.flash_mem_bkdr_read_check(flash_op, flash_op_data); + + endtask : body + +endclass : flash_ctrl_sw_op_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv new file mode 100644 index 0000000000000..39e506743fa11 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_vseq_list.sv @@ -0,0 +1,67 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "flash_ctrl_base_vseq.sv" +`include "flash_ctrl_callback_vseq.sv" +`include "flash_ctrl_otf_base_vseq.sv" +`include "flash_ctrl_common_vseq.sv" +`include "flash_ctrl_fetch_code_vseq.sv" +`include "flash_ctrl_rand_ops_base_vseq.sv" +`include "flash_ctrl_smoke_vseq.sv" +`include "flash_ctrl_smoke_hw_vseq.sv" +`include "flash_ctrl_rand_ops_vseq.sv" +`include "flash_ctrl_sw_op_vseq.sv" +`include "flash_ctrl_host_dir_rd_vseq.sv" +`include "flash_ctrl_rd_buff_evict_vseq.sv" +`include "flash_ctrl_phy_arb_vseq.sv" +`include "flash_ctrl_hw_sec_otp_vseq.sv" +`include "flash_ctrl_erase_suspend_vseq.sv" +`include "flash_ctrl_hw_rma_vseq.sv" +`include "flash_ctrl_host_ctrl_arb_vseq.sv" +`include "flash_ctrl_mp_regions_vseq.sv" +`include "flash_ctrl_full_mem_access_vseq.sv" +`include "flash_ctrl_error_prog_type_vseq.sv" +`include "flash_ctrl_error_prog_win_vseq.sv" +`include "flash_ctrl_error_mp_vseq.sv" +`include "flash_ctrl_invalid_op_vseq.sv" +`include "flash_ctrl_mid_op_rst_vseq.sv" +`include "flash_ctrl_legacy_base_vseq.sv" +`include "flash_ctrl_wo_vseq.sv" +`include "flash_ctrl_ro_vseq.sv" +`include "flash_ctrl_rw_vseq.sv" +`include "flash_ctrl_write_word_sweep_vseq.sv" +`include "flash_ctrl_write_rnd_wd_vseq.sv" +`include "flash_ctrl_read_word_sweep_vseq.sv" +`include "flash_ctrl_read_rnd_wd_vseq.sv" +`include "flash_ctrl_rw_rnd_wd_vseq.sv" +`include "flash_ctrl_serr_counter_vseq.sv" +`include "flash_ctrl_serr_address_vseq.sv" +`include "flash_ctrl_derr_detect_vseq.sv" +`include "flash_ctrl_hw_rma_reset_vseq.sv" +`include "flash_ctrl_otp_reset_vseq.sv" +`include "flash_ctrl_intr_rd_vseq.sv" +`include "flash_ctrl_intr_wr_vseq.sv" +`include "flash_ctrl_prog_reset_vseq.sv" +`include "flash_ctrl_rw_evict_vseq.sv" +`include "flash_ctrl_re_evict_vseq.sv" +`include "flash_ctrl_oversize_error_vseq.sv" +`include "flash_ctrl_connect_vseq.sv" +`include "flash_ctrl_disable_vseq.sv" +`include "flash_ctrl_host_addr_infection_vseq.sv" +`include "flash_ctrl_rd_path_intg_vseq.sv" +`include "flash_ctrl_wr_path_intg_vseq.sv" +`include "flash_ctrl_info_part_access_vseq.sv" +`include "flash_ctrl_filesystem_support_vseq.sv" +`include "flash_ctrl_stress_all_vseq.sv" +`include "flash_ctrl_access_after_disable_vseq.sv" +`include "flash_ctrl_err_base_vseq.sv" +`include "flash_ctrl_phy_arb_redun_vseq.sv" +`include "flash_ctrl_phy_host_grant_err_vseq.sv" +`include "flash_ctrl_phy_ack_consistency_vseq.sv" +`include "flash_ctrl_config_regwen_vseq.sv" +`include "flash_ctrl_hw_rma_err_vseq.sv" +`include "flash_ctrl_lcmgr_intg_vseq.sv" +`include "flash_ctrl_hw_read_seed_err_vseq.sv" +`include "flash_ctrl_hw_prog_rma_wipe_err_vseq.sv" +`include "flash_ctrl_rd_ooo_vseq.sv" diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv new file mode 100644 index 0000000000000..607e5cefbd812 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wo_vseq.sv @@ -0,0 +1,25 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Send write only traffic +class flash_ctrl_wo_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_wo_vseq) + `uvm_object_new + + virtual task body(); + flash_op_t ctrl; + int num, bank; + + // Don't select a partition defined as read-only + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + + flash_program_data_c.constraint_mode(0); + + repeat(100) begin + if (cfg.stop_transaction_generators()) break; + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + prog_flash(ctrl, bank, num); + end + endtask +endclass : flash_ctrl_wo_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv new file mode 100644 index 0000000000000..ff1746f784160 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_wr_path_intg_vseq.sv @@ -0,0 +1,127 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This sequence sends write traffic with or without tlul memory +// bus write path error injection. +// This test will trigger fatal_std_err so clear fatal alert at the end of the test by reset. +class flash_ctrl_wr_path_intg_vseq extends flash_ctrl_rw_vseq; + `uvm_object_utils(flash_ctrl_wr_path_intg_vseq) + `uvm_object_new + + // Since we force bit 38 to 1, create more than one bus words + // to make sure data integrity error is created. + constraint fractions_c { + fractions >= 4; + fractions <= 16; + fractions[0] == 0; + } + + task body(); + string path = "tb.dut.u_prog_fifo.wdata_i[38]"; + int state_timeout_ns = 100000; // 100us + + // Don't select a partition defined as read-only + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + cfg.seq_cfg.addr_flash_word_aligned = 1'b1; + + repeat(5) begin + flash_otf_region_cfg(.scr_mode(scr_ecc_cfg), .ecc_mode(scr_ecc_cfg)); + `uvm_info(`gfn, "Assert write path err", UVM_LOW) + `DV_CHECK(uvm_hdl_force(path, 1'b1)) + $assertoff(0, "tb.dut.u_flash_mp.NoReqWhenErr_A"); + + // disable tl_rsp error check + cfg.m_tl_agent_cfg.check_tl_errs = 0; + cfg.otf_scb_h.mem_mon_off = 1; + cfg.scb_h.alert_count["fatal_std_err"] = 0; + fork + begin + uvm_reg_data_t ldata; + bit status_clear = 0; + + repeat(cfg.otf_num_rw) begin + randcase + cfg.otf_wr_pct: begin + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + cfg.scb_h.expected_alert["fatal_std_err"].expected = 1; + cfg.scb_h.expected_alert["fatal_std_err"].max_delay = 20_000; + cfg.scb_h.exp_alert_contd["fatal_std_err"] = 10000; + + // prog_err and mp_err + set_otf_exp_alert("recov_err"); + // If fatal error is triggered, flash is disabled right after + // on going operation is finished. + // This can causes test lock up while polling status. + // To avoid this, add another thread to check if fatal alert is triggered. + fork begin + fork + begin + prog_flash(ctrl, bank, 1, fractions, 1); + // Wait for op_done or op_err + csr_spinwait(.ptr(ral.op_status), .exp_data(2'b0), + .compare_op(CompareOpCaseNe), .backdoor(1)); + // clear op_status for the next round + csr_wr(.ptr(ral.op_status), .value(0), .blocking(1)); + status_clear = 1; + end + begin + wait(cfg.scb_h.alert_count["fatal_std_err"] > 0); + end + join_any + wait_no_outstanding_access(); + disable fork; + end join + end + cfg.otf_rd_pct: begin + `DV_CHECK_RANDOMIZE_FATAL(this) + ctrl = rand_op; + get_bank_and_num(ctrl, bank, num); + read_flash(ctrl, bank, num, fractions); + end + endcase + end // repeat (cfg.otf_num_rw) + // Check std_fault.prog_intg_err, err_code.prog_err + collect_err_cov_status(ral.std_fault_status); + csr_rd_check(.ptr(ral.std_fault_status.prog_intg_err), .compare_value(1)); + csr_rd_check(.ptr(ral.err_code.prog_err), .compare_value(1)); + if (!status_clear) csr_rd_check(.ptr(ral.op_status.err), .compare_value(1)); + ldata = get_csr_val_with_updated_field(ral.err_code.prog_err, ldata, 1); + csr_wr(.ptr(ral.err_code), .value(ldata)); + ldata = get_csr_val_with_updated_field(ral.op_status.err, ldata, 0); + csr_wr(.ptr(ral.op_status), .value(ldata)); + end + begin + for (int i = 0; i < cfg.otf_num_hr; ++i) begin + fork + send_rand_host_rd(); + join_none + #0; + end + csr_utils_pkg::wait_no_outstanding_access(); + end + join + + `uvm_info(`gfn, "Wait until all drain", UVM_LOW) + cfg.clk_rst_vif.wait_clks(100); + `DV_CHECK(uvm_hdl_release(path)) + + cfg.seq_cfg.disable_flash_init = 1; + cfg.seq_cfg.en_init_keys_seeds = 0; + apply_reset(); + cfg.otf_scb_h.clear_fifos(); + cfg.otf_scb_h.stop = 1; + csr_wr(.ptr(ral.init), .value(1)); + `uvm_info("Test","OTP",UVM_LOW) + otp_model(); + `DV_SPINWAIT(wait(cfg.flash_ctrl_vif.rd_buf_en == 1);, + "Timed out waiting for rd_buf_en", + state_timeout_ns) + cfg.clk_rst_vif.wait_clks(10); + cfg.otf_scb_h.stop = 0; + end + // disable tlul_err_cnt check + cfg.tlul_core_obs_cnt = cfg.tlul_core_exp_cnt; + endtask + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv new file mode 100644 index 0000000000000..4528bf682d4bb --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_rnd_wd_vseq.sv @@ -0,0 +1,30 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Write random size of fraction the page. +// fraction size : [1:16] buswords (4byte). +// Start address is 4byte aligned. +class flash_ctrl_write_rnd_wd_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_write_rnd_wd_vseq) + `uvm_object_new + + virtual task body(); + flash_op_t ctrl; + int num, bank; + int mywd; + + // Don't select a partition defined as read-only + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + + num = 1; + flash_program_data_c.constraint_mode(0); + repeat(100) begin + `DV_CHECK_MEMBER_RANDOMIZE_FATAL(rand_op) + ctrl = rand_op; + bank = rand_op.addr[OTFBankId]; + mywd = fractions; + prog_flash(ctrl, bank, num, mywd); + end + endtask +endclass // flash_ctrl_write_rnd_wd_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv new file mode 100644 index 0000000000000..f8bf49b88d905 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/env/seq_lib/flash_ctrl_write_word_sweep_vseq.sv @@ -0,0 +1,34 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Starting from 2 busword (4byte), increases by 2 words each round +// To avoid program window violation, word size never exceeeds 16. +class flash_ctrl_write_word_sweep_vseq extends flash_ctrl_otf_base_vseq; + `uvm_object_utils(flash_ctrl_write_word_sweep_vseq) + `uvm_object_new + + constraint ctrl_num_c {ctrl_num == 1;} + constraint fractions_c {fractions == 2;} + virtual task body(); + flash_op_t ctrl; + int num, bank; + int mywd; + addr_t addr; + + // Don't select a partition defined as read-only + cfg.seq_cfg.avoid_ro_partitions = 1'b1; + `DV_CHECK(try_create_prog_op(ctrl, bank, num), "Could not create a prog flash op") + num = 1; + mywd = fractions; + `DV_CHECK_EQ(mywd, 2) + addr = ctrl.addr; + repeat(10) begin + ctrl.addr = addr; + ctrl.otf_addr = addr; + prog_flash(ctrl, bank, num, mywd); + addr += num * mywd * 4; + mywd = (mywd % 16) + 2; + end + endtask +endclass : flash_ctrl_write_word_sweep_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson new file mode 100644 index 0000000000000..ccb3368730578 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_base_sim_cfg.hjson @@ -0,0 +1,503 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: flash_ctrl + + // Top level dut name (sv module). + dut: flash_ctrl + + // Top level testbench name (sv module). + tb: tb + + // Fusesoc core file used for building the file list. + fusesoc_core: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_sim:0.1 + + // Testplan hjson file. + testplan: "{self_dir}/../data/flash_ctrl_testplan.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", + // Config files to get the correct flags for crypto_dpi_prince + "{proj_root}/hw/ip/prim/dv/prim_prince/crypto_dpi_prince/crypto_dpi_prince_sim_opts.hjson", + // Common CIP test lists + "{proj_root}/hw/dv/tools/dvsim/tests/csr_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/mem_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/alert_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/intr_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/shadow_reg_errors_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/stress_all_test.hjson"], + + en_build_modes: ["{tool}_crypto_dpi_prince_build_opts"] + // Flash references pwrmgr directly, need to reference the top version + overrides: [ + { + name: design_level + value: "top" + } + { + name: "timescale" + value: "1ns/100ps" + } + ] + +// Add additional tops for simulation. + sim_tops: ["flash_ctrl_bind","flash_ctrl_cov_bind", "sec_cm_prim_onehot_check_bind", + "sec_cm_prim_count_bind", "sec_cm_prim_sparse_fsm_flop_bind"] + + // Default iterations for all tests - each test entry can override this. + reseed: 50 + + + run_modes: [ + { + name: csr_tests_mode + run_opts: ["+csr_test_mode=1"] + } + ] + + // Add default run opt + run_opts: ["+flash_rand_delay_en=1"] + + // Default UVM test and seq class name. + uvm_test: flash_ctrl_base_test + uvm_test_seq: flash_ctrl_base_vseq + + // Enable cdc instrumentation. + run_opts: ["+cdc_instrumentation_enabled=1"] + + // List of test specifications. + tests: [ + { + name: flash_ctrl_smoke + uvm_test_seq: flash_ctrl_smoke_vseq + reseed: 50 + } + { + name: flash_ctrl_smoke_hw + uvm_test_seq: flash_ctrl_smoke_hw_vseq + reseed: 5 + } + { + name: flash_ctrl_rand_ops + uvm_test_seq: flash_ctrl_rand_ops_vseq + reseed: 20 + } + { + name: flash_ctrl_sw_op + uvm_test_seq: flash_ctrl_sw_op_vseq + reseed: 5 + } + { + name: flash_ctrl_host_dir_rd + uvm_test_seq: flash_ctrl_host_dir_rd_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_rd_buff_evict + uvm_test_seq: flash_ctrl_rd_buff_evict_vseq + run_opts: ["+en_cov=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb + uvm_test_seq: flash_ctrl_phy_arb_vseq + run_opts: ["+zero_delays=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_sec_otp + uvm_test_seq: flash_ctrl_hw_sec_otp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 50 + } + { + name: flash_ctrl_erase_suspend + uvm_test_seq: flash_ctrl_erase_suspend_vseq + run_opts: ["+zero_delays=1"] + reseed: 5 + } + { + name: flash_ctrl_hw_rma + uvm_test_seq: flash_ctrl_hw_rma_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_hw_rma_reset + uvm_test_seq: flash_ctrl_hw_rma_reset_vseq + run_opts: ["+flash_program_latency=5", "+test_timeout_ns=300_000_000_000"] + reseed: 20 + } + { + name: flash_ctrl_otp_reset + uvm_test_seq: flash_ctrl_otp_reset_vseq + run_opts: ["+test_timeout_ns=300_000_000_000"] + reseed: 80 + } + { + name: flash_ctrl_host_ctrl_arb + uvm_test_seq: flash_ctrl_host_ctrl_arb_vseq + run_opts: ["+zero_delays=1", "+test_timeout_ns=300_000_000_000"] + reseed: 5 + } + { + name: flash_ctrl_mp_regions + uvm_test_seq: flash_ctrl_mp_regions_vseq + run_opts: ["+multi_alert=1", "+test_timeout_ns=300_000_000_000", + "+fast_rcvr_recov_err", "+op_readonly_on_info1_partition=0"] + reseed: 20 + } + { + name: flash_ctrl_fetch_code + uvm_test_seq: flash_ctrl_fetch_code_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 10 + } + { + name: flash_ctrl_full_mem_access + uvm_test_seq: flash_ctrl_full_mem_access_vseq + run_opts: ["+test_timeout_ns=500_000_000_000"] + reseed: 5 + run_timeout_mins: 180 + } + { + name: flash_ctrl_error_prog_type + uvm_test_seq: flash_ctrl_error_prog_type_vseq + run_opts: ["+op_readonly_on_info_partition=1", + "+op_readonly_on_info1_partition=1"] + reseed: 5 + } + { + name: flash_ctrl_error_prog_win + uvm_test_seq: flash_ctrl_error_prog_win_vseq + reseed: 10 + } + { + name: flash_ctrl_error_mp + uvm_test_seq: flash_ctrl_error_mp_vseq + run_opts: ["+test_timeout_ns=300_000_000_000", "+op_readonly_on_info_partition=0", + "+op_readonly_on_info1_partition=0", "+op_readonly_on_info2_partition=0"] + reseed: 10 + } + { + name: flash_ctrl_invalid_op + uvm_test_seq: flash_ctrl_invalid_op_vseq + run_opts: ["+fast_rcvr_recov_err"] + reseed: 20 + } + { + name: flash_ctrl_mid_op_rst + uvm_test_seq: flash_ctrl_mid_op_rst_vseq + reseed: 5 + } + { + name: flash_ctrl_wo + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=0", "+otf_rd_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_write_word_sweep + uvm_test_seq: flash_ctrl_write_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_read_word_sweep + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1"] + reseed: 1 + } + { + name: flash_ctrl_ro + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_rw + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+test_timeout_ns=5_000_000_000", "+ecc_mode=1"] + reseed: 20 + } + { + name: flash_ctrl_read_word_sweep_serr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3"] + reseed: 5 + } + { + name: flash_ctrl_ro_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0"] + reseed: 10 + } + { + name: flash_ctrl_rw_serr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000"] + reseed: 10 + } + { + name: flash_ctrl_serr_counter + uvm_test_seq: flash_ctrl_serr_counter_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=50", "+otf_num_hr=5"] + reseed: 5 + } + { + name: flash_ctrl_serr_address + uvm_test_seq: flash_ctrl_serr_address_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=1", + "+otf_num_rw=5", "+otf_num_hr=0"] + reseed: 5 + } + { + name: flash_ctrl_read_word_sweep_derr + uvm_test_seq: flash_ctrl_read_word_sweep_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_ro_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", "+otf_wr_pct=0", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_rw_derr + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=3", + "+otf_num_rw=100", "+otf_num_hr=1000", + "+bypass_alert_ready_to_end_check=1"] + reseed: 10 + } + { + name: flash_ctrl_derr_detect + uvm_test_seq: flash_ctrl_derr_detect_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=3", "+derr_pct=4", + "+otf_num_rw=50", "+otf_num_hr=200", + "+rerun=5", "+otf_wr_pct=1"] + reseed: 5 + } + { + name: flash_ctrl_oversize_error + uvm_test_seq: flash_ctrl_oversize_error_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+serr_pct=0", + "+otf_num_hr=1000", "+otf_num_rw=100", + "+otf_wr_pct=4", "+otf_rd_pct=4"] + reseed: 5 + } + { + name: flash_ctrl_integrity + uvm_test_seq: flash_ctrl_rw_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=4", "+ierr_pct=3", + "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_intr_rd + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 10 + } + { + name: flash_ctrl_intr_rd_slow_flash + uvm_test_seq: flash_ctrl_intr_rd_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", "+test_timeout_ns=500_000_000"] + reseed: 40 + } + { + name: flash_ctrl_intr_wr_slow_flash + uvm_test_seq: flash_ctrl_intr_wr_vseq + run_opts: ["+scb_otf_en=1", "+flash_read_latency=50", "+flash_program_latency=500", + "+rd_buf_en_to=500_000", "+test_timeout_ns=1_000_000_000"] + reseed: 10 + } + { + name: flash_ctrl_prog_reset + uvm_test_seq: flash_ctrl_prog_reset_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+test_timeout_ns=500_000_000"] + reseed: 30 + } + { + name: flash_ctrl_rw_evict + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 40 + } + { + name: flash_ctrl_rw_evict_all_en + uvm_test_seq: flash_ctrl_rw_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1", + "+en_always_prog=1", "en_rnd_data=0"] + reseed: 40 + } + { + name: flash_ctrl_re_evict + uvm_test_seq: flash_ctrl_re_evict_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_read=1"] + reseed: 20 + } + { + name: flash_ctrl_disable + uvm_test_seq: flash_ctrl_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=2", "+en_always_all=1", + "+bypass_alert_ready_to_end_check=1"] + reseed: 50 + } + { + name: flash_ctrl_sec_cm + run_timeout_mins: 180 + } + { + name: flash_ctrl_sec_info_access + uvm_test_seq: flash_ctrl_info_part_access_vseq + reseed: 50 + } + { + name: flash_ctrl_stress_all + reseed: 5 + } + { + name: flash_ctrl_connect + uvm_test_seq: flash_ctrl_connect_vseq + reseed: 80 + } + { + name: flash_ctrl_rd_intg + uvm_test_seq: flash_ctrl_rd_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + { + name: flash_ctrl_wr_intg + uvm_test_seq: flash_ctrl_wr_path_intg_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=0", "+ecc_mode=1", + "+en_always_prog=1", "+otf_rd_pct=0"] + reseed: 3 + } + { + name: flash_ctrl_access_after_disable + uvm_test_seq: flash_ctrl_access_after_disable_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+otf_num_rw=5", "+otf_num_hr=0", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 3 + } + { + name: flash_ctrl_fs_sup + uvm_test_seq: flash_ctrl_filesystem_support_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1", "+en_all_info_acc=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_arb_redun + uvm_test_seq: flash_ctrl_phy_arb_redun_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_host_grant_err + uvm_test_seq: flash_ctrl_phy_host_grant_err_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=50", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_phy_ack_consistency + uvm_test_seq: flash_ctrl_phy_ack_consistency_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=5", "+otf_num_hr=10", "+ecc_mode=1", "+bank0_pct=8", + "+otf_rd_pct=4", "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 5 + } + { + name: flash_ctrl_config_regwen + uvm_test_seq: flash_ctrl_config_regwen_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+en_always_all=1"] + reseed: 5 + } + { + name: flash_ctrl_rma_err + uvm_test_seq: flash_ctrl_hw_rma_err_vseq + run_opts: ["+flash_program_latency=5", "+flash_erase_latency=50", "+test_timeout_ns=300_000_000_000"] + reseed: 3 + } + { + name: flash_ctrl_lcmgr_intg + uvm_test_seq: flash_ctrl_lcmgr_intg_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_read_seed_err + uvm_test_seq: flash_ctrl_hw_read_seed_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_hw_prog_rma_wipe_err + uvm_test_seq: flash_ctrl_hw_prog_rma_wipe_err_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", "+flash_program_latency=5", + "+en_always_all=1", "+bypass_alert_ready_to_end_check=1"] + reseed: 20 + } + { + name: flash_ctrl_rd_ooo + uvm_test_seq: flash_ctrl_rd_ooo_vseq + run_opts: ["+scb_otf_en=1", "+otf_num_rw=10", "+otf_num_hr=100", + "+ecc_mode=1"] + reseed: 1 + } + { + name: flash_ctrl_host_addr_infection + uvm_test_seq: flash_ctrl_host_addr_infection_vseq + run_opts: ["+scb_otf_en=1", "+ecc_mode=1", + "+otf_num_hr=100", "+en_always_read=1"] + reseed: 3 + } + ] + + // List of regressions. + regressions: [ + { + name: smoke + tests: ["flash_ctrl_smoke"] + } + { + // For test clean up run subset of tests + name: evict + tests: ["flash_ctrl_rw_evict", + "flash_ctrl_re_evict", + "flash_ctrl_rw_evict_all_en" + ] + } + { + name: flash_err + tests: ["flash_ctrl_error_mp", "flash_ctrl_error_prog_win", + "flash_ctrl_error_prog_type" + ] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim.core new file mode 100644 index 0000000000000..1705a53332848 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim.core @@ -0,0 +1,38 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_sim:0.1 +description: "FLASH_CTRL DV sim target" +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:constants:top_englishbreakfast_top_pkg + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl:0.1 + file_type: systemVerilogSource + + files_dv: + depend: + - lowrisc:dv:mem_bkdr_util + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_test + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_sva + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_cov + files: + - tb/tb.sv + file_type: systemVerilogSource + +targets: + default: &default_target + toplevel: tb + filesets: + - files_rtl + - files_dv + + sim: + <<: *default_target + default_tool: vcs + + lint: + <<: *default_target + default_tool: vcs diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson new file mode 100644 index 0000000000000..cc5688530b1a4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/flash_ctrl_sim_cfg.hjson @@ -0,0 +1,18 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// We want to use a different tool in another flash_ctrl env, but overriding `tool` doesn't work, as +// it needs to first import all the included hjson to know what to override, but some sim_cfg hjson +// files depends on the `tool` variable, such as {tool}.hjson. +// To solve this issue, split out the sim_cfg file into 2 files. the base contains everything except +// `tool`, the other one includes the base and set the `tool`. +// +// In this file, only `tool` can be set. Tests or other configuration should be add in +// flash_ctrl_base_sim_cfg.hjson. +{ + // Simulator used to sign off this block + tool: vcs + + import_cfgs: ["{self_dir}/flash_ctrl_base_sim_cfg.hjson"] +} diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_bind.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_bind.sv new file mode 100644 index 0000000000000..e1658e8e7af7a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_bind.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module flash_ctrl_bind; + + bind flash_ctrl tlul_assert #( + .EndpointType("Device") + ) tlul_assert_device ( + .clk_i, + .rst_ni, + .h2d (core_tl_i), + .d2h (core_tl_o) + ); + + bind flash_ctrl flash_ctrl_core_csr_assert_fpv flash_ctrl_core_csr_assert ( + .clk_i, + .rst_ni, + .h2d (core_tl_i), + .d2h (core_tl_o) + ); + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_sva.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_sva.core new file mode 100644 index 0000000000000..3c41c1c52994a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/sva/flash_ctrl_sva.core @@ -0,0 +1,40 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_sva:0.1 +description: "FLASH_CTRL assertion modules and bind file." +filesets: + files_dv: + depend: + - lowrisc:ip:lc_ctrl_pkg + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_pkg + - lowrisc:tlul:headers + - lowrisc:fpv:csr_assert_gen + files: + - flash_ctrl_bind.sv + file_type: systemVerilogSource + + files_formal: + depend: + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../../data/flash_ctrl.hjson + +targets: + default: &default_target + filesets: + - files_dv + generate: + - csr_assert_gen + + formal: + <<: *default_target + filesets: + - files_formal + - files_dv + toplevel: flash_ctrl diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tb/tb.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tb/tb.sv new file mode 100644 index 0000000000000..b8b741f5c9942 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tb/tb.sv @@ -0,0 +1,350 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 top_pkg::*; + import dv_utils_pkg::*; + import flash_ctrl_pkg::*; + import flash_ctrl_env_pkg::*; + import flash_ctrl_test_pkg::*; + import mem_bkdr_util_pkg::mem_bkdr_util; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + // TB base test ENV_T & CFG_T specification + // + // Specify the parameters for the flash_ctrl_base_test + // This will invoke the UVM registry and link this test type to + // the name 'flash_ctrl_base_test' as a test name passed by UVM_TESTNAME + // + // This is done explicitly only for the prim_pkg::ImplGeneric implementation + // since partner base tests inherit from flash_ctrl_base_test#(CFG_T, ENV_T) and + // specify directly (CFG_T, ENV_T) via the class extension and use a different + // UVM_TESTNAME + if (`PRIM_DEFAULT_IMPL==prim_pkg::ImplGeneric) begin : gen_spec_base_test_params + typedef flash_ctrl_base_test #(.CFG_T(flash_ctrl_env_cfg), + .ENV_T(flash_ctrl_env)) flash_ctrl_base_test_t; + end + + wire clk, rst_n, rst_shadowed_n; + wire intr_prog_empty; + wire intr_prog_lvl; + wire intr_rd_full; + wire intr_rd_lvl; + wire intr_op_done; + wire intr_err; + wire [NUM_MAX_INTERRUPTS-1:0] interrupts; + + // interfaces + clk_rst_if clk_rst_if ( + .clk (clk), + .rst_n(rst_n) + ); + rst_shadowed_if rst_shadowed_if ( + .rst_n(rst_n), + .rst_shadowed_n(rst_shadowed_n) + ); + pins_if #(NUM_MAX_INTERRUPTS) intr_if (interrupts); + tl_if tl_if ( + .clk (clk), + .rst_n(rst_n) + ); + tl_if eflash_tl_if ( + .clk (clk), + .rst_n(rst_n) + ); + tl_if prim_tl_if ( + .clk (clk), + .rst_n(rst_n) + ); + flash_ctrl_if flash_ctrl_if ( + .clk (clk), + .rst_n(rst_n) + ); + flash_phy_prim_if fpp_if ( + .clk (clk), + .rst_n(rst_n) + ); + + `define FLASH_DEVICE_HIER tb.dut.u_eflash.u_flash + assign fpp_if.req = `FLASH_DEVICE_HIER.flash_req_i; + assign fpp_if.rsp = `FLASH_DEVICE_HIER.flash_rsp_o; + for (genvar i = 0; i < flash_ctrl_pkg::NumBanks; i++) begin : gen_bank_loop + assign fpp_if.rreq[i] = tb.dut.u_eflash.gen_flash_cores[i].u_core.u_rd.req_i; + assign fpp_if.rdy[i] = tb.dut.u_eflash.gen_flash_cores[i].u_core.u_rd.rdy_o; + + assign flash_ctrl_if.hazard[i] = + tb.dut.u_eflash.gen_flash_cores[i].u_core.u_rd.data_hazard[3:0]; + assign flash_ctrl_if.evict_prog[i] = + tb.dut.u_eflash.gen_flash_cores[i].u_core.u_rd.prog_i; + assign flash_ctrl_if.evict_erase[i] = + tb.dut.u_eflash.gen_flash_cores[i].u_core.u_rd.pg_erase_i; + for (genvar j = 0; j < flash_phy_pkg::NumBuf; j++) begin : gen_per_buffer + assign flash_ctrl_if.rd_buf[i][j] = + tb.dut.u_eflash.gen_flash_cores[i].u_core.u_rd.read_buf[j]; + end + end + assign flash_ctrl_if.fatal_err = tb.dut.fatal_err; + `undef FLASH_DEVICE_HIER + + `DV_ALERT_IF_CONNECT() + + // SIMPLE OTP KEY INTERFACE (Access via VIF) + + otp_ctrl_pkg::flash_otp_key_req_t otp_req; + otp_ctrl_pkg::flash_otp_key_rsp_t otp_rsp; + + assign flash_ctrl_if.otp_req.addr_req = otp_req.addr_req; + assign flash_ctrl_if.otp_req.data_req = otp_req.data_req; + + assign otp_rsp.addr_ack = flash_ctrl_if.otp_rsp.addr_ack; + assign otp_rsp.data_ack = flash_ctrl_if.otp_rsp.data_ack; + assign otp_rsp.key = flash_ctrl_if.otp_rsp.key; + assign otp_rsp.rand_key = flash_ctrl_if.otp_rsp.rand_key; + assign otp_rsp.seed_valid = flash_ctrl_if.otp_rsp.seed_valid; + + assign flash_ctrl_if.rd_buf_en = tb.dut.u_flash_hw_if.rd_buf_en_o; + assign flash_ctrl_if.rma_state = tb.dut.u_flash_hw_if.rma_state_q; + assign flash_ctrl_if.prog_state0 = + tb.dut.u_eflash.gen_flash_cores[0].u_core.gen_prog_data.u_prog.state_q; + assign flash_ctrl_if.prog_state1 = + tb.dut.u_eflash.gen_flash_cores[1].u_core.gen_prog_data.u_prog.state_q; + assign flash_ctrl_if.lcmgr_state = tb.dut.u_flash_hw_if.state_q; + assign flash_ctrl_if.init = tb.dut.u_flash_hw_if.init_i; + assign flash_ctrl_if.host_gnt = tb.dut.u_eflash.gen_flash_cores[0].u_core.host_gnt; + assign flash_ctrl_if.ctrl_fsm_idle = tb.dut.u_eflash.gen_flash_cores[0].u_core.ctrl_fsm_idle; + assign flash_ctrl_if.host_outstanding = + tb.dut.u_eflash.gen_flash_cores[0].u_core.host_outstanding[1:0]; + + assign flash_ctrl_if.hw_rvalid = + tb.dut.u_flash_hw_if.rvalid_i; + + wire flash_test_v; + assign (pull1, pull0) flash_test_v = 1'b1; + wire [1:0] flash_test_mode_a; + assign (pull1, pull0) flash_test_mode_a = 2'h3; + + // dut + flash_ctrl #( + .ProgFifoDepth(ProgFifoDepth), + .RdFifoDepth(ReadFifoDepth) + ) dut ( + .clk_i (clk), + .rst_ni (rst_n), + .rst_shadowed_ni(rst_shadowed_n), + .clk_otp_i (clk), + .rst_otp_ni (rst_n), + + // various tlul interfaces + .core_tl_i(tl_if.h2d), + .core_tl_o(tl_if.d2h), + .prim_tl_i(prim_tl_if.h2d), + .prim_tl_o(prim_tl_if.d2h), + .mem_tl_i (eflash_tl_if.h2d), + .mem_tl_o (eflash_tl_if.d2h), + + // otp interface + .otp_i(otp_rsp), + .otp_o(otp_req), + + // various life cycle decode signals + .lc_creator_seed_sw_rw_en_i(flash_ctrl_if.lc_creator_seed_sw_rw_en), + .lc_owner_seed_sw_rw_en_i (flash_ctrl_if.lc_owner_seed_sw_rw_en), + .lc_iso_part_sw_rd_en_i (flash_ctrl_if.lc_iso_part_sw_rd_en), + .lc_iso_part_sw_wr_en_i (flash_ctrl_if.lc_iso_part_sw_wr_en), + .lc_seed_hw_rd_en_i (flash_ctrl_if.lc_seed_hw_rd_en), + .lc_nvm_debug_en_i (flash_ctrl_if.lc_nvm_debug_en), + .lc_escalate_en_i (flash_ctrl_if.lc_escalate_en), + + // life cycle rma handling + .rma_req_i (flash_ctrl_if.rma_req), + .rma_seed_i(flash_ctrl_if.rma_seed), + .rma_ack_o (flash_ctrl_if.rma_ack), + + // power manager indication + .pwrmgr_o(flash_ctrl_if.pwrmgr), + .keymgr_o(flash_ctrl_if.keymgr), + + // flash prim signals + .flash_power_ready_h_i (flash_ctrl_if.power_ready_h), + .flash_power_down_h_i (flash_power_down_h), + .flash_bist_enable_i (prim_mubi_pkg::MuBi4False), + .flash_test_mode_a_io (flash_test_mode_a), + .flash_test_voltage_h_io(flash_test_v), + + // test + .scanmode_i (prim_mubi_pkg::MuBi4False), + .scan_rst_ni('0), + .scan_en_i ('0), + + // JTAG + .cio_tck_i (flash_ctrl_if.cio_tck), + .cio_tms_i (flash_ctrl_if.cio_tms), + .cio_tdi_i (flash_ctrl_if.cio_tdi), + .cio_tdo_en_o(flash_ctrl_if.cio_tdo_en), + .cio_tdo_o (flash_ctrl_if.cio_tdo), + + // alerts and interrupts + .intr_prog_empty_o(intr_prog_empty), + .intr_prog_lvl_o (intr_prog_lvl), + .intr_rd_full_o (intr_rd_full), + .intr_rd_lvl_o (intr_rd_lvl), + .intr_op_done_o (intr_op_done), + .intr_corr_err_o (intr_err), + .alert_rx_i (alert_rx), + .alert_tx_o (alert_tx) + ); + + // Create edge in flash_power_down_h_i, whenever reset is asserted + logic init_pd; + assign flash_power_down_h = (init_pd ? 1'b1 : 1'b0); + initial begin + forever begin + fork + begin : isolation_fork + fork + begin + if (rst_n === 1'b1) begin + // Wait time from reset deassertion to power-down deassertion. + clk_rst_if.wait_clks(5); + init_pd = 1'b0; + end else begin + // Wait time from reset assertion to power-down assertion. Should match flash-IP + // spec timing. + #(flash_ctrl_if.rst_to_pd_time_ns); + init_pd = 1'b1; + end + end + join_none + // Wait for the rst_n to change. + @(rst_n); + disable fork; + end : isolation_fork + join + end + end + + // Instantitate the memory backdoor util instances. + // + // This only applies to the generic eflash. A unique memory backdoor util instance is created for + // each type of flash partition in each bank. + // + // For eflash of a specific vendor implementation, set the hierarchy to the memory element + // correctly when creating these instances in the extended testbench. + `define FLASH_BANK_HIER(i) \ + tb.dut.u_eflash.u_flash.gen_generic.u_impl_generic.gen_prim_flash_banks[i]. \ + u_prim_flash_bank + + `define FLASH_DATA_MEM_HIER(i) \ + `FLASH_BANK_HIER(i).u_mem.gen_generic.u_impl_generic.mem + + `define FLASH_DATA_MEM_HIER_STR(i) \ + $sformatf({"tb.dut.u_eflash.u_flash.gen_generic.u_impl_generic.", \ + "gen_prim_flash_banks[%0d].u_prim_flash_bank.u_mem.gen_generic.", \ + "u_impl_generic.mem"}, i) + + `define FLASH_INFO_MEM_HIER(i, j) \ + tb.dut.u_eflash.u_flash.gen_generic.u_impl_generic.gen_prim_flash_banks[i]. \ + u_prim_flash_bank.gen_info_types[j].u_info_mem.gen_generic.u_impl_generic.mem + + `define FLASH_INFO_MEM_HIER_STR(i, j) \ + $sformatf({"tb.dut.u_eflash.u_flash.gen_generic.u_impl_generic.", \ + "gen_prim_flash_banks[%0d].u_prim_flash_bank.gen_info_types[%0d].", \ + "u_info_mem.gen_generic.u_impl_generic.mem"}, i, j) + + if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin : gen_generic + for (genvar i = 0; i < flash_ctrl_pkg::NumBanks; i++) begin : gen_each_bank + flash_dv_part_e part = part.first(); + + initial begin + flash_mem_bkdr_util m_mem_bkdr_util; + m_mem_bkdr_util = new( + .name($sformatf("mem_bkdr_util[%0s][%0d]", part.name(), i)), + .path(`FLASH_DATA_MEM_HIER_STR(i)), + .depth($size(`FLASH_DATA_MEM_HIER(i))), + .n_bits($bits(`FLASH_DATA_MEM_HIER(i))), + .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68) + ); + uvm_config_db#(mem_bkdr_util)::set(null, "*.env", m_mem_bkdr_util.get_name(), + m_mem_bkdr_util); + part = part.next(); + end + + for (genvar j = 0; j < flash_ctrl_pkg::InfoTypes; j++) begin : gen_each_info_type + initial begin + flash_mem_bkdr_util m_mem_bkdr_util; + m_mem_bkdr_util = new( + .name($sformatf("mem_bkdr_util[%0s][%0d]", part.name(), i)), + .path(`FLASH_INFO_MEM_HIER_STR(i, j)), + .depth($size(`FLASH_INFO_MEM_HIER(i, j))), + .n_bits($bits(`FLASH_INFO_MEM_HIER(i, j))), + .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_76_68) + ); + uvm_config_db#(mem_bkdr_util)::set(null, "*.env", m_mem_bkdr_util.get_name(), + m_mem_bkdr_util); + part = part.next(); + end + end : gen_each_info_type + + bind `FLASH_BANK_HIER(i) flash_ctrl_mem_if flash_ctrl_mem_if ( + .clk_i, + .rst_ni, + .data_mem_req, + .mem_wr, + .mem_addr, + .mem_wdata, + .mem_part, + .mem_info_sel, + .info0_mem_req (gen_info_types[0].info_mem_req), + .info1_mem_req (gen_info_types[1].info_mem_req), + .info2_mem_req (gen_info_types[2].info_mem_req) + ); + initial begin + uvm_config_db#(virtual flash_ctrl_mem_if)::set(null, "*.env", + $sformatf("flash_ctrl_mem_vif[%0d]", i), `FLASH_BANK_HIER(i).flash_ctrl_mem_if); + end + + end : gen_each_bank + end : gen_generic + + `undef FLASH_BANK_HIER + `undef FLASH_DATA_MEM_HIER + `undef FLASH_INFO_MEM_HIER + + // Connect the interrupts + assign interrupts[FlashCtrlIntrProgEmpty] = intr_prog_empty; + assign interrupts[FlashCtrlIntrProgLvl] = intr_prog_lvl; + assign interrupts[FlashCtrlIntrRdFull] = intr_rd_full; + assign interrupts[FlashCtrlIntrRdLvl] = intr_rd_lvl; + assign interrupts[FlashCtrlIntrOpDone] = intr_op_done; + assign interrupts[FlashCtrlIntrErr] = intr_err; + + initial begin + // drive clk and rst_n from clk_if + 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", + "clk_rst_vif_flash_ctrl_eflash_reg_block", clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", + "clk_rst_vif_flash_ctrl_prim_reg_block", clk_rst_if); + + uvm_config_db#(virtual rst_shadowed_if)::set(null, "*.env", "rst_shadowed_vif", + rst_shadowed_if); + uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if); + uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent_flash_ctrl_core_reg_block*", "vif", + tl_if); + uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent_flash_ctrl_eflash_reg_block*", "vif", + eflash_tl_if); + uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent_flash_ctrl_prim_reg_block*", "vif", + prim_tl_if); + uvm_config_db#(virtual flash_ctrl_if)::set(null, "*.env", "flash_ctrl_vif", flash_ctrl_if); + uvm_config_db#(virtual flash_phy_prim_if)::set(null, "*.env.m_fpp_agent*", "vif", fpp_if); + $timeformat(-9, 1, " ns", 9); + run_test(); + end +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_base_test.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_base_test.sv new file mode 100644 index 0000000000000..b4266e1eb7720 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_base_test.sv @@ -0,0 +1,103 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class flash_ctrl_base_test #( + type CFG_T = flash_ctrl_env_cfg, + type ENV_T = flash_ctrl_env + ) extends cip_base_test #( + .CFG_T(CFG_T), + .ENV_T(ENV_T) + ); + + // A prototype for the registry to associate the parameterized base test + // with the name 'flash_ctrl_base_test' + // + // Register the name 'flash_ctrl_base_test' with the UVM factory to be associated + // with the template base test class parameterized with the default types (see + // declaration. We cannot invoke the standard UVM factory automation macro t + // (uvm_component_param_utils) to register a parameterized test class with the + // factory because the creation of the test by name (via the UVM_TESTNAME + // plusarg) does not work. We expand the contents of the automation macro + // here instead. See the following paper for details: + // https://verificationacademy-news.s3.amazonaws.com/DVCon2016/Papers/ + // dvcon-2016_paramaters-uvm-coverage-and-emulation-take-two-and-call-me-in-the-morning_paper.pdf + typedef uvm_component_registry#(flash_ctrl_base_test#(CFG_T, ENV_T), + "flash_ctrl_base_test") type_id; + + // functions to support the component registry above + static function type_id get_type(); + return type_id::get(); + endfunction : get_type + + virtual function uvm_object_wrapper get_object_type(); + return type_id::get(); + endfunction : get_object_type + + const static string type_name = "flash_ctrl_base_test"; + + virtual function string get_type_name(); + return type_name; + endfunction : get_type_name + + `uvm_component_new + int run_cnt = 1; + // the base class dv_base_test creates the following instances: + // flash_ctrl_env_cfg: cfg + // flash_ctrl_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 + + // Add flash_ctrl only plusarg + virtual function void build_phase(uvm_phase phase); + super.build_phase(phase); + // Knob to use small page rma + void'($value$plusargs("en_small_rma=%0b", cfg.en_small_rma)); + void'($value$plusargs("scb_otf_en=%0b", cfg.scb_otf_en)); + void'($value$plusargs("multi_alert=%0b", cfg.multi_alert_en)); + void'($value$plusargs("ecc_mode=%0d", cfg.ecc_mode)); + void'($value$plusargs("serr_pct=%0d", cfg.serr_pct)); + void'($value$plusargs("derr_pct=%0d", cfg.derr_pct)); + void'($value$plusargs("ierr_pct=%0d", cfg.ierr_pct)); + void'($value$plusargs("otf_num_rw=%0d", cfg.otf_num_rw)); + void'($value$plusargs("otf_num_hr=%0d", cfg.otf_num_hr)); + void'($value$plusargs("otf_wr_pct=%0d", cfg.otf_wr_pct)); + void'($value$plusargs("otf_rd_pct=%0d", cfg.otf_rd_pct)); + void'($value$plusargs("en_always_all=%0d", cfg.en_always_all)); + void'($value$plusargs("en_always_read=%0d", cfg.en_always_read)); + void'($value$plusargs("en_always_erase=%0d", cfg.en_always_erase)); + void'($value$plusargs("en_always_prog=%0d", cfg.en_always_prog)); + void'($value$plusargs("en_all_info_acc=%0d", cfg.en_all_info_acc)); + void'($value$plusargs("rd_buf_en_to=%0d", cfg.wait_rd_buf_en_timeout_ns)); + void'($value$plusargs("en_rnd_data=%0b", cfg.wr_rnd_data)); + if (cfg.en_always_all) begin + cfg.en_always_read = 1; + cfg.en_always_prog = 1; + cfg.en_always_erase = 1; + end + cfg.en_always_any = (cfg.en_always_read | cfg.en_always_erase | + cfg.en_always_prog); + endfunction + + task run_phase(uvm_phase phase); + int dbg_run_cnt = 0; + if ($value$plusargs("rerun=%0d", run_cnt)) begin + `uvm_info("TEST", $sformatf("run_cnt is set to %0d", run_cnt), UVM_LOW) + end + phase.raise_objection(this); + run_test_seq = 0; + super.run_phase(phase); + + repeat(run_cnt) begin + run_seq(test_seq_s, phase); + if (run_cnt > 1) begin + env.virtual_sequencer.stop_sequences(); + `uvm_info("Test", $sformatf("TESTEND %0d",++dbg_run_cnt), UVM_MEDIUM) + foreach (env.m_tl_agents[i]) env.m_tl_agents[i].monitor.pending_a_req.delete(); + end + end + phase.drop_objection(this); + + endtask // run_phase +endclass : flash_ctrl_base_test diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test.core new file mode 100644 index 0000000000000..8320666d817fb --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_test:0.1 +description: "FLASH_CTRL DV UVM test" +filesets: + files_dv: + depend: + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_env + files: + - flash_ctrl_test_pkg.sv + - flash_ctrl_base_test.sv: {is_include_file: true} + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test_pkg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test_pkg.sv new file mode 100644 index 0000000000000..28587f83aafea --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tests/flash_ctrl_test_pkg.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package flash_ctrl_test_pkg; + // dep packages + import uvm_pkg::*; + import cip_base_pkg::*; + import flash_ctrl_env_pkg::*; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + // local types + + // functions + + // package sources + `include "flash_ctrl_base_test.sv" + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tools/xcelium/xfile b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tools/xcelium/xfile new file mode 100644 index 0000000000000..d861a79197259 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/dv/tools/xcelium/xfile @@ -0,0 +1 @@ +SCOPE tb.dut F diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl.core new file mode 100644 index 0000000000000..41d8d60ac49c3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl.core @@ -0,0 +1,96 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl:0.1 +description: "Flash Controller" + +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:prim:all + - lowrisc:prim:count + - lowrisc:prim:edge_detector + - lowrisc:prim:flash + - lowrisc:prim:flop_2sync + - lowrisc:prim:gf_mult + - lowrisc:prim:lc_sync + - lowrisc:prim:lfsr + - lowrisc:prim:secded + - lowrisc:prim:sparse_fsm + - lowrisc:ip:otp_ctrl_pkg + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_pkg + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_reg + - lowrisc:constants:top_englishbreakfast_top_pkg + - lowrisc:ip:jtag_pkg + files: + - rtl/flash_ctrl.sv + - rtl/flash_ctrl_erase.sv + - rtl/flash_ctrl_prog.sv + - rtl/flash_ctrl_rd.sv + - rtl/flash_ctrl_arb.sv + - rtl/flash_ctrl_info_cfg.sv + - rtl/flash_ctrl_lcmgr.sv + - rtl/flash_ctrl_region_cfg.sv + - rtl/flash_mp.sv + - rtl/flash_mp_data_region_sel.sv + - rtl/flash_phy.sv + - rtl/flash_phy_core.sv + - rtl/flash_phy_rd.sv + - rtl/flash_phy_rd_buffers.sv + - rtl/flash_phy_rd_buf_dep.sv + - rtl/flash_phy_prog.sv + - rtl/flash_phy_erase.sv + - rtl/flash_phy_scramble.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/flash_ctrl.vlt + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/flash_ctrl.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: flash_ctrl + + lint: + <<: *default_target + default_tool: verilator + parameters: + - SYNTHESIS=true + tools: + verilator: + mode: lint-only + verilator_options: + - "-Wall" diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_pkg.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_pkg.core new file mode 100644 index 0000000000000..04f04f72eb7ad --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_pkg.core @@ -0,0 +1,59 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_pkg:0.1 +description: "Top specific flash package" +virtual: + - lowrisc:ip_interfaces:flash_ctrl_pkg + +filesets: + files_rtl: + depend: + - lowrisc:constants:top_englishbreakfast_top_pkg + - lowrisc:prim:util + - lowrisc:ip:lc_ctrl_pkg + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + - lowrisc:ip:jtag_pkg + - lowrisc:ip:edn_pkg + - lowrisc:tlul:headers + - "fileset_partner ? (partner:systems:ast_pkg)" + - "!fileset_partner ? (lowrisc:systems:ast_pkg)" + files: + - rtl/flash_ctrl_reg_pkg.sv + - rtl/flash_ctrl_pkg.sv + - rtl/flash_phy_pkg.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/flash_ctrl_pkg.vlt + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/flash_ctrl_pkg.waiver + file_type: waiver + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_prim_reg_top.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_prim_reg_top.core new file mode 100644 index 0000000000000..185cdabad2106 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_prim_reg_top.core @@ -0,0 +1,29 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_prim_reg_top:1.0 +description: "Generic register top for the FLASH wrapper" +virtual: + - lowrisc:ip_interfaces:flash_ctrl_prim_reg_top + +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_pkg + files: + - rtl/flash_ctrl_prim_reg_top.sv + file_type: systemVerilogSource + + +parameters: + SYNTHESIS: + datatype: bool + paramtype: vlogdefine + + +targets: + default: &default_target + filesets: + - files_rtl + toplevel: lc_ctrl diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_reg.core b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_reg.core new file mode 100644 index 0000000000000..df63deb7811df --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/flash_ctrl_reg.core @@ -0,0 +1,20 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_flash_ctrl_reg:0.1 +description: "Flash registers" + +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:opentitan:top_englishbreakfast_flash_ctrl_pkg + files: + - rtl/flash_ctrl_core_reg_top.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.vlt b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.vlt new file mode 100644 index 0000000000000..106142f021040 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.vlt @@ -0,0 +1,27 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// waiver file for flash_ctrl + +`verilator_config + +// When we calculate the size for the top region config, we use NumBanks * +// PagesPerBank. This is a constant integer calculation, whose result is +// assigned to the 10-bit "size" field. Here, the "10" comes from the hjson. +// Waive the Verilator warning, rather than slice the result, so that +// AscentLint will complain if we've messed up and NumBanks * PagesPerBank is +// too big to represent. +// +// The slightly odd-looking path glob is to match the auto-generated version of +// the code too (which is at .../rtl/autogen/flash_ctrl.sv) +lint_off -rule WIDTH -file "*/rtl/*flash_ctrl.sv" -match "Operator ASSIGNW expects 10 bits*MUL generates 32 bits." + +// The following are int parameter assignments into variables +// While the variables themselves are technically not large enough to accommodate a 32b integer, synthsizers +// are smart enough to do the right thing +lint_off -rule WIDTH -file "*flash_ctrl_lcmgr.sv" -match "Operator EQ expects 32 bits on the LHS, but LHS's VARREF 'seed_cnt_q' generates 2 bits." +lint_off -rule WIDTH -file "*flash_ctrl_lcmgr.sv" -match "Operator ADD expects 32 bits on the LHS, but LHS's VARREF 'word_cnt' generates 10 bits." +lint_off -rule WIDTH -file "*flash_ctrl_lcmgr.sv" -match "Operator ASSIGNDLY expects 10 bits on the Assign RHS, but Assign RHS's ADD generates 32 bits." +lint_off -rule WIDTH -file "*flash_ctrl_lcmgr.sv" -match "Operator ASSIGNW expects 12 bits on the Assign RHS, but Assign RHS's SUB generates 32 bits." +lint_off -rule WIDTH -file "*flash_ctrl_lcmgr.sv" -match "Operator LT expects 32 bits on the LHS, but LHS's VARREF 'word_cnt' generates 10 bits." diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.waiver b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.waiver new file mode 100644 index 0000000000000..6097f164a6b31 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl.waiver @@ -0,0 +1,24 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# waiver file for Flash Controller + +# Sparsely encoded states all have terminal behavior +waive -rules TERMINAL_STATE -location {flash_ctrl_lcmgr.sv} -regexp {.*StInvalid.*} \ + -comment "StInvalid is intended to be a terminal state" + +waive -rules TERMINAL_STATE -location {flash_phy_core.sv} -regexp {.*(StInvalid|StDisable).*} \ + -comment "Behavior is part of terminal invalid and disable states" + +# the rst done signals were an intentional choice to address resets +# that could potentially release at different times +waive -rules CONST_FF -location {flash_ctrl_core_reg_top.sv} \ + -regexp {.*rst_done.*} \ + +# State is handled as part of "default" +waive -rules MISSING_STATE -location {flash_phy_core.sv} \ + -regexp {.*'StDisable' does not have corresponding case branch tag} + +waive -rules USE_BEFORE_DECL -location {flash_ctrl_pkg.sv} -msg {'max_info_pages' is referenced before its declaration at flash_ctrl_pkg.sv} \ + -comment "max_info_pages is a function defined towards the end of the file." diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.vlt b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.vlt new file mode 100644 index 0000000000000..ae80069d14160 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.vlt @@ -0,0 +1,5 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// waiver file for flash_ctrl_pkg diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.waiver b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.waiver new file mode 100644 index 0000000000000..fbb90a471ae9d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/lint/flash_ctrl_pkg.waiver @@ -0,0 +1,8 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# + + +waive -rules UNSIZED_BIT_CONTEXT -location {flash_ctrl_pkg.sv} -regexp {Unsized bit literal "'1" encountered within a parameter declaration} \ + -comment "This instance of an unsized parameter literal is difficult to circumvent, as the width of the assigned field is not readily available in this package." diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv new file mode 100644 index 0000000000000..8da2231f483d6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl.sv @@ -0,0 +1,1501 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Controller Module +// +// + +`include "prim_assert.sv" +`include "prim_fifo_assert.svh" + +module flash_ctrl + import flash_ctrl_pkg::*; import flash_ctrl_reg_pkg::*; +#( + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter flash_key_t RndCnstAddrKey = RndCnstAddrKeyDefault, + parameter flash_key_t RndCnstDataKey = RndCnstDataKeyDefault, + parameter all_seeds_t RndCnstAllSeeds = RndCnstAllSeedsDefault, + parameter lfsr_seed_t RndCnstLfsrSeed = RndCnstLfsrSeedDefault, + parameter lfsr_perm_t RndCnstLfsrPerm = RndCnstLfsrPermDefault, + parameter int ProgFifoDepth = MaxFifoDepth, + parameter int RdFifoDepth = MaxFifoDepth, + parameter bit SecScrambleEn = 1'b1 +) ( + input clk_i, + input rst_ni, + input rst_shadowed_ni, + + input clk_otp_i, + input rst_otp_ni, + + // life cycle interface + // SEC_CM: LC_CTRL.INTERSIG.MUBI + input lc_ctrl_pkg::lc_tx_t lc_creator_seed_sw_rw_en_i, + input lc_ctrl_pkg::lc_tx_t lc_owner_seed_sw_rw_en_i, + input lc_ctrl_pkg::lc_tx_t lc_iso_part_sw_rd_en_i, + input lc_ctrl_pkg::lc_tx_t lc_iso_part_sw_wr_en_i, + input lc_ctrl_pkg::lc_tx_t lc_seed_hw_rd_en_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + input lc_ctrl_pkg::lc_tx_t lc_nvm_debug_en_i, + + // Bus Interface + input tlul_pkg::tl_h2d_t core_tl_i, + output tlul_pkg::tl_d2h_t core_tl_o, + input tlul_pkg::tl_h2d_t prim_tl_i, + output tlul_pkg::tl_d2h_t prim_tl_o, + input tlul_pkg::tl_h2d_t mem_tl_i, + output tlul_pkg::tl_d2h_t mem_tl_o, + + // otp/lc/pwrmgr/keymgr Interface + // SEC_CM: SCRAMBLE.KEY.SIDELOAD + output otp_ctrl_pkg::flash_otp_key_req_t otp_o, + input otp_ctrl_pkg::flash_otp_key_rsp_t otp_i, + input lc_ctrl_pkg::lc_tx_t rma_req_i, + input lc_ctrl_pkg::lc_flash_rma_seed_t rma_seed_i, + output lc_ctrl_pkg::lc_tx_t rma_ack_o, + output pwrmgr_pkg::pwr_flash_t pwrmgr_o, + output keymgr_flash_t keymgr_o, + + // IOs + input cio_tck_i, + input cio_tms_i, + input cio_tdi_i, + output logic cio_tdo_en_o, + output logic cio_tdo_o, + + // Interrupts + output logic intr_corr_err_o, // Correctable errors encountered + output logic intr_prog_empty_o, // Program fifo is empty + output logic intr_prog_lvl_o, // Program fifo is empty + output logic intr_rd_full_o, // Read fifo is full + output logic intr_rd_lvl_o, // Read fifo is full + output logic intr_op_done_o, // Requested flash operation (wr/erase) done + + // Alerts + input prim_alert_pkg::alert_rx_t [flash_ctrl_reg_pkg::NumAlerts-1:0] alert_rx_i, + output prim_alert_pkg::alert_tx_t [flash_ctrl_reg_pkg::NumAlerts-1:0] alert_tx_o, + + // Observability + input ast_pkg::ast_obs_ctrl_t obs_ctrl_i, + output logic [7:0] fla_obs_o, + + // Flash test interface + input scan_en_i, + input prim_mubi_pkg::mubi4_t scanmode_i, + input scan_rst_ni, + input prim_mubi_pkg::mubi4_t flash_bist_enable_i, + input flash_power_down_h_i, + input flash_power_ready_h_i, + inout [1:0] flash_test_mode_a_io, + inout flash_test_voltage_h_io +); + + ////////////////////////////////////////////////////////// + // Double check supplied param is not bigger than allowed + ////////////////////////////////////////////////////////// + `ASSERT_INIT(FifoDepthCheck_A, (ProgFifoDepth <= MaxFifoDepth) & + (RdFifoDepth <= MaxFifoDepth)) + + import prim_mubi_pkg::mubi4_t; + + flash_ctrl_core_reg2hw_t reg2hw; + flash_ctrl_core_hw2reg_t hw2reg; + + tlul_pkg::tl_h2d_t tl_win_h2d [2]; + tlul_pkg::tl_d2h_t tl_win_d2h [2]; + + // Register module + logic storage_err; + logic update_err; + logic intg_err; + logic eflash_cmd_intg_err; + logic tl_gate_intg_err; + logic tl_prog_gate_intg_err; + + // SEC_CM: REG.BUS.INTEGRITY + // SEC_CM: CTRL.CONFIG.REGWEN + // SEC_CM: DATA_REGIONS.CONFIG.REGWEN, DATA_REGIONS.CONFIG.SHADOW + // SEC_CM: INFO_REGIONS.CONFIG.REGWEN, INFO_REGIONS.CONFIG.SHADOW + // SEC_CM: BANK.CONFIG.REGWEN, BANK.CONFIG.SHADOW + flash_ctrl_core_reg_top u_reg_core ( + .clk_i, + .rst_ni, + .rst_shadowed_ni, + + .tl_i(core_tl_i), + .tl_o(core_tl_o), + + .tl_win_o (tl_win_h2d), + .tl_win_i (tl_win_d2h), + + .reg2hw, + .hw2reg, + + .shadowed_storage_err_o (storage_err), + .shadowed_update_err_o (update_err), + .intg_err_o (intg_err) + ); + + bank_cfg_t [NumBanks-1:0] bank_cfgs; + mp_region_cfg_t [MpRegions:0] region_cfgs; + info_page_cfg_t [NumBanks-1:0][InfoTypes-1:0][InfosPerBank-1:0] info_page_cfgs; + + flash_ctrl_region_cfg u_region_cfg ( + .clk_i, + .rst_ni, + .lc_creator_seed_sw_rw_en_i, + .lc_owner_seed_sw_rw_en_i, + .lc_iso_part_sw_wr_en_i, + .lc_iso_part_sw_rd_en_i, + .bank_cfg_i(reg2hw.mp_bank_cfg_shadowed), + .region_i(reg2hw.mp_region), + .region_cfg_i(reg2hw.mp_region_cfg), + .default_cfg_i(reg2hw.default_region), + .bank0_info0_cfg_i(reg2hw.bank0_info0_page_cfg), + .bank0_info1_cfg_i(reg2hw.bank0_info1_page_cfg), + .bank0_info2_cfg_i(reg2hw.bank0_info2_page_cfg), + .bank1_info0_cfg_i(reg2hw.bank1_info0_page_cfg), + .bank1_info1_cfg_i(reg2hw.bank1_info1_page_cfg), + .bank1_info2_cfg_i(reg2hw.bank1_info2_page_cfg), + .bank_cfg_o(bank_cfgs), + .region_cfgs_o(region_cfgs), + .info_page_cfgs_o(info_page_cfgs) + ); + + // FIFO Connections + localparam int ProgDepthW = prim_util_pkg::vbits(ProgFifoDepth+1); + localparam int RdDepthW = prim_util_pkg::vbits(RdFifoDepth+1); + + logic prog_fifo_wvalid; + logic prog_fifo_wready; + logic prog_fifo_rvalid; + logic prog_fifo_ren; + logic [BusFullWidth-1:0] prog_fifo_wdata; + logic [BusFullWidth-1:0] prog_fifo_rdata; + logic [ProgDepthW-1:0] prog_fifo_depth; + + // Program Control Connections + logic prog_flash_req; + logic prog_flash_ovfl; + logic [BusAddrW-1:0] prog_flash_addr; + logic prog_op_valid; + + // Read Control Connections + logic rd_flash_req; + logic rd_flash_ovfl; + logic [BusAddrW-1:0] rd_flash_addr; + logic rd_op_valid; + logic rd_ctrl_wen; + logic [BusFullWidth-1:0] rd_ctrl_wdata; + + + // Erase Control Connections + logic erase_flash_req; + logic [BusAddrW-1:0] erase_flash_addr; + flash_erase_e erase_flash_type; + logic erase_op_valid; + + // Done / Error signaling from ctrl modules + logic prog_done, rd_done, erase_done; + flash_ctrl_err_t prog_err, rd_err, erase_err; + logic [BusAddrW-1:0] prog_err_addr, rd_err_addr, erase_err_addr; + + // Flash Memory Properties Connections + logic [BusAddrW-1:0] flash_addr; + logic flash_req; + logic flash_rd_done, flash_prog_done, flash_erase_done; + logic flash_mp_err; + logic [BusFullWidth-1:0] flash_prog_data; + logic flash_prog_last; + flash_prog_e flash_prog_type; + logic [BusFullWidth-1:0] flash_rd_data; + logic flash_rd_err; + logic flash_phy_busy; + logic rd_op; + logic prog_op; + logic erase_op; + flash_lcmgr_phase_e phase; + + // Flash control arbitration connections to hardware interface + flash_key_t addr_key; + flash_key_t rand_addr_key; + flash_key_t data_key; + flash_key_t rand_data_key; + flash_ctrl_reg2hw_control_reg_t hw_ctrl; + logic hw_req; + logic [BusAddrByteW-1:0] hw_addr; + logic hw_done; + flash_ctrl_err_t hw_err; + logic hw_wvalid; + logic [BusFullWidth-1:0] hw_wdata; + logic hw_wready; + flash_sel_e if_sel; + logic sw_sel; + flash_lcmgr_phase_e hw_phase; + logic lcmgr_err; + logic lcmgr_intg_err; + logic arb_fsm_err; + logic seed_err; + + // Flash lcmgr interface to direct read fifo + logic lcmgr_rready; + + // Flash control arbitration connections to software interface + logic sw_ctrl_done; + flash_ctrl_err_t sw_ctrl_err; + + // Flash control muxed connections + flash_ctrl_reg2hw_control_reg_t muxed_ctrl; + logic [BusAddrByteW-1:0] muxed_addr; + logic op_start; + logic [11:0] op_num_words; + logic [BusAddrW-1:0] op_addr; + logic [BusAddrW-1:0] ctrl_err_addr; + flash_op_e op_type; + flash_part_e op_part; + logic [InfoTypesWidth-1:0] op_info_sel; + flash_erase_e op_erase_type; + flash_prog_e op_prog_type; + + logic ctrl_init_busy; + logic ctrl_initialized; + logic fifo_clr; + + // sw read fifo interface + logic sw_rfifo_wen; + logic sw_rfifo_wready; + logic [BusFullWidth-1:0] sw_rfifo_wdata; + logic sw_rfifo_full; + logic [RdDepthW-1:0] sw_rfifo_depth; + logic sw_rfifo_rvalid; + logic sw_rfifo_rready; + logic [BusFullWidth-1:0] sw_rfifo_rdata; + + // software tlul interface to read fifo + logic adapter_req; + logic adapter_rvalid; + logic adapter_fifo_err; + + // software tlul interface to prog fifo + logic sw_wvalid; + logic [BusFullWidth-1:0] sw_wdata; + logic sw_wready; + + // lfsr for local entropy usage + logic [31:0] rand_val; + logic lfsr_en; + logic lfsr_seed_en; + + // interface to flash phy + flash_rsp_t flash_phy_rsp; + flash_req_t flash_phy_req; + + // import commonly used routines + import lc_ctrl_pkg::lc_tx_test_true_strict; + + // life cycle connections + lc_ctrl_pkg::lc_tx_t lc_seed_hw_rd_en; + + lc_ctrl_pkg::lc_tx_t dis_access; + + prim_lc_sync #( + .NumCopies(1) + ) u_lc_seed_hw_rd_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_seed_hw_rd_en_i), + .lc_en_o({lc_seed_hw_rd_en}) + ); + + prim_lfsr #( + .EntropyDw(EdnWidth), + .LfsrDw(LfsrWidth), + .StateOutDw(LfsrWidth), + .DefaultSeed(RndCnstLfsrSeed), + .StatePermEn(1), + .StatePerm(RndCnstLfsrPerm) + ) u_lfsr ( + .clk_i, + .rst_ni, + .seed_en_i(lfsr_seed_en), + .seed_i(rma_seed_i), + .lfsr_en_i(lfsr_en), + .entropy_i('0), + .state_o(rand_val) + ); + + // flash disable declaration + mubi4_t [FlashDisableLast-1:0] flash_disable; + + // flash control arbitration between software and hardware interfaces + flash_ctrl_arb u_ctrl_arb ( + .clk_i, + .rst_ni, + + // combined disable + .disable_i(flash_disable[ArbFsmDisableIdx]), + + // error output shared by both interfaces + .ctrl_err_addr_o(ctrl_err_addr), + + // software interface to rd_ctrl / erase_ctrl + .sw_ctrl_i(reg2hw.control), + .sw_addr_i(reg2hw.addr.q), + .sw_ack_o(sw_ctrl_done), + .sw_err_o(sw_ctrl_err), + + // software interface to prog_fifo + // if prog operation not selected, software interface + // writes have no meaning + .sw_wvalid_i(sw_wvalid & prog_op_valid), + .sw_wdata_i(sw_wdata), + .sw_wready_o(sw_wready), + + // hardware interface to rd_ctrl / erase_ctrl + .hw_req_i(hw_req), + .hw_ctrl_i(hw_ctrl), + + // hardware interface indicating operation phase + .hw_phase_i(hw_phase), + + // hardware works on word address, however software expects byte address + .hw_addr_i(hw_addr), + .hw_ack_o(hw_done), + .hw_err_o(hw_err), + + // hardware interface to rd_fifo + .hw_wvalid_i(hw_wvalid), + .hw_wdata_i(hw_wdata), + .hw_wready_o(hw_wready), + + // hardware interface does not talk to prog_fifo + + // muxed interface to rd_ctrl / erase_ctrl + .muxed_ctrl_o(muxed_ctrl), + .muxed_addr_o(muxed_addr), + .prog_ack_i(prog_done), + .prog_err_i(prog_err), + .prog_err_addr_i(prog_err_addr), + .rd_ack_i(rd_done), + .rd_err_i(rd_err), + .rd_err_addr_i(rd_err_addr), + .erase_ack_i(erase_done), + .erase_err_i(erase_err), + .erase_err_addr_i(erase_err_addr), + + // muxed interface to prog_fifo + .prog_fifo_wvalid_o(prog_fifo_wvalid), + .prog_fifo_wdata_o(prog_fifo_wdata), + .prog_fifo_wready_i(prog_fifo_wready), + + // flash phy initialization ongoing + .flash_phy_busy_i(flash_phy_busy), + + // clear fifos + .fifo_clr_o(fifo_clr), + + // phase indication + .phase_o(phase), + + // indication that sw has been selected + .sel_o(if_sel), + .fsm_err_o(arb_fsm_err) + ); + + assign op_start = muxed_ctrl.start.q; + assign op_num_words = muxed_ctrl.num.q; + assign op_erase_type = flash_erase_e'(muxed_ctrl.erase_sel.q); + assign op_prog_type = flash_prog_e'(muxed_ctrl.prog_sel.q); + assign op_addr = muxed_addr[BusByteWidth +: BusAddrW]; + assign op_type = flash_op_e'(muxed_ctrl.op.q); + assign op_part = flash_part_e'(muxed_ctrl.partition_sel.q); + assign op_info_sel = muxed_ctrl.info_sel.q; + assign rd_op = op_type == FlashOpRead; + assign prog_op = op_type == FlashOpProgram; + assign erase_op = op_type == FlashOpErase; + assign sw_sel = if_sel == SwSel; + + // hardware interface + flash_ctrl_lcmgr #( + .RndCnstAddrKey(RndCnstAddrKey), + .RndCnstDataKey(RndCnstDataKey), + .RndCnstAllSeeds(RndCnstAllSeeds) + ) u_flash_hw_if ( + .clk_i, + .rst_ni, + .clk_otp_i, + .rst_otp_ni, + + .init_i(reg2hw.init), + .provision_en_i(lc_tx_test_true_strict(lc_seed_hw_rd_en)), + + // combined disable + .disable_i(flash_disable[LcMgrDisableIdx]), + + // interface to ctrl arb control ports + .ctrl_o(hw_ctrl), + .req_o(hw_req), + .addr_o(hw_addr), + .done_i(hw_done), + .err_i(hw_err), + + // interface to ctrl_arb data ports + .wready_i(hw_wready), + .wvalid_o(hw_wvalid), + .wdata_o(hw_wdata), + + // interface to hw interface read fifo + .rready_o(lcmgr_rready), + .rvalid_i(~sw_sel & rd_ctrl_wen), + .rdata_i(rd_ctrl_wdata), + + // external rma request + .rma_req_i, + .rma_ack_o, + + // outgoing seeds + .seeds_o(keymgr_o.seeds), + .seed_err_o(seed_err), + + // phase indication + .phase_o(hw_phase), + + // phy read buffer enable + .rd_buf_en_o(flash_phy_req.rd_buf_en), + + // connection to otp + .otp_key_req_o(otp_o), + .otp_key_rsp_i(otp_i), + .addr_key_o(addr_key), + .data_key_o(data_key), + .rand_addr_key_o(rand_addr_key), + .rand_data_key_o(rand_data_key), + + // entropy interface + .edn_req_o(lfsr_seed_en), + .edn_ack_i(1'b1), + .lfsr_en_o(lfsr_en), + .rand_i(rand_val), + + // error indication + .fatal_err_o(lcmgr_err), + .intg_err_o(lcmgr_intg_err), + + // disable access to flash storage after rma process + .dis_access_o(dis_access), + + // init ongoing + .init_busy_o(ctrl_init_busy), + .initialized_o(ctrl_initialized), + + .debug_state_o(hw2reg.debug_state.d) + ); + + + + + // Program FIFO + // Since the program and read FIFOs are never used at the same time, it should really be one + // FIFO with muxed inputs and outputs. This should be addressed once the flash integration + // strategy has been identified + assign prog_op_valid = op_start & prog_op; + + tlul_pkg::tl_h2d_t prog_tl_h2d; + tlul_pkg::tl_d2h_t prog_tl_d2h; + + // the program path also needs an lc gate to error back when flash is disabled. + // This is because tlul_adapter_sram does not actually have a way of signaling + // write errors, only read errors. + // SEC_CM: PROG_TL_LC_GATE.FSM.SPARSE + tlul_lc_gate u_prog_tl_gate ( + .clk_i, + .rst_ni, + .tl_h2d_i(tl_win_h2d[0]), + .tl_d2h_o(tl_win_d2h[0]), + .tl_h2d_o(prog_tl_h2d), + .tl_d2h_i(prog_tl_d2h), + .flush_req_i('0), + .flush_ack_o(), + .resp_pending_o(), + .lc_en_i(lc_ctrl_pkg::mubi4_to_lc_inv(flash_disable[ProgFifoIdx])), + .err_o(tl_prog_gate_intg_err) + ); + + tlul_adapter_sram #( + .SramAw(1), //address unused + .SramDw(BusWidth), + .ByteAccess(0), //flash may not support byte access + .ErrOnRead(1), //reads not supported + .EnableDataIntgPt(1) //passthrough data integrity + ) u_to_prog_fifo ( + .clk_i, + .rst_ni, + .tl_i (prog_tl_h2d), + .tl_o (prog_tl_d2h), + .en_ifetch_i (prim_mubi_pkg::MuBi4False), + .req_o (sw_wvalid), + .req_type_o (), + .gnt_i (sw_wready), + .we_o (), + .addr_o (), + .wmask_o (), + .intg_error_o (), + .user_rsvd_o (), + .wdata_o (sw_wdata), + .rdata_i ('0), + .rvalid_i (1'b0), + .rerror_i (2'b0), + .compound_txn_in_progress_o (), + .readback_en_i (prim_mubi_pkg::MuBi4False), + .readback_error_o (), + .wr_collision_i (1'b0), + .write_pending_i (1'b0) + ); + + prim_fifo_sync #( + .Width(BusFullWidth), + .Depth(ProgFifoDepth) + ) u_prog_fifo ( + .clk_i, + .rst_ni, + .clr_i (reg2hw.fifo_rst.q | fifo_clr | sw_ctrl_done), + .wvalid_i(prog_fifo_wvalid), + .wready_o(prog_fifo_wready), + .wdata_i (prog_fifo_wdata), + .depth_o (prog_fifo_depth), + .full_o (), + .rvalid_o(prog_fifo_rvalid), + .rready_i(prog_fifo_ren), + .rdata_o (prog_fifo_rdata), + .err_o () + ); + assign hw2reg.curr_fifo_lvl.prog.d = MaxFifoWidth'(prog_fifo_depth); + + // Program handler is consumer of prog_fifo + logic [1:0] prog_type_en; + assign prog_type_en[FlashProgNormal] = flash_phy_rsp.prog_type_avail[FlashProgNormal] & + reg2hw.prog_type_en.normal.q; + assign prog_type_en[FlashProgRepair] = flash_phy_rsp.prog_type_avail[FlashProgRepair] & + reg2hw.prog_type_en.repair.q; + + logic prog_cnt_err; + flash_ctrl_prog u_flash_ctrl_prog ( + .clk_i, + .rst_ni, + + // Control interface + .op_start_i (prog_op_valid), + .op_num_words_i (op_num_words), + .op_done_o (prog_done), + .op_err_o (prog_err), + .op_addr_i (op_addr), + .op_addr_oob_i ('0), + .op_type_i (op_prog_type), + .type_avail_i (prog_type_en), + .op_err_addr_o (prog_err_addr), + .cnt_err_o (prog_cnt_err), + + // FIFO Interface + .data_i (prog_fifo_rdata), + .data_rdy_i (prog_fifo_rvalid), + .data_rd_o (prog_fifo_ren), + + // Flash Macro Interface + .flash_req_o (prog_flash_req), + .flash_addr_o (prog_flash_addr), + .flash_ovfl_o (prog_flash_ovfl), + .flash_data_o (flash_prog_data), + .flash_last_o (flash_prog_last), + .flash_type_o (flash_prog_type), + .flash_done_i (flash_prog_done), + .flash_prog_intg_err_i (flash_phy_rsp.prog_intg_err), + .flash_mp_err_i (flash_mp_err) + ); + + + + // a read request is seen from software but a read operation is not enabled + // AND there are no pending entries to read from the fifo. + // This indicates software has issued a read when it should not have. + logic rd_no_op_d, rd_no_op_q; + logic sw_rd_op; + assign sw_rd_op = reg2hw.control.start.q & (reg2hw.control.op.q == FlashOpRead); + + // If software ever attempts to read when the FIFO is empty AND if it has never + // initiated a transaction, OR when flash is disabled, then it is a read that + // can never complete, error back immediately. + assign rd_no_op_d = adapter_req & ((~sw_rd_op & ~sw_rfifo_rvalid) | + (prim_mubi_pkg::mubi4_test_true_loose(flash_disable[RdFifoIdx]))); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + adapter_rvalid <= 1'b0; + rd_no_op_q <= 1'b0; + end else begin + adapter_rvalid <= adapter_req & sw_rfifo_rvalid; + rd_no_op_q <= rd_no_op_d; + end + end + + // tlul adapter represents software's access interface to flash + tlul_adapter_sram #( + .SramAw(1), //address unused + .SramDw(BusWidth), + .ByteAccess(0), //flash may not support byte access + .ErrOnWrite(1), //writes not supported + .EnableDataIntgPt(1), + .SecFifoPtr(1) // SEC_CM: FIFO.CTR.REDUN + ) u_to_rd_fifo ( + .clk_i, + .rst_ni, + .tl_i (tl_win_h2d[1]), + .tl_o (tl_win_d2h[1]), + .en_ifetch_i (prim_mubi_pkg::MuBi4False), + .req_o (adapter_req), + .req_type_o (), + // if there is no valid read operation, don't hang the + // bus, just let things normally return + .gnt_i (sw_rfifo_rvalid | rd_no_op_d), + .we_o (), + .addr_o (), + .wmask_o (), + .wdata_o (), + .intg_error_o (adapter_fifo_err), + .user_rsvd_o (), + .rdata_i (sw_rfifo_rdata), + .rvalid_i (adapter_rvalid | rd_no_op_q), + .rerror_i ({rd_no_op_q, 1'b0}), + .compound_txn_in_progress_o (), + .readback_en_i (prim_mubi_pkg::MuBi4False), + .readback_error_o (), + .wr_collision_i (1'b0), + .write_pending_i (1'b0) + ); + + assign sw_rfifo_wen = sw_sel & rd_ctrl_wen; + assign sw_rfifo_wdata = rd_ctrl_wdata; + assign sw_rfifo_rready = adapter_rvalid; + + // the read fifo below is dedicated to the software read path. + prim_fifo_sync #( + .Width(BusFullWidth), + .Depth(RdFifoDepth) + ) u_sw_rd_fifo ( + .clk_i, + .rst_ni, + .clr_i (reg2hw.fifo_rst.q), + .wvalid_i(sw_rfifo_wen), + .wready_o(sw_rfifo_wready), + .wdata_i (sw_rfifo_wdata), + .full_o (sw_rfifo_full), + .depth_o (sw_rfifo_depth), + .rvalid_o(sw_rfifo_rvalid), + .rready_i(sw_rfifo_rready), + .rdata_o (sw_rfifo_rdata), + .err_o () + ); + assign hw2reg.curr_fifo_lvl.rd.d = sw_rfifo_depth; + + logic rd_cnt_err; + // Read handler is consumer of rd_fifo + assign rd_op_valid = op_start & rd_op; + flash_ctrl_rd u_flash_ctrl_rd ( + .clk_i, + .rst_ni, + + // To arbiter Interface + .op_start_i (rd_op_valid), + .op_num_words_i (op_num_words), + .op_done_o (rd_done), + .op_err_o (rd_err), + .op_err_addr_o (rd_err_addr), + .op_addr_i (op_addr), + .op_addr_oob_i ('0), + .cnt_err_o (rd_cnt_err), + + // FIFO Interface + .data_rdy_i (sw_sel ? sw_rfifo_wready : lcmgr_rready), + .data_o (rd_ctrl_wdata), + .data_wr_o (rd_ctrl_wen), + + // Flash Macro Interface + .flash_req_o (rd_flash_req), + .flash_addr_o (rd_flash_addr), + .flash_ovfl_o (rd_flash_ovfl), + .flash_data_i (flash_rd_data), + .flash_done_i (flash_rd_done), + .flash_mp_err_i (flash_mp_err), + .flash_rd_err_i (flash_rd_err) + ); + + // Erase handler does not consume fifo + assign erase_op_valid = op_start & erase_op; + flash_ctrl_erase u_flash_ctrl_erase ( + // Software Interface + .op_start_i (erase_op_valid), + .op_type_i (op_erase_type), + .op_done_o (erase_done), + .op_err_o (erase_err), + .op_addr_i (op_addr), + .op_addr_oob_i ('0), + .op_err_addr_o (erase_err_addr), + + // Flash Macro Interface + .flash_req_o (erase_flash_req), + .flash_addr_o (erase_flash_addr), + .flash_op_o (erase_flash_type), + .flash_done_i (flash_erase_done), + .flash_mp_err_i (flash_mp_err) + ); + + // Final muxing to flash macro module + always_comb begin + unique case (op_type) + FlashOpRead: begin + flash_req = rd_flash_req; + flash_addr = rd_flash_addr; + end + FlashOpProgram: begin + flash_req = prog_flash_req; + flash_addr = prog_flash_addr; + end + FlashOpErase: begin + flash_req = erase_flash_req; + flash_addr = erase_flash_addr; + end + default: begin + flash_req = 1'b0; + flash_addr = '0; + end + endcase // unique case (op_type) + end + + + + ////////////////////////////////////// + // Info partition properties configuration + ////////////////////////////////////// + + + ////////////////////////////////////// + // flash memory properties + ////////////////////////////////////// + // direct assignment since prog/rd/erase_ctrl do not make use of op_part + flash_part_e flash_part_sel; + logic [InfoTypesWidth-1:0] flash_info_sel; + assign flash_part_sel = op_part; + assign flash_info_sel = op_info_sel; + + // tie off hardware clear path + assign hw2reg.erase_suspend.d = 1'b0; + + // Flash memory Properties + // Memory property is page based and thus should use phy addressing + // This should move to flash_phy long term + lc_ctrl_pkg::lc_tx_t lc_escalate_en; + flash_mp u_flash_mp ( + .clk_i, + .rst_ni, + + // This is only used in SVAs, hence we do not have to feed in a copy. + .lc_escalate_en_i(lc_escalate_en), + + // disable flash through memory protection + .flash_disable_i(flash_disable[MpDisableIdx]), + + // hw info configuration overrides + .hw_info_scramble_dis_i(mubi4_t'(reg2hw.hw_info_cfg_override.scramble_dis.q)), + .hw_info_ecc_dis_i(mubi4_t'(reg2hw.hw_info_cfg_override.ecc_dis.q)), + + // arbiter interface selection + .if_sel_i(if_sel), + + // sw configuration for data partition + .region_cfgs_i(region_cfgs), + .bank_cfgs_i(bank_cfgs), + + // sw configuration for info partition + .info_page_cfgs_i(info_page_cfgs), + + // read / prog / erase controls + .req_i(flash_req), + .phase_i(phase), + .req_addr_i(flash_addr[BusAddrW-1 -: AllPagesW]), + .req_part_i(flash_part_sel), + .info_sel_i(flash_info_sel), + .addr_ovfl_i(rd_flash_ovfl | prog_flash_ovfl), + .rd_i(rd_op), + .prog_i(prog_op), + .pg_erase_i(erase_op & (erase_flash_type == FlashErasePage)), + .bk_erase_i(erase_op & (erase_flash_type == FlashEraseBank)), + .erase_suspend_i(reg2hw.erase_suspend), + .erase_suspend_done_o(hw2reg.erase_suspend.de), + .rd_done_o(flash_rd_done), + .prog_done_o(flash_prog_done), + .erase_done_o(flash_erase_done), + .error_o(flash_mp_err), + + // flash phy interface + .req_o(flash_phy_req.req), + .scramble_en_o(flash_phy_req.scramble_en), + .ecc_en_o(flash_phy_req.ecc_en), + .he_en_o(flash_phy_req.he_en), + .rd_o(flash_phy_req.rd), + .prog_o(flash_phy_req.prog), + .pg_erase_o(flash_phy_req.pg_erase), + .bk_erase_o(flash_phy_req.bk_erase), + .erase_suspend_o(flash_phy_req.erase_suspend), + .rd_done_i(flash_phy_rsp.rd_done), + .prog_done_i(flash_phy_rsp.prog_done), + .erase_done_i(flash_phy_rsp.erase_done) + ); + + + // software interface feedback + // most values (other than flash_phy_busy) should only update when software operations + // are actually selected + assign hw2reg.op_status.done.d = 1'b1; + assign hw2reg.op_status.done.de = sw_ctrl_done; + assign hw2reg.op_status.err.d = 1'b1; + assign hw2reg.op_status.err.de = |sw_ctrl_err; + assign hw2reg.status.rd_full.d = sw_rfifo_full; + assign hw2reg.status.rd_full.de = sw_sel; + assign hw2reg.status.rd_empty.d = ~sw_rfifo_rvalid; + assign hw2reg.status.rd_empty.de = sw_sel; + assign hw2reg.status.prog_full.d = ~prog_fifo_wready; + assign hw2reg.status.prog_full.de = sw_sel; + assign hw2reg.status.prog_empty.d = ~prog_fifo_rvalid; + assign hw2reg.status.prog_empty.de = sw_sel; + assign hw2reg.status.init_wip.d = flash_phy_busy | ctrl_init_busy; + assign hw2reg.status.init_wip.de = 1'b1; + assign hw2reg.status.initialized.d = ctrl_initialized & ~flash_phy_busy; + assign hw2reg.status.initialized.de = 1'b1; + assign hw2reg.control.start.d = 1'b0; + assign hw2reg.control.start.de = sw_ctrl_done; + // if software operation selected, based on transaction start + // if software operation not selected, software is free to change contents + assign hw2reg.ctrl_regwen.d = sw_sel ? !op_start : 1'b1; + + // phy status + assign hw2reg.phy_status.init_wip.d = flash_phy_busy; + assign hw2reg.phy_status.init_wip.de = 1'b1; + assign hw2reg.phy_status.prog_normal_avail.d = flash_phy_rsp.prog_type_avail[FlashProgNormal]; + assign hw2reg.phy_status.prog_normal_avail.de = 1'b1; + assign hw2reg.phy_status.prog_repair_avail.d = flash_phy_rsp.prog_type_avail[FlashProgRepair]; + assign hw2reg.phy_status.prog_repair_avail.de = 1'b1; + + // Flash Interface + assign flash_phy_req.addr = flash_addr; + assign flash_phy_req.part = flash_part_sel; + assign flash_phy_req.info_sel = flash_info_sel; + assign flash_phy_req.prog_type = flash_prog_type; + assign flash_phy_req.prog_data = flash_prog_data; + assign flash_phy_req.prog_last = flash_prog_last; + assign flash_phy_req.region_cfgs = region_cfgs; + assign flash_phy_req.addr_key = addr_key; + assign flash_phy_req.data_key = data_key; + assign flash_phy_req.rand_addr_key = rand_addr_key; + assign flash_phy_req.rand_data_key = rand_data_key; + assign flash_phy_req.alert_trig = reg2hw.phy_alert_cfg.alert_trig.q; + assign flash_phy_req.alert_ack = reg2hw.phy_alert_cfg.alert_ack.q; + assign flash_phy_req.jtag_req.tck = cio_tck_i; + assign flash_phy_req.jtag_req.tms = cio_tms_i; + assign flash_phy_req.jtag_req.tdi = cio_tdi_i; + assign flash_phy_req.jtag_req.trst_n = '0; + assign cio_tdo_o = flash_phy_rsp.jtag_rsp.tdo; + assign cio_tdo_en_o = flash_phy_rsp.jtag_rsp.tdo_oe; + assign flash_rd_err = flash_phy_rsp.rd_err; + assign flash_rd_data = flash_phy_rsp.rd_data; + assign flash_phy_busy = flash_phy_rsp.init_busy; + + + // Interface to pwrmgr + // flash is not idle as long as there is a stateful operation ongoing + logic flash_idle_d; + assign flash_idle_d = ~(flash_phy_req.req & + (flash_phy_req.prog | flash_phy_req.pg_erase | flash_phy_req.bk_erase)); + + prim_flop #( + .Width(1), + .ResetValue(1'b1) + ) u_reg_idle ( + .clk_i, + .rst_ni, + .d_i(flash_idle_d), + .q_o(pwrmgr_o.flash_idle) + ); + + ////////////////////////////////////// + // Alert senders + ////////////////////////////////////// + + + logic [NumAlerts-1:0] alert_srcs; + logic [NumAlerts-1:0] alert_tests; + logic fatal_prim_flash_alert, recov_prim_flash_alert; + + // An excessive number of recoverable errors may also indicate an attack + logic recov_err; + assign recov_err = (sw_ctrl_done & |sw_ctrl_err) | + flash_phy_rsp.macro_err | + update_err; + + logic fatal_err; + assign fatal_err = |reg2hw.fault_status; + + logic fatal_std_err; + assign fatal_std_err = |reg2hw.std_fault_status; + + lc_ctrl_pkg::lc_tx_t local_esc; + assign local_esc = lc_ctrl_pkg::lc_tx_bool_to_lc_tx(fatal_std_err); + + assign alert_srcs = { + recov_prim_flash_alert, + fatal_prim_flash_alert, + fatal_err, + fatal_std_err, + recov_err + }; + + assign alert_tests = { + reg2hw.alert_test.recov_prim_flash_alert.q & reg2hw.alert_test.recov_prim_flash_alert.qe, + reg2hw.alert_test.fatal_prim_flash_alert.q & reg2hw.alert_test.fatal_prim_flash_alert.qe, + reg2hw.alert_test.fatal_err.q & reg2hw.alert_test.fatal_err.qe, + reg2hw.alert_test.fatal_std_err.q & reg2hw.alert_test.fatal_std_err.qe, + reg2hw.alert_test.recov_err.q & reg2hw.alert_test.recov_err.qe + }; + + // The alert generated for errors reported in the fault status CSR (fatal_err) is not fatal. + // This is to enable firmware dealing with multi-bit ECC errors (phy_relbl_err) as well as ICV + // (phy_storage_err) errors inside the PHY during firmware selection and verification. + // Once firmware has cleared the corresponding bits in the fault status CSR and the alert + // handler has acknowledged the alert, the prim_alert_sender will stop triggering the alert. + // After firmware has passed the firmware selection / verification stage, the alert handler + // config can be adjusted to still classify the alert as fatal on the receiver side. + // + // This doesn't hold for the other errors conditions reported in the fault status CSR. The + // corresponding bits in the register cannot be unset. The alert thus keeps triggering until + // reset for these bits. + // + // For more details, refer to lowRISC/OpenTitan#21353. + localparam logic [NumAlerts-1:0] IsFatal = {1'b0, 1'b1, 1'b0, 1'b1, 1'b0}; + for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_senders + prim_alert_sender #( + .AsyncOn(AlertAsyncOn[i]), + .IsFatal(IsFatal[i]) + ) u_alert_sender ( + .clk_i, + .rst_ni, + .alert_req_i(alert_srcs[i]), + .alert_test_i(alert_tests[i]), + .alert_ack_o(), + .alert_state_o(), + .alert_rx_i(alert_rx_i[i]), + .alert_tx_o(alert_tx_o[i]) + ); + end + + ////////////////////////////////////// + // Flash Disable and execute enable + ////////////////////////////////////// + + prim_lc_sync #( + .NumCopies(1) + ) u_lc_escalation_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_escalate_en_i), + .lc_en_o({lc_escalate_en}) + ); + + lc_ctrl_pkg::lc_tx_t escalate_en; + // SEC_CM: MEM.CTRL.LOCAL_ESC + assign escalate_en = lc_ctrl_pkg::lc_tx_or_hi(dis_access, local_esc); + + // flash functional disable + lc_ctrl_pkg::lc_tx_t lc_disable; + assign lc_disable = lc_ctrl_pkg::lc_tx_or_hi(lc_escalate_en, escalate_en); + + // Normally, faults (those registered in fault_status) should also cause flash access + // to disable. However, most errors encountered by hardware during flash access + // are registered as faults (since they functionally never happen). Out of an abundance + // of caution for the first iteration, we will not kill flash access based on those + // faults immediately just in case there are unexpected corner conditions. + // In other words...cowardice. + // SEC_CM: MEM.CTRL.GLOBAL_ESC + // SEC_CM: MEM_DISABLE.CONFIG.MUBI + mubi4_t lc_conv_disable; + mubi4_t flash_disable_pre_buf; + assign lc_conv_disable = lc_ctrl_pkg::lc_to_mubi4(lc_disable); + assign flash_disable_pre_buf = prim_mubi_pkg::mubi4_or_hi( + lc_conv_disable, + mubi4_t'(reg2hw.dis.q)); + + prim_mubi4_sync #( + .NumCopies(int'(FlashDisableLast)), + .AsyncOn(0) + ) u_disable_buf ( + .clk_i, + .rst_ni, + .mubi_i(flash_disable_pre_buf), + .mubi_o(flash_disable) + ); + + assign flash_phy_req.flash_disable = flash_disable[PhyDisableIdx]; + + logic [prim_mubi_pkg::MuBi4Width-1:0] sw_flash_exec_en; + mubi4_t flash_exec_en; + + // SEC_CM: EXEC.CONFIG.REDUN + prim_sec_anchor_buf #( + .Width(prim_mubi_pkg::MuBi4Width) + ) u_exec_en_buf ( + .in_i(prim_mubi_pkg::mubi4_bool_to_mubi(reg2hw.exec.q == unsigned'(ExecEn))), + .out_o(sw_flash_exec_en) + ); + + mubi4_t disable_exec; + assign disable_exec = mubi4_t'(~flash_disable[IFetchDisableIdx]); + assign flash_exec_en = prim_mubi_pkg::mubi4_and_hi( + disable_exec, + mubi4_t'(sw_flash_exec_en) + ); + + ////////////////////////////////////// + // Errors and Interrupts + ////////////////////////////////////// + + // all software interface errors are treated as synchronous errors + assign hw2reg.err_code.op_err.d = 1'b1; + assign hw2reg.err_code.mp_err.d = 1'b1; + assign hw2reg.err_code.rd_err.d = 1'b1; + assign hw2reg.err_code.prog_err.d = 1'b1; + assign hw2reg.err_code.prog_win_err.d = 1'b1; + assign hw2reg.err_code.prog_type_err.d = 1'b1; + assign hw2reg.err_code.update_err.d = 1'b1; + assign hw2reg.err_code.macro_err.d = 1'b1; + assign hw2reg.err_code.op_err.de = sw_ctrl_err.invalid_op_err; + assign hw2reg.err_code.mp_err.de = sw_ctrl_err.mp_err; + assign hw2reg.err_code.rd_err.de = sw_ctrl_err.rd_err; + assign hw2reg.err_code.prog_err.de = sw_ctrl_err.prog_err; + assign hw2reg.err_code.prog_win_err.de = sw_ctrl_err.prog_win_err; + assign hw2reg.err_code.prog_type_err.de = sw_ctrl_err.prog_type_err; + assign hw2reg.err_code.update_err.de = update_err; + assign hw2reg.err_code.macro_err.de = flash_phy_rsp.macro_err; + assign hw2reg.err_addr.d = {ctrl_err_addr, {BusByteWidth{1'h0}}}; + assign hw2reg.err_addr.de = sw_ctrl_err.mp_err | + sw_ctrl_err.rd_err | + sw_ctrl_err.prog_err; + + + // all hardware interface errors are considered faults + // There are two types of faults + // standard faults - things like fsm / counter / tlul integrity + // custom faults - things like hardware interface not working correctly + assign hw2reg.fault_status.op_err.d = 1'b1; + assign hw2reg.fault_status.mp_err.d = 1'b1; + assign hw2reg.fault_status.rd_err.d = 1'b1; + assign hw2reg.fault_status.prog_err.d = 1'b1; + assign hw2reg.fault_status.prog_win_err.d = 1'b1; + assign hw2reg.fault_status.prog_type_err.d = 1'b1; + assign hw2reg.fault_status.seed_err.d = 1'b1; + assign hw2reg.fault_status.phy_relbl_err.d = 1'b1; + assign hw2reg.fault_status.phy_storage_err.d = 1'b1; + assign hw2reg.fault_status.spurious_ack.d = 1'b1; + assign hw2reg.fault_status.arb_err.d = 1'b1; + assign hw2reg.fault_status.host_gnt_err.d = 1'b1; + assign hw2reg.fault_status.op_err.de = hw_err.invalid_op_err; + assign hw2reg.fault_status.mp_err.de = hw_err.mp_err; + assign hw2reg.fault_status.rd_err.de = hw_err.rd_err; + assign hw2reg.fault_status.prog_err.de = hw_err.prog_err; + assign hw2reg.fault_status.prog_win_err.de = hw_err.prog_win_err; + assign hw2reg.fault_status.prog_type_err.de = hw_err.prog_type_err; + assign hw2reg.fault_status.seed_err.de = seed_err; + assign hw2reg.fault_status.phy_relbl_err.de = flash_phy_rsp.storage_relbl_err; + assign hw2reg.fault_status.phy_storage_err.de = flash_phy_rsp.storage_intg_err; + assign hw2reg.fault_status.spurious_ack.de = flash_phy_rsp.spurious_ack; + assign hw2reg.fault_status.arb_err.de = flash_phy_rsp.arb_err; + assign hw2reg.fault_status.host_gnt_err.de = flash_phy_rsp.host_gnt_err; + + // standard faults + assign hw2reg.std_fault_status.reg_intg_err.d = 1'b1; + assign hw2reg.std_fault_status.prog_intg_err.d = 1'b1; + assign hw2reg.std_fault_status.lcmgr_err.d = 1'b1; + assign hw2reg.std_fault_status.lcmgr_intg_err.d = 1'b1; + assign hw2reg.std_fault_status.arb_fsm_err.d = 1'b1; + assign hw2reg.std_fault_status.storage_err.d = 1'b1; + assign hw2reg.std_fault_status.phy_fsm_err.d = 1'b1; + assign hw2reg.std_fault_status.ctrl_cnt_err.d = 1'b1; + assign hw2reg.std_fault_status.fifo_err.d = 1'b1; + assign hw2reg.std_fault_status.reg_intg_err.de = intg_err | eflash_cmd_intg_err | + tl_gate_intg_err | tl_prog_gate_intg_err; + assign hw2reg.std_fault_status.prog_intg_err.de = flash_phy_rsp.prog_intg_err; + assign hw2reg.std_fault_status.lcmgr_err.de = lcmgr_err; + assign hw2reg.std_fault_status.lcmgr_intg_err.de = lcmgr_intg_err; + assign hw2reg.std_fault_status.arb_fsm_err.de = arb_fsm_err; + assign hw2reg.std_fault_status.storage_err.de = storage_err; + assign hw2reg.std_fault_status.phy_fsm_err.de = flash_phy_rsp.fsm_err; + assign hw2reg.std_fault_status.ctrl_cnt_err.de = rd_cnt_err | prog_cnt_err; + assign hw2reg.std_fault_status.fifo_err.de = flash_phy_rsp.fifo_err | adapter_fifo_err; + + // Correctable ECC count / address + for (genvar i = 0; i < NumBanks; i++) begin : gen_ecc_single_err_reg + assign hw2reg.ecc_single_err_cnt[i].de = flash_phy_rsp.ecc_single_err[i]; + assign hw2reg.ecc_single_err_cnt[i].d = ®2hw.ecc_single_err_cnt[i].q ? + reg2hw.ecc_single_err_cnt[i].q : + reg2hw.ecc_single_err_cnt[i].q + 1'b1; + + assign hw2reg.ecc_single_err_addr[i].de = flash_phy_rsp.ecc_single_err[i]; + assign hw2reg.ecc_single_err_addr[i].d = {flash_phy_rsp.ecc_addr[i], {BusByteWidth{1'b0}}}; + end + + logic [LastIntrIdx-1:0] intr_event; + // Status types + assign intr_event[ProgEmpty] = !prog_fifo_rvalid; + // Check whether this FIFO has been drained to a certain level. + assign intr_event[ProgLvl] = reg2hw.fifo_lvl.prog.q >= MaxFifoWidth'(prog_fifo_depth); + assign intr_event[RdFull] = sw_rfifo_full; + // Check whether this FIFO has been filled to a certain level. + assign intr_event[RdLvl] = reg2hw.fifo_lvl.rd.q <= sw_rfifo_depth; + // Event types + assign intr_event[OpDone] = sw_ctrl_done; + assign intr_event[CorrErr] = |flash_phy_rsp.ecc_single_err; + + prim_intr_hw #( + .Width(1), + .IntrT ("Status") + ) u_intr_prog_empty ( + .clk_i, + .rst_ni, + .event_intr_i (intr_event[ProgEmpty]), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.prog_empty.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.prog_empty.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.prog_empty.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.prog_empty.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.prog_empty.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.prog_empty.d), + .intr_o (intr_prog_empty_o) + ); + + prim_intr_hw #( + .Width(1), + .IntrT ("Status") + ) u_intr_prog_lvl ( + .clk_i, + .rst_ni, + .event_intr_i (intr_event[ProgLvl]), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.prog_lvl.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.prog_lvl.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.prog_lvl.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.prog_lvl.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.prog_lvl.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.prog_lvl.d), + .intr_o (intr_prog_lvl_o) + ); + + prim_intr_hw #( + .Width(1), + .IntrT ("Status") + ) u_intr_rd_full ( + .clk_i, + .rst_ni, + .event_intr_i (intr_event[RdFull]), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rd_full.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.rd_full.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.rd_full.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.rd_full.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.rd_full.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.rd_full.d), + .intr_o (intr_rd_full_o) + ); + + prim_intr_hw #( + .Width(1), + .IntrT ("Status") + ) u_intr_rd_lvl ( + .clk_i, + .rst_ni, + .event_intr_i (intr_event[RdLvl]), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.rd_lvl.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.rd_lvl.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.rd_lvl.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.rd_lvl.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.rd_lvl.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.rd_lvl.d), + .intr_o (intr_rd_lvl_o) + ); + + prim_intr_hw #( + .Width(1), + .IntrT ("Event") + ) u_intr_op_done ( + .clk_i, + .rst_ni, + .event_intr_i (intr_event[OpDone]), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.op_done.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.op_done.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.op_done.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.op_done.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.op_done.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.op_done.d), + .intr_o (intr_op_done_o) + ); + + prim_intr_hw #( + .Width(1), + .IntrT ("Event") + ) u_intr_corr_err ( + .clk_i, + .rst_ni, + .event_intr_i (intr_event[CorrErr]), + .reg2hw_intr_enable_q_i (reg2hw.intr_enable.corr_err.q), + .reg2hw_intr_test_q_i (reg2hw.intr_test.corr_err.q), + .reg2hw_intr_test_qe_i (reg2hw.intr_test.corr_err.qe), + .reg2hw_intr_state_q_i (reg2hw.intr_state.corr_err.q), + .hw2reg_intr_state_de_o (hw2reg.intr_state.corr_err.de), + .hw2reg_intr_state_d_o (hw2reg.intr_state.corr_err.d), + .intr_o (intr_corr_err_o) + ); + + // Unused bits + logic [BusByteWidth-1:0] unused_byte_sel; + logic [top_pkg::TL_AW-1:0] unused_scratch; + + // Unused signals + assign unused_byte_sel = muxed_addr[BusByteWidth-1:0]; + assign unused_scratch = reg2hw.scratch; + + + ////////////////////////////////////// + // flash phy module + ////////////////////////////////////// + logic flash_host_req; + logic flash_host_req_rdy; + logic flash_host_req_done; + logic flash_host_rderr; + logic [flash_ctrl_pkg::BusFullWidth-1:0] flash_host_rdata; + logic [flash_ctrl_pkg::BusAddrW-1:0] flash_host_addr; + + lc_ctrl_pkg::lc_tx_t host_enable; + + // if flash disable is activated, error back from the adapter interface immediately + assign host_enable = lc_ctrl_pkg::mubi4_to_lc_inv(flash_disable[HostDisableIdx]); + + tlul_pkg::tl_h2d_t gate_tl_h2d; + tlul_pkg::tl_d2h_t gate_tl_d2h; + + // SEC_CM: MEM_TL_LC_GATE.FSM.SPARSE + tlul_lc_gate u_tl_gate ( + .clk_i, + .rst_ni, + .tl_h2d_i(mem_tl_i), + .tl_d2h_o(mem_tl_o), + .tl_h2d_o(gate_tl_h2d), + .tl_d2h_i(gate_tl_d2h), + .flush_req_i('0), + .flush_ack_o(), + .resp_pending_o(), + .lc_en_i(host_enable), + .err_o(tl_gate_intg_err) + ); + + // SEC_CM: HOST.BUS.INTEGRITY + // SEC_CM: MEM.ADDR_INFECTION + tlul_adapter_sram #( + .SramAw(BusAddrW), + .SramDw(BusWidth), + .SramBusBankAW(BusBankAddrW), + .Outstanding(2), + .ByteAccess(0), + .ErrOnWrite(1), + .CmdIntgCheck(1), + .EnableRspIntgGen(1), + .EnableDataIntgGen(0), + .EnableDataIntgPt(1), + .SecFifoPtr(1), + .DataXorAddr(1) + ) u_tl_adapter_eflash ( + .clk_i, + .rst_ni, + .tl_i (gate_tl_h2d), + .tl_o (gate_tl_d2h), + .en_ifetch_i (flash_exec_en), + .req_o (flash_host_req), + .req_type_o (), + .gnt_i (flash_host_req_rdy), + .we_o (), + .addr_o (flash_host_addr), + .wdata_o (), + .wmask_o (), + .intg_error_o (eflash_cmd_intg_err), + .user_rsvd_o (), + .rdata_i (flash_host_rdata), + .rvalid_i (flash_host_req_done), + .rerror_i ({flash_host_rderr,1'b0}), + .compound_txn_in_progress_o (), + .readback_en_i (prim_mubi_pkg::MuBi4False), + .readback_error_o (), + .wr_collision_i (1'b0), + .write_pending_i (1'b0) + ); + + flash_phy #( + .SecScrambleEn(SecScrambleEn) + ) u_eflash ( + .clk_i, + .rst_ni, + .host_req_i (flash_host_req), + .host_addr_i (flash_host_addr), + .host_req_rdy_o (flash_host_req_rdy), + .host_req_done_o (flash_host_req_done), + .host_rderr_o (flash_host_rderr), + .host_rdata_o (flash_host_rdata), + .flash_ctrl_i (flash_phy_req), + .flash_ctrl_o (flash_phy_rsp), + .tl_i (prim_tl_i), + .tl_o (prim_tl_o), + .obs_ctrl_i, + .fla_obs_o, + .lc_nvm_debug_en_i, + .flash_bist_enable_i, + .flash_power_down_h_i, + .flash_power_ready_h_i, + .flash_test_mode_a_io, + .flash_test_voltage_h_io, + .fatal_prim_flash_alert_o(fatal_prim_flash_alert), + .recov_prim_flash_alert_o(recov_prim_flash_alert), + .scanmode_i, + .scan_en_i, + .scan_rst_ni + ); + + ///////////////////////////////// + // Assertions + ///////////////////////////////// + + `ASSERT_KNOWN(TlDValidKnownO_A, core_tl_o.d_valid ) + `ASSERT_KNOWN(TlAReadyKnownO_A, core_tl_o.a_ready ) + `ASSERT_KNOWN_IF(RspPayLoad_A, core_tl_o, core_tl_o.d_valid) + `ASSERT_KNOWN(PrimTlDValidKnownO_A, prim_tl_o.d_valid ) + `ASSERT_KNOWN(PrimTlAReadyKnownO_A, prim_tl_o.a_ready ) + `ASSERT_KNOWN_IF(PrimRspPayLoad_A, prim_tl_o, prim_tl_o.d_valid) + `ASSERT_KNOWN(MemTlDValidKnownO_A, mem_tl_o.d_valid ) + `ASSERT_KNOWN(MemTlAReadyKnownO_A, mem_tl_o.a_ready ) + `ASSERT_KNOWN_IF(MemRspPayLoad_A, mem_tl_o, mem_tl_o.d_valid) + `ASSERT_KNOWN(FlashKnownO_A, {flash_phy_req.req, flash_phy_req.rd, + flash_phy_req.prog, flash_phy_req.pg_erase, + flash_phy_req.bk_erase}) + `ASSERT_KNOWN_IF(FlashAddrKnown_A, flash_phy_req.addr, flash_phy_req.req) + `ASSERT_KNOWN_IF(FlashProgKnown_A, flash_phy_req.prog_data, + flash_phy_req.prog & flash_phy_req.req) + `ASSERT_KNOWN(IntrProgEmptyKnownO_A, intr_prog_empty_o) + `ASSERT_KNOWN(IntrProgLvlKnownO_A, intr_prog_lvl_o ) + `ASSERT_KNOWN(IntrProgRdFullKnownO_A, intr_rd_full_o ) + `ASSERT_KNOWN(IntrRdLvlKnownO_A, intr_rd_lvl_o ) + `ASSERT_KNOWN(IntrOpDoneKnownO_A, intr_op_done_o ) + `ASSERT_KNOWN(IntrErrO_A, intr_corr_err_o ) + `ASSERT_KNOWN(TdoKnown_A, cio_tdo_o ) + `ASSERT(TdoEnIsOne_A, cio_tdo_en_o === 1'b1) + + // combined indication that an operation has started + // This is used only for assertions + logic unused_op_valid; + assign unused_op_valid = prog_op_valid | rd_op_valid | erase_op_valid; + + // add more assertions + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(SeedCntAlertCheck_A, u_flash_hw_if.u_seed_cnt, + alert_tx_o[1]) + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(AddrCntAlertCheck_A, u_flash_hw_if.u_addr_cnt, + alert_tx_o[1]) + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(PageCntAlertCheck_A, u_flash_hw_if.u_page_cnt, + alert_tx_o[1]) + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(WordCntAlertCheck_A, u_flash_hw_if.u_word_cnt, + alert_tx_o[1]) + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(WipeIdx_A, u_flash_hw_if.u_wipe_idx_cnt, + alert_tx_o[1]) + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(ProgCnt_A, u_flash_ctrl_prog.u_cnt, + alert_tx_o[1]) + `ASSERT_PRIM_COUNT_ERROR_TRIGGER_ALERT(RdCnt_A, u_flash_ctrl_rd.u_cnt, + alert_tx_o[1]) + + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(LcCtrlFsmCheck_A, + u_flash_hw_if.u_state_regs, alert_tx_o[1]) + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(LcCtrlRmaFsmCheck_A, + u_flash_hw_if.u_rma_state_regs, alert_tx_o[1]) + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(ArbFsmCheck_A, + u_ctrl_arb.u_state_regs, alert_tx_o[1]) + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(TlLcGateFsm_A, + u_tl_gate.u_state_regs, alert_tx_o[1]) + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT(TlProgLcGateFsm_A, + u_prog_tl_gate.u_state_regs, alert_tx_o[1]) + + for (genvar i=0; i__{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic intr_state_we; + logic intr_state_prog_empty_qs; + logic intr_state_prog_lvl_qs; + logic intr_state_rd_full_qs; + logic intr_state_rd_lvl_qs; + logic intr_state_op_done_qs; + logic intr_state_op_done_wd; + logic intr_state_corr_err_qs; + logic intr_state_corr_err_wd; + logic intr_enable_we; + logic intr_enable_prog_empty_qs; + logic intr_enable_prog_empty_wd; + logic intr_enable_prog_lvl_qs; + logic intr_enable_prog_lvl_wd; + logic intr_enable_rd_full_qs; + logic intr_enable_rd_full_wd; + logic intr_enable_rd_lvl_qs; + logic intr_enable_rd_lvl_wd; + logic intr_enable_op_done_qs; + logic intr_enable_op_done_wd; + logic intr_enable_corr_err_qs; + logic intr_enable_corr_err_wd; + logic intr_test_we; + logic intr_test_prog_empty_wd; + logic intr_test_prog_lvl_wd; + logic intr_test_rd_full_wd; + logic intr_test_rd_lvl_wd; + logic intr_test_op_done_wd; + logic intr_test_corr_err_wd; + logic alert_test_we; + logic alert_test_recov_err_wd; + logic alert_test_fatal_std_err_wd; + logic alert_test_fatal_err_wd; + logic alert_test_fatal_prim_flash_alert_wd; + logic alert_test_recov_prim_flash_alert_wd; + logic dis_we; + logic [3:0] dis_qs; + logic [3:0] dis_wd; + logic exec_we; + logic [31:0] exec_qs; + logic [31:0] exec_wd; + logic init_we; + logic init_qs; + logic init_wd; + logic ctrl_regwen_re; + logic ctrl_regwen_qs; + logic control_we; + logic control_start_qs; + logic control_start_wd; + logic [1:0] control_op_qs; + logic [1:0] control_op_wd; + logic control_prog_sel_qs; + logic control_prog_sel_wd; + logic control_erase_sel_qs; + logic control_erase_sel_wd; + logic control_partition_sel_qs; + logic control_partition_sel_wd; + logic [1:0] control_info_sel_qs; + logic [1:0] control_info_sel_wd; + logic [11:0] control_num_qs; + logic [11:0] control_num_wd; + logic addr_we; + logic [15:0] addr_qs; + logic [15:0] addr_wd; + logic prog_type_en_we; + logic prog_type_en_normal_qs; + logic prog_type_en_normal_wd; + logic prog_type_en_repair_qs; + logic prog_type_en_repair_wd; + logic erase_suspend_we; + logic erase_suspend_qs; + logic erase_suspend_wd; + logic region_cfg_regwen_0_we; + logic region_cfg_regwen_0_qs; + logic region_cfg_regwen_0_wd; + logic region_cfg_regwen_1_we; + logic region_cfg_regwen_1_qs; + logic region_cfg_regwen_1_wd; + logic region_cfg_regwen_2_we; + logic region_cfg_regwen_2_qs; + logic region_cfg_regwen_2_wd; + logic region_cfg_regwen_3_we; + logic region_cfg_regwen_3_qs; + logic region_cfg_regwen_3_wd; + logic region_cfg_regwen_4_we; + logic region_cfg_regwen_4_qs; + logic region_cfg_regwen_4_wd; + logic region_cfg_regwen_5_we; + logic region_cfg_regwen_5_qs; + logic region_cfg_regwen_5_wd; + logic region_cfg_regwen_6_we; + logic region_cfg_regwen_6_qs; + logic region_cfg_regwen_6_wd; + logic region_cfg_regwen_7_we; + logic region_cfg_regwen_7_qs; + logic region_cfg_regwen_7_wd; + logic mp_region_cfg_0_we; + logic [3:0] mp_region_cfg_0_en_0_qs; + logic [3:0] mp_region_cfg_0_en_0_wd; + logic [3:0] mp_region_cfg_0_rd_en_0_qs; + logic [3:0] mp_region_cfg_0_rd_en_0_wd; + logic [3:0] mp_region_cfg_0_prog_en_0_qs; + logic [3:0] mp_region_cfg_0_prog_en_0_wd; + logic [3:0] mp_region_cfg_0_erase_en_0_qs; + logic [3:0] mp_region_cfg_0_erase_en_0_wd; + logic [3:0] mp_region_cfg_0_scramble_en_0_qs; + logic [3:0] mp_region_cfg_0_scramble_en_0_wd; + logic [3:0] mp_region_cfg_0_ecc_en_0_qs; + logic [3:0] mp_region_cfg_0_ecc_en_0_wd; + logic [3:0] mp_region_cfg_0_he_en_0_qs; + logic [3:0] mp_region_cfg_0_he_en_0_wd; + logic mp_region_cfg_1_we; + logic [3:0] mp_region_cfg_1_en_1_qs; + logic [3:0] mp_region_cfg_1_en_1_wd; + logic [3:0] mp_region_cfg_1_rd_en_1_qs; + logic [3:0] mp_region_cfg_1_rd_en_1_wd; + logic [3:0] mp_region_cfg_1_prog_en_1_qs; + logic [3:0] mp_region_cfg_1_prog_en_1_wd; + logic [3:0] mp_region_cfg_1_erase_en_1_qs; + logic [3:0] mp_region_cfg_1_erase_en_1_wd; + logic [3:0] mp_region_cfg_1_scramble_en_1_qs; + logic [3:0] mp_region_cfg_1_scramble_en_1_wd; + logic [3:0] mp_region_cfg_1_ecc_en_1_qs; + logic [3:0] mp_region_cfg_1_ecc_en_1_wd; + logic [3:0] mp_region_cfg_1_he_en_1_qs; + logic [3:0] mp_region_cfg_1_he_en_1_wd; + logic mp_region_cfg_2_we; + logic [3:0] mp_region_cfg_2_en_2_qs; + logic [3:0] mp_region_cfg_2_en_2_wd; + logic [3:0] mp_region_cfg_2_rd_en_2_qs; + logic [3:0] mp_region_cfg_2_rd_en_2_wd; + logic [3:0] mp_region_cfg_2_prog_en_2_qs; + logic [3:0] mp_region_cfg_2_prog_en_2_wd; + logic [3:0] mp_region_cfg_2_erase_en_2_qs; + logic [3:0] mp_region_cfg_2_erase_en_2_wd; + logic [3:0] mp_region_cfg_2_scramble_en_2_qs; + logic [3:0] mp_region_cfg_2_scramble_en_2_wd; + logic [3:0] mp_region_cfg_2_ecc_en_2_qs; + logic [3:0] mp_region_cfg_2_ecc_en_2_wd; + logic [3:0] mp_region_cfg_2_he_en_2_qs; + logic [3:0] mp_region_cfg_2_he_en_2_wd; + logic mp_region_cfg_3_we; + logic [3:0] mp_region_cfg_3_en_3_qs; + logic [3:0] mp_region_cfg_3_en_3_wd; + logic [3:0] mp_region_cfg_3_rd_en_3_qs; + logic [3:0] mp_region_cfg_3_rd_en_3_wd; + logic [3:0] mp_region_cfg_3_prog_en_3_qs; + logic [3:0] mp_region_cfg_3_prog_en_3_wd; + logic [3:0] mp_region_cfg_3_erase_en_3_qs; + logic [3:0] mp_region_cfg_3_erase_en_3_wd; + logic [3:0] mp_region_cfg_3_scramble_en_3_qs; + logic [3:0] mp_region_cfg_3_scramble_en_3_wd; + logic [3:0] mp_region_cfg_3_ecc_en_3_qs; + logic [3:0] mp_region_cfg_3_ecc_en_3_wd; + logic [3:0] mp_region_cfg_3_he_en_3_qs; + logic [3:0] mp_region_cfg_3_he_en_3_wd; + logic mp_region_cfg_4_we; + logic [3:0] mp_region_cfg_4_en_4_qs; + logic [3:0] mp_region_cfg_4_en_4_wd; + logic [3:0] mp_region_cfg_4_rd_en_4_qs; + logic [3:0] mp_region_cfg_4_rd_en_4_wd; + logic [3:0] mp_region_cfg_4_prog_en_4_qs; + logic [3:0] mp_region_cfg_4_prog_en_4_wd; + logic [3:0] mp_region_cfg_4_erase_en_4_qs; + logic [3:0] mp_region_cfg_4_erase_en_4_wd; + logic [3:0] mp_region_cfg_4_scramble_en_4_qs; + logic [3:0] mp_region_cfg_4_scramble_en_4_wd; + logic [3:0] mp_region_cfg_4_ecc_en_4_qs; + logic [3:0] mp_region_cfg_4_ecc_en_4_wd; + logic [3:0] mp_region_cfg_4_he_en_4_qs; + logic [3:0] mp_region_cfg_4_he_en_4_wd; + logic mp_region_cfg_5_we; + logic [3:0] mp_region_cfg_5_en_5_qs; + logic [3:0] mp_region_cfg_5_en_5_wd; + logic [3:0] mp_region_cfg_5_rd_en_5_qs; + logic [3:0] mp_region_cfg_5_rd_en_5_wd; + logic [3:0] mp_region_cfg_5_prog_en_5_qs; + logic [3:0] mp_region_cfg_5_prog_en_5_wd; + logic [3:0] mp_region_cfg_5_erase_en_5_qs; + logic [3:0] mp_region_cfg_5_erase_en_5_wd; + logic [3:0] mp_region_cfg_5_scramble_en_5_qs; + logic [3:0] mp_region_cfg_5_scramble_en_5_wd; + logic [3:0] mp_region_cfg_5_ecc_en_5_qs; + logic [3:0] mp_region_cfg_5_ecc_en_5_wd; + logic [3:0] mp_region_cfg_5_he_en_5_qs; + logic [3:0] mp_region_cfg_5_he_en_5_wd; + logic mp_region_cfg_6_we; + logic [3:0] mp_region_cfg_6_en_6_qs; + logic [3:0] mp_region_cfg_6_en_6_wd; + logic [3:0] mp_region_cfg_6_rd_en_6_qs; + logic [3:0] mp_region_cfg_6_rd_en_6_wd; + logic [3:0] mp_region_cfg_6_prog_en_6_qs; + logic [3:0] mp_region_cfg_6_prog_en_6_wd; + logic [3:0] mp_region_cfg_6_erase_en_6_qs; + logic [3:0] mp_region_cfg_6_erase_en_6_wd; + logic [3:0] mp_region_cfg_6_scramble_en_6_qs; + logic [3:0] mp_region_cfg_6_scramble_en_6_wd; + logic [3:0] mp_region_cfg_6_ecc_en_6_qs; + logic [3:0] mp_region_cfg_6_ecc_en_6_wd; + logic [3:0] mp_region_cfg_6_he_en_6_qs; + logic [3:0] mp_region_cfg_6_he_en_6_wd; + logic mp_region_cfg_7_we; + logic [3:0] mp_region_cfg_7_en_7_qs; + logic [3:0] mp_region_cfg_7_en_7_wd; + logic [3:0] mp_region_cfg_7_rd_en_7_qs; + logic [3:0] mp_region_cfg_7_rd_en_7_wd; + logic [3:0] mp_region_cfg_7_prog_en_7_qs; + logic [3:0] mp_region_cfg_7_prog_en_7_wd; + logic [3:0] mp_region_cfg_7_erase_en_7_qs; + logic [3:0] mp_region_cfg_7_erase_en_7_wd; + logic [3:0] mp_region_cfg_7_scramble_en_7_qs; + logic [3:0] mp_region_cfg_7_scramble_en_7_wd; + logic [3:0] mp_region_cfg_7_ecc_en_7_qs; + logic [3:0] mp_region_cfg_7_ecc_en_7_wd; + logic [3:0] mp_region_cfg_7_he_en_7_qs; + logic [3:0] mp_region_cfg_7_he_en_7_wd; + logic mp_region_0_we; + logic [4:0] mp_region_0_base_0_qs; + logic [4:0] mp_region_0_base_0_wd; + logic [5:0] mp_region_0_size_0_qs; + logic [5:0] mp_region_0_size_0_wd; + logic mp_region_1_we; + logic [4:0] mp_region_1_base_1_qs; + logic [4:0] mp_region_1_base_1_wd; + logic [5:0] mp_region_1_size_1_qs; + logic [5:0] mp_region_1_size_1_wd; + logic mp_region_2_we; + logic [4:0] mp_region_2_base_2_qs; + logic [4:0] mp_region_2_base_2_wd; + logic [5:0] mp_region_2_size_2_qs; + logic [5:0] mp_region_2_size_2_wd; + logic mp_region_3_we; + logic [4:0] mp_region_3_base_3_qs; + logic [4:0] mp_region_3_base_3_wd; + logic [5:0] mp_region_3_size_3_qs; + logic [5:0] mp_region_3_size_3_wd; + logic mp_region_4_we; + logic [4:0] mp_region_4_base_4_qs; + logic [4:0] mp_region_4_base_4_wd; + logic [5:0] mp_region_4_size_4_qs; + logic [5:0] mp_region_4_size_4_wd; + logic mp_region_5_we; + logic [4:0] mp_region_5_base_5_qs; + logic [4:0] mp_region_5_base_5_wd; + logic [5:0] mp_region_5_size_5_qs; + logic [5:0] mp_region_5_size_5_wd; + logic mp_region_6_we; + logic [4:0] mp_region_6_base_6_qs; + logic [4:0] mp_region_6_base_6_wd; + logic [5:0] mp_region_6_size_6_qs; + logic [5:0] mp_region_6_size_6_wd; + logic mp_region_7_we; + logic [4:0] mp_region_7_base_7_qs; + logic [4:0] mp_region_7_base_7_wd; + logic [5:0] mp_region_7_size_7_qs; + logic [5:0] mp_region_7_size_7_wd; + logic default_region_we; + logic [3:0] default_region_rd_en_qs; + logic [3:0] default_region_rd_en_wd; + logic [3:0] default_region_prog_en_qs; + logic [3:0] default_region_prog_en_wd; + logic [3:0] default_region_erase_en_qs; + logic [3:0] default_region_erase_en_wd; + logic [3:0] default_region_scramble_en_qs; + logic [3:0] default_region_scramble_en_wd; + logic [3:0] default_region_ecc_en_qs; + logic [3:0] default_region_ecc_en_wd; + logic [3:0] default_region_he_en_qs; + logic [3:0] default_region_he_en_wd; + logic bank0_info0_regwen_0_we; + logic bank0_info0_regwen_0_qs; + logic bank0_info0_regwen_0_wd; + logic bank0_info0_regwen_1_we; + logic bank0_info0_regwen_1_qs; + logic bank0_info0_regwen_1_wd; + logic bank0_info0_regwen_2_we; + logic bank0_info0_regwen_2_qs; + logic bank0_info0_regwen_2_wd; + logic bank0_info0_regwen_3_we; + logic bank0_info0_regwen_3_qs; + logic bank0_info0_regwen_3_wd; + logic bank0_info0_regwen_4_we; + logic bank0_info0_regwen_4_qs; + logic bank0_info0_regwen_4_wd; + logic bank0_info0_regwen_5_we; + logic bank0_info0_regwen_5_qs; + logic bank0_info0_regwen_5_wd; + logic bank0_info0_regwen_6_we; + logic bank0_info0_regwen_6_qs; + logic bank0_info0_regwen_6_wd; + logic bank0_info0_regwen_7_we; + logic bank0_info0_regwen_7_qs; + logic bank0_info0_regwen_7_wd; + logic bank0_info0_regwen_8_we; + logic bank0_info0_regwen_8_qs; + logic bank0_info0_regwen_8_wd; + logic bank0_info0_regwen_9_we; + logic bank0_info0_regwen_9_qs; + logic bank0_info0_regwen_9_wd; + logic bank0_info0_page_cfg_0_we; + logic [3:0] bank0_info0_page_cfg_0_en_0_qs; + logic [3:0] bank0_info0_page_cfg_0_en_0_wd; + logic [3:0] bank0_info0_page_cfg_0_rd_en_0_qs; + logic [3:0] bank0_info0_page_cfg_0_rd_en_0_wd; + logic [3:0] bank0_info0_page_cfg_0_prog_en_0_qs; + logic [3:0] bank0_info0_page_cfg_0_prog_en_0_wd; + logic [3:0] bank0_info0_page_cfg_0_erase_en_0_qs; + logic [3:0] bank0_info0_page_cfg_0_erase_en_0_wd; + logic [3:0] bank0_info0_page_cfg_0_scramble_en_0_qs; + logic [3:0] bank0_info0_page_cfg_0_scramble_en_0_wd; + logic [3:0] bank0_info0_page_cfg_0_ecc_en_0_qs; + logic [3:0] bank0_info0_page_cfg_0_ecc_en_0_wd; + logic [3:0] bank0_info0_page_cfg_0_he_en_0_qs; + logic [3:0] bank0_info0_page_cfg_0_he_en_0_wd; + logic bank0_info0_page_cfg_1_we; + logic [3:0] bank0_info0_page_cfg_1_en_1_qs; + logic [3:0] bank0_info0_page_cfg_1_en_1_wd; + logic [3:0] bank0_info0_page_cfg_1_rd_en_1_qs; + logic [3:0] bank0_info0_page_cfg_1_rd_en_1_wd; + logic [3:0] bank0_info0_page_cfg_1_prog_en_1_qs; + logic [3:0] bank0_info0_page_cfg_1_prog_en_1_wd; + logic [3:0] bank0_info0_page_cfg_1_erase_en_1_qs; + logic [3:0] bank0_info0_page_cfg_1_erase_en_1_wd; + logic [3:0] bank0_info0_page_cfg_1_scramble_en_1_qs; + logic [3:0] bank0_info0_page_cfg_1_scramble_en_1_wd; + logic [3:0] bank0_info0_page_cfg_1_ecc_en_1_qs; + logic [3:0] bank0_info0_page_cfg_1_ecc_en_1_wd; + logic [3:0] bank0_info0_page_cfg_1_he_en_1_qs; + logic [3:0] bank0_info0_page_cfg_1_he_en_1_wd; + logic bank0_info0_page_cfg_2_we; + logic [3:0] bank0_info0_page_cfg_2_en_2_qs; + logic [3:0] bank0_info0_page_cfg_2_en_2_wd; + logic [3:0] bank0_info0_page_cfg_2_rd_en_2_qs; + logic [3:0] bank0_info0_page_cfg_2_rd_en_2_wd; + logic [3:0] bank0_info0_page_cfg_2_prog_en_2_qs; + logic [3:0] bank0_info0_page_cfg_2_prog_en_2_wd; + logic [3:0] bank0_info0_page_cfg_2_erase_en_2_qs; + logic [3:0] bank0_info0_page_cfg_2_erase_en_2_wd; + logic [3:0] bank0_info0_page_cfg_2_scramble_en_2_qs; + logic [3:0] bank0_info0_page_cfg_2_scramble_en_2_wd; + logic [3:0] bank0_info0_page_cfg_2_ecc_en_2_qs; + logic [3:0] bank0_info0_page_cfg_2_ecc_en_2_wd; + logic [3:0] bank0_info0_page_cfg_2_he_en_2_qs; + logic [3:0] bank0_info0_page_cfg_2_he_en_2_wd; + logic bank0_info0_page_cfg_3_we; + logic [3:0] bank0_info0_page_cfg_3_en_3_qs; + logic [3:0] bank0_info0_page_cfg_3_en_3_wd; + logic [3:0] bank0_info0_page_cfg_3_rd_en_3_qs; + logic [3:0] bank0_info0_page_cfg_3_rd_en_3_wd; + logic [3:0] bank0_info0_page_cfg_3_prog_en_3_qs; + logic [3:0] bank0_info0_page_cfg_3_prog_en_3_wd; + logic [3:0] bank0_info0_page_cfg_3_erase_en_3_qs; + logic [3:0] bank0_info0_page_cfg_3_erase_en_3_wd; + logic [3:0] bank0_info0_page_cfg_3_scramble_en_3_qs; + logic [3:0] bank0_info0_page_cfg_3_scramble_en_3_wd; + logic [3:0] bank0_info0_page_cfg_3_ecc_en_3_qs; + logic [3:0] bank0_info0_page_cfg_3_ecc_en_3_wd; + logic [3:0] bank0_info0_page_cfg_3_he_en_3_qs; + logic [3:0] bank0_info0_page_cfg_3_he_en_3_wd; + logic bank0_info0_page_cfg_4_we; + logic [3:0] bank0_info0_page_cfg_4_en_4_qs; + logic [3:0] bank0_info0_page_cfg_4_en_4_wd; + logic [3:0] bank0_info0_page_cfg_4_rd_en_4_qs; + logic [3:0] bank0_info0_page_cfg_4_rd_en_4_wd; + logic [3:0] bank0_info0_page_cfg_4_prog_en_4_qs; + logic [3:0] bank0_info0_page_cfg_4_prog_en_4_wd; + logic [3:0] bank0_info0_page_cfg_4_erase_en_4_qs; + logic [3:0] bank0_info0_page_cfg_4_erase_en_4_wd; + logic [3:0] bank0_info0_page_cfg_4_scramble_en_4_qs; + logic [3:0] bank0_info0_page_cfg_4_scramble_en_4_wd; + logic [3:0] bank0_info0_page_cfg_4_ecc_en_4_qs; + logic [3:0] bank0_info0_page_cfg_4_ecc_en_4_wd; + logic [3:0] bank0_info0_page_cfg_4_he_en_4_qs; + logic [3:0] bank0_info0_page_cfg_4_he_en_4_wd; + logic bank0_info0_page_cfg_5_we; + logic [3:0] bank0_info0_page_cfg_5_en_5_qs; + logic [3:0] bank0_info0_page_cfg_5_en_5_wd; + logic [3:0] bank0_info0_page_cfg_5_rd_en_5_qs; + logic [3:0] bank0_info0_page_cfg_5_rd_en_5_wd; + logic [3:0] bank0_info0_page_cfg_5_prog_en_5_qs; + logic [3:0] bank0_info0_page_cfg_5_prog_en_5_wd; + logic [3:0] bank0_info0_page_cfg_5_erase_en_5_qs; + logic [3:0] bank0_info0_page_cfg_5_erase_en_5_wd; + logic [3:0] bank0_info0_page_cfg_5_scramble_en_5_qs; + logic [3:0] bank0_info0_page_cfg_5_scramble_en_5_wd; + logic [3:0] bank0_info0_page_cfg_5_ecc_en_5_qs; + logic [3:0] bank0_info0_page_cfg_5_ecc_en_5_wd; + logic [3:0] bank0_info0_page_cfg_5_he_en_5_qs; + logic [3:0] bank0_info0_page_cfg_5_he_en_5_wd; + logic bank0_info0_page_cfg_6_we; + logic [3:0] bank0_info0_page_cfg_6_en_6_qs; + logic [3:0] bank0_info0_page_cfg_6_en_6_wd; + logic [3:0] bank0_info0_page_cfg_6_rd_en_6_qs; + logic [3:0] bank0_info0_page_cfg_6_rd_en_6_wd; + logic [3:0] bank0_info0_page_cfg_6_prog_en_6_qs; + logic [3:0] bank0_info0_page_cfg_6_prog_en_6_wd; + logic [3:0] bank0_info0_page_cfg_6_erase_en_6_qs; + logic [3:0] bank0_info0_page_cfg_6_erase_en_6_wd; + logic [3:0] bank0_info0_page_cfg_6_scramble_en_6_qs; + logic [3:0] bank0_info0_page_cfg_6_scramble_en_6_wd; + logic [3:0] bank0_info0_page_cfg_6_ecc_en_6_qs; + logic [3:0] bank0_info0_page_cfg_6_ecc_en_6_wd; + logic [3:0] bank0_info0_page_cfg_6_he_en_6_qs; + logic [3:0] bank0_info0_page_cfg_6_he_en_6_wd; + logic bank0_info0_page_cfg_7_we; + logic [3:0] bank0_info0_page_cfg_7_en_7_qs; + logic [3:0] bank0_info0_page_cfg_7_en_7_wd; + logic [3:0] bank0_info0_page_cfg_7_rd_en_7_qs; + logic [3:0] bank0_info0_page_cfg_7_rd_en_7_wd; + logic [3:0] bank0_info0_page_cfg_7_prog_en_7_qs; + logic [3:0] bank0_info0_page_cfg_7_prog_en_7_wd; + logic [3:0] bank0_info0_page_cfg_7_erase_en_7_qs; + logic [3:0] bank0_info0_page_cfg_7_erase_en_7_wd; + logic [3:0] bank0_info0_page_cfg_7_scramble_en_7_qs; + logic [3:0] bank0_info0_page_cfg_7_scramble_en_7_wd; + logic [3:0] bank0_info0_page_cfg_7_ecc_en_7_qs; + logic [3:0] bank0_info0_page_cfg_7_ecc_en_7_wd; + logic [3:0] bank0_info0_page_cfg_7_he_en_7_qs; + logic [3:0] bank0_info0_page_cfg_7_he_en_7_wd; + logic bank0_info0_page_cfg_8_we; + logic [3:0] bank0_info0_page_cfg_8_en_8_qs; + logic [3:0] bank0_info0_page_cfg_8_en_8_wd; + logic [3:0] bank0_info0_page_cfg_8_rd_en_8_qs; + logic [3:0] bank0_info0_page_cfg_8_rd_en_8_wd; + logic [3:0] bank0_info0_page_cfg_8_prog_en_8_qs; + logic [3:0] bank0_info0_page_cfg_8_prog_en_8_wd; + logic [3:0] bank0_info0_page_cfg_8_erase_en_8_qs; + logic [3:0] bank0_info0_page_cfg_8_erase_en_8_wd; + logic [3:0] bank0_info0_page_cfg_8_scramble_en_8_qs; + logic [3:0] bank0_info0_page_cfg_8_scramble_en_8_wd; + logic [3:0] bank0_info0_page_cfg_8_ecc_en_8_qs; + logic [3:0] bank0_info0_page_cfg_8_ecc_en_8_wd; + logic [3:0] bank0_info0_page_cfg_8_he_en_8_qs; + logic [3:0] bank0_info0_page_cfg_8_he_en_8_wd; + logic bank0_info0_page_cfg_9_we; + logic [3:0] bank0_info0_page_cfg_9_en_9_qs; + logic [3:0] bank0_info0_page_cfg_9_en_9_wd; + logic [3:0] bank0_info0_page_cfg_9_rd_en_9_qs; + logic [3:0] bank0_info0_page_cfg_9_rd_en_9_wd; + logic [3:0] bank0_info0_page_cfg_9_prog_en_9_qs; + logic [3:0] bank0_info0_page_cfg_9_prog_en_9_wd; + logic [3:0] bank0_info0_page_cfg_9_erase_en_9_qs; + logic [3:0] bank0_info0_page_cfg_9_erase_en_9_wd; + logic [3:0] bank0_info0_page_cfg_9_scramble_en_9_qs; + logic [3:0] bank0_info0_page_cfg_9_scramble_en_9_wd; + logic [3:0] bank0_info0_page_cfg_9_ecc_en_9_qs; + logic [3:0] bank0_info0_page_cfg_9_ecc_en_9_wd; + logic [3:0] bank0_info0_page_cfg_9_he_en_9_qs; + logic [3:0] bank0_info0_page_cfg_9_he_en_9_wd; + logic bank0_info1_regwen_we; + logic bank0_info1_regwen_qs; + logic bank0_info1_regwen_wd; + logic bank0_info1_page_cfg_we; + logic [3:0] bank0_info1_page_cfg_en_0_qs; + logic [3:0] bank0_info1_page_cfg_en_0_wd; + logic [3:0] bank0_info1_page_cfg_rd_en_0_qs; + logic [3:0] bank0_info1_page_cfg_rd_en_0_wd; + logic [3:0] bank0_info1_page_cfg_prog_en_0_qs; + logic [3:0] bank0_info1_page_cfg_prog_en_0_wd; + logic [3:0] bank0_info1_page_cfg_erase_en_0_qs; + logic [3:0] bank0_info1_page_cfg_erase_en_0_wd; + logic [3:0] bank0_info1_page_cfg_scramble_en_0_qs; + logic [3:0] bank0_info1_page_cfg_scramble_en_0_wd; + logic [3:0] bank0_info1_page_cfg_ecc_en_0_qs; + logic [3:0] bank0_info1_page_cfg_ecc_en_0_wd; + logic [3:0] bank0_info1_page_cfg_he_en_0_qs; + logic [3:0] bank0_info1_page_cfg_he_en_0_wd; + logic bank0_info2_regwen_0_we; + logic bank0_info2_regwen_0_qs; + logic bank0_info2_regwen_0_wd; + logic bank0_info2_regwen_1_we; + logic bank0_info2_regwen_1_qs; + logic bank0_info2_regwen_1_wd; + logic bank0_info2_page_cfg_0_we; + logic [3:0] bank0_info2_page_cfg_0_en_0_qs; + logic [3:0] bank0_info2_page_cfg_0_en_0_wd; + logic [3:0] bank0_info2_page_cfg_0_rd_en_0_qs; + logic [3:0] bank0_info2_page_cfg_0_rd_en_0_wd; + logic [3:0] bank0_info2_page_cfg_0_prog_en_0_qs; + logic [3:0] bank0_info2_page_cfg_0_prog_en_0_wd; + logic [3:0] bank0_info2_page_cfg_0_erase_en_0_qs; + logic [3:0] bank0_info2_page_cfg_0_erase_en_0_wd; + logic [3:0] bank0_info2_page_cfg_0_scramble_en_0_qs; + logic [3:0] bank0_info2_page_cfg_0_scramble_en_0_wd; + logic [3:0] bank0_info2_page_cfg_0_ecc_en_0_qs; + logic [3:0] bank0_info2_page_cfg_0_ecc_en_0_wd; + logic [3:0] bank0_info2_page_cfg_0_he_en_0_qs; + logic [3:0] bank0_info2_page_cfg_0_he_en_0_wd; + logic bank0_info2_page_cfg_1_we; + logic [3:0] bank0_info2_page_cfg_1_en_1_qs; + logic [3:0] bank0_info2_page_cfg_1_en_1_wd; + logic [3:0] bank0_info2_page_cfg_1_rd_en_1_qs; + logic [3:0] bank0_info2_page_cfg_1_rd_en_1_wd; + logic [3:0] bank0_info2_page_cfg_1_prog_en_1_qs; + logic [3:0] bank0_info2_page_cfg_1_prog_en_1_wd; + logic [3:0] bank0_info2_page_cfg_1_erase_en_1_qs; + logic [3:0] bank0_info2_page_cfg_1_erase_en_1_wd; + logic [3:0] bank0_info2_page_cfg_1_scramble_en_1_qs; + logic [3:0] bank0_info2_page_cfg_1_scramble_en_1_wd; + logic [3:0] bank0_info2_page_cfg_1_ecc_en_1_qs; + logic [3:0] bank0_info2_page_cfg_1_ecc_en_1_wd; + logic [3:0] bank0_info2_page_cfg_1_he_en_1_qs; + logic [3:0] bank0_info2_page_cfg_1_he_en_1_wd; + logic bank1_info0_regwen_0_we; + logic bank1_info0_regwen_0_qs; + logic bank1_info0_regwen_0_wd; + logic bank1_info0_regwen_1_we; + logic bank1_info0_regwen_1_qs; + logic bank1_info0_regwen_1_wd; + logic bank1_info0_regwen_2_we; + logic bank1_info0_regwen_2_qs; + logic bank1_info0_regwen_2_wd; + logic bank1_info0_regwen_3_we; + logic bank1_info0_regwen_3_qs; + logic bank1_info0_regwen_3_wd; + logic bank1_info0_regwen_4_we; + logic bank1_info0_regwen_4_qs; + logic bank1_info0_regwen_4_wd; + logic bank1_info0_regwen_5_we; + logic bank1_info0_regwen_5_qs; + logic bank1_info0_regwen_5_wd; + logic bank1_info0_regwen_6_we; + logic bank1_info0_regwen_6_qs; + logic bank1_info0_regwen_6_wd; + logic bank1_info0_regwen_7_we; + logic bank1_info0_regwen_7_qs; + logic bank1_info0_regwen_7_wd; + logic bank1_info0_regwen_8_we; + logic bank1_info0_regwen_8_qs; + logic bank1_info0_regwen_8_wd; + logic bank1_info0_regwen_9_we; + logic bank1_info0_regwen_9_qs; + logic bank1_info0_regwen_9_wd; + logic bank1_info0_page_cfg_0_we; + logic [3:0] bank1_info0_page_cfg_0_en_0_qs; + logic [3:0] bank1_info0_page_cfg_0_en_0_wd; + logic [3:0] bank1_info0_page_cfg_0_rd_en_0_qs; + logic [3:0] bank1_info0_page_cfg_0_rd_en_0_wd; + logic [3:0] bank1_info0_page_cfg_0_prog_en_0_qs; + logic [3:0] bank1_info0_page_cfg_0_prog_en_0_wd; + logic [3:0] bank1_info0_page_cfg_0_erase_en_0_qs; + logic [3:0] bank1_info0_page_cfg_0_erase_en_0_wd; + logic [3:0] bank1_info0_page_cfg_0_scramble_en_0_qs; + logic [3:0] bank1_info0_page_cfg_0_scramble_en_0_wd; + logic [3:0] bank1_info0_page_cfg_0_ecc_en_0_qs; + logic [3:0] bank1_info0_page_cfg_0_ecc_en_0_wd; + logic [3:0] bank1_info0_page_cfg_0_he_en_0_qs; + logic [3:0] bank1_info0_page_cfg_0_he_en_0_wd; + logic bank1_info0_page_cfg_1_we; + logic [3:0] bank1_info0_page_cfg_1_en_1_qs; + logic [3:0] bank1_info0_page_cfg_1_en_1_wd; + logic [3:0] bank1_info0_page_cfg_1_rd_en_1_qs; + logic [3:0] bank1_info0_page_cfg_1_rd_en_1_wd; + logic [3:0] bank1_info0_page_cfg_1_prog_en_1_qs; + logic [3:0] bank1_info0_page_cfg_1_prog_en_1_wd; + logic [3:0] bank1_info0_page_cfg_1_erase_en_1_qs; + logic [3:0] bank1_info0_page_cfg_1_erase_en_1_wd; + logic [3:0] bank1_info0_page_cfg_1_scramble_en_1_qs; + logic [3:0] bank1_info0_page_cfg_1_scramble_en_1_wd; + logic [3:0] bank1_info0_page_cfg_1_ecc_en_1_qs; + logic [3:0] bank1_info0_page_cfg_1_ecc_en_1_wd; + logic [3:0] bank1_info0_page_cfg_1_he_en_1_qs; + logic [3:0] bank1_info0_page_cfg_1_he_en_1_wd; + logic bank1_info0_page_cfg_2_we; + logic [3:0] bank1_info0_page_cfg_2_en_2_qs; + logic [3:0] bank1_info0_page_cfg_2_en_2_wd; + logic [3:0] bank1_info0_page_cfg_2_rd_en_2_qs; + logic [3:0] bank1_info0_page_cfg_2_rd_en_2_wd; + logic [3:0] bank1_info0_page_cfg_2_prog_en_2_qs; + logic [3:0] bank1_info0_page_cfg_2_prog_en_2_wd; + logic [3:0] bank1_info0_page_cfg_2_erase_en_2_qs; + logic [3:0] bank1_info0_page_cfg_2_erase_en_2_wd; + logic [3:0] bank1_info0_page_cfg_2_scramble_en_2_qs; + logic [3:0] bank1_info0_page_cfg_2_scramble_en_2_wd; + logic [3:0] bank1_info0_page_cfg_2_ecc_en_2_qs; + logic [3:0] bank1_info0_page_cfg_2_ecc_en_2_wd; + logic [3:0] bank1_info0_page_cfg_2_he_en_2_qs; + logic [3:0] bank1_info0_page_cfg_2_he_en_2_wd; + logic bank1_info0_page_cfg_3_we; + logic [3:0] bank1_info0_page_cfg_3_en_3_qs; + logic [3:0] bank1_info0_page_cfg_3_en_3_wd; + logic [3:0] bank1_info0_page_cfg_3_rd_en_3_qs; + logic [3:0] bank1_info0_page_cfg_3_rd_en_3_wd; + logic [3:0] bank1_info0_page_cfg_3_prog_en_3_qs; + logic [3:0] bank1_info0_page_cfg_3_prog_en_3_wd; + logic [3:0] bank1_info0_page_cfg_3_erase_en_3_qs; + logic [3:0] bank1_info0_page_cfg_3_erase_en_3_wd; + logic [3:0] bank1_info0_page_cfg_3_scramble_en_3_qs; + logic [3:0] bank1_info0_page_cfg_3_scramble_en_3_wd; + logic [3:0] bank1_info0_page_cfg_3_ecc_en_3_qs; + logic [3:0] bank1_info0_page_cfg_3_ecc_en_3_wd; + logic [3:0] bank1_info0_page_cfg_3_he_en_3_qs; + logic [3:0] bank1_info0_page_cfg_3_he_en_3_wd; + logic bank1_info0_page_cfg_4_we; + logic [3:0] bank1_info0_page_cfg_4_en_4_qs; + logic [3:0] bank1_info0_page_cfg_4_en_4_wd; + logic [3:0] bank1_info0_page_cfg_4_rd_en_4_qs; + logic [3:0] bank1_info0_page_cfg_4_rd_en_4_wd; + logic [3:0] bank1_info0_page_cfg_4_prog_en_4_qs; + logic [3:0] bank1_info0_page_cfg_4_prog_en_4_wd; + logic [3:0] bank1_info0_page_cfg_4_erase_en_4_qs; + logic [3:0] bank1_info0_page_cfg_4_erase_en_4_wd; + logic [3:0] bank1_info0_page_cfg_4_scramble_en_4_qs; + logic [3:0] bank1_info0_page_cfg_4_scramble_en_4_wd; + logic [3:0] bank1_info0_page_cfg_4_ecc_en_4_qs; + logic [3:0] bank1_info0_page_cfg_4_ecc_en_4_wd; + logic [3:0] bank1_info0_page_cfg_4_he_en_4_qs; + logic [3:0] bank1_info0_page_cfg_4_he_en_4_wd; + logic bank1_info0_page_cfg_5_we; + logic [3:0] bank1_info0_page_cfg_5_en_5_qs; + logic [3:0] bank1_info0_page_cfg_5_en_5_wd; + logic [3:0] bank1_info0_page_cfg_5_rd_en_5_qs; + logic [3:0] bank1_info0_page_cfg_5_rd_en_5_wd; + logic [3:0] bank1_info0_page_cfg_5_prog_en_5_qs; + logic [3:0] bank1_info0_page_cfg_5_prog_en_5_wd; + logic [3:0] bank1_info0_page_cfg_5_erase_en_5_qs; + logic [3:0] bank1_info0_page_cfg_5_erase_en_5_wd; + logic [3:0] bank1_info0_page_cfg_5_scramble_en_5_qs; + logic [3:0] bank1_info0_page_cfg_5_scramble_en_5_wd; + logic [3:0] bank1_info0_page_cfg_5_ecc_en_5_qs; + logic [3:0] bank1_info0_page_cfg_5_ecc_en_5_wd; + logic [3:0] bank1_info0_page_cfg_5_he_en_5_qs; + logic [3:0] bank1_info0_page_cfg_5_he_en_5_wd; + logic bank1_info0_page_cfg_6_we; + logic [3:0] bank1_info0_page_cfg_6_en_6_qs; + logic [3:0] bank1_info0_page_cfg_6_en_6_wd; + logic [3:0] bank1_info0_page_cfg_6_rd_en_6_qs; + logic [3:0] bank1_info0_page_cfg_6_rd_en_6_wd; + logic [3:0] bank1_info0_page_cfg_6_prog_en_6_qs; + logic [3:0] bank1_info0_page_cfg_6_prog_en_6_wd; + logic [3:0] bank1_info0_page_cfg_6_erase_en_6_qs; + logic [3:0] bank1_info0_page_cfg_6_erase_en_6_wd; + logic [3:0] bank1_info0_page_cfg_6_scramble_en_6_qs; + logic [3:0] bank1_info0_page_cfg_6_scramble_en_6_wd; + logic [3:0] bank1_info0_page_cfg_6_ecc_en_6_qs; + logic [3:0] bank1_info0_page_cfg_6_ecc_en_6_wd; + logic [3:0] bank1_info0_page_cfg_6_he_en_6_qs; + logic [3:0] bank1_info0_page_cfg_6_he_en_6_wd; + logic bank1_info0_page_cfg_7_we; + logic [3:0] bank1_info0_page_cfg_7_en_7_qs; + logic [3:0] bank1_info0_page_cfg_7_en_7_wd; + logic [3:0] bank1_info0_page_cfg_7_rd_en_7_qs; + logic [3:0] bank1_info0_page_cfg_7_rd_en_7_wd; + logic [3:0] bank1_info0_page_cfg_7_prog_en_7_qs; + logic [3:0] bank1_info0_page_cfg_7_prog_en_7_wd; + logic [3:0] bank1_info0_page_cfg_7_erase_en_7_qs; + logic [3:0] bank1_info0_page_cfg_7_erase_en_7_wd; + logic [3:0] bank1_info0_page_cfg_7_scramble_en_7_qs; + logic [3:0] bank1_info0_page_cfg_7_scramble_en_7_wd; + logic [3:0] bank1_info0_page_cfg_7_ecc_en_7_qs; + logic [3:0] bank1_info0_page_cfg_7_ecc_en_7_wd; + logic [3:0] bank1_info0_page_cfg_7_he_en_7_qs; + logic [3:0] bank1_info0_page_cfg_7_he_en_7_wd; + logic bank1_info0_page_cfg_8_we; + logic [3:0] bank1_info0_page_cfg_8_en_8_qs; + logic [3:0] bank1_info0_page_cfg_8_en_8_wd; + logic [3:0] bank1_info0_page_cfg_8_rd_en_8_qs; + logic [3:0] bank1_info0_page_cfg_8_rd_en_8_wd; + logic [3:0] bank1_info0_page_cfg_8_prog_en_8_qs; + logic [3:0] bank1_info0_page_cfg_8_prog_en_8_wd; + logic [3:0] bank1_info0_page_cfg_8_erase_en_8_qs; + logic [3:0] bank1_info0_page_cfg_8_erase_en_8_wd; + logic [3:0] bank1_info0_page_cfg_8_scramble_en_8_qs; + logic [3:0] bank1_info0_page_cfg_8_scramble_en_8_wd; + logic [3:0] bank1_info0_page_cfg_8_ecc_en_8_qs; + logic [3:0] bank1_info0_page_cfg_8_ecc_en_8_wd; + logic [3:0] bank1_info0_page_cfg_8_he_en_8_qs; + logic [3:0] bank1_info0_page_cfg_8_he_en_8_wd; + logic bank1_info0_page_cfg_9_we; + logic [3:0] bank1_info0_page_cfg_9_en_9_qs; + logic [3:0] bank1_info0_page_cfg_9_en_9_wd; + logic [3:0] bank1_info0_page_cfg_9_rd_en_9_qs; + logic [3:0] bank1_info0_page_cfg_9_rd_en_9_wd; + logic [3:0] bank1_info0_page_cfg_9_prog_en_9_qs; + logic [3:0] bank1_info0_page_cfg_9_prog_en_9_wd; + logic [3:0] bank1_info0_page_cfg_9_erase_en_9_qs; + logic [3:0] bank1_info0_page_cfg_9_erase_en_9_wd; + logic [3:0] bank1_info0_page_cfg_9_scramble_en_9_qs; + logic [3:0] bank1_info0_page_cfg_9_scramble_en_9_wd; + logic [3:0] bank1_info0_page_cfg_9_ecc_en_9_qs; + logic [3:0] bank1_info0_page_cfg_9_ecc_en_9_wd; + logic [3:0] bank1_info0_page_cfg_9_he_en_9_qs; + logic [3:0] bank1_info0_page_cfg_9_he_en_9_wd; + logic bank1_info1_regwen_we; + logic bank1_info1_regwen_qs; + logic bank1_info1_regwen_wd; + logic bank1_info1_page_cfg_we; + logic [3:0] bank1_info1_page_cfg_en_0_qs; + logic [3:0] bank1_info1_page_cfg_en_0_wd; + logic [3:0] bank1_info1_page_cfg_rd_en_0_qs; + logic [3:0] bank1_info1_page_cfg_rd_en_0_wd; + logic [3:0] bank1_info1_page_cfg_prog_en_0_qs; + logic [3:0] bank1_info1_page_cfg_prog_en_0_wd; + logic [3:0] bank1_info1_page_cfg_erase_en_0_qs; + logic [3:0] bank1_info1_page_cfg_erase_en_0_wd; + logic [3:0] bank1_info1_page_cfg_scramble_en_0_qs; + logic [3:0] bank1_info1_page_cfg_scramble_en_0_wd; + logic [3:0] bank1_info1_page_cfg_ecc_en_0_qs; + logic [3:0] bank1_info1_page_cfg_ecc_en_0_wd; + logic [3:0] bank1_info1_page_cfg_he_en_0_qs; + logic [3:0] bank1_info1_page_cfg_he_en_0_wd; + logic bank1_info2_regwen_0_we; + logic bank1_info2_regwen_0_qs; + logic bank1_info2_regwen_0_wd; + logic bank1_info2_regwen_1_we; + logic bank1_info2_regwen_1_qs; + logic bank1_info2_regwen_1_wd; + logic bank1_info2_page_cfg_0_we; + logic [3:0] bank1_info2_page_cfg_0_en_0_qs; + logic [3:0] bank1_info2_page_cfg_0_en_0_wd; + logic [3:0] bank1_info2_page_cfg_0_rd_en_0_qs; + logic [3:0] bank1_info2_page_cfg_0_rd_en_0_wd; + logic [3:0] bank1_info2_page_cfg_0_prog_en_0_qs; + logic [3:0] bank1_info2_page_cfg_0_prog_en_0_wd; + logic [3:0] bank1_info2_page_cfg_0_erase_en_0_qs; + logic [3:0] bank1_info2_page_cfg_0_erase_en_0_wd; + logic [3:0] bank1_info2_page_cfg_0_scramble_en_0_qs; + logic [3:0] bank1_info2_page_cfg_0_scramble_en_0_wd; + logic [3:0] bank1_info2_page_cfg_0_ecc_en_0_qs; + logic [3:0] bank1_info2_page_cfg_0_ecc_en_0_wd; + logic [3:0] bank1_info2_page_cfg_0_he_en_0_qs; + logic [3:0] bank1_info2_page_cfg_0_he_en_0_wd; + logic bank1_info2_page_cfg_1_we; + logic [3:0] bank1_info2_page_cfg_1_en_1_qs; + logic [3:0] bank1_info2_page_cfg_1_en_1_wd; + logic [3:0] bank1_info2_page_cfg_1_rd_en_1_qs; + logic [3:0] bank1_info2_page_cfg_1_rd_en_1_wd; + logic [3:0] bank1_info2_page_cfg_1_prog_en_1_qs; + logic [3:0] bank1_info2_page_cfg_1_prog_en_1_wd; + logic [3:0] bank1_info2_page_cfg_1_erase_en_1_qs; + logic [3:0] bank1_info2_page_cfg_1_erase_en_1_wd; + logic [3:0] bank1_info2_page_cfg_1_scramble_en_1_qs; + logic [3:0] bank1_info2_page_cfg_1_scramble_en_1_wd; + logic [3:0] bank1_info2_page_cfg_1_ecc_en_1_qs; + logic [3:0] bank1_info2_page_cfg_1_ecc_en_1_wd; + logic [3:0] bank1_info2_page_cfg_1_he_en_1_qs; + logic [3:0] bank1_info2_page_cfg_1_he_en_1_wd; + logic hw_info_cfg_override_we; + logic [3:0] hw_info_cfg_override_scramble_dis_qs; + logic [3:0] hw_info_cfg_override_scramble_dis_wd; + logic [3:0] hw_info_cfg_override_ecc_dis_qs; + logic [3:0] hw_info_cfg_override_ecc_dis_wd; + logic bank_cfg_regwen_we; + logic bank_cfg_regwen_qs; + logic bank_cfg_regwen_wd; + logic mp_bank_cfg_shadowed_re; + logic mp_bank_cfg_shadowed_we; + logic mp_bank_cfg_shadowed_erase_en_0_qs; + logic mp_bank_cfg_shadowed_erase_en_0_wd; + logic mp_bank_cfg_shadowed_erase_en_0_storage_err; + logic mp_bank_cfg_shadowed_erase_en_0_update_err; + logic mp_bank_cfg_shadowed_erase_en_1_qs; + logic mp_bank_cfg_shadowed_erase_en_1_wd; + logic mp_bank_cfg_shadowed_erase_en_1_storage_err; + logic mp_bank_cfg_shadowed_erase_en_1_update_err; + logic op_status_we; + logic op_status_done_qs; + logic op_status_done_wd; + logic op_status_err_qs; + logic op_status_err_wd; + logic status_rd_full_qs; + logic status_rd_empty_qs; + logic status_prog_full_qs; + logic status_prog_empty_qs; + logic status_init_wip_qs; + logic status_initialized_qs; + logic debug_state_re; + logic [10:0] debug_state_qs; + logic err_code_we; + logic err_code_op_err_qs; + logic err_code_op_err_wd; + logic err_code_mp_err_qs; + logic err_code_mp_err_wd; + logic err_code_rd_err_qs; + logic err_code_rd_err_wd; + logic err_code_prog_err_qs; + logic err_code_prog_err_wd; + logic err_code_prog_win_err_qs; + logic err_code_prog_win_err_wd; + logic err_code_prog_type_err_qs; + logic err_code_prog_type_err_wd; + logic err_code_update_err_qs; + logic err_code_update_err_wd; + logic err_code_macro_err_qs; + logic err_code_macro_err_wd; + logic std_fault_status_reg_intg_err_qs; + logic std_fault_status_prog_intg_err_qs; + logic std_fault_status_lcmgr_err_qs; + logic std_fault_status_lcmgr_intg_err_qs; + logic std_fault_status_arb_fsm_err_qs; + logic std_fault_status_storage_err_qs; + logic std_fault_status_phy_fsm_err_qs; + logic std_fault_status_ctrl_cnt_err_qs; + logic std_fault_status_fifo_err_qs; + logic fault_status_we; + logic fault_status_op_err_qs; + logic fault_status_mp_err_qs; + logic fault_status_rd_err_qs; + logic fault_status_prog_err_qs; + logic fault_status_prog_win_err_qs; + logic fault_status_prog_type_err_qs; + logic fault_status_seed_err_qs; + logic fault_status_phy_relbl_err_qs; + logic fault_status_phy_relbl_err_wd; + logic fault_status_phy_storage_err_qs; + logic fault_status_phy_storage_err_wd; + logic fault_status_spurious_ack_qs; + logic fault_status_arb_err_qs; + logic fault_status_host_gnt_err_qs; + logic [15:0] err_addr_qs; + logic ecc_single_err_cnt_we; + logic [7:0] ecc_single_err_cnt_ecc_single_err_cnt_0_qs; + logic [7:0] ecc_single_err_cnt_ecc_single_err_cnt_0_wd; + logic [7:0] ecc_single_err_cnt_ecc_single_err_cnt_1_qs; + logic [7:0] ecc_single_err_cnt_ecc_single_err_cnt_1_wd; + logic [15:0] ecc_single_err_addr_0_qs; + logic [15:0] ecc_single_err_addr_1_qs; + logic phy_alert_cfg_we; + logic phy_alert_cfg_alert_ack_qs; + logic phy_alert_cfg_alert_ack_wd; + logic phy_alert_cfg_alert_trig_qs; + logic phy_alert_cfg_alert_trig_wd; + logic phy_status_init_wip_qs; + logic phy_status_prog_normal_avail_qs; + logic phy_status_prog_repair_avail_qs; + logic scratch_we; + logic [31:0] scratch_qs; + logic [31:0] scratch_wd; + logic fifo_lvl_we; + logic [4:0] fifo_lvl_prog_qs; + logic [4:0] fifo_lvl_prog_wd; + logic [4:0] fifo_lvl_rd_qs; + logic [4:0] fifo_lvl_rd_wd; + logic fifo_rst_we; + logic fifo_rst_qs; + logic fifo_rst_wd; + logic curr_fifo_lvl_re; + logic [4:0] curr_fifo_lvl_prog_qs; + logic [4:0] curr_fifo_lvl_rd_qs; + + // Register instances + // R[intr_state]: V(False) + // F[prog_empty]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_intr_state_prog_empty ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.intr_state.prog_empty.de), + .d (hw2reg.intr_state.prog_empty.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.prog_empty.q), + .ds (), + + // to register interface (read) + .qs (intr_state_prog_empty_qs) + ); + + // F[prog_lvl]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_intr_state_prog_lvl ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.intr_state.prog_lvl.de), + .d (hw2reg.intr_state.prog_lvl.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.prog_lvl.q), + .ds (), + + // to register interface (read) + .qs (intr_state_prog_lvl_qs) + ); + + // F[rd_full]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_rd_full ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.intr_state.rd_full.de), + .d (hw2reg.intr_state.rd_full.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.rd_full.q), + .ds (), + + // to register interface (read) + .qs (intr_state_rd_full_qs) + ); + + // F[rd_lvl]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_rd_lvl ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.intr_state.rd_lvl.de), + .d (hw2reg.intr_state.rd_lvl.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.rd_lvl.q), + .ds (), + + // to register interface (read) + .qs (intr_state_rd_lvl_qs) + ); + + // F[op_done]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_op_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_op_done_wd), + + // from internal hardware + .de (hw2reg.intr_state.op_done.de), + .d (hw2reg.intr_state.op_done.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.op_done.q), + .ds (), + + // to register interface (read) + .qs (intr_state_op_done_qs) + ); + + // F[corr_err]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_state_corr_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_state_we), + .wd (intr_state_corr_err_wd), + + // from internal hardware + .de (hw2reg.intr_state.corr_err.de), + .d (hw2reg.intr_state.corr_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.intr_state.corr_err.q), + .ds (), + + // to register interface (read) + .qs (intr_state_corr_err_qs) + ); + + + // R[intr_enable]: V(False) + // F[prog_empty]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_prog_empty ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_prog_empty_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.prog_empty.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_prog_empty_qs) + ); + + // F[prog_lvl]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_prog_lvl ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_prog_lvl_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.prog_lvl.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_prog_lvl_qs) + ); + + // F[rd_full]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_rd_full ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_rd_full_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.rd_full.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_rd_full_qs) + ); + + // F[rd_lvl]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_rd_lvl ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_rd_lvl_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.rd_lvl.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_rd_lvl_qs) + ); + + // F[op_done]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_op_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_op_done_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.op_done.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_op_done_qs) + ); + + // F[corr_err]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_intr_enable_corr_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (intr_enable_we), + .wd (intr_enable_corr_err_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.intr_enable.corr_err.q), + .ds (), + + // to register interface (read) + .qs (intr_enable_corr_err_qs) + ); + + + // R[intr_test]: V(True) + logic intr_test_qe; + logic [5:0] intr_test_flds_we; + assign intr_test_qe = &intr_test_flds_we; + // F[prog_empty]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_intr_test_prog_empty ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_prog_empty_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[0]), + .q (reg2hw.intr_test.prog_empty.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.prog_empty.qe = intr_test_qe; + + // F[prog_lvl]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_intr_test_prog_lvl ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_prog_lvl_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[1]), + .q (reg2hw.intr_test.prog_lvl.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.prog_lvl.qe = intr_test_qe; + + // F[rd_full]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_intr_test_rd_full ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_rd_full_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[2]), + .q (reg2hw.intr_test.rd_full.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.rd_full.qe = intr_test_qe; + + // F[rd_lvl]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_intr_test_rd_lvl ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_rd_lvl_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[3]), + .q (reg2hw.intr_test.rd_lvl.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.rd_lvl.qe = intr_test_qe; + + // F[op_done]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_intr_test_op_done ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_op_done_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[4]), + .q (reg2hw.intr_test.op_done.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.op_done.qe = intr_test_qe; + + // F[corr_err]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_intr_test_corr_err ( + .re (1'b0), + .we (intr_test_we), + .wd (intr_test_corr_err_wd), + .d ('0), + .qre (), + .qe (intr_test_flds_we[5]), + .q (reg2hw.intr_test.corr_err.q), + .ds (), + .qs () + ); + assign reg2hw.intr_test.corr_err.qe = intr_test_qe; + + + // R[alert_test]: V(True) + logic alert_test_qe; + logic [4:0] alert_test_flds_we; + assign alert_test_qe = &alert_test_flds_we; + // F[recov_err]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_recov_err ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_recov_err_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[0]), + .q (reg2hw.alert_test.recov_err.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.recov_err.qe = alert_test_qe; + + // F[fatal_std_err]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_std_err ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_std_err_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[1]), + .q (reg2hw.alert_test.fatal_std_err.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_std_err.qe = alert_test_qe; + + // F[fatal_err]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_err ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_err_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[2]), + .q (reg2hw.alert_test.fatal_err.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_err.qe = alert_test_qe; + + // F[fatal_prim_flash_alert]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_prim_flash_alert ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_prim_flash_alert_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[3]), + .q (reg2hw.alert_test.fatal_prim_flash_alert.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_prim_flash_alert.qe = alert_test_qe; + + // F[recov_prim_flash_alert]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_recov_prim_flash_alert ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_recov_prim_flash_alert_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[4]), + .q (reg2hw.alert_test.recov_prim_flash_alert.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.recov_prim_flash_alert.qe = alert_test_qe; + + + // R[dis]: V(False) + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessW1S), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_dis ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dis_we), + .wd (dis_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dis.q), + .ds (), + + // to register interface (read) + .qs (dis_qs) + ); + + + // R[exec]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_exec ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (exec_we), + .wd (exec_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.exec.q), + .ds (), + + // to register interface (read) + .qs (exec_qs) + ); + + + // R[init]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1S), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_init ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (init_we), + .wd (init_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.init.q), + .ds (), + + // to register interface (read) + .qs (init_qs) + ); + + + // R[ctrl_regwen]: V(True) + prim_subreg_ext #( + .DW (1) + ) u_ctrl_regwen ( + .re (ctrl_regwen_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.ctrl_regwen.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (ctrl_regwen_qs) + ); + + + // R[control]: V(False) + // Create REGWEN-gated WE signal + logic control_gated_we; + assign control_gated_we = control_we & ctrl_regwen_qs; + // F[start]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_control_start ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (control_gated_we), + .wd (control_start_wd), + + // from internal hardware + .de (hw2reg.control.start.de), + .d (hw2reg.control.start.d), + + // to internal hardware + .qe (), + .q (reg2hw.control.start.q), + .ds (), + + // to register interface (read) + .qs (control_start_qs) + ); + + // F[op]: 5:4 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_control_op ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (control_gated_we), + .wd (control_op_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.control.op.q), + .ds (), + + // to register interface (read) + .qs (control_op_qs) + ); + + // F[prog_sel]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_control_prog_sel ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (control_gated_we), + .wd (control_prog_sel_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.control.prog_sel.q), + .ds (), + + // to register interface (read) + .qs (control_prog_sel_qs) + ); + + // F[erase_sel]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_control_erase_sel ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (control_gated_we), + .wd (control_erase_sel_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.control.erase_sel.q), + .ds (), + + // to register interface (read) + .qs (control_erase_sel_qs) + ); + + // F[partition_sel]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_control_partition_sel ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (control_gated_we), + .wd (control_partition_sel_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.control.partition_sel.q), + .ds (), + + // to register interface (read) + .qs (control_partition_sel_qs) + ); + + // F[info_sel]: 10:9 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_control_info_sel ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (control_gated_we), + .wd (control_info_sel_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.control.info_sel.q), + .ds (), + + // to register interface (read) + .qs (control_info_sel_qs) + ); + + // F[num]: 27:16 + prim_subreg #( + .DW (12), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (12'h0), + .Mubi (1'b0) + ) u_control_num ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (control_gated_we), + .wd (control_num_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.control.num.q), + .ds (), + + // to register interface (read) + .qs (control_num_qs) + ); + + + // R[addr]: V(False) + // Create REGWEN-gated WE signal + logic addr_gated_we; + assign addr_gated_we = addr_we & ctrl_regwen_qs; + prim_subreg #( + .DW (16), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (16'h0), + .Mubi (1'b0) + ) u_addr ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (addr_gated_we), + .wd (addr_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.addr.q), + .ds (), + + // to register interface (read) + .qs (addr_qs) + ); + + + // R[prog_type_en]: V(False) + // Create REGWEN-gated WE signal + logic prog_type_en_gated_we; + assign prog_type_en_gated_we = prog_type_en_we & ctrl_regwen_qs; + // F[normal]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_prog_type_en_normal ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prog_type_en_gated_we), + .wd (prog_type_en_normal_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prog_type_en.normal.q), + .ds (), + + // to register interface (read) + .qs (prog_type_en_normal_qs) + ); + + // F[repair]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_prog_type_en_repair ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prog_type_en_gated_we), + .wd (prog_type_en_repair_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prog_type_en.repair.q), + .ds (), + + // to register interface (read) + .qs (prog_type_en_repair_qs) + ); + + + // R[erase_suspend]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_erase_suspend ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (erase_suspend_we), + .wd (erase_suspend_wd), + + // from internal hardware + .de (hw2reg.erase_suspend.de), + .d (hw2reg.erase_suspend.d), + + // to internal hardware + .qe (), + .q (reg2hw.erase_suspend.q), + .ds (), + + // to register interface (read) + .qs (erase_suspend_qs) + ); + + + // Subregister 0 of Multireg region_cfg_regwen + // R[region_cfg_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_0_we), + .wd (region_cfg_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_0_qs) + ); + + + // Subregister 1 of Multireg region_cfg_regwen + // R[region_cfg_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_1_we), + .wd (region_cfg_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_1_qs) + ); + + + // Subregister 2 of Multireg region_cfg_regwen + // R[region_cfg_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_2_we), + .wd (region_cfg_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_2_qs) + ); + + + // Subregister 3 of Multireg region_cfg_regwen + // R[region_cfg_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_3_we), + .wd (region_cfg_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_3_qs) + ); + + + // Subregister 4 of Multireg region_cfg_regwen + // R[region_cfg_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_4_we), + .wd (region_cfg_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_4_qs) + ); + + + // Subregister 5 of Multireg region_cfg_regwen + // R[region_cfg_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_5_we), + .wd (region_cfg_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_5_qs) + ); + + + // Subregister 6 of Multireg region_cfg_regwen + // R[region_cfg_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_6_we), + .wd (region_cfg_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_6_qs) + ); + + + // Subregister 7 of Multireg region_cfg_regwen + // R[region_cfg_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_region_cfg_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (region_cfg_regwen_7_we), + .wd (region_cfg_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (region_cfg_regwen_7_qs) + ); + + + // Subregister 0 of Multireg mp_region_cfg + // R[mp_region_cfg_0]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_0_gated_we; + assign mp_region_cfg_0_gated_we = mp_region_cfg_0_we & region_cfg_regwen_0_qs; + // F[en_0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_0_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_0_gated_we), + .wd (mp_region_cfg_0_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[0].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_0_en_0_qs) + ); + + // F[rd_en_0]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_0_rd_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_0_gated_we), + .wd (mp_region_cfg_0_rd_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[0].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_0_rd_en_0_qs) + ); + + // F[prog_en_0]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_0_prog_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_0_gated_we), + .wd (mp_region_cfg_0_prog_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[0].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_0_prog_en_0_qs) + ); + + // F[erase_en_0]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_0_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_0_gated_we), + .wd (mp_region_cfg_0_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[0].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_0_erase_en_0_qs) + ); + + // F[scramble_en_0]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_0_scramble_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_0_gated_we), + .wd (mp_region_cfg_0_scramble_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[0].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_0_scramble_en_0_qs) + ); + + // F[ecc_en_0]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_0_ecc_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_0_gated_we), + .wd (mp_region_cfg_0_ecc_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[0].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_0_ecc_en_0_qs) + ); + + // F[he_en_0]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_0_he_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_0_gated_we), + .wd (mp_region_cfg_0_he_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[0].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_0_he_en_0_qs) + ); + + + // Subregister 1 of Multireg mp_region_cfg + // R[mp_region_cfg_1]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_1_gated_we; + assign mp_region_cfg_1_gated_we = mp_region_cfg_1_we & region_cfg_regwen_1_qs; + // F[en_1]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_1_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_1_gated_we), + .wd (mp_region_cfg_1_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[1].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_1_en_1_qs) + ); + + // F[rd_en_1]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_1_rd_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_1_gated_we), + .wd (mp_region_cfg_1_rd_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[1].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_1_rd_en_1_qs) + ); + + // F[prog_en_1]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_1_prog_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_1_gated_we), + .wd (mp_region_cfg_1_prog_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[1].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_1_prog_en_1_qs) + ); + + // F[erase_en_1]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_1_erase_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_1_gated_we), + .wd (mp_region_cfg_1_erase_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[1].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_1_erase_en_1_qs) + ); + + // F[scramble_en_1]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_1_scramble_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_1_gated_we), + .wd (mp_region_cfg_1_scramble_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[1].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_1_scramble_en_1_qs) + ); + + // F[ecc_en_1]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_1_ecc_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_1_gated_we), + .wd (mp_region_cfg_1_ecc_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[1].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_1_ecc_en_1_qs) + ); + + // F[he_en_1]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_1_he_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_1_gated_we), + .wd (mp_region_cfg_1_he_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[1].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_1_he_en_1_qs) + ); + + + // Subregister 2 of Multireg mp_region_cfg + // R[mp_region_cfg_2]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_2_gated_we; + assign mp_region_cfg_2_gated_we = mp_region_cfg_2_we & region_cfg_regwen_2_qs; + // F[en_2]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_2_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_2_gated_we), + .wd (mp_region_cfg_2_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[2].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_2_en_2_qs) + ); + + // F[rd_en_2]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_2_rd_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_2_gated_we), + .wd (mp_region_cfg_2_rd_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[2].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_2_rd_en_2_qs) + ); + + // F[prog_en_2]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_2_prog_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_2_gated_we), + .wd (mp_region_cfg_2_prog_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[2].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_2_prog_en_2_qs) + ); + + // F[erase_en_2]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_2_erase_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_2_gated_we), + .wd (mp_region_cfg_2_erase_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[2].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_2_erase_en_2_qs) + ); + + // F[scramble_en_2]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_2_scramble_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_2_gated_we), + .wd (mp_region_cfg_2_scramble_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[2].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_2_scramble_en_2_qs) + ); + + // F[ecc_en_2]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_2_ecc_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_2_gated_we), + .wd (mp_region_cfg_2_ecc_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[2].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_2_ecc_en_2_qs) + ); + + // F[he_en_2]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_2_he_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_2_gated_we), + .wd (mp_region_cfg_2_he_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[2].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_2_he_en_2_qs) + ); + + + // Subregister 3 of Multireg mp_region_cfg + // R[mp_region_cfg_3]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_3_gated_we; + assign mp_region_cfg_3_gated_we = mp_region_cfg_3_we & region_cfg_regwen_3_qs; + // F[en_3]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_3_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_3_gated_we), + .wd (mp_region_cfg_3_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[3].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_3_en_3_qs) + ); + + // F[rd_en_3]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_3_rd_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_3_gated_we), + .wd (mp_region_cfg_3_rd_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[3].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_3_rd_en_3_qs) + ); + + // F[prog_en_3]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_3_prog_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_3_gated_we), + .wd (mp_region_cfg_3_prog_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[3].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_3_prog_en_3_qs) + ); + + // F[erase_en_3]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_3_erase_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_3_gated_we), + .wd (mp_region_cfg_3_erase_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[3].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_3_erase_en_3_qs) + ); + + // F[scramble_en_3]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_3_scramble_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_3_gated_we), + .wd (mp_region_cfg_3_scramble_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[3].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_3_scramble_en_3_qs) + ); + + // F[ecc_en_3]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_3_ecc_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_3_gated_we), + .wd (mp_region_cfg_3_ecc_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[3].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_3_ecc_en_3_qs) + ); + + // F[he_en_3]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_3_he_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_3_gated_we), + .wd (mp_region_cfg_3_he_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[3].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_3_he_en_3_qs) + ); + + + // Subregister 4 of Multireg mp_region_cfg + // R[mp_region_cfg_4]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_4_gated_we; + assign mp_region_cfg_4_gated_we = mp_region_cfg_4_we & region_cfg_regwen_4_qs; + // F[en_4]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_4_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_4_gated_we), + .wd (mp_region_cfg_4_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[4].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_4_en_4_qs) + ); + + // F[rd_en_4]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_4_rd_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_4_gated_we), + .wd (mp_region_cfg_4_rd_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[4].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_4_rd_en_4_qs) + ); + + // F[prog_en_4]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_4_prog_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_4_gated_we), + .wd (mp_region_cfg_4_prog_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[4].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_4_prog_en_4_qs) + ); + + // F[erase_en_4]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_4_erase_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_4_gated_we), + .wd (mp_region_cfg_4_erase_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[4].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_4_erase_en_4_qs) + ); + + // F[scramble_en_4]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_4_scramble_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_4_gated_we), + .wd (mp_region_cfg_4_scramble_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[4].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_4_scramble_en_4_qs) + ); + + // F[ecc_en_4]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_4_ecc_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_4_gated_we), + .wd (mp_region_cfg_4_ecc_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[4].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_4_ecc_en_4_qs) + ); + + // F[he_en_4]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_4_he_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_4_gated_we), + .wd (mp_region_cfg_4_he_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[4].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_4_he_en_4_qs) + ); + + + // Subregister 5 of Multireg mp_region_cfg + // R[mp_region_cfg_5]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_5_gated_we; + assign mp_region_cfg_5_gated_we = mp_region_cfg_5_we & region_cfg_regwen_5_qs; + // F[en_5]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_5_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_5_gated_we), + .wd (mp_region_cfg_5_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[5].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_5_en_5_qs) + ); + + // F[rd_en_5]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_5_rd_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_5_gated_we), + .wd (mp_region_cfg_5_rd_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[5].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_5_rd_en_5_qs) + ); + + // F[prog_en_5]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_5_prog_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_5_gated_we), + .wd (mp_region_cfg_5_prog_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[5].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_5_prog_en_5_qs) + ); + + // F[erase_en_5]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_5_erase_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_5_gated_we), + .wd (mp_region_cfg_5_erase_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[5].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_5_erase_en_5_qs) + ); + + // F[scramble_en_5]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_5_scramble_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_5_gated_we), + .wd (mp_region_cfg_5_scramble_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[5].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_5_scramble_en_5_qs) + ); + + // F[ecc_en_5]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_5_ecc_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_5_gated_we), + .wd (mp_region_cfg_5_ecc_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[5].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_5_ecc_en_5_qs) + ); + + // F[he_en_5]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_5_he_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_5_gated_we), + .wd (mp_region_cfg_5_he_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[5].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_5_he_en_5_qs) + ); + + + // Subregister 6 of Multireg mp_region_cfg + // R[mp_region_cfg_6]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_6_gated_we; + assign mp_region_cfg_6_gated_we = mp_region_cfg_6_we & region_cfg_regwen_6_qs; + // F[en_6]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_6_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_6_gated_we), + .wd (mp_region_cfg_6_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[6].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_6_en_6_qs) + ); + + // F[rd_en_6]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_6_rd_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_6_gated_we), + .wd (mp_region_cfg_6_rd_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[6].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_6_rd_en_6_qs) + ); + + // F[prog_en_6]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_6_prog_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_6_gated_we), + .wd (mp_region_cfg_6_prog_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[6].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_6_prog_en_6_qs) + ); + + // F[erase_en_6]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_6_erase_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_6_gated_we), + .wd (mp_region_cfg_6_erase_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[6].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_6_erase_en_6_qs) + ); + + // F[scramble_en_6]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_6_scramble_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_6_gated_we), + .wd (mp_region_cfg_6_scramble_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[6].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_6_scramble_en_6_qs) + ); + + // F[ecc_en_6]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_6_ecc_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_6_gated_we), + .wd (mp_region_cfg_6_ecc_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[6].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_6_ecc_en_6_qs) + ); + + // F[he_en_6]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_6_he_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_6_gated_we), + .wd (mp_region_cfg_6_he_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[6].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_6_he_en_6_qs) + ); + + + // Subregister 7 of Multireg mp_region_cfg + // R[mp_region_cfg_7]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_cfg_7_gated_we; + assign mp_region_cfg_7_gated_we = mp_region_cfg_7_we & region_cfg_regwen_7_qs; + // F[en_7]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_7_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_7_gated_we), + .wd (mp_region_cfg_7_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[7].en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_7_en_7_qs) + ); + + // F[rd_en_7]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_7_rd_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_7_gated_we), + .wd (mp_region_cfg_7_rd_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[7].rd_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_7_rd_en_7_qs) + ); + + // F[prog_en_7]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_7_prog_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_7_gated_we), + .wd (mp_region_cfg_7_prog_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[7].prog_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_7_prog_en_7_qs) + ); + + // F[erase_en_7]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_7_erase_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_7_gated_we), + .wd (mp_region_cfg_7_erase_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[7].erase_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_7_erase_en_7_qs) + ); + + // F[scramble_en_7]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_7_scramble_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_7_gated_we), + .wd (mp_region_cfg_7_scramble_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[7].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_7_scramble_en_7_qs) + ); + + // F[ecc_en_7]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_7_ecc_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_7_gated_we), + .wd (mp_region_cfg_7_ecc_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[7].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_7_ecc_en_7_qs) + ); + + // F[he_en_7]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_mp_region_cfg_7_he_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_cfg_7_gated_we), + .wd (mp_region_cfg_7_he_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region_cfg[7].he_en.q), + .ds (), + + // to register interface (read) + .qs (mp_region_cfg_7_he_en_7_qs) + ); + + + // Subregister 0 of Multireg mp_region + // R[mp_region_0]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_0_gated_we; + assign mp_region_0_gated_we = mp_region_0_we & region_cfg_regwen_0_qs; + // F[base_0]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_0_base_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_0_gated_we), + .wd (mp_region_0_base_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[0].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_0_base_0_qs) + ); + + // F[size_0]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_0_size_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_0_gated_we), + .wd (mp_region_0_size_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[0].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_0_size_0_qs) + ); + + + // Subregister 1 of Multireg mp_region + // R[mp_region_1]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_1_gated_we; + assign mp_region_1_gated_we = mp_region_1_we & region_cfg_regwen_1_qs; + // F[base_1]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_1_base_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_1_gated_we), + .wd (mp_region_1_base_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[1].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_1_base_1_qs) + ); + + // F[size_1]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_1_size_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_1_gated_we), + .wd (mp_region_1_size_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[1].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_1_size_1_qs) + ); + + + // Subregister 2 of Multireg mp_region + // R[mp_region_2]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_2_gated_we; + assign mp_region_2_gated_we = mp_region_2_we & region_cfg_regwen_2_qs; + // F[base_2]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_2_base_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_2_gated_we), + .wd (mp_region_2_base_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[2].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_2_base_2_qs) + ); + + // F[size_2]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_2_size_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_2_gated_we), + .wd (mp_region_2_size_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[2].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_2_size_2_qs) + ); + + + // Subregister 3 of Multireg mp_region + // R[mp_region_3]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_3_gated_we; + assign mp_region_3_gated_we = mp_region_3_we & region_cfg_regwen_3_qs; + // F[base_3]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_3_base_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_3_gated_we), + .wd (mp_region_3_base_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[3].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_3_base_3_qs) + ); + + // F[size_3]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_3_size_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_3_gated_we), + .wd (mp_region_3_size_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[3].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_3_size_3_qs) + ); + + + // Subregister 4 of Multireg mp_region + // R[mp_region_4]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_4_gated_we; + assign mp_region_4_gated_we = mp_region_4_we & region_cfg_regwen_4_qs; + // F[base_4]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_4_base_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_4_gated_we), + .wd (mp_region_4_base_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[4].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_4_base_4_qs) + ); + + // F[size_4]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_4_size_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_4_gated_we), + .wd (mp_region_4_size_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[4].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_4_size_4_qs) + ); + + + // Subregister 5 of Multireg mp_region + // R[mp_region_5]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_5_gated_we; + assign mp_region_5_gated_we = mp_region_5_we & region_cfg_regwen_5_qs; + // F[base_5]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_5_base_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_5_gated_we), + .wd (mp_region_5_base_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[5].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_5_base_5_qs) + ); + + // F[size_5]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_5_size_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_5_gated_we), + .wd (mp_region_5_size_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[5].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_5_size_5_qs) + ); + + + // Subregister 6 of Multireg mp_region + // R[mp_region_6]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_6_gated_we; + assign mp_region_6_gated_we = mp_region_6_we & region_cfg_regwen_6_qs; + // F[base_6]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_6_base_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_6_gated_we), + .wd (mp_region_6_base_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[6].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_6_base_6_qs) + ); + + // F[size_6]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_6_size_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_6_gated_we), + .wd (mp_region_6_size_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[6].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_6_size_6_qs) + ); + + + // Subregister 7 of Multireg mp_region + // R[mp_region_7]: V(False) + // Create REGWEN-gated WE signal + logic mp_region_7_gated_we; + assign mp_region_7_gated_we = mp_region_7_we & region_cfg_regwen_7_qs; + // F[base_7]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_mp_region_7_base_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_7_gated_we), + .wd (mp_region_7_base_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[7].base.q), + .ds (), + + // to register interface (read) + .qs (mp_region_7_base_7_qs) + ); + + // F[size_7]: 10:5 + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mp_region_7_size_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mp_region_7_gated_we), + .wd (mp_region_7_size_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_region[7].size.q), + .ds (), + + // to register interface (read) + .qs (mp_region_7_size_7_qs) + ); + + + // R[default_region]: V(False) + // F[rd_en]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_default_region_rd_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (default_region_we), + .wd (default_region_rd_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.default_region.rd_en.q), + .ds (), + + // to register interface (read) + .qs (default_region_rd_en_qs) + ); + + // F[prog_en]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_default_region_prog_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (default_region_we), + .wd (default_region_prog_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.default_region.prog_en.q), + .ds (), + + // to register interface (read) + .qs (default_region_prog_en_qs) + ); + + // F[erase_en]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_default_region_erase_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (default_region_we), + .wd (default_region_erase_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.default_region.erase_en.q), + .ds (), + + // to register interface (read) + .qs (default_region_erase_en_qs) + ); + + // F[scramble_en]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_default_region_scramble_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (default_region_we), + .wd (default_region_scramble_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.default_region.scramble_en.q), + .ds (), + + // to register interface (read) + .qs (default_region_scramble_en_qs) + ); + + // F[ecc_en]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_default_region_ecc_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (default_region_we), + .wd (default_region_ecc_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.default_region.ecc_en.q), + .ds (), + + // to register interface (read) + .qs (default_region_ecc_en_qs) + ); + + // F[he_en]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_default_region_he_en ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (default_region_we), + .wd (default_region_he_en_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.default_region.he_en.q), + .ds (), + + // to register interface (read) + .qs (default_region_he_en_qs) + ); + + + // Subregister 0 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_0_we), + .wd (bank0_info0_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_0_qs) + ); + + + // Subregister 1 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_1_we), + .wd (bank0_info0_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_1_qs) + ); + + + // Subregister 2 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_2_we), + .wd (bank0_info0_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_2_qs) + ); + + + // Subregister 3 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_3_we), + .wd (bank0_info0_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_3_qs) + ); + + + // Subregister 4 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_4_we), + .wd (bank0_info0_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_4_qs) + ); + + + // Subregister 5 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_5_we), + .wd (bank0_info0_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_5_qs) + ); + + + // Subregister 6 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_6_we), + .wd (bank0_info0_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_6_qs) + ); + + + // Subregister 7 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_7_we), + .wd (bank0_info0_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_7_qs) + ); + + + // Subregister 8 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_8_we), + .wd (bank0_info0_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_8_qs) + ); + + + // Subregister 9 of Multireg bank0_info0_regwen + // R[bank0_info0_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info0_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_regwen_9_we), + .wd (bank0_info0_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info0_regwen_9_qs) + ); + + + // Subregister 0 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_0]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_0_gated_we; + assign bank0_info0_page_cfg_0_gated_we = bank0_info0_page_cfg_0_we & bank0_info0_regwen_0_qs; + // F[en_0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_0_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_0_gated_we), + .wd (bank0_info0_page_cfg_0_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[0].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_0_en_0_qs) + ); + + // F[rd_en_0]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_0_rd_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_0_gated_we), + .wd (bank0_info0_page_cfg_0_rd_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[0].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_0_rd_en_0_qs) + ); + + // F[prog_en_0]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_0_prog_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_0_gated_we), + .wd (bank0_info0_page_cfg_0_prog_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[0].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_0_prog_en_0_qs) + ); + + // F[erase_en_0]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_0_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_0_gated_we), + .wd (bank0_info0_page_cfg_0_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[0].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_0_erase_en_0_qs) + ); + + // F[scramble_en_0]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_0_scramble_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_0_gated_we), + .wd (bank0_info0_page_cfg_0_scramble_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[0].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_0_scramble_en_0_qs) + ); + + // F[ecc_en_0]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_0_ecc_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_0_gated_we), + .wd (bank0_info0_page_cfg_0_ecc_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[0].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_0_ecc_en_0_qs) + ); + + // F[he_en_0]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_0_he_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_0_gated_we), + .wd (bank0_info0_page_cfg_0_he_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[0].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_0_he_en_0_qs) + ); + + + // Subregister 1 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_1]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_1_gated_we; + assign bank0_info0_page_cfg_1_gated_we = bank0_info0_page_cfg_1_we & bank0_info0_regwen_1_qs; + // F[en_1]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_1_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_1_gated_we), + .wd (bank0_info0_page_cfg_1_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[1].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_1_en_1_qs) + ); + + // F[rd_en_1]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_1_rd_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_1_gated_we), + .wd (bank0_info0_page_cfg_1_rd_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[1].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_1_rd_en_1_qs) + ); + + // F[prog_en_1]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_1_prog_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_1_gated_we), + .wd (bank0_info0_page_cfg_1_prog_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[1].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_1_prog_en_1_qs) + ); + + // F[erase_en_1]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_1_erase_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_1_gated_we), + .wd (bank0_info0_page_cfg_1_erase_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[1].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_1_erase_en_1_qs) + ); + + // F[scramble_en_1]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_1_scramble_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_1_gated_we), + .wd (bank0_info0_page_cfg_1_scramble_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[1].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_1_scramble_en_1_qs) + ); + + // F[ecc_en_1]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_1_ecc_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_1_gated_we), + .wd (bank0_info0_page_cfg_1_ecc_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[1].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_1_ecc_en_1_qs) + ); + + // F[he_en_1]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_1_he_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_1_gated_we), + .wd (bank0_info0_page_cfg_1_he_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[1].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_1_he_en_1_qs) + ); + + + // Subregister 2 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_2]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_2_gated_we; + assign bank0_info0_page_cfg_2_gated_we = bank0_info0_page_cfg_2_we & bank0_info0_regwen_2_qs; + // F[en_2]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_2_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_2_gated_we), + .wd (bank0_info0_page_cfg_2_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[2].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_2_en_2_qs) + ); + + // F[rd_en_2]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_2_rd_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_2_gated_we), + .wd (bank0_info0_page_cfg_2_rd_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[2].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_2_rd_en_2_qs) + ); + + // F[prog_en_2]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_2_prog_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_2_gated_we), + .wd (bank0_info0_page_cfg_2_prog_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[2].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_2_prog_en_2_qs) + ); + + // F[erase_en_2]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_2_erase_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_2_gated_we), + .wd (bank0_info0_page_cfg_2_erase_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[2].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_2_erase_en_2_qs) + ); + + // F[scramble_en_2]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_2_scramble_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_2_gated_we), + .wd (bank0_info0_page_cfg_2_scramble_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[2].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_2_scramble_en_2_qs) + ); + + // F[ecc_en_2]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_2_ecc_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_2_gated_we), + .wd (bank0_info0_page_cfg_2_ecc_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[2].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_2_ecc_en_2_qs) + ); + + // F[he_en_2]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_2_he_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_2_gated_we), + .wd (bank0_info0_page_cfg_2_he_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[2].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_2_he_en_2_qs) + ); + + + // Subregister 3 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_3]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_3_gated_we; + assign bank0_info0_page_cfg_3_gated_we = bank0_info0_page_cfg_3_we & bank0_info0_regwen_3_qs; + // F[en_3]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_3_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_3_gated_we), + .wd (bank0_info0_page_cfg_3_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[3].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_3_en_3_qs) + ); + + // F[rd_en_3]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_3_rd_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_3_gated_we), + .wd (bank0_info0_page_cfg_3_rd_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[3].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_3_rd_en_3_qs) + ); + + // F[prog_en_3]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_3_prog_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_3_gated_we), + .wd (bank0_info0_page_cfg_3_prog_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[3].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_3_prog_en_3_qs) + ); + + // F[erase_en_3]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_3_erase_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_3_gated_we), + .wd (bank0_info0_page_cfg_3_erase_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[3].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_3_erase_en_3_qs) + ); + + // F[scramble_en_3]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_3_scramble_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_3_gated_we), + .wd (bank0_info0_page_cfg_3_scramble_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[3].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_3_scramble_en_3_qs) + ); + + // F[ecc_en_3]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_3_ecc_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_3_gated_we), + .wd (bank0_info0_page_cfg_3_ecc_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[3].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_3_ecc_en_3_qs) + ); + + // F[he_en_3]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_3_he_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_3_gated_we), + .wd (bank0_info0_page_cfg_3_he_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[3].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_3_he_en_3_qs) + ); + + + // Subregister 4 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_4]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_4_gated_we; + assign bank0_info0_page_cfg_4_gated_we = bank0_info0_page_cfg_4_we & bank0_info0_regwen_4_qs; + // F[en_4]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_4_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_4_gated_we), + .wd (bank0_info0_page_cfg_4_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[4].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_4_en_4_qs) + ); + + // F[rd_en_4]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_4_rd_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_4_gated_we), + .wd (bank0_info0_page_cfg_4_rd_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[4].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_4_rd_en_4_qs) + ); + + // F[prog_en_4]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_4_prog_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_4_gated_we), + .wd (bank0_info0_page_cfg_4_prog_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[4].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_4_prog_en_4_qs) + ); + + // F[erase_en_4]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_4_erase_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_4_gated_we), + .wd (bank0_info0_page_cfg_4_erase_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[4].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_4_erase_en_4_qs) + ); + + // F[scramble_en_4]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_4_scramble_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_4_gated_we), + .wd (bank0_info0_page_cfg_4_scramble_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[4].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_4_scramble_en_4_qs) + ); + + // F[ecc_en_4]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_4_ecc_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_4_gated_we), + .wd (bank0_info0_page_cfg_4_ecc_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[4].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_4_ecc_en_4_qs) + ); + + // F[he_en_4]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_4_he_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_4_gated_we), + .wd (bank0_info0_page_cfg_4_he_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[4].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_4_he_en_4_qs) + ); + + + // Subregister 5 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_5]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_5_gated_we; + assign bank0_info0_page_cfg_5_gated_we = bank0_info0_page_cfg_5_we & bank0_info0_regwen_5_qs; + // F[en_5]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_5_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_5_gated_we), + .wd (bank0_info0_page_cfg_5_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[5].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_5_en_5_qs) + ); + + // F[rd_en_5]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_5_rd_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_5_gated_we), + .wd (bank0_info0_page_cfg_5_rd_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[5].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_5_rd_en_5_qs) + ); + + // F[prog_en_5]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_5_prog_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_5_gated_we), + .wd (bank0_info0_page_cfg_5_prog_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[5].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_5_prog_en_5_qs) + ); + + // F[erase_en_5]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_5_erase_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_5_gated_we), + .wd (bank0_info0_page_cfg_5_erase_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[5].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_5_erase_en_5_qs) + ); + + // F[scramble_en_5]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_5_scramble_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_5_gated_we), + .wd (bank0_info0_page_cfg_5_scramble_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[5].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_5_scramble_en_5_qs) + ); + + // F[ecc_en_5]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_5_ecc_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_5_gated_we), + .wd (bank0_info0_page_cfg_5_ecc_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[5].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_5_ecc_en_5_qs) + ); + + // F[he_en_5]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_5_he_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_5_gated_we), + .wd (bank0_info0_page_cfg_5_he_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[5].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_5_he_en_5_qs) + ); + + + // Subregister 6 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_6]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_6_gated_we; + assign bank0_info0_page_cfg_6_gated_we = bank0_info0_page_cfg_6_we & bank0_info0_regwen_6_qs; + // F[en_6]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_6_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_6_gated_we), + .wd (bank0_info0_page_cfg_6_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[6].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_6_en_6_qs) + ); + + // F[rd_en_6]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_6_rd_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_6_gated_we), + .wd (bank0_info0_page_cfg_6_rd_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[6].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_6_rd_en_6_qs) + ); + + // F[prog_en_6]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_6_prog_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_6_gated_we), + .wd (bank0_info0_page_cfg_6_prog_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[6].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_6_prog_en_6_qs) + ); + + // F[erase_en_6]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_6_erase_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_6_gated_we), + .wd (bank0_info0_page_cfg_6_erase_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[6].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_6_erase_en_6_qs) + ); + + // F[scramble_en_6]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_6_scramble_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_6_gated_we), + .wd (bank0_info0_page_cfg_6_scramble_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[6].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_6_scramble_en_6_qs) + ); + + // F[ecc_en_6]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_6_ecc_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_6_gated_we), + .wd (bank0_info0_page_cfg_6_ecc_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[6].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_6_ecc_en_6_qs) + ); + + // F[he_en_6]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_6_he_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_6_gated_we), + .wd (bank0_info0_page_cfg_6_he_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[6].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_6_he_en_6_qs) + ); + + + // Subregister 7 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_7]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_7_gated_we; + assign bank0_info0_page_cfg_7_gated_we = bank0_info0_page_cfg_7_we & bank0_info0_regwen_7_qs; + // F[en_7]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_7_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_7_gated_we), + .wd (bank0_info0_page_cfg_7_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[7].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_7_en_7_qs) + ); + + // F[rd_en_7]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_7_rd_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_7_gated_we), + .wd (bank0_info0_page_cfg_7_rd_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[7].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_7_rd_en_7_qs) + ); + + // F[prog_en_7]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_7_prog_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_7_gated_we), + .wd (bank0_info0_page_cfg_7_prog_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[7].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_7_prog_en_7_qs) + ); + + // F[erase_en_7]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_7_erase_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_7_gated_we), + .wd (bank0_info0_page_cfg_7_erase_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[7].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_7_erase_en_7_qs) + ); + + // F[scramble_en_7]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_7_scramble_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_7_gated_we), + .wd (bank0_info0_page_cfg_7_scramble_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[7].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_7_scramble_en_7_qs) + ); + + // F[ecc_en_7]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_7_ecc_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_7_gated_we), + .wd (bank0_info0_page_cfg_7_ecc_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[7].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_7_ecc_en_7_qs) + ); + + // F[he_en_7]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_7_he_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_7_gated_we), + .wd (bank0_info0_page_cfg_7_he_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[7].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_7_he_en_7_qs) + ); + + + // Subregister 8 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_8]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_8_gated_we; + assign bank0_info0_page_cfg_8_gated_we = bank0_info0_page_cfg_8_we & bank0_info0_regwen_8_qs; + // F[en_8]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_8_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_8_gated_we), + .wd (bank0_info0_page_cfg_8_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[8].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_8_en_8_qs) + ); + + // F[rd_en_8]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_8_rd_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_8_gated_we), + .wd (bank0_info0_page_cfg_8_rd_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[8].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_8_rd_en_8_qs) + ); + + // F[prog_en_8]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_8_prog_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_8_gated_we), + .wd (bank0_info0_page_cfg_8_prog_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[8].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_8_prog_en_8_qs) + ); + + // F[erase_en_8]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_8_erase_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_8_gated_we), + .wd (bank0_info0_page_cfg_8_erase_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[8].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_8_erase_en_8_qs) + ); + + // F[scramble_en_8]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_8_scramble_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_8_gated_we), + .wd (bank0_info0_page_cfg_8_scramble_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[8].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_8_scramble_en_8_qs) + ); + + // F[ecc_en_8]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_8_ecc_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_8_gated_we), + .wd (bank0_info0_page_cfg_8_ecc_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[8].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_8_ecc_en_8_qs) + ); + + // F[he_en_8]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_8_he_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_8_gated_we), + .wd (bank0_info0_page_cfg_8_he_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[8].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_8_he_en_8_qs) + ); + + + // Subregister 9 of Multireg bank0_info0_page_cfg + // R[bank0_info0_page_cfg_9]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info0_page_cfg_9_gated_we; + assign bank0_info0_page_cfg_9_gated_we = bank0_info0_page_cfg_9_we & bank0_info0_regwen_9_qs; + // F[en_9]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_9_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_9_gated_we), + .wd (bank0_info0_page_cfg_9_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[9].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_9_en_9_qs) + ); + + // F[rd_en_9]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_9_rd_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_9_gated_we), + .wd (bank0_info0_page_cfg_9_rd_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[9].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_9_rd_en_9_qs) + ); + + // F[prog_en_9]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_9_prog_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_9_gated_we), + .wd (bank0_info0_page_cfg_9_prog_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[9].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_9_prog_en_9_qs) + ); + + // F[erase_en_9]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_9_erase_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_9_gated_we), + .wd (bank0_info0_page_cfg_9_erase_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[9].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_9_erase_en_9_qs) + ); + + // F[scramble_en_9]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_9_scramble_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_9_gated_we), + .wd (bank0_info0_page_cfg_9_scramble_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[9].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_9_scramble_en_9_qs) + ); + + // F[ecc_en_9]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_9_ecc_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_9_gated_we), + .wd (bank0_info0_page_cfg_9_ecc_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[9].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_9_ecc_en_9_qs) + ); + + // F[he_en_9]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info0_page_cfg_9_he_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info0_page_cfg_9_gated_we), + .wd (bank0_info0_page_cfg_9_he_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info0_page_cfg[9].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info0_page_cfg_9_he_en_9_qs) + ); + + + // Subregister 0 of Multireg bank0_info1_regwen + // R[bank0_info1_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info1_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_regwen_we), + .wd (bank0_info1_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info1_regwen_qs) + ); + + + // Subregister 0 of Multireg bank0_info1_page_cfg + // R[bank0_info1_page_cfg]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info1_page_cfg_gated_we; + assign bank0_info1_page_cfg_gated_we = bank0_info1_page_cfg_we & bank0_info1_regwen_qs; + // F[en_0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info1_page_cfg_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_page_cfg_gated_we), + .wd (bank0_info1_page_cfg_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info1_page_cfg[0].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info1_page_cfg_en_0_qs) + ); + + // F[rd_en_0]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info1_page_cfg_rd_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_page_cfg_gated_we), + .wd (bank0_info1_page_cfg_rd_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info1_page_cfg[0].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info1_page_cfg_rd_en_0_qs) + ); + + // F[prog_en_0]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info1_page_cfg_prog_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_page_cfg_gated_we), + .wd (bank0_info1_page_cfg_prog_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info1_page_cfg[0].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info1_page_cfg_prog_en_0_qs) + ); + + // F[erase_en_0]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info1_page_cfg_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_page_cfg_gated_we), + .wd (bank0_info1_page_cfg_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info1_page_cfg[0].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info1_page_cfg_erase_en_0_qs) + ); + + // F[scramble_en_0]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info1_page_cfg_scramble_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_page_cfg_gated_we), + .wd (bank0_info1_page_cfg_scramble_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info1_page_cfg[0].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info1_page_cfg_scramble_en_0_qs) + ); + + // F[ecc_en_0]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info1_page_cfg_ecc_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_page_cfg_gated_we), + .wd (bank0_info1_page_cfg_ecc_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info1_page_cfg[0].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info1_page_cfg_ecc_en_0_qs) + ); + + // F[he_en_0]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info1_page_cfg_he_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info1_page_cfg_gated_we), + .wd (bank0_info1_page_cfg_he_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info1_page_cfg[0].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info1_page_cfg_he_en_0_qs) + ); + + + // Subregister 0 of Multireg bank0_info2_regwen + // R[bank0_info2_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info2_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_regwen_0_we), + .wd (bank0_info2_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info2_regwen_0_qs) + ); + + + // Subregister 1 of Multireg bank0_info2_regwen + // R[bank0_info2_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank0_info2_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_regwen_1_we), + .wd (bank0_info2_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank0_info2_regwen_1_qs) + ); + + + // Subregister 0 of Multireg bank0_info2_page_cfg + // R[bank0_info2_page_cfg_0]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info2_page_cfg_0_gated_we; + assign bank0_info2_page_cfg_0_gated_we = bank0_info2_page_cfg_0_we & bank0_info2_regwen_0_qs; + // F[en_0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_0_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_0_gated_we), + .wd (bank0_info2_page_cfg_0_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[0].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_0_en_0_qs) + ); + + // F[rd_en_0]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_0_rd_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_0_gated_we), + .wd (bank0_info2_page_cfg_0_rd_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[0].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_0_rd_en_0_qs) + ); + + // F[prog_en_0]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_0_prog_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_0_gated_we), + .wd (bank0_info2_page_cfg_0_prog_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[0].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_0_prog_en_0_qs) + ); + + // F[erase_en_0]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_0_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_0_gated_we), + .wd (bank0_info2_page_cfg_0_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[0].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_0_erase_en_0_qs) + ); + + // F[scramble_en_0]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_0_scramble_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_0_gated_we), + .wd (bank0_info2_page_cfg_0_scramble_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[0].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_0_scramble_en_0_qs) + ); + + // F[ecc_en_0]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_0_ecc_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_0_gated_we), + .wd (bank0_info2_page_cfg_0_ecc_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[0].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_0_ecc_en_0_qs) + ); + + // F[he_en_0]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_0_he_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_0_gated_we), + .wd (bank0_info2_page_cfg_0_he_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[0].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_0_he_en_0_qs) + ); + + + // Subregister 1 of Multireg bank0_info2_page_cfg + // R[bank0_info2_page_cfg_1]: V(False) + // Create REGWEN-gated WE signal + logic bank0_info2_page_cfg_1_gated_we; + assign bank0_info2_page_cfg_1_gated_we = bank0_info2_page_cfg_1_we & bank0_info2_regwen_1_qs; + // F[en_1]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_1_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_1_gated_we), + .wd (bank0_info2_page_cfg_1_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[1].en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_1_en_1_qs) + ); + + // F[rd_en_1]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_1_rd_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_1_gated_we), + .wd (bank0_info2_page_cfg_1_rd_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[1].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_1_rd_en_1_qs) + ); + + // F[prog_en_1]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_1_prog_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_1_gated_we), + .wd (bank0_info2_page_cfg_1_prog_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[1].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_1_prog_en_1_qs) + ); + + // F[erase_en_1]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_1_erase_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_1_gated_we), + .wd (bank0_info2_page_cfg_1_erase_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[1].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_1_erase_en_1_qs) + ); + + // F[scramble_en_1]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_1_scramble_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_1_gated_we), + .wd (bank0_info2_page_cfg_1_scramble_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[1].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_1_scramble_en_1_qs) + ); + + // F[ecc_en_1]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_1_ecc_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_1_gated_we), + .wd (bank0_info2_page_cfg_1_ecc_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[1].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_1_ecc_en_1_qs) + ); + + // F[he_en_1]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank0_info2_page_cfg_1_he_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank0_info2_page_cfg_1_gated_we), + .wd (bank0_info2_page_cfg_1_he_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank0_info2_page_cfg[1].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank0_info2_page_cfg_1_he_en_1_qs) + ); + + + // Subregister 0 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_0_we), + .wd (bank1_info0_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_0_qs) + ); + + + // Subregister 1 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_1_we), + .wd (bank1_info0_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_1_qs) + ); + + + // Subregister 2 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_2_we), + .wd (bank1_info0_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_2_qs) + ); + + + // Subregister 3 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_3_we), + .wd (bank1_info0_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_3_qs) + ); + + + // Subregister 4 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_4_we), + .wd (bank1_info0_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_4_qs) + ); + + + // Subregister 5 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_5_we), + .wd (bank1_info0_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_5_qs) + ); + + + // Subregister 6 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_6_we), + .wd (bank1_info0_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_6_qs) + ); + + + // Subregister 7 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_7_we), + .wd (bank1_info0_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_7_qs) + ); + + + // Subregister 8 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_8_we), + .wd (bank1_info0_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_8_qs) + ); + + + // Subregister 9 of Multireg bank1_info0_regwen + // R[bank1_info0_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info0_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_regwen_9_we), + .wd (bank1_info0_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info0_regwen_9_qs) + ); + + + // Subregister 0 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_0]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_0_gated_we; + assign bank1_info0_page_cfg_0_gated_we = bank1_info0_page_cfg_0_we & bank1_info0_regwen_0_qs; + // F[en_0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_0_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_0_gated_we), + .wd (bank1_info0_page_cfg_0_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[0].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_0_en_0_qs) + ); + + // F[rd_en_0]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_0_rd_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_0_gated_we), + .wd (bank1_info0_page_cfg_0_rd_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[0].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_0_rd_en_0_qs) + ); + + // F[prog_en_0]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_0_prog_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_0_gated_we), + .wd (bank1_info0_page_cfg_0_prog_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[0].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_0_prog_en_0_qs) + ); + + // F[erase_en_0]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_0_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_0_gated_we), + .wd (bank1_info0_page_cfg_0_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[0].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_0_erase_en_0_qs) + ); + + // F[scramble_en_0]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_0_scramble_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_0_gated_we), + .wd (bank1_info0_page_cfg_0_scramble_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[0].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_0_scramble_en_0_qs) + ); + + // F[ecc_en_0]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_0_ecc_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_0_gated_we), + .wd (bank1_info0_page_cfg_0_ecc_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[0].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_0_ecc_en_0_qs) + ); + + // F[he_en_0]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_0_he_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_0_gated_we), + .wd (bank1_info0_page_cfg_0_he_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[0].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_0_he_en_0_qs) + ); + + + // Subregister 1 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_1]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_1_gated_we; + assign bank1_info0_page_cfg_1_gated_we = bank1_info0_page_cfg_1_we & bank1_info0_regwen_1_qs; + // F[en_1]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_1_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_1_gated_we), + .wd (bank1_info0_page_cfg_1_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[1].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_1_en_1_qs) + ); + + // F[rd_en_1]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_1_rd_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_1_gated_we), + .wd (bank1_info0_page_cfg_1_rd_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[1].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_1_rd_en_1_qs) + ); + + // F[prog_en_1]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_1_prog_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_1_gated_we), + .wd (bank1_info0_page_cfg_1_prog_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[1].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_1_prog_en_1_qs) + ); + + // F[erase_en_1]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_1_erase_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_1_gated_we), + .wd (bank1_info0_page_cfg_1_erase_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[1].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_1_erase_en_1_qs) + ); + + // F[scramble_en_1]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_1_scramble_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_1_gated_we), + .wd (bank1_info0_page_cfg_1_scramble_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[1].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_1_scramble_en_1_qs) + ); + + // F[ecc_en_1]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_1_ecc_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_1_gated_we), + .wd (bank1_info0_page_cfg_1_ecc_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[1].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_1_ecc_en_1_qs) + ); + + // F[he_en_1]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_1_he_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_1_gated_we), + .wd (bank1_info0_page_cfg_1_he_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[1].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_1_he_en_1_qs) + ); + + + // Subregister 2 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_2]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_2_gated_we; + assign bank1_info0_page_cfg_2_gated_we = bank1_info0_page_cfg_2_we & bank1_info0_regwen_2_qs; + // F[en_2]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_2_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_2_gated_we), + .wd (bank1_info0_page_cfg_2_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[2].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_2_en_2_qs) + ); + + // F[rd_en_2]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_2_rd_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_2_gated_we), + .wd (bank1_info0_page_cfg_2_rd_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[2].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_2_rd_en_2_qs) + ); + + // F[prog_en_2]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_2_prog_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_2_gated_we), + .wd (bank1_info0_page_cfg_2_prog_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[2].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_2_prog_en_2_qs) + ); + + // F[erase_en_2]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_2_erase_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_2_gated_we), + .wd (bank1_info0_page_cfg_2_erase_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[2].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_2_erase_en_2_qs) + ); + + // F[scramble_en_2]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_2_scramble_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_2_gated_we), + .wd (bank1_info0_page_cfg_2_scramble_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[2].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_2_scramble_en_2_qs) + ); + + // F[ecc_en_2]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_2_ecc_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_2_gated_we), + .wd (bank1_info0_page_cfg_2_ecc_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[2].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_2_ecc_en_2_qs) + ); + + // F[he_en_2]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_2_he_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_2_gated_we), + .wd (bank1_info0_page_cfg_2_he_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[2].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_2_he_en_2_qs) + ); + + + // Subregister 3 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_3]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_3_gated_we; + assign bank1_info0_page_cfg_3_gated_we = bank1_info0_page_cfg_3_we & bank1_info0_regwen_3_qs; + // F[en_3]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_3_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_3_gated_we), + .wd (bank1_info0_page_cfg_3_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[3].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_3_en_3_qs) + ); + + // F[rd_en_3]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_3_rd_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_3_gated_we), + .wd (bank1_info0_page_cfg_3_rd_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[3].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_3_rd_en_3_qs) + ); + + // F[prog_en_3]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_3_prog_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_3_gated_we), + .wd (bank1_info0_page_cfg_3_prog_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[3].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_3_prog_en_3_qs) + ); + + // F[erase_en_3]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_3_erase_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_3_gated_we), + .wd (bank1_info0_page_cfg_3_erase_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[3].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_3_erase_en_3_qs) + ); + + // F[scramble_en_3]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_3_scramble_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_3_gated_we), + .wd (bank1_info0_page_cfg_3_scramble_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[3].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_3_scramble_en_3_qs) + ); + + // F[ecc_en_3]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_3_ecc_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_3_gated_we), + .wd (bank1_info0_page_cfg_3_ecc_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[3].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_3_ecc_en_3_qs) + ); + + // F[he_en_3]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_3_he_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_3_gated_we), + .wd (bank1_info0_page_cfg_3_he_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[3].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_3_he_en_3_qs) + ); + + + // Subregister 4 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_4]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_4_gated_we; + assign bank1_info0_page_cfg_4_gated_we = bank1_info0_page_cfg_4_we & bank1_info0_regwen_4_qs; + // F[en_4]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_4_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_4_gated_we), + .wd (bank1_info0_page_cfg_4_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[4].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_4_en_4_qs) + ); + + // F[rd_en_4]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_4_rd_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_4_gated_we), + .wd (bank1_info0_page_cfg_4_rd_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[4].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_4_rd_en_4_qs) + ); + + // F[prog_en_4]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_4_prog_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_4_gated_we), + .wd (bank1_info0_page_cfg_4_prog_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[4].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_4_prog_en_4_qs) + ); + + // F[erase_en_4]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_4_erase_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_4_gated_we), + .wd (bank1_info0_page_cfg_4_erase_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[4].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_4_erase_en_4_qs) + ); + + // F[scramble_en_4]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_4_scramble_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_4_gated_we), + .wd (bank1_info0_page_cfg_4_scramble_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[4].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_4_scramble_en_4_qs) + ); + + // F[ecc_en_4]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_4_ecc_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_4_gated_we), + .wd (bank1_info0_page_cfg_4_ecc_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[4].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_4_ecc_en_4_qs) + ); + + // F[he_en_4]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_4_he_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_4_gated_we), + .wd (bank1_info0_page_cfg_4_he_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[4].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_4_he_en_4_qs) + ); + + + // Subregister 5 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_5]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_5_gated_we; + assign bank1_info0_page_cfg_5_gated_we = bank1_info0_page_cfg_5_we & bank1_info0_regwen_5_qs; + // F[en_5]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_5_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_5_gated_we), + .wd (bank1_info0_page_cfg_5_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[5].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_5_en_5_qs) + ); + + // F[rd_en_5]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_5_rd_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_5_gated_we), + .wd (bank1_info0_page_cfg_5_rd_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[5].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_5_rd_en_5_qs) + ); + + // F[prog_en_5]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_5_prog_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_5_gated_we), + .wd (bank1_info0_page_cfg_5_prog_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[5].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_5_prog_en_5_qs) + ); + + // F[erase_en_5]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_5_erase_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_5_gated_we), + .wd (bank1_info0_page_cfg_5_erase_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[5].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_5_erase_en_5_qs) + ); + + // F[scramble_en_5]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_5_scramble_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_5_gated_we), + .wd (bank1_info0_page_cfg_5_scramble_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[5].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_5_scramble_en_5_qs) + ); + + // F[ecc_en_5]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_5_ecc_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_5_gated_we), + .wd (bank1_info0_page_cfg_5_ecc_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[5].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_5_ecc_en_5_qs) + ); + + // F[he_en_5]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_5_he_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_5_gated_we), + .wd (bank1_info0_page_cfg_5_he_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[5].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_5_he_en_5_qs) + ); + + + // Subregister 6 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_6]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_6_gated_we; + assign bank1_info0_page_cfg_6_gated_we = bank1_info0_page_cfg_6_we & bank1_info0_regwen_6_qs; + // F[en_6]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_6_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_6_gated_we), + .wd (bank1_info0_page_cfg_6_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[6].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_6_en_6_qs) + ); + + // F[rd_en_6]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_6_rd_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_6_gated_we), + .wd (bank1_info0_page_cfg_6_rd_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[6].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_6_rd_en_6_qs) + ); + + // F[prog_en_6]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_6_prog_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_6_gated_we), + .wd (bank1_info0_page_cfg_6_prog_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[6].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_6_prog_en_6_qs) + ); + + // F[erase_en_6]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_6_erase_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_6_gated_we), + .wd (bank1_info0_page_cfg_6_erase_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[6].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_6_erase_en_6_qs) + ); + + // F[scramble_en_6]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_6_scramble_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_6_gated_we), + .wd (bank1_info0_page_cfg_6_scramble_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[6].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_6_scramble_en_6_qs) + ); + + // F[ecc_en_6]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_6_ecc_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_6_gated_we), + .wd (bank1_info0_page_cfg_6_ecc_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[6].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_6_ecc_en_6_qs) + ); + + // F[he_en_6]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_6_he_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_6_gated_we), + .wd (bank1_info0_page_cfg_6_he_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[6].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_6_he_en_6_qs) + ); + + + // Subregister 7 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_7]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_7_gated_we; + assign bank1_info0_page_cfg_7_gated_we = bank1_info0_page_cfg_7_we & bank1_info0_regwen_7_qs; + // F[en_7]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_7_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_7_gated_we), + .wd (bank1_info0_page_cfg_7_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[7].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_7_en_7_qs) + ); + + // F[rd_en_7]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_7_rd_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_7_gated_we), + .wd (bank1_info0_page_cfg_7_rd_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[7].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_7_rd_en_7_qs) + ); + + // F[prog_en_7]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_7_prog_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_7_gated_we), + .wd (bank1_info0_page_cfg_7_prog_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[7].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_7_prog_en_7_qs) + ); + + // F[erase_en_7]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_7_erase_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_7_gated_we), + .wd (bank1_info0_page_cfg_7_erase_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[7].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_7_erase_en_7_qs) + ); + + // F[scramble_en_7]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_7_scramble_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_7_gated_we), + .wd (bank1_info0_page_cfg_7_scramble_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[7].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_7_scramble_en_7_qs) + ); + + // F[ecc_en_7]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_7_ecc_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_7_gated_we), + .wd (bank1_info0_page_cfg_7_ecc_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[7].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_7_ecc_en_7_qs) + ); + + // F[he_en_7]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_7_he_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_7_gated_we), + .wd (bank1_info0_page_cfg_7_he_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[7].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_7_he_en_7_qs) + ); + + + // Subregister 8 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_8]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_8_gated_we; + assign bank1_info0_page_cfg_8_gated_we = bank1_info0_page_cfg_8_we & bank1_info0_regwen_8_qs; + // F[en_8]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_8_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_8_gated_we), + .wd (bank1_info0_page_cfg_8_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[8].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_8_en_8_qs) + ); + + // F[rd_en_8]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_8_rd_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_8_gated_we), + .wd (bank1_info0_page_cfg_8_rd_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[8].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_8_rd_en_8_qs) + ); + + // F[prog_en_8]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_8_prog_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_8_gated_we), + .wd (bank1_info0_page_cfg_8_prog_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[8].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_8_prog_en_8_qs) + ); + + // F[erase_en_8]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_8_erase_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_8_gated_we), + .wd (bank1_info0_page_cfg_8_erase_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[8].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_8_erase_en_8_qs) + ); + + // F[scramble_en_8]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_8_scramble_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_8_gated_we), + .wd (bank1_info0_page_cfg_8_scramble_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[8].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_8_scramble_en_8_qs) + ); + + // F[ecc_en_8]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_8_ecc_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_8_gated_we), + .wd (bank1_info0_page_cfg_8_ecc_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[8].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_8_ecc_en_8_qs) + ); + + // F[he_en_8]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_8_he_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_8_gated_we), + .wd (bank1_info0_page_cfg_8_he_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[8].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_8_he_en_8_qs) + ); + + + // Subregister 9 of Multireg bank1_info0_page_cfg + // R[bank1_info0_page_cfg_9]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info0_page_cfg_9_gated_we; + assign bank1_info0_page_cfg_9_gated_we = bank1_info0_page_cfg_9_we & bank1_info0_regwen_9_qs; + // F[en_9]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_9_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_9_gated_we), + .wd (bank1_info0_page_cfg_9_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[9].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_9_en_9_qs) + ); + + // F[rd_en_9]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_9_rd_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_9_gated_we), + .wd (bank1_info0_page_cfg_9_rd_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[9].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_9_rd_en_9_qs) + ); + + // F[prog_en_9]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_9_prog_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_9_gated_we), + .wd (bank1_info0_page_cfg_9_prog_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[9].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_9_prog_en_9_qs) + ); + + // F[erase_en_9]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_9_erase_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_9_gated_we), + .wd (bank1_info0_page_cfg_9_erase_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[9].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_9_erase_en_9_qs) + ); + + // F[scramble_en_9]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_9_scramble_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_9_gated_we), + .wd (bank1_info0_page_cfg_9_scramble_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[9].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_9_scramble_en_9_qs) + ); + + // F[ecc_en_9]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_9_ecc_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_9_gated_we), + .wd (bank1_info0_page_cfg_9_ecc_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[9].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_9_ecc_en_9_qs) + ); + + // F[he_en_9]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info0_page_cfg_9_he_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info0_page_cfg_9_gated_we), + .wd (bank1_info0_page_cfg_9_he_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info0_page_cfg[9].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info0_page_cfg_9_he_en_9_qs) + ); + + + // Subregister 0 of Multireg bank1_info1_regwen + // R[bank1_info1_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info1_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_regwen_we), + .wd (bank1_info1_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info1_regwen_qs) + ); + + + // Subregister 0 of Multireg bank1_info1_page_cfg + // R[bank1_info1_page_cfg]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info1_page_cfg_gated_we; + assign bank1_info1_page_cfg_gated_we = bank1_info1_page_cfg_we & bank1_info1_regwen_qs; + // F[en_0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info1_page_cfg_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_page_cfg_gated_we), + .wd (bank1_info1_page_cfg_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info1_page_cfg[0].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info1_page_cfg_en_0_qs) + ); + + // F[rd_en_0]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info1_page_cfg_rd_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_page_cfg_gated_we), + .wd (bank1_info1_page_cfg_rd_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info1_page_cfg[0].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info1_page_cfg_rd_en_0_qs) + ); + + // F[prog_en_0]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info1_page_cfg_prog_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_page_cfg_gated_we), + .wd (bank1_info1_page_cfg_prog_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info1_page_cfg[0].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info1_page_cfg_prog_en_0_qs) + ); + + // F[erase_en_0]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info1_page_cfg_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_page_cfg_gated_we), + .wd (bank1_info1_page_cfg_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info1_page_cfg[0].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info1_page_cfg_erase_en_0_qs) + ); + + // F[scramble_en_0]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info1_page_cfg_scramble_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_page_cfg_gated_we), + .wd (bank1_info1_page_cfg_scramble_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info1_page_cfg[0].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info1_page_cfg_scramble_en_0_qs) + ); + + // F[ecc_en_0]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info1_page_cfg_ecc_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_page_cfg_gated_we), + .wd (bank1_info1_page_cfg_ecc_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info1_page_cfg[0].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info1_page_cfg_ecc_en_0_qs) + ); + + // F[he_en_0]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info1_page_cfg_he_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info1_page_cfg_gated_we), + .wd (bank1_info1_page_cfg_he_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info1_page_cfg[0].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info1_page_cfg_he_en_0_qs) + ); + + + // Subregister 0 of Multireg bank1_info2_regwen + // R[bank1_info2_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info2_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_regwen_0_we), + .wd (bank1_info2_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info2_regwen_0_qs) + ); + + + // Subregister 1 of Multireg bank1_info2_regwen + // R[bank1_info2_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank1_info2_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_regwen_1_we), + .wd (bank1_info2_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank1_info2_regwen_1_qs) + ); + + + // Subregister 0 of Multireg bank1_info2_page_cfg + // R[bank1_info2_page_cfg_0]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info2_page_cfg_0_gated_we; + assign bank1_info2_page_cfg_0_gated_we = bank1_info2_page_cfg_0_we & bank1_info2_regwen_0_qs; + // F[en_0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_0_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_0_gated_we), + .wd (bank1_info2_page_cfg_0_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[0].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_0_en_0_qs) + ); + + // F[rd_en_0]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_0_rd_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_0_gated_we), + .wd (bank1_info2_page_cfg_0_rd_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[0].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_0_rd_en_0_qs) + ); + + // F[prog_en_0]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_0_prog_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_0_gated_we), + .wd (bank1_info2_page_cfg_0_prog_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[0].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_0_prog_en_0_qs) + ); + + // F[erase_en_0]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_0_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_0_gated_we), + .wd (bank1_info2_page_cfg_0_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[0].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_0_erase_en_0_qs) + ); + + // F[scramble_en_0]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_0_scramble_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_0_gated_we), + .wd (bank1_info2_page_cfg_0_scramble_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[0].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_0_scramble_en_0_qs) + ); + + // F[ecc_en_0]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_0_ecc_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_0_gated_we), + .wd (bank1_info2_page_cfg_0_ecc_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[0].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_0_ecc_en_0_qs) + ); + + // F[he_en_0]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_0_he_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_0_gated_we), + .wd (bank1_info2_page_cfg_0_he_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[0].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_0_he_en_0_qs) + ); + + + // Subregister 1 of Multireg bank1_info2_page_cfg + // R[bank1_info2_page_cfg_1]: V(False) + // Create REGWEN-gated WE signal + logic bank1_info2_page_cfg_1_gated_we; + assign bank1_info2_page_cfg_1_gated_we = bank1_info2_page_cfg_1_we & bank1_info2_regwen_1_qs; + // F[en_1]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_1_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_1_gated_we), + .wd (bank1_info2_page_cfg_1_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[1].en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_1_en_1_qs) + ); + + // F[rd_en_1]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_1_rd_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_1_gated_we), + .wd (bank1_info2_page_cfg_1_rd_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[1].rd_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_1_rd_en_1_qs) + ); + + // F[prog_en_1]: 11:8 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_1_prog_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_1_gated_we), + .wd (bank1_info2_page_cfg_1_prog_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[1].prog_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_1_prog_en_1_qs) + ); + + // F[erase_en_1]: 15:12 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_1_erase_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_1_gated_we), + .wd (bank1_info2_page_cfg_1_erase_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[1].erase_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_1_erase_en_1_qs) + ); + + // F[scramble_en_1]: 19:16 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_1_scramble_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_1_gated_we), + .wd (bank1_info2_page_cfg_1_scramble_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[1].scramble_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_1_scramble_en_1_qs) + ); + + // F[ecc_en_1]: 23:20 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_1_ecc_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_1_gated_we), + .wd (bank1_info2_page_cfg_1_ecc_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[1].ecc_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_1_ecc_en_1_qs) + ); + + // F[he_en_1]: 27:24 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_bank1_info2_page_cfg_1_he_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank1_info2_page_cfg_1_gated_we), + .wd (bank1_info2_page_cfg_1_he_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.bank1_info2_page_cfg[1].he_en.q), + .ds (), + + // to register interface (read) + .qs (bank1_info2_page_cfg_1_he_en_1_qs) + ); + + + // R[hw_info_cfg_override]: V(False) + // F[scramble_dis]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_hw_info_cfg_override_scramble_dis ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (hw_info_cfg_override_we), + .wd (hw_info_cfg_override_scramble_dis_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.hw_info_cfg_override.scramble_dis.q), + .ds (), + + // to register interface (read) + .qs (hw_info_cfg_override_scramble_dis_qs) + ); + + // F[ecc_dis]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_hw_info_cfg_override_ecc_dis ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (hw_info_cfg_override_we), + .wd (hw_info_cfg_override_ecc_dis_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.hw_info_cfg_override.ecc_dis.q), + .ds (), + + // to register interface (read) + .qs (hw_info_cfg_override_ecc_dis_qs) + ); + + + // R[bank_cfg_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_bank_cfg_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (bank_cfg_regwen_we), + .wd (bank_cfg_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (bank_cfg_regwen_qs) + ); + + + // Subregister 0 of Multireg mp_bank_cfg_shadowed + // R[mp_bank_cfg_shadowed]: V(False) + // Create REGWEN-gated WE signal + logic mp_bank_cfg_shadowed_gated_we; + assign mp_bank_cfg_shadowed_gated_we = mp_bank_cfg_shadowed_we & bank_cfg_regwen_qs; + // F[erase_en_0]: 0:0 + prim_subreg_shadow #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mp_bank_cfg_shadowed_erase_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (mp_bank_cfg_shadowed_re), + .we (mp_bank_cfg_shadowed_gated_we), + .wd (mp_bank_cfg_shadowed_erase_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_bank_cfg_shadowed[0].q), + .ds (), + + // to register interface (read) + .qs (mp_bank_cfg_shadowed_erase_en_0_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (mp_bank_cfg_shadowed_erase_en_0_update_err), + .err_storage (mp_bank_cfg_shadowed_erase_en_0_storage_err) + ); + + // F[erase_en_1]: 1:1 + prim_subreg_shadow #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mp_bank_cfg_shadowed_erase_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .rst_shadowed_ni (rst_shadowed_ni), + + // from register interface + .re (mp_bank_cfg_shadowed_re), + .we (mp_bank_cfg_shadowed_gated_we), + .wd (mp_bank_cfg_shadowed_erase_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mp_bank_cfg_shadowed[1].q), + .ds (), + + // to register interface (read) + .qs (mp_bank_cfg_shadowed_erase_en_1_qs), + + // Shadow register phase. Relevant for hwext only. + .phase (), + + // Shadow register error conditions + .err_update (mp_bank_cfg_shadowed_erase_en_1_update_err), + .err_storage (mp_bank_cfg_shadowed_erase_en_1_storage_err) + ); + + + // R[op_status]: V(False) + // F[done]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_op_status_done ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (op_status_we), + .wd (op_status_done_wd), + + // from internal hardware + .de (hw2reg.op_status.done.de), + .d (hw2reg.op_status.done.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (op_status_done_qs) + ); + + // F[err]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_op_status_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (op_status_we), + .wd (op_status_err_wd), + + // from internal hardware + .de (hw2reg.op_status.err.de), + .d (hw2reg.op_status.err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (op_status_err_qs) + ); + + + // R[status]: V(False) + // F[rd_full]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_rd_full ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.rd_full.de), + .d (hw2reg.status.rd_full.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_rd_full_qs) + ); + + // F[rd_empty]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_status_rd_empty ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.rd_empty.de), + .d (hw2reg.status.rd_empty.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_rd_empty_qs) + ); + + // F[prog_full]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_prog_full ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.prog_full.de), + .d (hw2reg.status.prog_full.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_prog_full_qs) + ); + + // F[prog_empty]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_status_prog_empty ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.prog_empty.de), + .d (hw2reg.status.prog_empty.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_prog_empty_qs) + ); + + // F[init_wip]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_init_wip ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.init_wip.de), + .d (hw2reg.status.init_wip.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_init_wip_qs) + ); + + // F[initialized]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_status_initialized ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.status.initialized.de), + .d (hw2reg.status.initialized.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (status_initialized_qs) + ); + + + // R[debug_state]: V(True) + prim_subreg_ext #( + .DW (11) + ) u_debug_state ( + .re (debug_state_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.debug_state.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (debug_state_qs) + ); + + + // R[err_code]: V(False) + // F[op_err]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_op_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_op_err_wd), + + // from internal hardware + .de (hw2reg.err_code.op_err.de), + .d (hw2reg.err_code.op_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_op_err_qs) + ); + + // F[mp_err]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_mp_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_mp_err_wd), + + // from internal hardware + .de (hw2reg.err_code.mp_err.de), + .d (hw2reg.err_code.mp_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_mp_err_qs) + ); + + // F[rd_err]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_rd_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_rd_err_wd), + + // from internal hardware + .de (hw2reg.err_code.rd_err.de), + .d (hw2reg.err_code.rd_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_rd_err_qs) + ); + + // F[prog_err]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_prog_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_prog_err_wd), + + // from internal hardware + .de (hw2reg.err_code.prog_err.de), + .d (hw2reg.err_code.prog_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_prog_err_qs) + ); + + // F[prog_win_err]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_prog_win_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_prog_win_err_wd), + + // from internal hardware + .de (hw2reg.err_code.prog_win_err.de), + .d (hw2reg.err_code.prog_win_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_prog_win_err_qs) + ); + + // F[prog_type_err]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_prog_type_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_prog_type_err_wd), + + // from internal hardware + .de (hw2reg.err_code.prog_type_err.de), + .d (hw2reg.err_code.prog_type_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_prog_type_err_qs) + ); + + // F[update_err]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_update_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_update_err_wd), + + // from internal hardware + .de (hw2reg.err_code.update_err.de), + .d (hw2reg.err_code.update_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_update_err_qs) + ); + + // F[macro_err]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_macro_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (err_code_we), + .wd (err_code_macro_err_wd), + + // from internal hardware + .de (hw2reg.err_code.macro_err.de), + .d (hw2reg.err_code.macro_err.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_code_macro_err_qs) + ); + + + // R[std_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_std_fault_status_reg_intg_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.reg_intg_err.de), + .d (hw2reg.std_fault_status.reg_intg_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.reg_intg_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_reg_intg_err_qs) + ); + + // F[prog_intg_err]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_prog_intg_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.prog_intg_err.de), + .d (hw2reg.std_fault_status.prog_intg_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.prog_intg_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_prog_intg_err_qs) + ); + + // F[lcmgr_err]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_lcmgr_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.lcmgr_err.de), + .d (hw2reg.std_fault_status.lcmgr_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.lcmgr_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_lcmgr_err_qs) + ); + + // F[lcmgr_intg_err]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_lcmgr_intg_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.lcmgr_intg_err.de), + .d (hw2reg.std_fault_status.lcmgr_intg_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.lcmgr_intg_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_lcmgr_intg_err_qs) + ); + + // F[arb_fsm_err]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_arb_fsm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.arb_fsm_err.de), + .d (hw2reg.std_fault_status.arb_fsm_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.arb_fsm_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_arb_fsm_err_qs) + ); + + // F[storage_err]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_storage_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.storage_err.de), + .d (hw2reg.std_fault_status.storage_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.storage_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_storage_err_qs) + ); + + // F[phy_fsm_err]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_phy_fsm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.phy_fsm_err.de), + .d (hw2reg.std_fault_status.phy_fsm_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.phy_fsm_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_phy_fsm_err_qs) + ); + + // F[ctrl_cnt_err]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_ctrl_cnt_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.ctrl_cnt_err.de), + .d (hw2reg.std_fault_status.ctrl_cnt_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.ctrl_cnt_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_ctrl_cnt_err_qs) + ); + + // F[fifo_err]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_std_fault_status_fifo_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.std_fault_status.fifo_err.de), + .d (hw2reg.std_fault_status.fifo_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.std_fault_status.fifo_err.q), + .ds (), + + // to register interface (read) + .qs (std_fault_status_fifo_err_qs) + ); + + + // R[fault_status]: V(False) + // F[op_err]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_op_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.op_err.de), + .d (hw2reg.fault_status.op_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.op_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_op_err_qs) + ); + + // F[mp_err]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_mp_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.mp_err.de), + .d (hw2reg.fault_status.mp_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.mp_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_mp_err_qs) + ); + + // F[rd_err]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_rd_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.rd_err.de), + .d (hw2reg.fault_status.rd_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.rd_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_rd_err_qs) + ); + + // F[prog_err]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_prog_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.prog_err.de), + .d (hw2reg.fault_status.prog_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.prog_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_prog_err_qs) + ); + + // F[prog_win_err]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_prog_win_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.prog_win_err.de), + .d (hw2reg.fault_status.prog_win_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.prog_win_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_prog_win_err_qs) + ); + + // F[prog_type_err]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_prog_type_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.prog_type_err.de), + .d (hw2reg.fault_status.prog_type_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.prog_type_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_prog_type_err_qs) + ); + + // F[seed_err]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_seed_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.seed_err.de), + .d (hw2reg.fault_status.seed_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.seed_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_seed_err_qs) + ); + + // F[phy_relbl_err]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_phy_relbl_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fault_status_we), + .wd (fault_status_phy_relbl_err_wd), + + // from internal hardware + .de (hw2reg.fault_status.phy_relbl_err.de), + .d (hw2reg.fault_status.phy_relbl_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.phy_relbl_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_phy_relbl_err_qs) + ); + + // F[phy_storage_err]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_phy_storage_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fault_status_we), + .wd (fault_status_phy_storage_err_wd), + + // from internal hardware + .de (hw2reg.fault_status.phy_storage_err.de), + .d (hw2reg.fault_status.phy_storage_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.phy_storage_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_phy_storage_err_qs) + ); + + // F[spurious_ack]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_spurious_ack ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.spurious_ack.de), + .d (hw2reg.fault_status.spurious_ack.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.spurious_ack.q), + .ds (), + + // to register interface (read) + .qs (fault_status_spurious_ack_qs) + ); + + // F[arb_err]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_arb_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.arb_err.de), + .d (hw2reg.fault_status.arb_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.arb_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_arb_err_qs) + ); + + // F[host_gnt_err]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fault_status_host_gnt_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.fault_status.host_gnt_err.de), + .d (hw2reg.fault_status.host_gnt_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.fault_status.host_gnt_err.q), + .ds (), + + // to register interface (read) + .qs (fault_status_host_gnt_err_qs) + ); + + + // R[err_addr]: V(False) + prim_subreg #( + .DW (16), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (16'h0), + .Mubi (1'b0) + ) u_err_addr ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_addr.de), + .d (hw2reg.err_addr.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (err_addr_qs) + ); + + + // Subregister 0 of Multireg ecc_single_err_cnt + // R[ecc_single_err_cnt]: V(False) + // F[ecc_single_err_cnt_0]: 7:0 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_ecc_single_err_cnt_ecc_single_err_cnt_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ecc_single_err_cnt_we), + .wd (ecc_single_err_cnt_ecc_single_err_cnt_0_wd), + + // from internal hardware + .de (hw2reg.ecc_single_err_cnt[0].de), + .d (hw2reg.ecc_single_err_cnt[0].d), + + // to internal hardware + .qe (), + .q (reg2hw.ecc_single_err_cnt[0].q), + .ds (), + + // to register interface (read) + .qs (ecc_single_err_cnt_ecc_single_err_cnt_0_qs) + ); + + // F[ecc_single_err_cnt_1]: 15:8 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_ecc_single_err_cnt_ecc_single_err_cnt_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ecc_single_err_cnt_we), + .wd (ecc_single_err_cnt_ecc_single_err_cnt_1_wd), + + // from internal hardware + .de (hw2reg.ecc_single_err_cnt[1].de), + .d (hw2reg.ecc_single_err_cnt[1].d), + + // to internal hardware + .qe (), + .q (reg2hw.ecc_single_err_cnt[1].q), + .ds (), + + // to register interface (read) + .qs (ecc_single_err_cnt_ecc_single_err_cnt_1_qs) + ); + + + // Subregister 0 of Multireg ecc_single_err_addr + // R[ecc_single_err_addr_0]: V(False) + prim_subreg #( + .DW (16), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (16'h0), + .Mubi (1'b0) + ) u_ecc_single_err_addr_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ecc_single_err_addr[0].de), + .d (hw2reg.ecc_single_err_addr[0].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ecc_single_err_addr_0_qs) + ); + + + // Subregister 1 of Multireg ecc_single_err_addr + // R[ecc_single_err_addr_1]: V(False) + prim_subreg #( + .DW (16), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (16'h0), + .Mubi (1'b0) + ) u_ecc_single_err_addr_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ecc_single_err_addr[1].de), + .d (hw2reg.ecc_single_err_addr[1].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ecc_single_err_addr_1_qs) + ); + + + // R[phy_alert_cfg]: V(False) + // F[alert_ack]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_phy_alert_cfg_alert_ack ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (phy_alert_cfg_we), + .wd (phy_alert_cfg_alert_ack_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.phy_alert_cfg.alert_ack.q), + .ds (), + + // to register interface (read) + .qs (phy_alert_cfg_alert_ack_qs) + ); + + // F[alert_trig]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_phy_alert_cfg_alert_trig ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (phy_alert_cfg_we), + .wd (phy_alert_cfg_alert_trig_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.phy_alert_cfg.alert_trig.q), + .ds (), + + // to register interface (read) + .qs (phy_alert_cfg_alert_trig_qs) + ); + + + // R[phy_status]: V(False) + // F[init_wip]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_phy_status_init_wip ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.phy_status.init_wip.de), + .d (hw2reg.phy_status.init_wip.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (phy_status_init_wip_qs) + ); + + // F[prog_normal_avail]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_phy_status_prog_normal_avail ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.phy_status.prog_normal_avail.de), + .d (hw2reg.phy_status.prog_normal_avail.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (phy_status_prog_normal_avail_qs) + ); + + // F[prog_repair_avail]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_phy_status_prog_repair_avail ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.phy_status.prog_repair_avail.de), + .d (hw2reg.phy_status.prog_repair_avail.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (phy_status_prog_repair_avail_qs) + ); + + + // R[scratch]: V(False) + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_scratch ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (scratch_we), + .wd (scratch_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.scratch.q), + .ds (), + + // to register interface (read) + .qs (scratch_qs) + ); + + + // R[fifo_lvl]: V(False) + // F[prog]: 4:0 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'hf), + .Mubi (1'b0) + ) u_fifo_lvl_prog ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fifo_lvl_we), + .wd (fifo_lvl_prog_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.fifo_lvl.prog.q), + .ds (), + + // to register interface (read) + .qs (fifo_lvl_prog_qs) + ); + + // F[rd]: 12:8 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'hf), + .Mubi (1'b0) + ) u_fifo_lvl_rd ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fifo_lvl_we), + .wd (fifo_lvl_rd_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.fifo_lvl.rd.q), + .ds (), + + // to register interface (read) + .qs (fifo_lvl_rd_qs) + ); + + + // R[fifo_rst]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_fifo_rst ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (fifo_rst_we), + .wd (fifo_rst_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.fifo_rst.q), + .ds (), + + // to register interface (read) + .qs (fifo_rst_qs) + ); + + + // R[curr_fifo_lvl]: V(True) + // F[prog]: 4:0 + prim_subreg_ext #( + .DW (5) + ) u_curr_fifo_lvl_prog ( + .re (curr_fifo_lvl_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.curr_fifo_lvl.prog.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (curr_fifo_lvl_prog_qs) + ); + + // F[rd]: 12:8 + prim_subreg_ext #( + .DW (5) + ) u_curr_fifo_lvl_rd ( + .re (curr_fifo_lvl_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.curr_fifo_lvl.rd.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (curr_fifo_lvl_rd_qs) + ); + + + + logic [107:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == FLASH_CTRL_INTR_STATE_OFFSET); + addr_hit[ 1] = (reg_addr == FLASH_CTRL_INTR_ENABLE_OFFSET); + addr_hit[ 2] = (reg_addr == FLASH_CTRL_INTR_TEST_OFFSET); + addr_hit[ 3] = (reg_addr == FLASH_CTRL_ALERT_TEST_OFFSET); + addr_hit[ 4] = (reg_addr == FLASH_CTRL_DIS_OFFSET); + addr_hit[ 5] = (reg_addr == FLASH_CTRL_EXEC_OFFSET); + addr_hit[ 6] = (reg_addr == FLASH_CTRL_INIT_OFFSET); + addr_hit[ 7] = (reg_addr == FLASH_CTRL_CTRL_REGWEN_OFFSET); + addr_hit[ 8] = (reg_addr == FLASH_CTRL_CONTROL_OFFSET); + addr_hit[ 9] = (reg_addr == FLASH_CTRL_ADDR_OFFSET); + addr_hit[ 10] = (reg_addr == FLASH_CTRL_PROG_TYPE_EN_OFFSET); + addr_hit[ 11] = (reg_addr == FLASH_CTRL_ERASE_SUSPEND_OFFSET); + addr_hit[ 12] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_0_OFFSET); + addr_hit[ 13] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_1_OFFSET); + addr_hit[ 14] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_2_OFFSET); + addr_hit[ 15] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_3_OFFSET); + addr_hit[ 16] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_4_OFFSET); + addr_hit[ 17] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_5_OFFSET); + addr_hit[ 18] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_6_OFFSET); + addr_hit[ 19] = (reg_addr == FLASH_CTRL_REGION_CFG_REGWEN_7_OFFSET); + addr_hit[ 20] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_0_OFFSET); + addr_hit[ 21] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_1_OFFSET); + addr_hit[ 22] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_2_OFFSET); + addr_hit[ 23] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_3_OFFSET); + addr_hit[ 24] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_4_OFFSET); + addr_hit[ 25] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_5_OFFSET); + addr_hit[ 26] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_6_OFFSET); + addr_hit[ 27] = (reg_addr == FLASH_CTRL_MP_REGION_CFG_7_OFFSET); + addr_hit[ 28] = (reg_addr == FLASH_CTRL_MP_REGION_0_OFFSET); + addr_hit[ 29] = (reg_addr == FLASH_CTRL_MP_REGION_1_OFFSET); + addr_hit[ 30] = (reg_addr == FLASH_CTRL_MP_REGION_2_OFFSET); + addr_hit[ 31] = (reg_addr == FLASH_CTRL_MP_REGION_3_OFFSET); + addr_hit[ 32] = (reg_addr == FLASH_CTRL_MP_REGION_4_OFFSET); + addr_hit[ 33] = (reg_addr == FLASH_CTRL_MP_REGION_5_OFFSET); + addr_hit[ 34] = (reg_addr == FLASH_CTRL_MP_REGION_6_OFFSET); + addr_hit[ 35] = (reg_addr == FLASH_CTRL_MP_REGION_7_OFFSET); + addr_hit[ 36] = (reg_addr == FLASH_CTRL_DEFAULT_REGION_OFFSET); + addr_hit[ 37] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_0_OFFSET); + addr_hit[ 38] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_1_OFFSET); + addr_hit[ 39] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_2_OFFSET); + addr_hit[ 40] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_3_OFFSET); + addr_hit[ 41] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_4_OFFSET); + addr_hit[ 42] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_5_OFFSET); + addr_hit[ 43] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_6_OFFSET); + addr_hit[ 44] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_7_OFFSET); + addr_hit[ 45] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_8_OFFSET); + addr_hit[ 46] = (reg_addr == FLASH_CTRL_BANK0_INFO0_REGWEN_9_OFFSET); + addr_hit[ 47] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_OFFSET); + addr_hit[ 48] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_1_OFFSET); + addr_hit[ 49] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_2_OFFSET); + addr_hit[ 50] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_3_OFFSET); + addr_hit[ 51] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_4_OFFSET); + addr_hit[ 52] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_5_OFFSET); + addr_hit[ 53] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_6_OFFSET); + addr_hit[ 54] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_7_OFFSET); + addr_hit[ 55] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_8_OFFSET); + addr_hit[ 56] = (reg_addr == FLASH_CTRL_BANK0_INFO0_PAGE_CFG_9_OFFSET); + addr_hit[ 57] = (reg_addr == FLASH_CTRL_BANK0_INFO1_REGWEN_OFFSET); + addr_hit[ 58] = (reg_addr == FLASH_CTRL_BANK0_INFO1_PAGE_CFG_OFFSET); + addr_hit[ 59] = (reg_addr == FLASH_CTRL_BANK0_INFO2_REGWEN_0_OFFSET); + addr_hit[ 60] = (reg_addr == FLASH_CTRL_BANK0_INFO2_REGWEN_1_OFFSET); + addr_hit[ 61] = (reg_addr == FLASH_CTRL_BANK0_INFO2_PAGE_CFG_0_OFFSET); + addr_hit[ 62] = (reg_addr == FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_OFFSET); + addr_hit[ 63] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_0_OFFSET); + addr_hit[ 64] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_1_OFFSET); + addr_hit[ 65] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_2_OFFSET); + addr_hit[ 66] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_3_OFFSET); + addr_hit[ 67] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_4_OFFSET); + addr_hit[ 68] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_5_OFFSET); + addr_hit[ 69] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_6_OFFSET); + addr_hit[ 70] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_7_OFFSET); + addr_hit[ 71] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_8_OFFSET); + addr_hit[ 72] = (reg_addr == FLASH_CTRL_BANK1_INFO0_REGWEN_9_OFFSET); + addr_hit[ 73] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0_OFFSET); + addr_hit[ 74] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1_OFFSET); + addr_hit[ 75] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_2_OFFSET); + addr_hit[ 76] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_3_OFFSET); + addr_hit[ 77] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_4_OFFSET); + addr_hit[ 78] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_5_OFFSET); + addr_hit[ 79] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_6_OFFSET); + addr_hit[ 80] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_7_OFFSET); + addr_hit[ 81] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_8_OFFSET); + addr_hit[ 82] = (reg_addr == FLASH_CTRL_BANK1_INFO0_PAGE_CFG_9_OFFSET); + addr_hit[ 83] = (reg_addr == FLASH_CTRL_BANK1_INFO1_REGWEN_OFFSET); + addr_hit[ 84] = (reg_addr == FLASH_CTRL_BANK1_INFO1_PAGE_CFG_OFFSET); + addr_hit[ 85] = (reg_addr == FLASH_CTRL_BANK1_INFO2_REGWEN_0_OFFSET); + addr_hit[ 86] = (reg_addr == FLASH_CTRL_BANK1_INFO2_REGWEN_1_OFFSET); + addr_hit[ 87] = (reg_addr == FLASH_CTRL_BANK1_INFO2_PAGE_CFG_0_OFFSET); + addr_hit[ 88] = (reg_addr == FLASH_CTRL_BANK1_INFO2_PAGE_CFG_1_OFFSET); + addr_hit[ 89] = (reg_addr == FLASH_CTRL_HW_INFO_CFG_OVERRIDE_OFFSET); + addr_hit[ 90] = (reg_addr == FLASH_CTRL_BANK_CFG_REGWEN_OFFSET); + addr_hit[ 91] = (reg_addr == FLASH_CTRL_MP_BANK_CFG_SHADOWED_OFFSET); + addr_hit[ 92] = (reg_addr == FLASH_CTRL_OP_STATUS_OFFSET); + addr_hit[ 93] = (reg_addr == FLASH_CTRL_STATUS_OFFSET); + addr_hit[ 94] = (reg_addr == FLASH_CTRL_DEBUG_STATE_OFFSET); + addr_hit[ 95] = (reg_addr == FLASH_CTRL_ERR_CODE_OFFSET); + addr_hit[ 96] = (reg_addr == FLASH_CTRL_STD_FAULT_STATUS_OFFSET); + addr_hit[ 97] = (reg_addr == FLASH_CTRL_FAULT_STATUS_OFFSET); + addr_hit[ 98] = (reg_addr == FLASH_CTRL_ERR_ADDR_OFFSET); + addr_hit[ 99] = (reg_addr == FLASH_CTRL_ECC_SINGLE_ERR_CNT_OFFSET); + addr_hit[100] = (reg_addr == FLASH_CTRL_ECC_SINGLE_ERR_ADDR_0_OFFSET); + addr_hit[101] = (reg_addr == FLASH_CTRL_ECC_SINGLE_ERR_ADDR_1_OFFSET); + addr_hit[102] = (reg_addr == FLASH_CTRL_PHY_ALERT_CFG_OFFSET); + addr_hit[103] = (reg_addr == FLASH_CTRL_PHY_STATUS_OFFSET); + addr_hit[104] = (reg_addr == FLASH_CTRL_SCRATCH_OFFSET); + addr_hit[105] = (reg_addr == FLASH_CTRL_FIFO_LVL_OFFSET); + addr_hit[106] = (reg_addr == FLASH_CTRL_FIFO_RST_OFFSET); + addr_hit[107] = (reg_addr == FLASH_CTRL_CURR_FIFO_LVL_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] & (|(FLASH_CTRL_CORE_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(FLASH_CTRL_CORE_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(FLASH_CTRL_CORE_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(FLASH_CTRL_CORE_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(FLASH_CTRL_CORE_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(FLASH_CTRL_CORE_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(FLASH_CTRL_CORE_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(FLASH_CTRL_CORE_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(FLASH_CTRL_CORE_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(FLASH_CTRL_CORE_PERMIT[ 9] & ~reg_be))) | + (addr_hit[ 10] & (|(FLASH_CTRL_CORE_PERMIT[ 10] & ~reg_be))) | + (addr_hit[ 11] & (|(FLASH_CTRL_CORE_PERMIT[ 11] & ~reg_be))) | + (addr_hit[ 12] & (|(FLASH_CTRL_CORE_PERMIT[ 12] & ~reg_be))) | + (addr_hit[ 13] & (|(FLASH_CTRL_CORE_PERMIT[ 13] & ~reg_be))) | + (addr_hit[ 14] & (|(FLASH_CTRL_CORE_PERMIT[ 14] & ~reg_be))) | + (addr_hit[ 15] & (|(FLASH_CTRL_CORE_PERMIT[ 15] & ~reg_be))) | + (addr_hit[ 16] & (|(FLASH_CTRL_CORE_PERMIT[ 16] & ~reg_be))) | + (addr_hit[ 17] & (|(FLASH_CTRL_CORE_PERMIT[ 17] & ~reg_be))) | + (addr_hit[ 18] & (|(FLASH_CTRL_CORE_PERMIT[ 18] & ~reg_be))) | + (addr_hit[ 19] & (|(FLASH_CTRL_CORE_PERMIT[ 19] & ~reg_be))) | + (addr_hit[ 20] & (|(FLASH_CTRL_CORE_PERMIT[ 20] & ~reg_be))) | + (addr_hit[ 21] & (|(FLASH_CTRL_CORE_PERMIT[ 21] & ~reg_be))) | + (addr_hit[ 22] & (|(FLASH_CTRL_CORE_PERMIT[ 22] & ~reg_be))) | + (addr_hit[ 23] & (|(FLASH_CTRL_CORE_PERMIT[ 23] & ~reg_be))) | + (addr_hit[ 24] & (|(FLASH_CTRL_CORE_PERMIT[ 24] & ~reg_be))) | + (addr_hit[ 25] & (|(FLASH_CTRL_CORE_PERMIT[ 25] & ~reg_be))) | + (addr_hit[ 26] & (|(FLASH_CTRL_CORE_PERMIT[ 26] & ~reg_be))) | + (addr_hit[ 27] & (|(FLASH_CTRL_CORE_PERMIT[ 27] & ~reg_be))) | + (addr_hit[ 28] & (|(FLASH_CTRL_CORE_PERMIT[ 28] & ~reg_be))) | + (addr_hit[ 29] & (|(FLASH_CTRL_CORE_PERMIT[ 29] & ~reg_be))) | + (addr_hit[ 30] & (|(FLASH_CTRL_CORE_PERMIT[ 30] & ~reg_be))) | + (addr_hit[ 31] & (|(FLASH_CTRL_CORE_PERMIT[ 31] & ~reg_be))) | + (addr_hit[ 32] & (|(FLASH_CTRL_CORE_PERMIT[ 32] & ~reg_be))) | + (addr_hit[ 33] & (|(FLASH_CTRL_CORE_PERMIT[ 33] & ~reg_be))) | + (addr_hit[ 34] & (|(FLASH_CTRL_CORE_PERMIT[ 34] & ~reg_be))) | + (addr_hit[ 35] & (|(FLASH_CTRL_CORE_PERMIT[ 35] & ~reg_be))) | + (addr_hit[ 36] & (|(FLASH_CTRL_CORE_PERMIT[ 36] & ~reg_be))) | + (addr_hit[ 37] & (|(FLASH_CTRL_CORE_PERMIT[ 37] & ~reg_be))) | + (addr_hit[ 38] & (|(FLASH_CTRL_CORE_PERMIT[ 38] & ~reg_be))) | + (addr_hit[ 39] & (|(FLASH_CTRL_CORE_PERMIT[ 39] & ~reg_be))) | + (addr_hit[ 40] & (|(FLASH_CTRL_CORE_PERMIT[ 40] & ~reg_be))) | + (addr_hit[ 41] & (|(FLASH_CTRL_CORE_PERMIT[ 41] & ~reg_be))) | + (addr_hit[ 42] & (|(FLASH_CTRL_CORE_PERMIT[ 42] & ~reg_be))) | + (addr_hit[ 43] & (|(FLASH_CTRL_CORE_PERMIT[ 43] & ~reg_be))) | + (addr_hit[ 44] & (|(FLASH_CTRL_CORE_PERMIT[ 44] & ~reg_be))) | + (addr_hit[ 45] & (|(FLASH_CTRL_CORE_PERMIT[ 45] & ~reg_be))) | + (addr_hit[ 46] & (|(FLASH_CTRL_CORE_PERMIT[ 46] & ~reg_be))) | + (addr_hit[ 47] & (|(FLASH_CTRL_CORE_PERMIT[ 47] & ~reg_be))) | + (addr_hit[ 48] & (|(FLASH_CTRL_CORE_PERMIT[ 48] & ~reg_be))) | + (addr_hit[ 49] & (|(FLASH_CTRL_CORE_PERMIT[ 49] & ~reg_be))) | + (addr_hit[ 50] & (|(FLASH_CTRL_CORE_PERMIT[ 50] & ~reg_be))) | + (addr_hit[ 51] & (|(FLASH_CTRL_CORE_PERMIT[ 51] & ~reg_be))) | + (addr_hit[ 52] & (|(FLASH_CTRL_CORE_PERMIT[ 52] & ~reg_be))) | + (addr_hit[ 53] & (|(FLASH_CTRL_CORE_PERMIT[ 53] & ~reg_be))) | + (addr_hit[ 54] & (|(FLASH_CTRL_CORE_PERMIT[ 54] & ~reg_be))) | + (addr_hit[ 55] & (|(FLASH_CTRL_CORE_PERMIT[ 55] & ~reg_be))) | + (addr_hit[ 56] & (|(FLASH_CTRL_CORE_PERMIT[ 56] & ~reg_be))) | + (addr_hit[ 57] & (|(FLASH_CTRL_CORE_PERMIT[ 57] & ~reg_be))) | + (addr_hit[ 58] & (|(FLASH_CTRL_CORE_PERMIT[ 58] & ~reg_be))) | + (addr_hit[ 59] & (|(FLASH_CTRL_CORE_PERMIT[ 59] & ~reg_be))) | + (addr_hit[ 60] & (|(FLASH_CTRL_CORE_PERMIT[ 60] & ~reg_be))) | + (addr_hit[ 61] & (|(FLASH_CTRL_CORE_PERMIT[ 61] & ~reg_be))) | + (addr_hit[ 62] & (|(FLASH_CTRL_CORE_PERMIT[ 62] & ~reg_be))) | + (addr_hit[ 63] & (|(FLASH_CTRL_CORE_PERMIT[ 63] & ~reg_be))) | + (addr_hit[ 64] & (|(FLASH_CTRL_CORE_PERMIT[ 64] & ~reg_be))) | + (addr_hit[ 65] & (|(FLASH_CTRL_CORE_PERMIT[ 65] & ~reg_be))) | + (addr_hit[ 66] & (|(FLASH_CTRL_CORE_PERMIT[ 66] & ~reg_be))) | + (addr_hit[ 67] & (|(FLASH_CTRL_CORE_PERMIT[ 67] & ~reg_be))) | + (addr_hit[ 68] & (|(FLASH_CTRL_CORE_PERMIT[ 68] & ~reg_be))) | + (addr_hit[ 69] & (|(FLASH_CTRL_CORE_PERMIT[ 69] & ~reg_be))) | + (addr_hit[ 70] & (|(FLASH_CTRL_CORE_PERMIT[ 70] & ~reg_be))) | + (addr_hit[ 71] & (|(FLASH_CTRL_CORE_PERMIT[ 71] & ~reg_be))) | + (addr_hit[ 72] & (|(FLASH_CTRL_CORE_PERMIT[ 72] & ~reg_be))) | + (addr_hit[ 73] & (|(FLASH_CTRL_CORE_PERMIT[ 73] & ~reg_be))) | + (addr_hit[ 74] & (|(FLASH_CTRL_CORE_PERMIT[ 74] & ~reg_be))) | + (addr_hit[ 75] & (|(FLASH_CTRL_CORE_PERMIT[ 75] & ~reg_be))) | + (addr_hit[ 76] & (|(FLASH_CTRL_CORE_PERMIT[ 76] & ~reg_be))) | + (addr_hit[ 77] & (|(FLASH_CTRL_CORE_PERMIT[ 77] & ~reg_be))) | + (addr_hit[ 78] & (|(FLASH_CTRL_CORE_PERMIT[ 78] & ~reg_be))) | + (addr_hit[ 79] & (|(FLASH_CTRL_CORE_PERMIT[ 79] & ~reg_be))) | + (addr_hit[ 80] & (|(FLASH_CTRL_CORE_PERMIT[ 80] & ~reg_be))) | + (addr_hit[ 81] & (|(FLASH_CTRL_CORE_PERMIT[ 81] & ~reg_be))) | + (addr_hit[ 82] & (|(FLASH_CTRL_CORE_PERMIT[ 82] & ~reg_be))) | + (addr_hit[ 83] & (|(FLASH_CTRL_CORE_PERMIT[ 83] & ~reg_be))) | + (addr_hit[ 84] & (|(FLASH_CTRL_CORE_PERMIT[ 84] & ~reg_be))) | + (addr_hit[ 85] & (|(FLASH_CTRL_CORE_PERMIT[ 85] & ~reg_be))) | + (addr_hit[ 86] & (|(FLASH_CTRL_CORE_PERMIT[ 86] & ~reg_be))) | + (addr_hit[ 87] & (|(FLASH_CTRL_CORE_PERMIT[ 87] & ~reg_be))) | + (addr_hit[ 88] & (|(FLASH_CTRL_CORE_PERMIT[ 88] & ~reg_be))) | + (addr_hit[ 89] & (|(FLASH_CTRL_CORE_PERMIT[ 89] & ~reg_be))) | + (addr_hit[ 90] & (|(FLASH_CTRL_CORE_PERMIT[ 90] & ~reg_be))) | + (addr_hit[ 91] & (|(FLASH_CTRL_CORE_PERMIT[ 91] & ~reg_be))) | + (addr_hit[ 92] & (|(FLASH_CTRL_CORE_PERMIT[ 92] & ~reg_be))) | + (addr_hit[ 93] & (|(FLASH_CTRL_CORE_PERMIT[ 93] & ~reg_be))) | + (addr_hit[ 94] & (|(FLASH_CTRL_CORE_PERMIT[ 94] & ~reg_be))) | + (addr_hit[ 95] & (|(FLASH_CTRL_CORE_PERMIT[ 95] & ~reg_be))) | + (addr_hit[ 96] & (|(FLASH_CTRL_CORE_PERMIT[ 96] & ~reg_be))) | + (addr_hit[ 97] & (|(FLASH_CTRL_CORE_PERMIT[ 97] & ~reg_be))) | + (addr_hit[ 98] & (|(FLASH_CTRL_CORE_PERMIT[ 98] & ~reg_be))) | + (addr_hit[ 99] & (|(FLASH_CTRL_CORE_PERMIT[ 99] & ~reg_be))) | + (addr_hit[100] & (|(FLASH_CTRL_CORE_PERMIT[100] & ~reg_be))) | + (addr_hit[101] & (|(FLASH_CTRL_CORE_PERMIT[101] & ~reg_be))) | + (addr_hit[102] & (|(FLASH_CTRL_CORE_PERMIT[102] & ~reg_be))) | + (addr_hit[103] & (|(FLASH_CTRL_CORE_PERMIT[103] & ~reg_be))) | + (addr_hit[104] & (|(FLASH_CTRL_CORE_PERMIT[104] & ~reg_be))) | + (addr_hit[105] & (|(FLASH_CTRL_CORE_PERMIT[105] & ~reg_be))) | + (addr_hit[106] & (|(FLASH_CTRL_CORE_PERMIT[106] & ~reg_be))) | + (addr_hit[107] & (|(FLASH_CTRL_CORE_PERMIT[107] & ~reg_be))))); + end + + // Generate write-enables + assign intr_state_we = addr_hit[0] & reg_we & !reg_error; + + assign intr_state_op_done_wd = reg_wdata[4]; + + assign intr_state_corr_err_wd = reg_wdata[5]; + assign intr_enable_we = addr_hit[1] & reg_we & !reg_error; + + assign intr_enable_prog_empty_wd = reg_wdata[0]; + + assign intr_enable_prog_lvl_wd = reg_wdata[1]; + + assign intr_enable_rd_full_wd = reg_wdata[2]; + + assign intr_enable_rd_lvl_wd = reg_wdata[3]; + + assign intr_enable_op_done_wd = reg_wdata[4]; + + assign intr_enable_corr_err_wd = reg_wdata[5]; + assign intr_test_we = addr_hit[2] & reg_we & !reg_error; + + assign intr_test_prog_empty_wd = reg_wdata[0]; + + assign intr_test_prog_lvl_wd = reg_wdata[1]; + + assign intr_test_rd_full_wd = reg_wdata[2]; + + assign intr_test_rd_lvl_wd = reg_wdata[3]; + + assign intr_test_op_done_wd = reg_wdata[4]; + + assign intr_test_corr_err_wd = reg_wdata[5]; + assign alert_test_we = addr_hit[3] & reg_we & !reg_error; + + assign alert_test_recov_err_wd = reg_wdata[0]; + + assign alert_test_fatal_std_err_wd = reg_wdata[1]; + + assign alert_test_fatal_err_wd = reg_wdata[2]; + + assign alert_test_fatal_prim_flash_alert_wd = reg_wdata[3]; + + assign alert_test_recov_prim_flash_alert_wd = reg_wdata[4]; + assign dis_we = addr_hit[4] & reg_we & !reg_error; + + assign dis_wd = reg_wdata[3:0]; + assign exec_we = addr_hit[5] & reg_we & !reg_error; + + assign exec_wd = reg_wdata[31:0]; + assign init_we = addr_hit[6] & reg_we & !reg_error; + + assign init_wd = reg_wdata[0]; + assign ctrl_regwen_re = addr_hit[7] & reg_re & !reg_error; + assign control_we = addr_hit[8] & reg_we & !reg_error; + + assign control_start_wd = reg_wdata[0]; + + assign control_op_wd = reg_wdata[5:4]; + + assign control_prog_sel_wd = reg_wdata[6]; + + assign control_erase_sel_wd = reg_wdata[7]; + + assign control_partition_sel_wd = reg_wdata[8]; + + assign control_info_sel_wd = reg_wdata[10:9]; + + assign control_num_wd = reg_wdata[27:16]; + assign addr_we = addr_hit[9] & reg_we & !reg_error; + + assign addr_wd = reg_wdata[15:0]; + assign prog_type_en_we = addr_hit[10] & reg_we & !reg_error; + + assign prog_type_en_normal_wd = reg_wdata[0]; + + assign prog_type_en_repair_wd = reg_wdata[1]; + assign erase_suspend_we = addr_hit[11] & reg_we & !reg_error; + + assign erase_suspend_wd = reg_wdata[0]; + assign region_cfg_regwen_0_we = addr_hit[12] & reg_we & !reg_error; + + assign region_cfg_regwen_0_wd = reg_wdata[0]; + assign region_cfg_regwen_1_we = addr_hit[13] & reg_we & !reg_error; + + assign region_cfg_regwen_1_wd = reg_wdata[0]; + assign region_cfg_regwen_2_we = addr_hit[14] & reg_we & !reg_error; + + assign region_cfg_regwen_2_wd = reg_wdata[0]; + assign region_cfg_regwen_3_we = addr_hit[15] & reg_we & !reg_error; + + assign region_cfg_regwen_3_wd = reg_wdata[0]; + assign region_cfg_regwen_4_we = addr_hit[16] & reg_we & !reg_error; + + assign region_cfg_regwen_4_wd = reg_wdata[0]; + assign region_cfg_regwen_5_we = addr_hit[17] & reg_we & !reg_error; + + assign region_cfg_regwen_5_wd = reg_wdata[0]; + assign region_cfg_regwen_6_we = addr_hit[18] & reg_we & !reg_error; + + assign region_cfg_regwen_6_wd = reg_wdata[0]; + assign region_cfg_regwen_7_we = addr_hit[19] & reg_we & !reg_error; + + assign region_cfg_regwen_7_wd = reg_wdata[0]; + assign mp_region_cfg_0_we = addr_hit[20] & reg_we & !reg_error; + + assign mp_region_cfg_0_en_0_wd = reg_wdata[3:0]; + + assign mp_region_cfg_0_rd_en_0_wd = reg_wdata[7:4]; + + assign mp_region_cfg_0_prog_en_0_wd = reg_wdata[11:8]; + + assign mp_region_cfg_0_erase_en_0_wd = reg_wdata[15:12]; + + assign mp_region_cfg_0_scramble_en_0_wd = reg_wdata[19:16]; + + assign mp_region_cfg_0_ecc_en_0_wd = reg_wdata[23:20]; + + assign mp_region_cfg_0_he_en_0_wd = reg_wdata[27:24]; + assign mp_region_cfg_1_we = addr_hit[21] & reg_we & !reg_error; + + assign mp_region_cfg_1_en_1_wd = reg_wdata[3:0]; + + assign mp_region_cfg_1_rd_en_1_wd = reg_wdata[7:4]; + + assign mp_region_cfg_1_prog_en_1_wd = reg_wdata[11:8]; + + assign mp_region_cfg_1_erase_en_1_wd = reg_wdata[15:12]; + + assign mp_region_cfg_1_scramble_en_1_wd = reg_wdata[19:16]; + + assign mp_region_cfg_1_ecc_en_1_wd = reg_wdata[23:20]; + + assign mp_region_cfg_1_he_en_1_wd = reg_wdata[27:24]; + assign mp_region_cfg_2_we = addr_hit[22] & reg_we & !reg_error; + + assign mp_region_cfg_2_en_2_wd = reg_wdata[3:0]; + + assign mp_region_cfg_2_rd_en_2_wd = reg_wdata[7:4]; + + assign mp_region_cfg_2_prog_en_2_wd = reg_wdata[11:8]; + + assign mp_region_cfg_2_erase_en_2_wd = reg_wdata[15:12]; + + assign mp_region_cfg_2_scramble_en_2_wd = reg_wdata[19:16]; + + assign mp_region_cfg_2_ecc_en_2_wd = reg_wdata[23:20]; + + assign mp_region_cfg_2_he_en_2_wd = reg_wdata[27:24]; + assign mp_region_cfg_3_we = addr_hit[23] & reg_we & !reg_error; + + assign mp_region_cfg_3_en_3_wd = reg_wdata[3:0]; + + assign mp_region_cfg_3_rd_en_3_wd = reg_wdata[7:4]; + + assign mp_region_cfg_3_prog_en_3_wd = reg_wdata[11:8]; + + assign mp_region_cfg_3_erase_en_3_wd = reg_wdata[15:12]; + + assign mp_region_cfg_3_scramble_en_3_wd = reg_wdata[19:16]; + + assign mp_region_cfg_3_ecc_en_3_wd = reg_wdata[23:20]; + + assign mp_region_cfg_3_he_en_3_wd = reg_wdata[27:24]; + assign mp_region_cfg_4_we = addr_hit[24] & reg_we & !reg_error; + + assign mp_region_cfg_4_en_4_wd = reg_wdata[3:0]; + + assign mp_region_cfg_4_rd_en_4_wd = reg_wdata[7:4]; + + assign mp_region_cfg_4_prog_en_4_wd = reg_wdata[11:8]; + + assign mp_region_cfg_4_erase_en_4_wd = reg_wdata[15:12]; + + assign mp_region_cfg_4_scramble_en_4_wd = reg_wdata[19:16]; + + assign mp_region_cfg_4_ecc_en_4_wd = reg_wdata[23:20]; + + assign mp_region_cfg_4_he_en_4_wd = reg_wdata[27:24]; + assign mp_region_cfg_5_we = addr_hit[25] & reg_we & !reg_error; + + assign mp_region_cfg_5_en_5_wd = reg_wdata[3:0]; + + assign mp_region_cfg_5_rd_en_5_wd = reg_wdata[7:4]; + + assign mp_region_cfg_5_prog_en_5_wd = reg_wdata[11:8]; + + assign mp_region_cfg_5_erase_en_5_wd = reg_wdata[15:12]; + + assign mp_region_cfg_5_scramble_en_5_wd = reg_wdata[19:16]; + + assign mp_region_cfg_5_ecc_en_5_wd = reg_wdata[23:20]; + + assign mp_region_cfg_5_he_en_5_wd = reg_wdata[27:24]; + assign mp_region_cfg_6_we = addr_hit[26] & reg_we & !reg_error; + + assign mp_region_cfg_6_en_6_wd = reg_wdata[3:0]; + + assign mp_region_cfg_6_rd_en_6_wd = reg_wdata[7:4]; + + assign mp_region_cfg_6_prog_en_6_wd = reg_wdata[11:8]; + + assign mp_region_cfg_6_erase_en_6_wd = reg_wdata[15:12]; + + assign mp_region_cfg_6_scramble_en_6_wd = reg_wdata[19:16]; + + assign mp_region_cfg_6_ecc_en_6_wd = reg_wdata[23:20]; + + assign mp_region_cfg_6_he_en_6_wd = reg_wdata[27:24]; + assign mp_region_cfg_7_we = addr_hit[27] & reg_we & !reg_error; + + assign mp_region_cfg_7_en_7_wd = reg_wdata[3:0]; + + assign mp_region_cfg_7_rd_en_7_wd = reg_wdata[7:4]; + + assign mp_region_cfg_7_prog_en_7_wd = reg_wdata[11:8]; + + assign mp_region_cfg_7_erase_en_7_wd = reg_wdata[15:12]; + + assign mp_region_cfg_7_scramble_en_7_wd = reg_wdata[19:16]; + + assign mp_region_cfg_7_ecc_en_7_wd = reg_wdata[23:20]; + + assign mp_region_cfg_7_he_en_7_wd = reg_wdata[27:24]; + assign mp_region_0_we = addr_hit[28] & reg_we & !reg_error; + + assign mp_region_0_base_0_wd = reg_wdata[4:0]; + + assign mp_region_0_size_0_wd = reg_wdata[10:5]; + assign mp_region_1_we = addr_hit[29] & reg_we & !reg_error; + + assign mp_region_1_base_1_wd = reg_wdata[4:0]; + + assign mp_region_1_size_1_wd = reg_wdata[10:5]; + assign mp_region_2_we = addr_hit[30] & reg_we & !reg_error; + + assign mp_region_2_base_2_wd = reg_wdata[4:0]; + + assign mp_region_2_size_2_wd = reg_wdata[10:5]; + assign mp_region_3_we = addr_hit[31] & reg_we & !reg_error; + + assign mp_region_3_base_3_wd = reg_wdata[4:0]; + + assign mp_region_3_size_3_wd = reg_wdata[10:5]; + assign mp_region_4_we = addr_hit[32] & reg_we & !reg_error; + + assign mp_region_4_base_4_wd = reg_wdata[4:0]; + + assign mp_region_4_size_4_wd = reg_wdata[10:5]; + assign mp_region_5_we = addr_hit[33] & reg_we & !reg_error; + + assign mp_region_5_base_5_wd = reg_wdata[4:0]; + + assign mp_region_5_size_5_wd = reg_wdata[10:5]; + assign mp_region_6_we = addr_hit[34] & reg_we & !reg_error; + + assign mp_region_6_base_6_wd = reg_wdata[4:0]; + + assign mp_region_6_size_6_wd = reg_wdata[10:5]; + assign mp_region_7_we = addr_hit[35] & reg_we & !reg_error; + + assign mp_region_7_base_7_wd = reg_wdata[4:0]; + + assign mp_region_7_size_7_wd = reg_wdata[10:5]; + assign default_region_we = addr_hit[36] & reg_we & !reg_error; + + assign default_region_rd_en_wd = reg_wdata[3:0]; + + assign default_region_prog_en_wd = reg_wdata[7:4]; + + assign default_region_erase_en_wd = reg_wdata[11:8]; + + assign default_region_scramble_en_wd = reg_wdata[15:12]; + + assign default_region_ecc_en_wd = reg_wdata[19:16]; + + assign default_region_he_en_wd = reg_wdata[23:20]; + assign bank0_info0_regwen_0_we = addr_hit[37] & reg_we & !reg_error; + + assign bank0_info0_regwen_0_wd = reg_wdata[0]; + assign bank0_info0_regwen_1_we = addr_hit[38] & reg_we & !reg_error; + + assign bank0_info0_regwen_1_wd = reg_wdata[0]; + assign bank0_info0_regwen_2_we = addr_hit[39] & reg_we & !reg_error; + + assign bank0_info0_regwen_2_wd = reg_wdata[0]; + assign bank0_info0_regwen_3_we = addr_hit[40] & reg_we & !reg_error; + + assign bank0_info0_regwen_3_wd = reg_wdata[0]; + assign bank0_info0_regwen_4_we = addr_hit[41] & reg_we & !reg_error; + + assign bank0_info0_regwen_4_wd = reg_wdata[0]; + assign bank0_info0_regwen_5_we = addr_hit[42] & reg_we & !reg_error; + + assign bank0_info0_regwen_5_wd = reg_wdata[0]; + assign bank0_info0_regwen_6_we = addr_hit[43] & reg_we & !reg_error; + + assign bank0_info0_regwen_6_wd = reg_wdata[0]; + assign bank0_info0_regwen_7_we = addr_hit[44] & reg_we & !reg_error; + + assign bank0_info0_regwen_7_wd = reg_wdata[0]; + assign bank0_info0_regwen_8_we = addr_hit[45] & reg_we & !reg_error; + + assign bank0_info0_regwen_8_wd = reg_wdata[0]; + assign bank0_info0_regwen_9_we = addr_hit[46] & reg_we & !reg_error; + + assign bank0_info0_regwen_9_wd = reg_wdata[0]; + assign bank0_info0_page_cfg_0_we = addr_hit[47] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_0_en_0_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_0_rd_en_0_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_0_prog_en_0_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_0_erase_en_0_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_0_scramble_en_0_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_0_ecc_en_0_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_0_he_en_0_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_1_we = addr_hit[48] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_1_en_1_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_1_rd_en_1_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_1_prog_en_1_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_1_erase_en_1_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_1_scramble_en_1_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_1_ecc_en_1_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_1_he_en_1_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_2_we = addr_hit[49] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_2_en_2_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_2_rd_en_2_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_2_prog_en_2_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_2_erase_en_2_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_2_scramble_en_2_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_2_ecc_en_2_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_2_he_en_2_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_3_we = addr_hit[50] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_3_en_3_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_3_rd_en_3_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_3_prog_en_3_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_3_erase_en_3_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_3_scramble_en_3_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_3_ecc_en_3_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_3_he_en_3_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_4_we = addr_hit[51] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_4_en_4_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_4_rd_en_4_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_4_prog_en_4_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_4_erase_en_4_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_4_scramble_en_4_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_4_ecc_en_4_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_4_he_en_4_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_5_we = addr_hit[52] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_5_en_5_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_5_rd_en_5_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_5_prog_en_5_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_5_erase_en_5_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_5_scramble_en_5_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_5_ecc_en_5_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_5_he_en_5_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_6_we = addr_hit[53] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_6_en_6_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_6_rd_en_6_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_6_prog_en_6_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_6_erase_en_6_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_6_scramble_en_6_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_6_ecc_en_6_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_6_he_en_6_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_7_we = addr_hit[54] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_7_en_7_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_7_rd_en_7_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_7_prog_en_7_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_7_erase_en_7_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_7_scramble_en_7_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_7_ecc_en_7_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_7_he_en_7_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_8_we = addr_hit[55] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_8_en_8_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_8_rd_en_8_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_8_prog_en_8_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_8_erase_en_8_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_8_scramble_en_8_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_8_ecc_en_8_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_8_he_en_8_wd = reg_wdata[27:24]; + assign bank0_info0_page_cfg_9_we = addr_hit[56] & reg_we & !reg_error; + + assign bank0_info0_page_cfg_9_en_9_wd = reg_wdata[3:0]; + + assign bank0_info0_page_cfg_9_rd_en_9_wd = reg_wdata[7:4]; + + assign bank0_info0_page_cfg_9_prog_en_9_wd = reg_wdata[11:8]; + + assign bank0_info0_page_cfg_9_erase_en_9_wd = reg_wdata[15:12]; + + assign bank0_info0_page_cfg_9_scramble_en_9_wd = reg_wdata[19:16]; + + assign bank0_info0_page_cfg_9_ecc_en_9_wd = reg_wdata[23:20]; + + assign bank0_info0_page_cfg_9_he_en_9_wd = reg_wdata[27:24]; + assign bank0_info1_regwen_we = addr_hit[57] & reg_we & !reg_error; + + assign bank0_info1_regwen_wd = reg_wdata[0]; + assign bank0_info1_page_cfg_we = addr_hit[58] & reg_we & !reg_error; + + assign bank0_info1_page_cfg_en_0_wd = reg_wdata[3:0]; + + assign bank0_info1_page_cfg_rd_en_0_wd = reg_wdata[7:4]; + + assign bank0_info1_page_cfg_prog_en_0_wd = reg_wdata[11:8]; + + assign bank0_info1_page_cfg_erase_en_0_wd = reg_wdata[15:12]; + + assign bank0_info1_page_cfg_scramble_en_0_wd = reg_wdata[19:16]; + + assign bank0_info1_page_cfg_ecc_en_0_wd = reg_wdata[23:20]; + + assign bank0_info1_page_cfg_he_en_0_wd = reg_wdata[27:24]; + assign bank0_info2_regwen_0_we = addr_hit[59] & reg_we & !reg_error; + + assign bank0_info2_regwen_0_wd = reg_wdata[0]; + assign bank0_info2_regwen_1_we = addr_hit[60] & reg_we & !reg_error; + + assign bank0_info2_regwen_1_wd = reg_wdata[0]; + assign bank0_info2_page_cfg_0_we = addr_hit[61] & reg_we & !reg_error; + + assign bank0_info2_page_cfg_0_en_0_wd = reg_wdata[3:0]; + + assign bank0_info2_page_cfg_0_rd_en_0_wd = reg_wdata[7:4]; + + assign bank0_info2_page_cfg_0_prog_en_0_wd = reg_wdata[11:8]; + + assign bank0_info2_page_cfg_0_erase_en_0_wd = reg_wdata[15:12]; + + assign bank0_info2_page_cfg_0_scramble_en_0_wd = reg_wdata[19:16]; + + assign bank0_info2_page_cfg_0_ecc_en_0_wd = reg_wdata[23:20]; + + assign bank0_info2_page_cfg_0_he_en_0_wd = reg_wdata[27:24]; + assign bank0_info2_page_cfg_1_we = addr_hit[62] & reg_we & !reg_error; + + assign bank0_info2_page_cfg_1_en_1_wd = reg_wdata[3:0]; + + assign bank0_info2_page_cfg_1_rd_en_1_wd = reg_wdata[7:4]; + + assign bank0_info2_page_cfg_1_prog_en_1_wd = reg_wdata[11:8]; + + assign bank0_info2_page_cfg_1_erase_en_1_wd = reg_wdata[15:12]; + + assign bank0_info2_page_cfg_1_scramble_en_1_wd = reg_wdata[19:16]; + + assign bank0_info2_page_cfg_1_ecc_en_1_wd = reg_wdata[23:20]; + + assign bank0_info2_page_cfg_1_he_en_1_wd = reg_wdata[27:24]; + assign bank1_info0_regwen_0_we = addr_hit[63] & reg_we & !reg_error; + + assign bank1_info0_regwen_0_wd = reg_wdata[0]; + assign bank1_info0_regwen_1_we = addr_hit[64] & reg_we & !reg_error; + + assign bank1_info0_regwen_1_wd = reg_wdata[0]; + assign bank1_info0_regwen_2_we = addr_hit[65] & reg_we & !reg_error; + + assign bank1_info0_regwen_2_wd = reg_wdata[0]; + assign bank1_info0_regwen_3_we = addr_hit[66] & reg_we & !reg_error; + + assign bank1_info0_regwen_3_wd = reg_wdata[0]; + assign bank1_info0_regwen_4_we = addr_hit[67] & reg_we & !reg_error; + + assign bank1_info0_regwen_4_wd = reg_wdata[0]; + assign bank1_info0_regwen_5_we = addr_hit[68] & reg_we & !reg_error; + + assign bank1_info0_regwen_5_wd = reg_wdata[0]; + assign bank1_info0_regwen_6_we = addr_hit[69] & reg_we & !reg_error; + + assign bank1_info0_regwen_6_wd = reg_wdata[0]; + assign bank1_info0_regwen_7_we = addr_hit[70] & reg_we & !reg_error; + + assign bank1_info0_regwen_7_wd = reg_wdata[0]; + assign bank1_info0_regwen_8_we = addr_hit[71] & reg_we & !reg_error; + + assign bank1_info0_regwen_8_wd = reg_wdata[0]; + assign bank1_info0_regwen_9_we = addr_hit[72] & reg_we & !reg_error; + + assign bank1_info0_regwen_9_wd = reg_wdata[0]; + assign bank1_info0_page_cfg_0_we = addr_hit[73] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_0_en_0_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_0_rd_en_0_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_0_prog_en_0_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_0_erase_en_0_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_0_scramble_en_0_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_0_ecc_en_0_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_0_he_en_0_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_1_we = addr_hit[74] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_1_en_1_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_1_rd_en_1_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_1_prog_en_1_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_1_erase_en_1_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_1_scramble_en_1_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_1_ecc_en_1_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_1_he_en_1_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_2_we = addr_hit[75] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_2_en_2_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_2_rd_en_2_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_2_prog_en_2_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_2_erase_en_2_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_2_scramble_en_2_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_2_ecc_en_2_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_2_he_en_2_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_3_we = addr_hit[76] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_3_en_3_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_3_rd_en_3_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_3_prog_en_3_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_3_erase_en_3_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_3_scramble_en_3_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_3_ecc_en_3_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_3_he_en_3_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_4_we = addr_hit[77] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_4_en_4_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_4_rd_en_4_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_4_prog_en_4_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_4_erase_en_4_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_4_scramble_en_4_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_4_ecc_en_4_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_4_he_en_4_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_5_we = addr_hit[78] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_5_en_5_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_5_rd_en_5_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_5_prog_en_5_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_5_erase_en_5_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_5_scramble_en_5_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_5_ecc_en_5_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_5_he_en_5_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_6_we = addr_hit[79] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_6_en_6_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_6_rd_en_6_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_6_prog_en_6_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_6_erase_en_6_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_6_scramble_en_6_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_6_ecc_en_6_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_6_he_en_6_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_7_we = addr_hit[80] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_7_en_7_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_7_rd_en_7_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_7_prog_en_7_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_7_erase_en_7_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_7_scramble_en_7_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_7_ecc_en_7_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_7_he_en_7_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_8_we = addr_hit[81] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_8_en_8_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_8_rd_en_8_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_8_prog_en_8_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_8_erase_en_8_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_8_scramble_en_8_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_8_ecc_en_8_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_8_he_en_8_wd = reg_wdata[27:24]; + assign bank1_info0_page_cfg_9_we = addr_hit[82] & reg_we & !reg_error; + + assign bank1_info0_page_cfg_9_en_9_wd = reg_wdata[3:0]; + + assign bank1_info0_page_cfg_9_rd_en_9_wd = reg_wdata[7:4]; + + assign bank1_info0_page_cfg_9_prog_en_9_wd = reg_wdata[11:8]; + + assign bank1_info0_page_cfg_9_erase_en_9_wd = reg_wdata[15:12]; + + assign bank1_info0_page_cfg_9_scramble_en_9_wd = reg_wdata[19:16]; + + assign bank1_info0_page_cfg_9_ecc_en_9_wd = reg_wdata[23:20]; + + assign bank1_info0_page_cfg_9_he_en_9_wd = reg_wdata[27:24]; + assign bank1_info1_regwen_we = addr_hit[83] & reg_we & !reg_error; + + assign bank1_info1_regwen_wd = reg_wdata[0]; + assign bank1_info1_page_cfg_we = addr_hit[84] & reg_we & !reg_error; + + assign bank1_info1_page_cfg_en_0_wd = reg_wdata[3:0]; + + assign bank1_info1_page_cfg_rd_en_0_wd = reg_wdata[7:4]; + + assign bank1_info1_page_cfg_prog_en_0_wd = reg_wdata[11:8]; + + assign bank1_info1_page_cfg_erase_en_0_wd = reg_wdata[15:12]; + + assign bank1_info1_page_cfg_scramble_en_0_wd = reg_wdata[19:16]; + + assign bank1_info1_page_cfg_ecc_en_0_wd = reg_wdata[23:20]; + + assign bank1_info1_page_cfg_he_en_0_wd = reg_wdata[27:24]; + assign bank1_info2_regwen_0_we = addr_hit[85] & reg_we & !reg_error; + + assign bank1_info2_regwen_0_wd = reg_wdata[0]; + assign bank1_info2_regwen_1_we = addr_hit[86] & reg_we & !reg_error; + + assign bank1_info2_regwen_1_wd = reg_wdata[0]; + assign bank1_info2_page_cfg_0_we = addr_hit[87] & reg_we & !reg_error; + + assign bank1_info2_page_cfg_0_en_0_wd = reg_wdata[3:0]; + + assign bank1_info2_page_cfg_0_rd_en_0_wd = reg_wdata[7:4]; + + assign bank1_info2_page_cfg_0_prog_en_0_wd = reg_wdata[11:8]; + + assign bank1_info2_page_cfg_0_erase_en_0_wd = reg_wdata[15:12]; + + assign bank1_info2_page_cfg_0_scramble_en_0_wd = reg_wdata[19:16]; + + assign bank1_info2_page_cfg_0_ecc_en_0_wd = reg_wdata[23:20]; + + assign bank1_info2_page_cfg_0_he_en_0_wd = reg_wdata[27:24]; + assign bank1_info2_page_cfg_1_we = addr_hit[88] & reg_we & !reg_error; + + assign bank1_info2_page_cfg_1_en_1_wd = reg_wdata[3:0]; + + assign bank1_info2_page_cfg_1_rd_en_1_wd = reg_wdata[7:4]; + + assign bank1_info2_page_cfg_1_prog_en_1_wd = reg_wdata[11:8]; + + assign bank1_info2_page_cfg_1_erase_en_1_wd = reg_wdata[15:12]; + + assign bank1_info2_page_cfg_1_scramble_en_1_wd = reg_wdata[19:16]; + + assign bank1_info2_page_cfg_1_ecc_en_1_wd = reg_wdata[23:20]; + + assign bank1_info2_page_cfg_1_he_en_1_wd = reg_wdata[27:24]; + assign hw_info_cfg_override_we = addr_hit[89] & reg_we & !reg_error; + + assign hw_info_cfg_override_scramble_dis_wd = reg_wdata[3:0]; + + assign hw_info_cfg_override_ecc_dis_wd = reg_wdata[7:4]; + assign bank_cfg_regwen_we = addr_hit[90] & reg_we & !reg_error; + + assign bank_cfg_regwen_wd = reg_wdata[0]; + assign mp_bank_cfg_shadowed_re = addr_hit[91] & reg_re & !reg_error; + assign mp_bank_cfg_shadowed_we = addr_hit[91] & reg_we & !reg_error; + + assign mp_bank_cfg_shadowed_erase_en_0_wd = reg_wdata[0]; + + assign mp_bank_cfg_shadowed_erase_en_1_wd = reg_wdata[1]; + assign op_status_we = addr_hit[92] & reg_we & !reg_error; + + assign op_status_done_wd = reg_wdata[0]; + + assign op_status_err_wd = reg_wdata[1]; + assign debug_state_re = addr_hit[94] & reg_re & !reg_error; + assign err_code_we = addr_hit[95] & reg_we & !reg_error; + + assign err_code_op_err_wd = reg_wdata[0]; + + assign err_code_mp_err_wd = reg_wdata[1]; + + assign err_code_rd_err_wd = reg_wdata[2]; + + assign err_code_prog_err_wd = reg_wdata[3]; + + assign err_code_prog_win_err_wd = reg_wdata[4]; + + assign err_code_prog_type_err_wd = reg_wdata[5]; + + assign err_code_update_err_wd = reg_wdata[6]; + + assign err_code_macro_err_wd = reg_wdata[7]; + assign fault_status_we = addr_hit[97] & reg_we & !reg_error; + + assign fault_status_phy_relbl_err_wd = reg_wdata[7]; + + assign fault_status_phy_storage_err_wd = reg_wdata[8]; + assign ecc_single_err_cnt_we = addr_hit[99] & reg_we & !reg_error; + + assign ecc_single_err_cnt_ecc_single_err_cnt_0_wd = reg_wdata[7:0]; + + assign ecc_single_err_cnt_ecc_single_err_cnt_1_wd = reg_wdata[15:8]; + assign phy_alert_cfg_we = addr_hit[102] & reg_we & !reg_error; + + assign phy_alert_cfg_alert_ack_wd = reg_wdata[0]; + + assign phy_alert_cfg_alert_trig_wd = reg_wdata[1]; + assign scratch_we = addr_hit[104] & reg_we & !reg_error; + + assign scratch_wd = reg_wdata[31:0]; + assign fifo_lvl_we = addr_hit[105] & reg_we & !reg_error; + + assign fifo_lvl_prog_wd = reg_wdata[4:0]; + + assign fifo_lvl_rd_wd = reg_wdata[12:8]; + assign fifo_rst_we = addr_hit[106] & reg_we & !reg_error; + + assign fifo_rst_wd = reg_wdata[0]; + assign curr_fifo_lvl_re = addr_hit[107] & reg_re & !reg_error; + + // 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] = dis_we; + reg_we_check[5] = exec_we; + reg_we_check[6] = init_we; + reg_we_check[7] = 1'b0; + reg_we_check[8] = control_gated_we; + reg_we_check[9] = addr_gated_we; + reg_we_check[10] = prog_type_en_gated_we; + reg_we_check[11] = erase_suspend_we; + reg_we_check[12] = region_cfg_regwen_0_we; + reg_we_check[13] = region_cfg_regwen_1_we; + reg_we_check[14] = region_cfg_regwen_2_we; + reg_we_check[15] = region_cfg_regwen_3_we; + reg_we_check[16] = region_cfg_regwen_4_we; + reg_we_check[17] = region_cfg_regwen_5_we; + reg_we_check[18] = region_cfg_regwen_6_we; + reg_we_check[19] = region_cfg_regwen_7_we; + reg_we_check[20] = mp_region_cfg_0_gated_we; + reg_we_check[21] = mp_region_cfg_1_gated_we; + reg_we_check[22] = mp_region_cfg_2_gated_we; + reg_we_check[23] = mp_region_cfg_3_gated_we; + reg_we_check[24] = mp_region_cfg_4_gated_we; + reg_we_check[25] = mp_region_cfg_5_gated_we; + reg_we_check[26] = mp_region_cfg_6_gated_we; + reg_we_check[27] = mp_region_cfg_7_gated_we; + reg_we_check[28] = mp_region_0_gated_we; + reg_we_check[29] = mp_region_1_gated_we; + reg_we_check[30] = mp_region_2_gated_we; + reg_we_check[31] = mp_region_3_gated_we; + reg_we_check[32] = mp_region_4_gated_we; + reg_we_check[33] = mp_region_5_gated_we; + reg_we_check[34] = mp_region_6_gated_we; + reg_we_check[35] = mp_region_7_gated_we; + reg_we_check[36] = default_region_we; + reg_we_check[37] = bank0_info0_regwen_0_we; + reg_we_check[38] = bank0_info0_regwen_1_we; + reg_we_check[39] = bank0_info0_regwen_2_we; + reg_we_check[40] = bank0_info0_regwen_3_we; + reg_we_check[41] = bank0_info0_regwen_4_we; + reg_we_check[42] = bank0_info0_regwen_5_we; + reg_we_check[43] = bank0_info0_regwen_6_we; + reg_we_check[44] = bank0_info0_regwen_7_we; + reg_we_check[45] = bank0_info0_regwen_8_we; + reg_we_check[46] = bank0_info0_regwen_9_we; + reg_we_check[47] = bank0_info0_page_cfg_0_gated_we; + reg_we_check[48] = bank0_info0_page_cfg_1_gated_we; + reg_we_check[49] = bank0_info0_page_cfg_2_gated_we; + reg_we_check[50] = bank0_info0_page_cfg_3_gated_we; + reg_we_check[51] = bank0_info0_page_cfg_4_gated_we; + reg_we_check[52] = bank0_info0_page_cfg_5_gated_we; + reg_we_check[53] = bank0_info0_page_cfg_6_gated_we; + reg_we_check[54] = bank0_info0_page_cfg_7_gated_we; + reg_we_check[55] = bank0_info0_page_cfg_8_gated_we; + reg_we_check[56] = bank0_info0_page_cfg_9_gated_we; + reg_we_check[57] = bank0_info1_regwen_we; + reg_we_check[58] = bank0_info1_page_cfg_gated_we; + reg_we_check[59] = bank0_info2_regwen_0_we; + reg_we_check[60] = bank0_info2_regwen_1_we; + reg_we_check[61] = bank0_info2_page_cfg_0_gated_we; + reg_we_check[62] = bank0_info2_page_cfg_1_gated_we; + reg_we_check[63] = bank1_info0_regwen_0_we; + reg_we_check[64] = bank1_info0_regwen_1_we; + reg_we_check[65] = bank1_info0_regwen_2_we; + reg_we_check[66] = bank1_info0_regwen_3_we; + reg_we_check[67] = bank1_info0_regwen_4_we; + reg_we_check[68] = bank1_info0_regwen_5_we; + reg_we_check[69] = bank1_info0_regwen_6_we; + reg_we_check[70] = bank1_info0_regwen_7_we; + reg_we_check[71] = bank1_info0_regwen_8_we; + reg_we_check[72] = bank1_info0_regwen_9_we; + reg_we_check[73] = bank1_info0_page_cfg_0_gated_we; + reg_we_check[74] = bank1_info0_page_cfg_1_gated_we; + reg_we_check[75] = bank1_info0_page_cfg_2_gated_we; + reg_we_check[76] = bank1_info0_page_cfg_3_gated_we; + reg_we_check[77] = bank1_info0_page_cfg_4_gated_we; + reg_we_check[78] = bank1_info0_page_cfg_5_gated_we; + reg_we_check[79] = bank1_info0_page_cfg_6_gated_we; + reg_we_check[80] = bank1_info0_page_cfg_7_gated_we; + reg_we_check[81] = bank1_info0_page_cfg_8_gated_we; + reg_we_check[82] = bank1_info0_page_cfg_9_gated_we; + reg_we_check[83] = bank1_info1_regwen_we; + reg_we_check[84] = bank1_info1_page_cfg_gated_we; + reg_we_check[85] = bank1_info2_regwen_0_we; + reg_we_check[86] = bank1_info2_regwen_1_we; + reg_we_check[87] = bank1_info2_page_cfg_0_gated_we; + reg_we_check[88] = bank1_info2_page_cfg_1_gated_we; + reg_we_check[89] = hw_info_cfg_override_we; + reg_we_check[90] = bank_cfg_regwen_we; + reg_we_check[91] = mp_bank_cfg_shadowed_gated_we; + reg_we_check[92] = op_status_we; + reg_we_check[93] = 1'b0; + reg_we_check[94] = 1'b0; + reg_we_check[95] = err_code_we; + reg_we_check[96] = 1'b0; + reg_we_check[97] = fault_status_we; + reg_we_check[98] = 1'b0; + reg_we_check[99] = ecc_single_err_cnt_we; + reg_we_check[100] = 1'b0; + reg_we_check[101] = 1'b0; + reg_we_check[102] = phy_alert_cfg_we; + reg_we_check[103] = 1'b0; + reg_we_check[104] = scratch_we; + reg_we_check[105] = fifo_lvl_we; + reg_we_check[106] = fifo_rst_we; + reg_we_check[107] = 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_prog_empty_qs; + reg_rdata_next[1] = intr_state_prog_lvl_qs; + reg_rdata_next[2] = intr_state_rd_full_qs; + reg_rdata_next[3] = intr_state_rd_lvl_qs; + reg_rdata_next[4] = intr_state_op_done_qs; + reg_rdata_next[5] = intr_state_corr_err_qs; + end + + addr_hit[1]: begin + reg_rdata_next[0] = intr_enable_prog_empty_qs; + reg_rdata_next[1] = intr_enable_prog_lvl_qs; + reg_rdata_next[2] = intr_enable_rd_full_qs; + reg_rdata_next[3] = intr_enable_rd_lvl_qs; + reg_rdata_next[4] = intr_enable_op_done_qs; + reg_rdata_next[5] = intr_enable_corr_err_qs; + end + + addr_hit[2]: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + reg_rdata_next[2] = '0; + reg_rdata_next[3] = '0; + reg_rdata_next[4] = '0; + reg_rdata_next[5] = '0; + end + + addr_hit[3]: begin + reg_rdata_next[0] = '0; + reg_rdata_next[1] = '0; + reg_rdata_next[2] = '0; + reg_rdata_next[3] = '0; + reg_rdata_next[4] = '0; + end + + addr_hit[4]: begin + reg_rdata_next[3:0] = dis_qs; + end + + addr_hit[5]: begin + reg_rdata_next[31:0] = exec_qs; + end + + addr_hit[6]: begin + reg_rdata_next[0] = init_qs; + end + + addr_hit[7]: begin + reg_rdata_next[0] = ctrl_regwen_qs; + end + + addr_hit[8]: begin + reg_rdata_next[0] = control_start_qs; + reg_rdata_next[5:4] = control_op_qs; + reg_rdata_next[6] = control_prog_sel_qs; + reg_rdata_next[7] = control_erase_sel_qs; + reg_rdata_next[8] = control_partition_sel_qs; + reg_rdata_next[10:9] = control_info_sel_qs; + reg_rdata_next[27:16] = control_num_qs; + end + + addr_hit[9]: begin + reg_rdata_next[15:0] = addr_qs; + end + + addr_hit[10]: begin + reg_rdata_next[0] = prog_type_en_normal_qs; + reg_rdata_next[1] = prog_type_en_repair_qs; + end + + addr_hit[11]: begin + reg_rdata_next[0] = erase_suspend_qs; + end + + addr_hit[12]: begin + reg_rdata_next[0] = region_cfg_regwen_0_qs; + end + + addr_hit[13]: begin + reg_rdata_next[0] = region_cfg_regwen_1_qs; + end + + addr_hit[14]: begin + reg_rdata_next[0] = region_cfg_regwen_2_qs; + end + + addr_hit[15]: begin + reg_rdata_next[0] = region_cfg_regwen_3_qs; + end + + addr_hit[16]: begin + reg_rdata_next[0] = region_cfg_regwen_4_qs; + end + + addr_hit[17]: begin + reg_rdata_next[0] = region_cfg_regwen_5_qs; + end + + addr_hit[18]: begin + reg_rdata_next[0] = region_cfg_regwen_6_qs; + end + + addr_hit[19]: begin + reg_rdata_next[0] = region_cfg_regwen_7_qs; + end + + addr_hit[20]: begin + reg_rdata_next[3:0] = mp_region_cfg_0_en_0_qs; + reg_rdata_next[7:4] = mp_region_cfg_0_rd_en_0_qs; + reg_rdata_next[11:8] = mp_region_cfg_0_prog_en_0_qs; + reg_rdata_next[15:12] = mp_region_cfg_0_erase_en_0_qs; + reg_rdata_next[19:16] = mp_region_cfg_0_scramble_en_0_qs; + reg_rdata_next[23:20] = mp_region_cfg_0_ecc_en_0_qs; + reg_rdata_next[27:24] = mp_region_cfg_0_he_en_0_qs; + end + + addr_hit[21]: begin + reg_rdata_next[3:0] = mp_region_cfg_1_en_1_qs; + reg_rdata_next[7:4] = mp_region_cfg_1_rd_en_1_qs; + reg_rdata_next[11:8] = mp_region_cfg_1_prog_en_1_qs; + reg_rdata_next[15:12] = mp_region_cfg_1_erase_en_1_qs; + reg_rdata_next[19:16] = mp_region_cfg_1_scramble_en_1_qs; + reg_rdata_next[23:20] = mp_region_cfg_1_ecc_en_1_qs; + reg_rdata_next[27:24] = mp_region_cfg_1_he_en_1_qs; + end + + addr_hit[22]: begin + reg_rdata_next[3:0] = mp_region_cfg_2_en_2_qs; + reg_rdata_next[7:4] = mp_region_cfg_2_rd_en_2_qs; + reg_rdata_next[11:8] = mp_region_cfg_2_prog_en_2_qs; + reg_rdata_next[15:12] = mp_region_cfg_2_erase_en_2_qs; + reg_rdata_next[19:16] = mp_region_cfg_2_scramble_en_2_qs; + reg_rdata_next[23:20] = mp_region_cfg_2_ecc_en_2_qs; + reg_rdata_next[27:24] = mp_region_cfg_2_he_en_2_qs; + end + + addr_hit[23]: begin + reg_rdata_next[3:0] = mp_region_cfg_3_en_3_qs; + reg_rdata_next[7:4] = mp_region_cfg_3_rd_en_3_qs; + reg_rdata_next[11:8] = mp_region_cfg_3_prog_en_3_qs; + reg_rdata_next[15:12] = mp_region_cfg_3_erase_en_3_qs; + reg_rdata_next[19:16] = mp_region_cfg_3_scramble_en_3_qs; + reg_rdata_next[23:20] = mp_region_cfg_3_ecc_en_3_qs; + reg_rdata_next[27:24] = mp_region_cfg_3_he_en_3_qs; + end + + addr_hit[24]: begin + reg_rdata_next[3:0] = mp_region_cfg_4_en_4_qs; + reg_rdata_next[7:4] = mp_region_cfg_4_rd_en_4_qs; + reg_rdata_next[11:8] = mp_region_cfg_4_prog_en_4_qs; + reg_rdata_next[15:12] = mp_region_cfg_4_erase_en_4_qs; + reg_rdata_next[19:16] = mp_region_cfg_4_scramble_en_4_qs; + reg_rdata_next[23:20] = mp_region_cfg_4_ecc_en_4_qs; + reg_rdata_next[27:24] = mp_region_cfg_4_he_en_4_qs; + end + + addr_hit[25]: begin + reg_rdata_next[3:0] = mp_region_cfg_5_en_5_qs; + reg_rdata_next[7:4] = mp_region_cfg_5_rd_en_5_qs; + reg_rdata_next[11:8] = mp_region_cfg_5_prog_en_5_qs; + reg_rdata_next[15:12] = mp_region_cfg_5_erase_en_5_qs; + reg_rdata_next[19:16] = mp_region_cfg_5_scramble_en_5_qs; + reg_rdata_next[23:20] = mp_region_cfg_5_ecc_en_5_qs; + reg_rdata_next[27:24] = mp_region_cfg_5_he_en_5_qs; + end + + addr_hit[26]: begin + reg_rdata_next[3:0] = mp_region_cfg_6_en_6_qs; + reg_rdata_next[7:4] = mp_region_cfg_6_rd_en_6_qs; + reg_rdata_next[11:8] = mp_region_cfg_6_prog_en_6_qs; + reg_rdata_next[15:12] = mp_region_cfg_6_erase_en_6_qs; + reg_rdata_next[19:16] = mp_region_cfg_6_scramble_en_6_qs; + reg_rdata_next[23:20] = mp_region_cfg_6_ecc_en_6_qs; + reg_rdata_next[27:24] = mp_region_cfg_6_he_en_6_qs; + end + + addr_hit[27]: begin + reg_rdata_next[3:0] = mp_region_cfg_7_en_7_qs; + reg_rdata_next[7:4] = mp_region_cfg_7_rd_en_7_qs; + reg_rdata_next[11:8] = mp_region_cfg_7_prog_en_7_qs; + reg_rdata_next[15:12] = mp_region_cfg_7_erase_en_7_qs; + reg_rdata_next[19:16] = mp_region_cfg_7_scramble_en_7_qs; + reg_rdata_next[23:20] = mp_region_cfg_7_ecc_en_7_qs; + reg_rdata_next[27:24] = mp_region_cfg_7_he_en_7_qs; + end + + addr_hit[28]: begin + reg_rdata_next[4:0] = mp_region_0_base_0_qs; + reg_rdata_next[10:5] = mp_region_0_size_0_qs; + end + + addr_hit[29]: begin + reg_rdata_next[4:0] = mp_region_1_base_1_qs; + reg_rdata_next[10:5] = mp_region_1_size_1_qs; + end + + addr_hit[30]: begin + reg_rdata_next[4:0] = mp_region_2_base_2_qs; + reg_rdata_next[10:5] = mp_region_2_size_2_qs; + end + + addr_hit[31]: begin + reg_rdata_next[4:0] = mp_region_3_base_3_qs; + reg_rdata_next[10:5] = mp_region_3_size_3_qs; + end + + addr_hit[32]: begin + reg_rdata_next[4:0] = mp_region_4_base_4_qs; + reg_rdata_next[10:5] = mp_region_4_size_4_qs; + end + + addr_hit[33]: begin + reg_rdata_next[4:0] = mp_region_5_base_5_qs; + reg_rdata_next[10:5] = mp_region_5_size_5_qs; + end + + addr_hit[34]: begin + reg_rdata_next[4:0] = mp_region_6_base_6_qs; + reg_rdata_next[10:5] = mp_region_6_size_6_qs; + end + + addr_hit[35]: begin + reg_rdata_next[4:0] = mp_region_7_base_7_qs; + reg_rdata_next[10:5] = mp_region_7_size_7_qs; + end + + addr_hit[36]: begin + reg_rdata_next[3:0] = default_region_rd_en_qs; + reg_rdata_next[7:4] = default_region_prog_en_qs; + reg_rdata_next[11:8] = default_region_erase_en_qs; + reg_rdata_next[15:12] = default_region_scramble_en_qs; + reg_rdata_next[19:16] = default_region_ecc_en_qs; + reg_rdata_next[23:20] = default_region_he_en_qs; + end + + addr_hit[37]: begin + reg_rdata_next[0] = bank0_info0_regwen_0_qs; + end + + addr_hit[38]: begin + reg_rdata_next[0] = bank0_info0_regwen_1_qs; + end + + addr_hit[39]: begin + reg_rdata_next[0] = bank0_info0_regwen_2_qs; + end + + addr_hit[40]: begin + reg_rdata_next[0] = bank0_info0_regwen_3_qs; + end + + addr_hit[41]: begin + reg_rdata_next[0] = bank0_info0_regwen_4_qs; + end + + addr_hit[42]: begin + reg_rdata_next[0] = bank0_info0_regwen_5_qs; + end + + addr_hit[43]: begin + reg_rdata_next[0] = bank0_info0_regwen_6_qs; + end + + addr_hit[44]: begin + reg_rdata_next[0] = bank0_info0_regwen_7_qs; + end + + addr_hit[45]: begin + reg_rdata_next[0] = bank0_info0_regwen_8_qs; + end + + addr_hit[46]: begin + reg_rdata_next[0] = bank0_info0_regwen_9_qs; + end + + addr_hit[47]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_0_en_0_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_0_rd_en_0_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_0_prog_en_0_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_0_erase_en_0_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_0_scramble_en_0_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_0_ecc_en_0_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_0_he_en_0_qs; + end + + addr_hit[48]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_1_en_1_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_1_rd_en_1_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_1_prog_en_1_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_1_erase_en_1_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_1_scramble_en_1_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_1_ecc_en_1_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_1_he_en_1_qs; + end + + addr_hit[49]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_2_en_2_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_2_rd_en_2_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_2_prog_en_2_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_2_erase_en_2_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_2_scramble_en_2_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_2_ecc_en_2_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_2_he_en_2_qs; + end + + addr_hit[50]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_3_en_3_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_3_rd_en_3_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_3_prog_en_3_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_3_erase_en_3_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_3_scramble_en_3_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_3_ecc_en_3_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_3_he_en_3_qs; + end + + addr_hit[51]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_4_en_4_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_4_rd_en_4_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_4_prog_en_4_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_4_erase_en_4_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_4_scramble_en_4_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_4_ecc_en_4_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_4_he_en_4_qs; + end + + addr_hit[52]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_5_en_5_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_5_rd_en_5_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_5_prog_en_5_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_5_erase_en_5_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_5_scramble_en_5_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_5_ecc_en_5_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_5_he_en_5_qs; + end + + addr_hit[53]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_6_en_6_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_6_rd_en_6_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_6_prog_en_6_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_6_erase_en_6_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_6_scramble_en_6_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_6_ecc_en_6_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_6_he_en_6_qs; + end + + addr_hit[54]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_7_en_7_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_7_rd_en_7_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_7_prog_en_7_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_7_erase_en_7_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_7_scramble_en_7_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_7_ecc_en_7_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_7_he_en_7_qs; + end + + addr_hit[55]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_8_en_8_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_8_rd_en_8_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_8_prog_en_8_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_8_erase_en_8_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_8_scramble_en_8_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_8_ecc_en_8_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_8_he_en_8_qs; + end + + addr_hit[56]: begin + reg_rdata_next[3:0] = bank0_info0_page_cfg_9_en_9_qs; + reg_rdata_next[7:4] = bank0_info0_page_cfg_9_rd_en_9_qs; + reg_rdata_next[11:8] = bank0_info0_page_cfg_9_prog_en_9_qs; + reg_rdata_next[15:12] = bank0_info0_page_cfg_9_erase_en_9_qs; + reg_rdata_next[19:16] = bank0_info0_page_cfg_9_scramble_en_9_qs; + reg_rdata_next[23:20] = bank0_info0_page_cfg_9_ecc_en_9_qs; + reg_rdata_next[27:24] = bank0_info0_page_cfg_9_he_en_9_qs; + end + + addr_hit[57]: begin + reg_rdata_next[0] = bank0_info1_regwen_qs; + end + + addr_hit[58]: begin + reg_rdata_next[3:0] = bank0_info1_page_cfg_en_0_qs; + reg_rdata_next[7:4] = bank0_info1_page_cfg_rd_en_0_qs; + reg_rdata_next[11:8] = bank0_info1_page_cfg_prog_en_0_qs; + reg_rdata_next[15:12] = bank0_info1_page_cfg_erase_en_0_qs; + reg_rdata_next[19:16] = bank0_info1_page_cfg_scramble_en_0_qs; + reg_rdata_next[23:20] = bank0_info1_page_cfg_ecc_en_0_qs; + reg_rdata_next[27:24] = bank0_info1_page_cfg_he_en_0_qs; + end + + addr_hit[59]: begin + reg_rdata_next[0] = bank0_info2_regwen_0_qs; + end + + addr_hit[60]: begin + reg_rdata_next[0] = bank0_info2_regwen_1_qs; + end + + addr_hit[61]: begin + reg_rdata_next[3:0] = bank0_info2_page_cfg_0_en_0_qs; + reg_rdata_next[7:4] = bank0_info2_page_cfg_0_rd_en_0_qs; + reg_rdata_next[11:8] = bank0_info2_page_cfg_0_prog_en_0_qs; + reg_rdata_next[15:12] = bank0_info2_page_cfg_0_erase_en_0_qs; + reg_rdata_next[19:16] = bank0_info2_page_cfg_0_scramble_en_0_qs; + reg_rdata_next[23:20] = bank0_info2_page_cfg_0_ecc_en_0_qs; + reg_rdata_next[27:24] = bank0_info2_page_cfg_0_he_en_0_qs; + end + + addr_hit[62]: begin + reg_rdata_next[3:0] = bank0_info2_page_cfg_1_en_1_qs; + reg_rdata_next[7:4] = bank0_info2_page_cfg_1_rd_en_1_qs; + reg_rdata_next[11:8] = bank0_info2_page_cfg_1_prog_en_1_qs; + reg_rdata_next[15:12] = bank0_info2_page_cfg_1_erase_en_1_qs; + reg_rdata_next[19:16] = bank0_info2_page_cfg_1_scramble_en_1_qs; + reg_rdata_next[23:20] = bank0_info2_page_cfg_1_ecc_en_1_qs; + reg_rdata_next[27:24] = bank0_info2_page_cfg_1_he_en_1_qs; + end + + addr_hit[63]: begin + reg_rdata_next[0] = bank1_info0_regwen_0_qs; + end + + addr_hit[64]: begin + reg_rdata_next[0] = bank1_info0_regwen_1_qs; + end + + addr_hit[65]: begin + reg_rdata_next[0] = bank1_info0_regwen_2_qs; + end + + addr_hit[66]: begin + reg_rdata_next[0] = bank1_info0_regwen_3_qs; + end + + addr_hit[67]: begin + reg_rdata_next[0] = bank1_info0_regwen_4_qs; + end + + addr_hit[68]: begin + reg_rdata_next[0] = bank1_info0_regwen_5_qs; + end + + addr_hit[69]: begin + reg_rdata_next[0] = bank1_info0_regwen_6_qs; + end + + addr_hit[70]: begin + reg_rdata_next[0] = bank1_info0_regwen_7_qs; + end + + addr_hit[71]: begin + reg_rdata_next[0] = bank1_info0_regwen_8_qs; + end + + addr_hit[72]: begin + reg_rdata_next[0] = bank1_info0_regwen_9_qs; + end + + addr_hit[73]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_0_en_0_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_0_rd_en_0_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_0_prog_en_0_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_0_erase_en_0_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_0_scramble_en_0_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_0_ecc_en_0_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_0_he_en_0_qs; + end + + addr_hit[74]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_1_en_1_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_1_rd_en_1_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_1_prog_en_1_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_1_erase_en_1_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_1_scramble_en_1_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_1_ecc_en_1_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_1_he_en_1_qs; + end + + addr_hit[75]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_2_en_2_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_2_rd_en_2_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_2_prog_en_2_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_2_erase_en_2_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_2_scramble_en_2_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_2_ecc_en_2_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_2_he_en_2_qs; + end + + addr_hit[76]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_3_en_3_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_3_rd_en_3_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_3_prog_en_3_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_3_erase_en_3_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_3_scramble_en_3_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_3_ecc_en_3_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_3_he_en_3_qs; + end + + addr_hit[77]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_4_en_4_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_4_rd_en_4_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_4_prog_en_4_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_4_erase_en_4_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_4_scramble_en_4_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_4_ecc_en_4_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_4_he_en_4_qs; + end + + addr_hit[78]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_5_en_5_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_5_rd_en_5_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_5_prog_en_5_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_5_erase_en_5_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_5_scramble_en_5_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_5_ecc_en_5_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_5_he_en_5_qs; + end + + addr_hit[79]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_6_en_6_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_6_rd_en_6_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_6_prog_en_6_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_6_erase_en_6_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_6_scramble_en_6_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_6_ecc_en_6_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_6_he_en_6_qs; + end + + addr_hit[80]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_7_en_7_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_7_rd_en_7_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_7_prog_en_7_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_7_erase_en_7_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_7_scramble_en_7_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_7_ecc_en_7_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_7_he_en_7_qs; + end + + addr_hit[81]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_8_en_8_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_8_rd_en_8_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_8_prog_en_8_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_8_erase_en_8_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_8_scramble_en_8_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_8_ecc_en_8_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_8_he_en_8_qs; + end + + addr_hit[82]: begin + reg_rdata_next[3:0] = bank1_info0_page_cfg_9_en_9_qs; + reg_rdata_next[7:4] = bank1_info0_page_cfg_9_rd_en_9_qs; + reg_rdata_next[11:8] = bank1_info0_page_cfg_9_prog_en_9_qs; + reg_rdata_next[15:12] = bank1_info0_page_cfg_9_erase_en_9_qs; + reg_rdata_next[19:16] = bank1_info0_page_cfg_9_scramble_en_9_qs; + reg_rdata_next[23:20] = bank1_info0_page_cfg_9_ecc_en_9_qs; + reg_rdata_next[27:24] = bank1_info0_page_cfg_9_he_en_9_qs; + end + + addr_hit[83]: begin + reg_rdata_next[0] = bank1_info1_regwen_qs; + end + + addr_hit[84]: begin + reg_rdata_next[3:0] = bank1_info1_page_cfg_en_0_qs; + reg_rdata_next[7:4] = bank1_info1_page_cfg_rd_en_0_qs; + reg_rdata_next[11:8] = bank1_info1_page_cfg_prog_en_0_qs; + reg_rdata_next[15:12] = bank1_info1_page_cfg_erase_en_0_qs; + reg_rdata_next[19:16] = bank1_info1_page_cfg_scramble_en_0_qs; + reg_rdata_next[23:20] = bank1_info1_page_cfg_ecc_en_0_qs; + reg_rdata_next[27:24] = bank1_info1_page_cfg_he_en_0_qs; + end + + addr_hit[85]: begin + reg_rdata_next[0] = bank1_info2_regwen_0_qs; + end + + addr_hit[86]: begin + reg_rdata_next[0] = bank1_info2_regwen_1_qs; + end + + addr_hit[87]: begin + reg_rdata_next[3:0] = bank1_info2_page_cfg_0_en_0_qs; + reg_rdata_next[7:4] = bank1_info2_page_cfg_0_rd_en_0_qs; + reg_rdata_next[11:8] = bank1_info2_page_cfg_0_prog_en_0_qs; + reg_rdata_next[15:12] = bank1_info2_page_cfg_0_erase_en_0_qs; + reg_rdata_next[19:16] = bank1_info2_page_cfg_0_scramble_en_0_qs; + reg_rdata_next[23:20] = bank1_info2_page_cfg_0_ecc_en_0_qs; + reg_rdata_next[27:24] = bank1_info2_page_cfg_0_he_en_0_qs; + end + + addr_hit[88]: begin + reg_rdata_next[3:0] = bank1_info2_page_cfg_1_en_1_qs; + reg_rdata_next[7:4] = bank1_info2_page_cfg_1_rd_en_1_qs; + reg_rdata_next[11:8] = bank1_info2_page_cfg_1_prog_en_1_qs; + reg_rdata_next[15:12] = bank1_info2_page_cfg_1_erase_en_1_qs; + reg_rdata_next[19:16] = bank1_info2_page_cfg_1_scramble_en_1_qs; + reg_rdata_next[23:20] = bank1_info2_page_cfg_1_ecc_en_1_qs; + reg_rdata_next[27:24] = bank1_info2_page_cfg_1_he_en_1_qs; + end + + addr_hit[89]: begin + reg_rdata_next[3:0] = hw_info_cfg_override_scramble_dis_qs; + reg_rdata_next[7:4] = hw_info_cfg_override_ecc_dis_qs; + end + + addr_hit[90]: begin + reg_rdata_next[0] = bank_cfg_regwen_qs; + end + + addr_hit[91]: begin + reg_rdata_next[0] = mp_bank_cfg_shadowed_erase_en_0_qs; + reg_rdata_next[1] = mp_bank_cfg_shadowed_erase_en_1_qs; + end + + addr_hit[92]: begin + reg_rdata_next[0] = op_status_done_qs; + reg_rdata_next[1] = op_status_err_qs; + end + + addr_hit[93]: begin + reg_rdata_next[0] = status_rd_full_qs; + reg_rdata_next[1] = status_rd_empty_qs; + reg_rdata_next[2] = status_prog_full_qs; + reg_rdata_next[3] = status_prog_empty_qs; + reg_rdata_next[4] = status_init_wip_qs; + reg_rdata_next[5] = status_initialized_qs; + end + + addr_hit[94]: begin + reg_rdata_next[10:0] = debug_state_qs; + end + + addr_hit[95]: begin + reg_rdata_next[0] = err_code_op_err_qs; + reg_rdata_next[1] = err_code_mp_err_qs; + reg_rdata_next[2] = err_code_rd_err_qs; + reg_rdata_next[3] = err_code_prog_err_qs; + reg_rdata_next[4] = err_code_prog_win_err_qs; + reg_rdata_next[5] = err_code_prog_type_err_qs; + reg_rdata_next[6] = err_code_update_err_qs; + reg_rdata_next[7] = err_code_macro_err_qs; + end + + addr_hit[96]: begin + reg_rdata_next[0] = std_fault_status_reg_intg_err_qs; + reg_rdata_next[1] = std_fault_status_prog_intg_err_qs; + reg_rdata_next[2] = std_fault_status_lcmgr_err_qs; + reg_rdata_next[3] = std_fault_status_lcmgr_intg_err_qs; + reg_rdata_next[4] = std_fault_status_arb_fsm_err_qs; + reg_rdata_next[5] = std_fault_status_storage_err_qs; + reg_rdata_next[6] = std_fault_status_phy_fsm_err_qs; + reg_rdata_next[7] = std_fault_status_ctrl_cnt_err_qs; + reg_rdata_next[8] = std_fault_status_fifo_err_qs; + end + + addr_hit[97]: begin + reg_rdata_next[0] = fault_status_op_err_qs; + reg_rdata_next[1] = fault_status_mp_err_qs; + reg_rdata_next[2] = fault_status_rd_err_qs; + reg_rdata_next[3] = fault_status_prog_err_qs; + reg_rdata_next[4] = fault_status_prog_win_err_qs; + reg_rdata_next[5] = fault_status_prog_type_err_qs; + reg_rdata_next[6] = fault_status_seed_err_qs; + reg_rdata_next[7] = fault_status_phy_relbl_err_qs; + reg_rdata_next[8] = fault_status_phy_storage_err_qs; + reg_rdata_next[9] = fault_status_spurious_ack_qs; + reg_rdata_next[10] = fault_status_arb_err_qs; + reg_rdata_next[11] = fault_status_host_gnt_err_qs; + end + + addr_hit[98]: begin + reg_rdata_next[15:0] = err_addr_qs; + end + + addr_hit[99]: begin + reg_rdata_next[7:0] = ecc_single_err_cnt_ecc_single_err_cnt_0_qs; + reg_rdata_next[15:8] = ecc_single_err_cnt_ecc_single_err_cnt_1_qs; + end + + addr_hit[100]: begin + reg_rdata_next[15:0] = ecc_single_err_addr_0_qs; + end + + addr_hit[101]: begin + reg_rdata_next[15:0] = ecc_single_err_addr_1_qs; + end + + addr_hit[102]: begin + reg_rdata_next[0] = phy_alert_cfg_alert_ack_qs; + reg_rdata_next[1] = phy_alert_cfg_alert_trig_qs; + end + + addr_hit[103]: begin + reg_rdata_next[0] = phy_status_init_wip_qs; + reg_rdata_next[1] = phy_status_prog_normal_avail_qs; + reg_rdata_next[2] = phy_status_prog_repair_avail_qs; + end + + addr_hit[104]: begin + reg_rdata_next[31:0] = scratch_qs; + end + + addr_hit[105]: begin + reg_rdata_next[4:0] = fifo_lvl_prog_qs; + reg_rdata_next[12:8] = fifo_lvl_rd_qs; + end + + addr_hit[106]: begin + reg_rdata_next[0] = fifo_rst_qs; + end + + addr_hit[107]: begin + reg_rdata_next[4:0] = curr_fifo_lvl_prog_qs; + reg_rdata_next[12:8] = curr_fifo_lvl_rd_qs; + end + + default: begin + reg_rdata_next = '1; + end + endcase + end + + // shadow busy + logic shadow_busy; + logic rst_done; + logic shadow_rst_done; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rst_done <= '0; + end else begin + rst_done <= 1'b1; + end + end + + always_ff @(posedge clk_i or negedge rst_shadowed_ni) begin + if (!rst_shadowed_ni) begin + shadow_rst_done <= '0; + end else begin + shadow_rst_done <= 1'b1; + end + end + + // both shadow and normal resets have been released + assign shadow_busy = ~(rst_done & shadow_rst_done); + + // Collect up storage and update errors + assign shadowed_storage_err_o = |{ + mp_bank_cfg_shadowed_erase_en_0_storage_err, + mp_bank_cfg_shadowed_erase_en_1_storage_err + }; + assign shadowed_update_err_o = |{ + mp_bank_cfg_shadowed_erase_en_0_update_err, + mp_bank_cfg_shadowed_erase_en_1_update_err + }; + + // 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_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_erase.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_erase.sv new file mode 100644 index 0000000000000..2fde25933ea4b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_erase.sv @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Faux Flash Erase Control +// + +module flash_ctrl_erase import flash_ctrl_pkg::*; ( + // Software Interface + input op_start_i, + input flash_erase_e op_type_i, + input [BusAddrW-1:0] op_addr_i, + input op_addr_oob_i, + output logic op_done_o, + output flash_ctrl_err_t op_err_o, + output logic [BusAddrW-1:0] op_err_addr_o, + + // Flash Macro Interface + output logic flash_req_o, + output logic [BusAddrW-1:0] flash_addr_o, + output flash_erase_e flash_op_o, + input flash_done_i, + input flash_mp_err_i +); + + localparam int WordsBitWidth = $clog2(BusWordsPerPage); + localparam int PagesBitWidth = $clog2(PagesPerBank); + + // The *AddrMask below masks out the bits that are not required + // e.g, assume we have an address 0x5_0004_345C + // 0x5 represents bank address + // 0x0004 represents page address + // PageAddrMask would be 0xF_FFFF_0000 + // BankAddrMask would be 0xF_0000_0000 + // + localparam int unsigned PageAddrMaskInt = ~(('h1 << WordsBitWidth) - 1'b1); + localparam int unsigned BankAddrMaskInt = ~(('h1 << (PagesBitWidth + WordsBitWidth)) - 1'b1); + localparam logic [BusAddrW-1:0] PageAddrMask = PageAddrMaskInt[BusAddrW-1:0]; + localparam logic [BusAddrW-1:0] BankAddrMask = BankAddrMaskInt[BusAddrW-1:0]; + + // out of bounds condition, the initial starting address is beyond the flash + logic oob_err; + assign oob_err = op_start_i & op_addr_oob_i; + + // IO assignments + assign op_done_o = flash_req_o & (flash_done_i | oob_err); + + always_comb begin + op_err_o = '0; + op_err_o.oob_err = op_done_o & oob_err; + op_err_o.mp_err = op_done_o & flash_mp_err_i; + end + + + // Flash Interface assignments + assign flash_req_o = op_start_i & ~op_addr_oob_i; + assign flash_op_o = op_type_i; + assign flash_addr_o = (op_type_i == FlashErasePage) ? + op_addr_i & PageAddrMask : + op_addr_i & BankAddrMask; + + assign op_err_addr_o = flash_addr_o; + + // unused bus + logic [WordsBitWidth-1:0] unused_addr_i; + assign unused_addr_i = op_addr_i[WordsBitWidth-1:0]; + + +endmodule // flash_ctrl_erase diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_info_cfg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_info_cfg.sv new file mode 100644 index 0000000000000..3f2b025873801 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_info_cfg.sv @@ -0,0 +1,133 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash info page protection assignment +// This module takes into account seed pages and assigns privileges accordingly. + +`include "prim_assert.sv" + +module flash_ctrl_info_cfg import flash_ctrl_pkg::*; # ( + parameter logic [BankW-1:0] Bank = 0, + parameter logic [InfoTypesWidth-1:0] InfoSel = 0 +) ( + input clk_i, + input rst_ni, + input info_page_cfg_t [InfosPerBank-1:0] cfgs_i, + input creator_seed_priv_i, + input owner_seed_priv_i, + input iso_flash_wr_en_i, + input iso_flash_rd_en_i, + output info_page_cfg_t [InfosPerBank-1:0] cfgs_o +); + + import prim_mubi_pkg::mubi4_t; + import prim_mubi_pkg::MuBi4True; + import prim_mubi_pkg::mubi4_bool_to_mubi; + + info_page_cfg_t creator_seed_qual, owner_seed_qual, isolate_qual; + + mubi4_t creator_en; + prim_mubi4_sender #( + .AsyncOn(0), + .EnSecBuf(1) + ) u_creator_mubi ( + .clk_i, + .rst_ni, + .mubi_i(mubi4_bool_to_mubi(creator_seed_priv_i)), + .mubi_o(creator_en) + ); + + mubi4_t owner_en; + prim_mubi4_sender #( + .AsyncOn(0), + .EnSecBuf(1) + ) u_owner_mubi ( + .clk_i, + .rst_ni, + .mubi_i(mubi4_bool_to_mubi(owner_seed_priv_i)), + .mubi_o(owner_en) + ); + + assign creator_seed_qual = '{ + en: creator_en, + rd_en: creator_en, + prog_en: creator_en, + erase_en: creator_en, + scramble_en: MuBi4True, + ecc_en: MuBi4True, + he_en : MuBi4True + }; + + assign owner_seed_qual = '{ + en: owner_en, + rd_en: owner_en, + prog_en: owner_en, + erase_en: owner_en, + scramble_en: MuBi4True, + ecc_en: MuBi4True, + he_en : MuBi4True + }; + + assign isolate_qual = '{ + en: MuBi4True, + rd_en: mubi4_bool_to_mubi(iso_flash_rd_en_i), + prog_en: mubi4_bool_to_mubi(iso_flash_wr_en_i), + erase_en: mubi4_bool_to_mubi(iso_flash_wr_en_i), + scramble_en: MuBi4True, + ecc_en: MuBi4True, + he_en : MuBi4True + }; + + // The code below uses page_addr_t to represent a page inside an Info partition, but a page_addr_t + // is really designed a page inside a Data partition (the "addr" field has width BankW + PageW, + // not BankW + InfoPageW). This will work just fine so long as InfoPageW <= PageW, but we should + // check that's always true. + `ASSERT_INIT(InfoNoBiggerThanData_A, InfoPageW <= PageW) + + for (genvar i = 0; i < InfosPerBank; i++) begin : gen_info_priv + + localparam logic [InfoPageW-1:0] CurPage = i; + localparam page_addr_t CurAddr = '{sel: InfoSel, addr: {Bank, PageW'(CurPage)}}; + + if (i > InfoTypeSize[InfoSel]) begin : gen_invalid_region + assign cfgs_o[i] = CfgInfoDisable; + + // For info types that have fewer pages than the maximum, not the full config (cfgs_i[i] for i + // greater than InfoTypeSize[InfoSel]) is used. + info_page_cfg_t unused_cfgs; + assign unused_cfgs = cfgs_i[i]; + + // if match creator, only allow access when creator privilege is set + end else if (CurAddr == SeedInfoPageSel[CreatorSeedIdx]) begin : gen_creator + assign cfgs_o[i] = info_cfg_qual(cfgs_i[i], creator_seed_qual); + + // if match owner, only allow access when owner privilege is set + end else if (CurAddr == SeedInfoPageSel[OwnerSeedIdx]) begin : gen_owner + assign cfgs_o[i] = info_cfg_qual(cfgs_i[i], owner_seed_qual); + + // if match isolated partition, only allow read when provision privilege is set + end else if (CurAddr == IsolatedPageSel) begin : gen_isolated_page + assign cfgs_o[i] = info_cfg_qual(cfgs_i[i], isolate_qual); + + // since certain fields will always be 0'd out based on mubi values, + // the software input will look like it is unused to lint + info_page_cfg_t unused_cfgs; + assign unused_cfgs = cfgs_i[i]; + + // if other, just passthrough configuration + end else begin : gen_normal + assign cfgs_o[i] = cfgs_i[i]; + end + end + + // if bank does not contain seed pages, tie off the privilege signals + if (SeedBank != Bank || SeedInfoSel != InfoSel) begin : gen_tieoffs + info_page_cfg_t unused_pg_cfg; + assign unused_pg_cfg = creator_seed_qual^owner_seed_qual^isolate_qual; + end + + + + +endmodule // flash_ctrl_info_cfg diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_lcmgr.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_lcmgr.sv new file mode 100644 index 0000000000000..06e4dc8583970 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_lcmgr.sv @@ -0,0 +1,947 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Controller for life cycle / key management handling +// + +module flash_ctrl_lcmgr + import flash_ctrl_pkg::*; + import lc_ctrl_pkg::lc_tx_t; +#( + parameter flash_key_t RndCnstAddrKey = RndCnstAddrKeyDefault, + parameter flash_key_t RndCnstDataKey = RndCnstDataKeyDefault, + parameter all_seeds_t RndCnstAllSeeds = RndCnstAllSeedsDefault +) ( + input clk_i, + input rst_ni, + input clk_otp_i, + input rst_otp_ni, + + // initialization command + input init_i, + + // only access seeds when provisioned + input provision_en_i, + + // combined escalation disable + input prim_mubi_pkg::mubi4_t disable_i, + + // interface to ctrl arb control ports + output flash_ctrl_reg_pkg::flash_ctrl_reg2hw_control_reg_t ctrl_o, + output logic req_o, + output logic [BusAddrByteW-1:0] addr_o, + input done_i, + input flash_ctrl_err_t err_i, + + // interface to ctrl_arb data ports + output logic rready_o, + input rvalid_i, + output logic wvalid_o, + input wready_i, + + // direct form rd_fifo + // rdata_i is {data_integrity, data}, the upper bits store integrity + input [BusFullWidth-1:0] rdata_i, + + // direct to wr_fifo + output logic [BusFullWidth-1:0] wdata_o, + + // external rma request + // This should be simplified to just multi-bit request and multi-bit response + input lc_tx_t rma_req_i, + output lc_tx_t rma_ack_o, + + // seeds to the outside world, + output logic [NumSeeds-1:0][SeedWidth-1:0] seeds_o, + + // indicate to memory protection what phase the hw interface is in + output flash_lcmgr_phase_e phase_o, + + // fatal errors + output logic fatal_err_o, + output logic intg_err_o, + + // error status to registers + output logic seed_err_o, + + // enable read buffer in flash_phy + output logic rd_buf_en_o, + + // request otp keys + output otp_ctrl_pkg::flash_otp_key_req_t otp_key_req_o, + input otp_ctrl_pkg::flash_otp_key_rsp_t otp_key_rsp_i, + output flash_key_t addr_key_o, + output flash_key_t data_key_o, + output flash_key_t rand_addr_key_o, + output flash_key_t rand_data_key_o, + + // entropy interface + output logic edn_req_o, + input edn_ack_i, + output logic lfsr_en_o, + input [BusWidth-1:0] rand_i, + + // disable access to flash + output lc_tx_t dis_access_o, + + // init ongoing + output logic init_busy_o, + output logic initialized_o, + + // debug state output + output logic [10:0] debug_state_o +); + + import lc_ctrl_pkg::lc_tx_test_true_strict; + + // total number of pages to be wiped during RMA entry + localparam int unsigned WipeIdxWidth = prim_util_pkg::vbits(WipeEntries); + localparam int unsigned MaxWipeEntry = WipeEntries - 1; + + // seed related local params + localparam int unsigned SeedReads = SeedWidth / BusWidth; + localparam int unsigned SeedRdsWidth = $clog2(SeedReads); + localparam int unsigned SeedCntWidth = $clog2(NumSeeds+1); + localparam int unsigned NumSeedWidth = $clog2(NumSeeds); + + // the various seed outputs + logic [NumSeeds-1:0][SeedReads-1:0][BusWidth-1:0] seeds_q; + + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: -- + // 5: |||||||||||||||||||| (40.00%) + // 6: |||||||||||||||| (33.33%) + // 7: ||||| (11.11%) + // 8: |||||| (13.33%) + // 9: | (2.22%) + // 10: -- + // 11: -- + // + // Minimum Hamming distance: 5 + // Maximum Hamming distance: 9 + // Minimum Hamming weight: 4 + // Maximum Hamming weight: 7 + // + localparam int StateWidth = 11; + typedef enum logic [StateWidth-1:0] { + StIdle = 11'b10001000001, + StReqAddrKey = 11'b01110101100, + StReqDataKey = 11'b01110010001, + StReadSeeds = 11'b11011111110, + StReadEval = 11'b01000100111, + StWait = 11'b00100111011, + StEntropyReseed = 11'b00011000110, + StRmaWipe = 11'b10010110101, + StRmaRsp = 11'b10110001010, + StDisabled = 11'b11111100011, + StInvalid = 11'b11101011000 + } lcmgr_state_e; + + lcmgr_state_e state_q, state_d; + logic state_err; + + assign debug_state_o = state_q; + + //SEC_CM: CTRL.FSM.SPARSE + `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, lcmgr_state_e, StIdle) + + lc_tx_t err_sts_d, err_sts_q; + logic err_sts_set; + lc_tx_t rma_ack_d, rma_ack_q; + logic validate_q, validate_d; + logic [SeedCntWidth-1:0] seed_cnt_q; + logic [SeedRdsWidth-1:0] addr_cnt_q; + logic seed_cnt_en, seed_cnt_clr; + logic addr_cnt_en, addr_cnt_clr; + logic rma_wipe_req, rma_wipe_done, rma_wipe_req_int; + logic [WipeIdxWidth-1:0] rma_wipe_idx; + logic rma_wipe_idx_incr; + flash_lcmgr_phase_e phase; + logic seed_phase; + logic rma_phase; + logic seed_err_q, seed_err_d; + + assign seed_phase = phase == PhaseSeed; + assign rma_phase = phase == PhaseRma; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + rma_ack_q <= lc_ctrl_pkg::Off; + validate_q <= 1'b0; + seed_err_q <= '0; + end else begin + rma_ack_q <= rma_ack_d; + validate_q <= validate_d; + seed_err_q <= seed_err_d; + end + end + + assign seed_err_o = seed_err_q | seed_err_d; + + // seed cnt tracks which seed round we are handling at the moment + // SEC_CM: CTR.REDUN + logic seed_cnt_err_d, seed_cnt_err_q; + prim_count #( + .Width(SeedCntWidth) + ) u_seed_cnt ( + .clk_i, + .rst_ni, + .clr_i(seed_cnt_clr), + .set_i('0), + .set_cnt_i('0), + .incr_en_i(seed_cnt_en), + .decr_en_i(1'b0), + .step_i(SeedCntWidth'(1'b1)), + .commit_i(1'b1), + .cnt_o(seed_cnt_q), + .cnt_after_commit_o(), + .err_o(seed_cnt_err_d) + ); + + // SEC_CM: CTR.REDUN + logic addr_cnt_err_d, addr_cnt_err_q; + prim_count #( + .Width(SeedRdsWidth) + ) u_addr_cnt ( + .clk_i, + .rst_ni, + .clr_i(addr_cnt_clr), + .set_i('0), + .set_cnt_i('0), + .incr_en_i(addr_cnt_en), + .decr_en_i(1'b0), + .step_i(SeedRdsWidth'(1'b1)), + .commit_i(1'b1), + .cnt_o(addr_cnt_q), + .cnt_after_commit_o(), + .err_o(addr_cnt_err_d) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + addr_cnt_err_q <= '0; + seed_cnt_err_q <= '0; + end else begin + addr_cnt_err_q <= addr_cnt_err_q | addr_cnt_err_d; + seed_cnt_err_q <= seed_cnt_err_q | seed_cnt_err_d; + end + end + + // read data integrity check + logic data_err; + logic data_intg_ok; + tlul_data_integ_dec u_data_intg_chk ( + .data_intg_i(rdata_i), + .data_err_o(data_err) + ); + assign data_intg_ok = ~data_err; + + // hold on to failed integrity until reset + logic data_invalid_d, data_invalid_q; + assign data_invalid_d = data_invalid_q | + (rvalid_i & ~data_intg_ok); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + data_invalid_q <= '0; + end else begin + data_invalid_q <= data_invalid_d; + end + end + + // capture the seed values + logic [SeedRdsWidth-1:0] rd_idx; + logic [NumSeedWidth-1:0] seed_idx; + assign rd_idx = addr_cnt_q[SeedRdsWidth-1:0]; + assign seed_idx = seed_cnt_q[NumSeedWidth-1:0]; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + seeds_q <= RndCnstAllSeeds; + end else if (seed_phase && validate_q && rvalid_i) begin + // validate current value + seeds_q[seed_idx][rd_idx] <= seeds_q[seed_idx][rd_idx] & + rdata_i[BusWidth-1:0]; + end else if (seed_phase && rvalid_i) begin + seeds_q[seed_idx][rd_idx] <= rdata_i[BusWidth-1:0]; + end + end + + page_addr_t seed_page; + logic [InfoTypesWidth-1:0] seed_info_sel; + logic [BusAddrW-1:0] seed_page_addr; + assign seed_page = SeedInfoPageSel[seed_idx]; + assign seed_info_sel = seed_page.sel; + assign seed_page_addr = BusAddrW'({seed_page.addr, BusWordW'(0)}); + + logic start; + flash_op_e op; + flash_prog_e prog_type; + flash_erase_e erase_type; + flash_part_e part_sel; + logic [InfoTypesWidth-1:0] info_sel; + logic [11:0] num_words; + logic [BusAddrW-1:0] addr; + + assign prog_type = FlashProgNormal; + assign erase_type = FlashErasePage; + // seed phase is always read + // rma phase is erase unless we are validating + assign op = FlashOpRead; + + // synchronize inputs + logic init_q; + + prim_flop_2sync #( + .Width(1), + .ResetValue(0) + ) u_sync_flash_init ( + .clk_i, + .rst_ni, + .d_i(init_i), + .q_o(init_q) + ); + + typedef enum logic [1:0] { + RmaReqInit, + RmaReqKey, + RmaReqWait, + RmaReqLast + } rma_req_idx_e; + + lc_tx_t [RmaReqLast-1:0] rma_req; + prim_lc_sync #( + .NumCopies(int'(RmaReqLast)) + ) u_sync_rma_req ( + .clk_i, + .rst_ni, + .lc_en_i(rma_req_i), + .lc_en_o(rma_req) + ); + + logic addr_key_req_d; + logic addr_key_ack_q; + logic data_key_req_d; + logic data_key_ack_q; + + // req/ack to otp + prim_sync_reqack u_addr_sync_reqack ( + .clk_src_i(clk_i), + .rst_src_ni(rst_ni), + .clk_dst_i(clk_otp_i), + .rst_dst_ni(rst_otp_ni), + .req_chk_i(1'b1), + .src_req_i(addr_key_req_d), + .src_ack_o(addr_key_ack_q), + .dst_req_o(otp_key_req_o.addr_req), + .dst_ack_i(otp_key_rsp_i.addr_ack) + ); + + // req/ack to otp + prim_sync_reqack u_data_sync_reqack ( + .clk_src_i(clk_i), + .rst_src_ni(rst_ni), + .clk_dst_i(clk_otp_i), + .rst_dst_ni(rst_otp_ni), + .req_chk_i(1'b1), + .src_req_i(data_key_req_d), + .src_ack_o(data_key_ack_q), + .dst_req_o(otp_key_req_o.data_req), + .dst_ack_i(otp_key_rsp_i.data_ack) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + addr_key_o <= RndCnstAddrKey; + data_key_o <= RndCnstDataKey; + end else begin + if (addr_key_req_d && addr_key_ack_q) begin + addr_key_o <= flash_key_t'(otp_key_rsp_i.key); + rand_addr_key_o <= flash_key_t'(otp_key_rsp_i.rand_key); + end + + if (data_key_req_d && data_key_ack_q) begin + data_key_o <= flash_key_t'(otp_key_rsp_i.key); + rand_data_key_o <= flash_key_t'(otp_key_rsp_i.rand_key); + end + end + end + + + /////////////////////////////// + // Hardware Interface FSM + /////////////////////////////// + logic rma_done; + assign rma_done = lc_tx_test_true_strict( + lc_ctrl_pkg::lc_tx_and_hi(rma_req_i,rma_ack_d)); + + always_comb begin + + // phases of the hardware interface + phase = PhaseNone; + + // timer controls + seed_cnt_en = 1'b0; + seed_cnt_clr = 1'b0; + addr_cnt_en = 1'b0; + addr_cnt_clr = 1'b0; + + // flash ctrl arb controls + start = 1'b0; + addr = '0; + part_sel = FlashPartInfo; + info_sel = 0; + num_words = SeedReads[11:0] - 12'd1; + + // seed status + seed_err_d = seed_err_q; + + state_d = state_q; + rma_ack_d = lc_ctrl_pkg::Off; + validate_d = validate_q; + + // read buffer enable + rd_buf_en_o = 1'b0; + + addr_key_req_d = 1'b0; + data_key_req_d = 1'b0; + + // entropy handling + edn_req_o = 1'b0; + lfsr_en_o = 1'b0; + + // rma related + rma_wipe_req = 1'b0; + rma_wipe_idx_incr = 1'b0; + + // disable flash access entirely + dis_access_o = lc_ctrl_pkg::Off; + + state_err = 1'b0; + + unique case (state_q) + + // If rma request is seen, directly transition to wipe. + // Since init has not been called, there are no guarantees + // to entropy behavior, thus do not reseed + StIdle: begin + if (lc_tx_test_true_strict(rma_req[RmaReqInit])) begin + state_d = StRmaWipe; + end else if (init_q) begin + state_d = StReqAddrKey; + end + end + + StReqAddrKey: begin + phase = PhaseSeed; + addr_key_req_d = 1'b1; + if (lc_tx_test_true_strict(rma_req[RmaReqKey])) begin + state_d = StRmaWipe; + end else if (addr_key_ack_q) begin + state_d = StReqDataKey; + end + end + + StReqDataKey: begin + phase = PhaseSeed; + data_key_req_d = 1'b1; + if (lc_tx_test_true_strict(rma_req[RmaReqKey])) begin + state_d = StRmaWipe; + end else if (data_key_ack_q) begin + // provision_en is only a "good" value after otp/lc initialization + state_d = provision_en_i ? StReadSeeds : StWait; + end + end + + // read seeds + StReadSeeds: begin + // seeds can be updated in this state + phase = PhaseSeed; + + // kick off flash transaction + start = 1'b1; + addr = BusAddrW'(seed_page_addr); + info_sel = seed_info_sel; + + // we have checked all seeds, proceed + addr_cnt_en = rvalid_i; + if (seed_cnt_q == NumSeeds) begin + start = 1'b0; + state_d = StWait; + end else if (done_i) begin + seed_err_d = |err_i; + state_d = StReadEval; + end + end // case: StReadSeeds + + StReadEval: begin + phase = PhaseSeed; + addr_cnt_clr = 1'b1; + state_d = StReadSeeds; + + if (validate_q) begin + seed_cnt_en = 1'b1; + validate_d = 1'b0; + end else begin + validate_d = 1'b1; + end + end + + // Waiting for an rma entry command + StWait: begin + rd_buf_en_o = 1'b1; + if (lc_tx_test_true_strict(rma_req[RmaReqWait])) begin + state_d = StEntropyReseed; + end + end + + // Reseed entropy + StEntropyReseed: begin + edn_req_o = 1'b1; + if(edn_ack_i) begin + state_d = StRmaWipe; + end + end + + StRmaWipe: begin + phase = PhaseRma; + lfsr_en_o = 1'b1; + rma_wipe_req = 1'b1; + + if (rma_wipe_idx == MaxWipeEntry[WipeIdxWidth-1:0] && rma_wipe_done) begin + // first check for error status + // If error status is set, go directly to invalid terminal state + // If error status is good, go to second check + state_d = lc_ctrl_pkg::lc_tx_test_false_loose(err_sts_q) ? StInvalid : StRmaRsp; + end else if (rma_wipe_done) begin + rma_wipe_idx_incr = 1; + end + end + + // response to rma request + // Second check for error status: + // If error status indicates error, jump to invalid terminal state + // Otherwise assign output to error status; + StRmaRsp: begin + phase = PhaseRma; + dis_access_o = lc_ctrl_pkg::On; + if (lc_ctrl_pkg::lc_tx_test_false_loose(err_sts_q)) begin + state_d = StInvalid; + end else begin + rma_ack_d = err_sts_q; + end + end + + // Disabled state is functionally equivalent to invalid, just without the + // the explicit error-ing + StDisabled: begin + dis_access_o = lc_ctrl_pkg::On; + rma_ack_d = lc_ctrl_pkg::Off; + state_d = StDisabled; + end + + StInvalid: begin + dis_access_o = lc_ctrl_pkg::On; + state_err = 1'b1; + rma_ack_d = lc_ctrl_pkg::Off; + state_d = StInvalid; + end + + // Invalid catch-all state + default: begin + dis_access_o = lc_ctrl_pkg::On; + state_err = 1'b1; + state_d = StInvalid; + end + + endcase // unique case (state_q) + + // This fsm does not directly interface with flash so can be + // be transitioned to invalid immediately. + // If rma transition is successful however, do not transition + // and continue acking the life cycle controller, as disable is + // expected behavior under this situation. + if (prim_mubi_pkg::mubi4_test_true_loose(disable_i) && + state_d != StInvalid && + !rma_done) begin + state_d = StDisabled; + end + + end // always_comb + + // If state is already invalid, disable has no impact. + // If state is currently in StRmaRsp with a successful RMA transition, also do not + // transition to disabled state as we need to continue acknowledging lc_ctrl. + `ASSERT(DisableChk_A, prim_mubi_pkg::mubi4_test_true_loose(disable_i) & state_q != StRmaRsp + |=> state_q == StDisabled) + + /////////////////////////////// + // RMA wiping Mechanism + /////////////////////////////// + + localparam int unsigned PageCntWidth = prim_util_pkg::vbits(PagesPerBank + 1); + localparam int unsigned WordCntWidth = prim_util_pkg::vbits(BusWordsPerPage + 1); + localparam int unsigned MaxRmaProgBurst = WidthMultiple * 2; + localparam int unsigned BeatCntWidth = prim_util_pkg::vbits(MaxRmaProgBurst); + localparam int unsigned MaxBeatCnt = MaxRmaProgBurst - 1; + + logic page_cnt_ld; + logic page_cnt_incr; + logic page_cnt_clr; + logic word_cnt_incr; + logic word_cnt_ld; + logic word_cnt_clr; + logic prog_cnt_en; + logic rd_cnt_en; + logic beat_cnt_clr; + logic [PageCntWidth-1:0] page_cnt, end_page; + logic [WordCntWidth-1:0] word_cnt; + logic [BeatCntWidth-1:0] beat_cnt; + logic [MaxBeatCnt:0][BusWidth-1:0] prog_data; + + assign end_page = RmaWipeEntries[rma_wipe_idx].start_page + + RmaWipeEntries[rma_wipe_idx].num_pages; + + rma_state_e rma_state_d, rma_state_q; + + // SEC_CM: CTRL.FSM.SPARSE + `PRIM_FLOP_SPARSE_FSM(u_rma_state_regs, rma_state_d, rma_state_q, rma_state_e, StRmaIdle) + + // SEC_CM: CTR.REDUN + logic page_err_q, page_err_d; + prim_count #( + .Width(PageCntWidth) + ) u_page_cnt ( + .clk_i, + .rst_ni, + .clr_i(page_cnt_clr), + .set_i(page_cnt_ld), + .set_cnt_i(RmaWipeEntries[rma_wipe_idx].start_page), + .incr_en_i(page_cnt_incr), + .decr_en_i(1'b0), + .step_i(PageCntWidth'(1)), + .commit_i(1'b1), + .cnt_o(page_cnt), + .cnt_after_commit_o(), + .err_o(page_err_d) + ); + + logic word_err_q, word_err_d; + //SEC_CM: CTR.REDUN + prim_count #( + .Width(WordCntWidth) + ) u_word_cnt ( + .clk_i, + .rst_ni, + .clr_i(word_cnt_clr), + .set_i(word_cnt_ld), + .set_cnt_i('0), + .incr_en_i(word_cnt_incr), + .decr_en_i(1'b0), + .step_i(WordCntWidth'(MaxRmaProgBurst)), + .commit_i(1'b1), + .cnt_o(word_cnt), + .cnt_after_commit_o(), + .err_o(word_err_d) + ); + + logic rma_idx_err_q, rma_idx_err_d; + //SEC_CM: CTR.REDUN + prim_count #( + .Width(WipeIdxWidth) + ) u_wipe_idx_cnt ( + .clk_i, + .rst_ni, + .clr_i('0), + .set_i('0), + .set_cnt_i('0), + .incr_en_i(rma_wipe_idx_incr), + .decr_en_i(1'b0), + .step_i(WipeIdxWidth'(1'b1)), + .commit_i(1'b1), + .cnt_o(rma_wipe_idx), + .cnt_after_commit_o(), + .err_o(rma_idx_err_d) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + page_err_q <= '0; + word_err_q <= '0; + rma_idx_err_q <= '0; + end else begin + page_err_q <= page_err_q | page_err_d; + word_err_q <= word_err_q | word_err_d; + rma_idx_err_q <= rma_idx_err_q | rma_idx_err_d; + end + end + + // beat cnt is not made a prim_count because if beat_cnt + // if tampered, the read verification stage will automatically + // fail. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + beat_cnt <= '0; + end else if (beat_cnt_clr) begin + beat_cnt <= '0; + end else if (prog_cnt_en) begin + if (wvalid_o && wready_i) begin + beat_cnt <= beat_cnt + 1'b1; + end + end else if (rd_cnt_en) begin + if (rvalid_i && rready_o) begin + beat_cnt <= beat_cnt + 1'b1; + end + end + end + + // latch data programmed + always_ff @(posedge clk_i) begin + if (prog_cnt_en && wvalid_o && wready_i) begin + prog_data[beat_cnt] <= rand_i; + end + end + + // once error is set to off, it cannot be unset without a reboot + // On - no errors + // Off - errors were observed + logic [lc_ctrl_pkg::TxWidth-1:0] err_sts_raw_q; + assign err_sts_q = lc_tx_t'(err_sts_raw_q); + assign err_sts_d = err_sts_set && lc_ctrl_pkg::lc_tx_test_true_loose(err_sts_q) ? + lc_ctrl_pkg::Off : err_sts_q; + // This primitive is used to place a size-only constraint on the flops in order to prevent + // optimizations. Without this Vivado may infer combo loops. For details, see + // https://github.com/lowRISC/opentitan/issues/10204 + prim_flop #( + .Width(lc_ctrl_pkg::TxWidth), + .ResetValue(lc_ctrl_pkg::TxWidth'(lc_ctrl_pkg::On)) + ) u_prim_flop_err_sts ( + .clk_i, + .rst_ni, + .d_i(err_sts_d), + .q_o(err_sts_raw_q) + ); + + logic rma_start; + logic [BusAddrW-1:0] rma_addr; + flash_op_e rma_op; + flash_part_e rma_part_sel; + logic [InfoTypesWidth-1:0] rma_info_sel; + logic [11:0] rma_num_words; + + assign rma_addr = {RmaWipeEntries[rma_wipe_idx].bank, + page_cnt[PageW-1:0], + word_cnt[BusWordW-1:0]}; + + assign rma_part_sel = RmaWipeEntries[rma_wipe_idx].part; + assign rma_info_sel = RmaWipeEntries[rma_wipe_idx].info_sel; + assign rma_num_words = MaxBeatCnt; + + // this variable is specifically here to work around some tooling issues identified in #9661. + // Certain tools identify rma_wipe_req as part of a combinational loop. + // It is not a combinational loop in the synthesized sense, but rather a combinational loop from + // the perspective of simulation scheduler. + // This is not a synthesized combo loop for the following reasons + // 1. rma_wipe_req is changed only based on the value of state_q, so it cannot be + // affected by non-flop signals + // 2. other lint tools do not identify (including sign-off tool) an issue. + // The direct feedthrough assignment below helps address some of the tooling issues. + assign rma_wipe_req_int = rma_wipe_req; + + //fsm for handling the actual wipe + logic fsm_err; + + // SEC_CM: RMA_ENTRY.MEM.SEC_WIPE + always_comb begin + rma_state_d = rma_state_q; + rma_wipe_done = 1'b0; + rma_start = 1'b0; + rma_op = FlashOpInvalid; + err_sts_set = 1'b0; + page_cnt_ld = 1'b0; + page_cnt_incr = 1'b0; + page_cnt_clr = 1'b0; + word_cnt_ld = 1'b0; + word_cnt_incr = 1'b0; + word_cnt_clr = 1'b0; + prog_cnt_en = 1'b0; + rd_cnt_en = 1'b0; + beat_cnt_clr = 1'b0; + fsm_err = 1'b0; + + unique case (rma_state_q) + // Transition to invalid state via disable only when any ongoing stateful + // operations are complete. This ensures we do not electrically disturb + // any ongoing operation. + // This of course cannot be guaranteed if the FSM state is directly disturbed, + // and that is considered an extremely invasive attack. + StRmaIdle: begin + if (prim_mubi_pkg::mubi4_test_true_loose(disable_i)) begin + rma_state_d = StRmaDisabled; + end else if (rma_wipe_req_int) begin + rma_state_d = StRmaPageSel; + page_cnt_ld = 1'b1; + end + end + + StRmaPageSel: begin + if (prim_mubi_pkg::mubi4_test_true_loose(disable_i)) begin + rma_state_d = StRmaDisabled; + end else if (page_cnt < end_page) begin + rma_state_d = StRmaErase; + end else begin + rma_wipe_done = 1'b1; + page_cnt_clr = 1'b1; + rma_state_d = StRmaIdle; + end + end + + StRmaErase: begin + rma_start = 1'b1; + rma_op = FlashOpErase; + if (done_i) begin + err_sts_set = |err_i; + rma_state_d = StRmaEraseWait; + end + end + + StRmaEraseWait: begin + word_cnt_ld = 1'b1; + rma_state_d = StRmaWordSel; + end + + StRmaWordSel: begin + if (prim_mubi_pkg::mubi4_test_true_loose(disable_i)) begin + rma_state_d = StRmaDisabled; + end else if (word_cnt < BusWordsPerPage) begin + rma_state_d = StRmaProgram; + end else begin + word_cnt_clr = 1'b1; + page_cnt_incr = 1'b1; + rma_state_d = StRmaPageSel; + end + end + + StRmaProgram: begin + rma_start = 1'b1; + rma_op = FlashOpProgram; + prog_cnt_en = 1'b1; + + if ((beat_cnt == MaxBeatCnt[BeatCntWidth-1:0]) && wready_i) begin + rma_state_d = StRmaProgramWait; + end + end + + StRmaProgramWait: begin + rma_start = 1'b1; + rma_op = FlashOpProgram; + + if (done_i) begin + beat_cnt_clr = 1'b1; + err_sts_set = |err_i; + rma_state_d = StRmaRdVerify; + end + end + + StRmaRdVerify: begin + rma_start = 1'b1; + rma_op = FlashOpRead; + rd_cnt_en = 1'b1; + + if ((beat_cnt == MaxBeatCnt[BeatCntWidth-1:0]) && done_i) begin + beat_cnt_clr = 1'b1; + word_cnt_incr = 1'b1; + rma_state_d = StRmaWordSel; + end + + if (rvalid_i && rready_o) begin + err_sts_set = prog_data[beat_cnt] != rdata_i[BusWidth-1:0]; + end + end + + StRmaDisabled: begin + rma_state_d = StRmaDisabled; + end + + StRmaInvalid: begin + rma_state_d = StRmaInvalid; + err_sts_set = 1'b1; + fsm_err = 1'b1; + end + + default: begin + rma_state_d = StRmaInvalid; + fsm_err = 1'b1; + end + + endcase // unique case (rma_state_q) + + end // always_comb + + tlul_data_integ_enc u_bus_intg ( + .data_i(rand_i), + .data_intg_o(wdata_o) + ); + + assign wvalid_o = prog_cnt_en; + assign ctrl_o.start.q = seed_phase ? start : rma_start; + assign ctrl_o.op.q = seed_phase ? op : rma_op; + assign ctrl_o.prog_sel.q = prog_type; + assign ctrl_o.erase_sel.q = erase_type; + assign ctrl_o.partition_sel.q = seed_phase ? part_sel : rma_part_sel; + assign ctrl_o.info_sel.q = seed_phase ? info_sel : rma_info_sel; + assign ctrl_o.num = seed_phase ? num_words : rma_num_words; + // address is consistent with software width format (full bus) + assign addr_o = seed_phase ? {addr, {BusByteWidth{1'b0}}} : + {rma_addr, {BusByteWidth{1'b0}}}; + assign init_busy_o = seed_phase; + + // Initialization is considered done when read buffer is enabled. + assign initialized_o = rd_buf_en_o; + assign req_o = seed_phase | rma_phase; + assign rready_o = 1'b1; + assign seeds_o = seeds_q; + assign phase_o = phase; + + assign rma_ack_o = rma_ack_q; + + // all of these are considered fatal errors + assign fatal_err_o = page_err_q | word_err_q | fsm_err | state_err | rma_idx_err_q | + addr_cnt_err_q | seed_cnt_err_q; + + // integrity error is its own category + assign intg_err_o = data_invalid_q; + + logic unused_seed_valid; + assign unused_seed_valid = otp_key_rsp_i.seed_valid; + + // assertion + +`ifdef INC_ASSERT + //VCS coverage off + // pragma coverage off + localparam int MaxRmaDataWidth = MaxRmaProgBurst * BusWidth; + localparam int ShiftWidth = (MaxRmaProgBurst - 1) * BusWidth; + logic [MaxRmaDataWidth-1:0] rma_data_q, rma_data; + always_ff @(posedge clk_i) begin + if (rma_start && rvalid_i && rready_o) begin + rma_data_q <= rma_data; + end + end + //VCS coverage on + // pragma coverage on + + assign rma_data = {rdata_i, rma_data_q[MaxRmaDataWidth-1 -: ShiftWidth]}; + + // check the rma programmed value actually matches what was read back + `ASSERT(ProgRdVerify_A, rma_start & rd_cnt_en & done_i |-> prog_data == rma_data) + +`endif + + +endmodule // flash_ctrl_lcmgr diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_mem_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_mem_reg_top.sv new file mode 100644 index 0000000000000..cf4c192a651d4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_mem_reg_top.sv @@ -0,0 +1,42 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 flash_ctrl_mem_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 + + // Integrity check errors + output logic intg_err_o +); + + import flash_ctrl_reg_pkg::* ; + + + + // Since there are no registers in this block, commands are routed through to windows which + // can report their own integrity errors. + assign intg_err_o = 1'b0; + + // 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; + + // Unused signal tieoff +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_pkg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_pkg.sv new file mode 100644 index 0000000000000..9486caf2e5b83 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_pkg.sv @@ -0,0 +1,628 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Controller package. +// + +package flash_ctrl_pkg; + + // design parameters that can be altered through topgen + parameter int unsigned NumBanks = flash_ctrl_reg_pkg::RegNumBanks; + parameter int unsigned PagesPerBank = flash_ctrl_reg_pkg::RegPagesPerBank; + parameter int unsigned BusPgmResBytes = flash_ctrl_reg_pkg::RegBusPgmResBytes; + // How many types of info per bank + parameter int InfoTypes = flash_ctrl_reg_pkg::NumInfoTypes; + + // fixed parameters of flash derived from topgen parameters + parameter int DataWidth = 64; + parameter int MetaDataWidth = 12; + +// The following hard-wired values are there to work-around verilator. +// For some reason if the values are assigned through parameters verilator thinks +// they are not constant + parameter int InfoTypeSize [InfoTypes] = '{ + flash_ctrl_reg_pkg::NumInfos0, + flash_ctrl_reg_pkg::NumInfos1, + flash_ctrl_reg_pkg::NumInfos2 + }; + parameter int InfosPerBank = max_info_pages(InfoTypeSize); + parameter int WordsPerPage = 256; // Number of flash words per page + parameter int BusWidth = top_pkg::TL_DW; + parameter int BusIntgWidth = tlul_pkg::DataIntgWidth; + parameter int BusFullWidth = BusWidth + BusIntgWidth; + parameter int MpRegions = 8; // flash controller protection regions + //parameter int FifoDepth = 16; // rd / prog fifos + parameter int InfoTypesWidth = prim_util_pkg::vbits(InfoTypes); + + // flash phy parameters + parameter int DataByteWidth = prim_util_pkg::vbits(DataWidth / 8); + parameter int BankW = prim_util_pkg::vbits(NumBanks); + parameter int InfoPageW = prim_util_pkg::vbits(InfosPerBank); + parameter int PageW = prim_util_pkg::vbits(PagesPerBank); + parameter int WordW = prim_util_pkg::vbits(WordsPerPage); + parameter int AddrW = BankW + PageW + WordW; // all flash range + parameter int BankAddrW = PageW + WordW; // 1 bank of flash range + parameter int AllPagesW = BankW + PageW; + + // flash ctrl / bus parameters + // flash / bus width may be different from actual flash word width + parameter int BusBytes = BusWidth / 8; + parameter int BusByteWidth = prim_util_pkg::vbits(BusBytes); + parameter int WidthMultiple = DataWidth / BusWidth; + // Number of bus words that can be programmed at once + parameter int BusPgmRes = BusPgmResBytes / BusBytes; + parameter int BusPgmResWidth = prim_util_pkg::vbits(BusPgmRes); + parameter int BusWordsPerPage = WordsPerPage * WidthMultiple; + parameter int BusWordW = prim_util_pkg::vbits(BusWordsPerPage); + parameter int BusAddrW = BankW + PageW + BusWordW; + parameter int BusAddrByteW = BusAddrW + BusByteWidth; + parameter int BusBankAddrW = PageW + BusWordW; + parameter int PhyAddrStart = BusWordW - WordW; + + // fifo parameters + //parameter int FifoDepthW = prim_util_pkg::vbits(FifoDepth+1); + + // The end address in bus words for each kind of partition in each bank + parameter logic [PageW-1:0] DataPartitionEndAddr = PageW'(PagesPerBank - 1); + parameter logic [PageW-1:0] InfoPartitionEndAddr [InfoTypes] = '{ + PageW'(InfoTypeSize[0] - 1), + PageW'(InfoTypeSize[1] - 1), + PageW'(InfoTypeSize[2] - 1) + }; + + // Flash Disable usage + typedef enum logic [3:0] { + PhyDisableIdx, + ArbFsmDisableIdx, + LcMgrDisableIdx, + MpDisableIdx, + HostDisableIdx, + IFetchDisableIdx, + RdFifoIdx, + ProgFifoIdx, + FlashDisableLast + } flash_disable_pos_e; + + //////////////////////////// + // All memory protection, seed related parameters + // Those related for seed pages should be template candidates + //////////////////////////// + + // parameters for connected components + parameter int SeedWidth = 256; + parameter int KeyWidth = 128; + parameter int EdnWidth = edn_pkg::ENDPOINT_BUS_WIDTH; + typedef logic [KeyWidth-1:0] flash_key_t; + + // Default Lfsr configurations + // These LFSR parameters have been generated with + // $ util/design/gen-lfsr-seed.py --width 32 --seed 1274809145 --prefix "" + parameter int LfsrWidth = 32; + typedef logic [LfsrWidth-1:0] lfsr_seed_t; + typedef logic [LfsrWidth-1:0][$clog2(LfsrWidth)-1:0] lfsr_perm_t; + parameter lfsr_seed_t RndCnstLfsrSeedDefault = 32'ha8cee782; + parameter lfsr_perm_t RndCnstLfsrPermDefault = { + 160'hd60bc7d86445da9347e0ccdd05b281df95238bb5 + }; + + // These LFSR parameters have been generated with + // $ util/design/gen-lfsr-seed.py --width 64 --seed 691876113 --prefix "" + + + // lcmgr phase enum + typedef enum logic [1:0] { + PhaseSeed, + PhaseRma, + PhaseNone, + PhaseInvalid + } flash_lcmgr_phase_e; + + import flash_ctrl_reg_pkg::flash_ctrl_reg2hw_mp_bank_cfg_shadowed_mreg_t; + import flash_ctrl_reg_pkg::flash_ctrl_reg2hw_mp_region_mreg_t; + import flash_ctrl_reg_pkg::flash_ctrl_reg2hw_mp_region_cfg_mreg_t; + import flash_ctrl_reg_pkg::flash_ctrl_reg2hw_bank0_info0_page_cfg_mreg_t; + import flash_ctrl_reg_pkg::flash_ctrl_reg2hw_default_region_reg_t; + + typedef flash_ctrl_reg2hw_mp_bank_cfg_shadowed_mreg_t sw_bank_cfg_t; + typedef flash_ctrl_reg2hw_mp_region_mreg_t sw_region_t; + typedef flash_ctrl_reg2hw_mp_region_cfg_mreg_t sw_region_cfg_t; + typedef flash_ctrl_reg2hw_default_region_reg_t sw_default_cfg_t; + typedef flash_ctrl_reg2hw_bank0_info0_page_cfg_mreg_t sw_info_cfg_t; + + // alias for super long reg_pkg typedef + typedef struct packed { + logic q; + } bank_cfg_t; + + import prim_mubi_pkg::mubi4_t; + import prim_mubi_pkg::MuBi4True; + import prim_mubi_pkg::MuBi4False; + + // This is identical to the reg structures but do not have err_updates / storage + typedef struct packed { + mubi4_t en; + mubi4_t rd_en; + mubi4_t prog_en; + mubi4_t erase_en; + mubi4_t scramble_en; + mubi4_t ecc_en; + mubi4_t he_en; + } info_page_cfg_t; + + // This is identical to the reg structures but do not have err_updates / storage + typedef struct packed { + mubi4_t en; + mubi4_t rd_en; + mubi4_t prog_en; + mubi4_t erase_en; + mubi4_t scramble_en; + mubi4_t ecc_en; + mubi4_t he_en; + logic [8:0] base; + logic [9:0] size; + } mp_region_cfg_t; + + // memory protection specific structs + typedef struct packed { + logic [InfoTypesWidth-1:0] sel; + logic [AllPagesW-1:0] addr; + } page_addr_t; + + typedef struct packed { + page_addr_t page; + flash_lcmgr_phase_e phase; + info_page_cfg_t cfg; + } info_page_attr_t; + + typedef struct packed { + flash_lcmgr_phase_e phase; + mp_region_cfg_t cfg; + } data_region_attr_t; + + // flash life cycle / key manager management constants + // One page for creator seeds + // One page for owner seeds + // One page for isolated flash page + parameter int NumSeeds = 2; + parameter bit [BankW-1:0] SeedBank = 0; + parameter bit [InfoTypesWidth-1:0] SeedInfoSel = 0; + parameter bit [0:0] CreatorSeedIdx = 0; + parameter bit [0:0] OwnerSeedIdx = 1; + parameter bit [PageW-1:0] CreatorInfoPage = 1; + parameter bit [PageW-1:0] OwnerInfoPage = 2; + parameter bit [PageW-1:0] IsolatedInfoPage = 3; + + parameter int TotalSeedWidth = SeedWidth * NumSeeds; + typedef logic [TotalSeedWidth-1:0] all_seeds_t; + + // which page of which info type of which bank for seed selection + parameter page_addr_t SeedInfoPageSel [NumSeeds] = '{ + '{ + sel: SeedInfoSel, + addr: {SeedBank, CreatorInfoPage} + }, + + '{ + sel: SeedInfoSel, + addr: {SeedBank, OwnerInfoPage} + } + }; + + // which page of which info type of which bank for isolated partition + parameter page_addr_t IsolatedPageSel = '{ + sel: SeedInfoSel, + addr: {SeedBank, IsolatedInfoPage} + }; + + // hardware interface memory protection rules + parameter int HwInfoRules = 5; + parameter int HwDataRules = 1; + + parameter info_page_cfg_t CfgAllowRead = '{ + en: MuBi4True, + rd_en: MuBi4True, + prog_en: MuBi4False, + erase_en: MuBi4False, + scramble_en: MuBi4True, + ecc_en: MuBi4True, + he_en: MuBi4True + }; + + parameter info_page_cfg_t CfgAllowReadProgErase = '{ + en: MuBi4True, + rd_en: MuBi4True, + prog_en: MuBi4True, + erase_en: MuBi4True, + scramble_en: MuBi4True, + ecc_en: MuBi4True, + he_en: MuBi4True // HW assumes high endurance + }; + + parameter info_page_cfg_t CfgInfoDisable = '{ + en: MuBi4False, + rd_en: MuBi4False, + prog_en: MuBi4False, + erase_en: MuBi4False, + scramble_en: MuBi4False, + ecc_en: MuBi4False, + he_en: MuBi4False + }; + + parameter info_page_attr_t HwInfoPageAttr[HwInfoRules] = '{ + '{ + page: SeedInfoPageSel[CreatorSeedIdx], + phase: PhaseSeed, + cfg: CfgAllowRead + }, + + '{ + page: SeedInfoPageSel[OwnerSeedIdx], + phase: PhaseSeed, + cfg: CfgAllowRead + }, + + '{ + page: SeedInfoPageSel[CreatorSeedIdx], + phase: PhaseRma, + cfg: CfgAllowReadProgErase + }, + + '{ + page: SeedInfoPageSel[OwnerSeedIdx], + phase: PhaseRma, + cfg: CfgAllowReadProgErase + }, + + '{ + page: IsolatedPageSel, + phase: PhaseRma, + cfg: CfgAllowReadProgErase + } + }; + + parameter data_region_attr_t HwDataAttr[HwDataRules] = '{ + '{ + phase: PhaseRma, + cfg: '{ + en: MuBi4True, + rd_en: MuBi4True, + prog_en: MuBi4True, + erase_en: MuBi4True, + scramble_en: MuBi4True, + ecc_en: MuBi4True, + he_en: MuBi4True, // HW assumes high endurance + base: '0, + size: NumBanks * PagesPerBank + } + } + }; + + + //////////////////////////// + // Design time constants + //////////////////////////// + parameter flash_key_t RndCnstAddrKeyDefault = + 128'h5d707f8a2d01d400928fa691c6a6e0a4; + parameter flash_key_t RndCnstDataKeyDefault = + 128'h39953618f2ca6f674af39f64975ea1f5; + parameter all_seeds_t RndCnstAllSeedsDefault = { + 256'h3528874c0d9e481ead4d240eb6238a2c6218896f5315edb5ccefe029a6d04091, + 256'h9cde77e25a313a76984ab0ebf990983432b03b48186dcd556565fe721b447477 + }; + + + //////////////////////////// + // Flash operation related enums + //////////////////////////// + + // Flash Operations Supported + typedef enum logic [1:0] { + FlashOpRead = 2'h0, + FlashOpProgram = 2'h1, + FlashOpErase = 2'h2, + FlashOpInvalid = 2'h3 + } flash_op_e; + + // Flash Program Operations Supported + typedef enum logic { + FlashProgNormal = 0, + FlashProgRepair = 1 + } flash_prog_e; + parameter int ProgTypes = 2; + + // Flash Erase Operations Supported + typedef enum logic { + FlashErasePage = 0, + FlashEraseBank = 1 + } flash_erase_e; + + // Flash function select + typedef enum logic [1:0] { + NoneSel, + SwSel, + HwSel + } flash_sel_e; + + // Flash tlul to fifo direction + typedef enum logic { + WriteDir = 1'b0, + ReadDir = 1'b1 + } flash_flfo_dir_e; + + // Flash partition type + typedef enum logic { + FlashPartData = 1'b0, + FlashPartInfo = 1'b1 + } flash_part_e; + + // Flash controller to memory + typedef struct packed { + logic req; + logic scramble_en; + logic ecc_en; + logic he_en; + logic rd_buf_en; + logic rd; + logic prog; + logic pg_erase; + logic bk_erase; + logic erase_suspend; + flash_part_e part; + logic [InfoTypesWidth-1:0] info_sel; + logic [BusAddrW-1:0] addr; + logic [BusFullWidth-1:0] prog_data; + logic prog_last; + flash_prog_e prog_type; + mp_region_cfg_t [MpRegions:0] region_cfgs; + logic [KeyWidth-1:0] addr_key; + logic [KeyWidth-1:0] data_key; + logic [KeyWidth-1:0] rand_addr_key; + logic [KeyWidth-1:0] rand_data_key; + logic alert_trig; + logic alert_ack; + jtag_pkg::jtag_req_t jtag_req; + prim_mubi_pkg::mubi4_t flash_disable; + } flash_req_t; + + // default value of flash_req_t (for dangling ports) + parameter flash_req_t FLASH_REQ_DEFAULT = '{ + req: '0, + scramble_en: '0, + ecc_en: '0, + he_en: '0, + rd_buf_en: 1'b0, + rd: '0, + prog: '0, + pg_erase: '0, + bk_erase: '0, + erase_suspend: '0, + part: FlashPartData, + info_sel: '0, + addr: '0, + prog_data: '0, + prog_last: '0, + prog_type: FlashProgNormal, + region_cfgs: '0, + addr_key: RndCnstAddrKeyDefault, + data_key: RndCnstDataKeyDefault, + rand_addr_key: '0, + rand_data_key: '0, + alert_trig: 1'b0, + alert_ack: 1'b0, + jtag_req: '0, + flash_disable: prim_mubi_pkg::MuBi4False + }; + + // memory to flash controller + typedef struct packed { + logic [ProgTypes-1:0] prog_type_avail; + logic rd_done; + logic prog_done; + logic erase_done; + logic rd_err; + logic [BusFullWidth-1:0] rd_data; + logic init_busy; + logic macro_err; + logic [NumBanks-1:0] ecc_single_err; + logic [NumBanks-1:0][BusAddrW-1:0] ecc_addr; + jtag_pkg::jtag_rsp_t jtag_rsp; + logic prog_intg_err; + logic storage_relbl_err; + logic storage_intg_err; + logic fsm_err; + logic spurious_ack; + logic arb_err; + logic host_gnt_err; + logic fifo_err; + } flash_rsp_t; + + // default value of flash_rsp_t (for dangling ports) + parameter flash_rsp_t FLASH_RSP_DEFAULT = '{ + prog_type_avail: {ProgTypes{1'b1}}, + rd_done: 1'b0, + prog_done: 1'b0, + erase_done: 1'b0, + rd_err: '0, + rd_data: '0, + init_busy: 1'b0, + macro_err: 1'b0, + ecc_single_err: '0, + ecc_addr: '0, + jtag_rsp: '0, + prog_intg_err: '0, + storage_relbl_err: '0, + storage_intg_err: '0, + fsm_err: '0, + spurious_ack: '0, + arb_err: '0, + host_gnt_err: '0, + fifo_err: '0 + }; + + // RMA entries + typedef struct packed { + logic [BankW-1:0] bank; + flash_part_e part; + logic [InfoTypesWidth-1:0] info_sel; + logic [PageW:0] start_page; + logic [PageW:0] num_pages; + } rma_wipe_entry_t; + + // entries to be wiped + parameter int WipeEntries = 5; + parameter rma_wipe_entry_t RmaWipeEntries[WipeEntries] = '{ + '{ + bank: SeedBank, + part: FlashPartInfo, + info_sel: SeedInfoSel, + start_page: {1'b0, CreatorInfoPage}, + num_pages: 1 + }, + + '{ + bank: SeedBank, + part: FlashPartInfo, + info_sel: SeedInfoSel, + start_page: {1'b0, OwnerInfoPage}, + num_pages: 1 + }, + + '{ + bank: SeedBank, + part: FlashPartInfo, + info_sel: SeedInfoSel, + start_page: {1'b0, IsolatedInfoPage}, + num_pages: 1 + }, + + '{ + bank: 0, + part: FlashPartData, + info_sel: 0, + start_page: 0, + num_pages: (PageW + 1)'(PagesPerBank) + }, + + '{ + bank: 1, + part: FlashPartData, + info_sel: 0, + start_page: 0, + num_pages: (PageW + 1)'(PagesPerBank) + } + }; + + + // flash_ctrl to keymgr + typedef struct packed { + logic [NumSeeds-1:0][SeedWidth-1:0] seeds; + } keymgr_flash_t; + + parameter keymgr_flash_t KEYMGR_FLASH_DEFAULT = '{ + seeds: '{ + 256'h9152e32c9380a4bcc3e0ab263581e6b0e8825186e1e445631646e8bef8c45d47, + 256'hfa365df52da48cd752fb3a026a8e608f0098cfe5fa9810494829d0cd9479eb78 + } + }; + + // dft_en jtag selection + typedef enum logic [2:0] { + FlashLcTckSel, + FlashLcTdiSel, + FlashLcTmsSel, + FlashLcTdoSel, + FlashBistSel, + FlashLcDftLast + } flash_lc_jtag_e; + + // Error bit positioning + typedef struct packed { + logic invalid_op_err; + logic oob_err; + logic mp_err; + logic rd_err; + logic prog_err; + logic prog_win_err; + logic prog_type_err; + } flash_ctrl_err_t; + + // interrupt bit positioning + typedef enum logic[2:0] { + ProgEmpty, + ProgLvl, + RdFull, + RdLvl, + OpDone, + CorrErr, + LastIntrIdx + } flash_ctrl_intr_e; + + // find the max number pages among info types + function automatic integer max_info_pages(int infos[InfoTypes]); + int current_max = 0; + for (int i = 0; i < InfoTypes; i++) begin + if (infos[i] > current_max) begin + current_max = infos[i]; + end + end + return current_max; + endfunction // max_info_banks + + // RMA control FSM encoding + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 5 -m 7 -n 10 // -s 3319803877 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: -- + // 5: |||||||||||||||||||| (47.62%) + // 6: |||||||||||||||| (38.10%) + // 7: |||| (9.52%) + // 8: || (4.76%) + // 9: -- + // 10: -- + // + // Minimum Hamming distance: 5 + // Maximum Hamming distance: 8 + // Minimum Hamming weight: 3 + // Maximum Hamming weight: 6 + // + localparam int RmaStateWidth = 11; + typedef enum logic [RmaStateWidth-1:0] { + StRmaIdle = 11'b11110001010, + StRmaPageSel = 11'b10111100111, + StRmaErase = 11'b11000010111, + StRmaEraseWait = 11'b01010100110, + StRmaWordSel = 11'b00010011001, + StRmaProgram = 11'b11011111101, + StRmaProgramWait = 11'b00111110000, + StRmaRdVerify = 11'b00101001100, + StRmaDisabled = 11'b01001011010, + StRmaInvalid = 11'b10100111011 + } rma_state_e; + + + // find the max number pages among info types + function automatic info_page_cfg_t info_cfg_qual(info_page_cfg_t in_cfg, + info_page_cfg_t qual_cfg); + + info_page_cfg_t out_cfg; + out_cfg = '{ + en: prim_mubi_pkg::mubi4_and_hi(in_cfg.en, qual_cfg.en), + rd_en: prim_mubi_pkg::mubi4_and_hi(in_cfg.rd_en, qual_cfg.rd_en), + prog_en: prim_mubi_pkg::mubi4_and_hi(in_cfg.prog_en, qual_cfg.prog_en), + erase_en: prim_mubi_pkg::mubi4_and_hi(in_cfg.erase_en, qual_cfg.erase_en), + scramble_en: prim_mubi_pkg::mubi4_and_hi(in_cfg.scramble_en, qual_cfg.scramble_en), + ecc_en: prim_mubi_pkg::mubi4_and_hi(in_cfg.ecc_en, qual_cfg.ecc_en), + he_en : prim_mubi_pkg::mubi4_and_hi(in_cfg.he_en, qual_cfg.he_en) + }; + + return out_cfg; + endfunction // max_info_banks + +endpackage : flash_ctrl_pkg diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv new file mode 100644 index 0000000000000..a3cb82dd1f229 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prim_reg_top.sv @@ -0,0 +1,2389 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 flash_ctrl_prim_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 flash_ctrl_reg_pkg::flash_ctrl_prim_reg2hw_t reg2hw, // Write + input flash_ctrl_reg_pkg::flash_ctrl_prim_hw2reg_t hw2reg, // Read + + // Integrity check errors + output logic intg_err_o +); + + import flash_ctrl_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 [20:0] reg_we_check; + prim_reg_we_check #( + .OneHotWidth(21) + ) 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 = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic csr0_regwen_we; + logic csr0_regwen_qs; + logic csr0_regwen_wd; + logic csr1_we; + logic [7:0] csr1_field0_qs; + logic [7:0] csr1_field0_wd; + logic [4:0] csr1_field1_qs; + logic [4:0] csr1_field1_wd; + logic csr2_we; + logic csr2_field0_qs; + logic csr2_field0_wd; + logic csr2_field1_qs; + logic csr2_field1_wd; + logic csr2_field2_qs; + logic csr2_field2_wd; + logic csr2_field3_qs; + logic csr2_field3_wd; + logic csr2_field4_qs; + logic csr2_field4_wd; + logic csr2_field5_qs; + logic csr2_field5_wd; + logic csr2_field6_qs; + logic csr2_field6_wd; + logic csr2_field7_qs; + logic csr2_field7_wd; + logic csr3_we; + logic [3:0] csr3_field0_qs; + logic [3:0] csr3_field0_wd; + logic [3:0] csr3_field1_qs; + logic [3:0] csr3_field1_wd; + logic [2:0] csr3_field2_qs; + logic [2:0] csr3_field2_wd; + logic [2:0] csr3_field3_qs; + logic [2:0] csr3_field3_wd; + logic [2:0] csr3_field4_qs; + logic [2:0] csr3_field4_wd; + logic [2:0] csr3_field5_qs; + logic [2:0] csr3_field5_wd; + logic csr3_field6_qs; + logic csr3_field6_wd; + logic [2:0] csr3_field7_qs; + logic [2:0] csr3_field7_wd; + logic [1:0] csr3_field8_qs; + logic [1:0] csr3_field8_wd; + logic [1:0] csr3_field9_qs; + logic [1:0] csr3_field9_wd; + logic csr4_we; + logic [2:0] csr4_field0_qs; + logic [2:0] csr4_field0_wd; + logic [2:0] csr4_field1_qs; + logic [2:0] csr4_field1_wd; + logic [2:0] csr4_field2_qs; + logic [2:0] csr4_field2_wd; + logic [2:0] csr4_field3_qs; + logic [2:0] csr4_field3_wd; + logic csr5_we; + logic [2:0] csr5_field0_qs; + logic [2:0] csr5_field0_wd; + logic [1:0] csr5_field1_qs; + logic [1:0] csr5_field1_wd; + logic [8:0] csr5_field2_qs; + logic [8:0] csr5_field2_wd; + logic [4:0] csr5_field3_qs; + logic [4:0] csr5_field3_wd; + logic [3:0] csr5_field4_qs; + logic [3:0] csr5_field4_wd; + logic csr6_we; + logic [2:0] csr6_field0_qs; + logic [2:0] csr6_field0_wd; + logic [2:0] csr6_field1_qs; + logic [2:0] csr6_field1_wd; + logic [7:0] csr6_field2_qs; + logic [7:0] csr6_field2_wd; + logic [2:0] csr6_field3_qs; + logic [2:0] csr6_field3_wd; + logic [1:0] csr6_field4_qs; + logic [1:0] csr6_field4_wd; + logic [1:0] csr6_field5_qs; + logic [1:0] csr6_field5_wd; + logic [1:0] csr6_field6_qs; + logic [1:0] csr6_field6_wd; + logic csr6_field7_qs; + logic csr6_field7_wd; + logic csr6_field8_qs; + logic csr6_field8_wd; + logic csr7_we; + logic [7:0] csr7_field0_qs; + logic [7:0] csr7_field0_wd; + logic [8:0] csr7_field1_qs; + logic [8:0] csr7_field1_wd; + logic csr8_we; + logic [31:0] csr8_qs; + logic [31:0] csr8_wd; + logic csr9_we; + logic [31:0] csr9_qs; + logic [31:0] csr9_wd; + logic csr10_we; + logic [31:0] csr10_qs; + logic [31:0] csr10_wd; + logic csr11_we; + logic [31:0] csr11_qs; + logic [31:0] csr11_wd; + logic csr12_we; + logic [9:0] csr12_qs; + logic [9:0] csr12_wd; + logic csr13_we; + logic [19:0] csr13_field0_qs; + logic [19:0] csr13_field0_wd; + logic csr13_field1_qs; + logic csr13_field1_wd; + logic csr14_we; + logic [7:0] csr14_field0_qs; + logic [7:0] csr14_field0_wd; + logic csr14_field1_qs; + logic csr14_field1_wd; + logic csr15_we; + logic [7:0] csr15_field0_qs; + logic [7:0] csr15_field0_wd; + logic csr15_field1_qs; + logic csr15_field1_wd; + logic csr16_we; + logic [7:0] csr16_field0_qs; + logic [7:0] csr16_field0_wd; + logic csr16_field1_qs; + logic csr16_field1_wd; + logic csr17_we; + logic [7:0] csr17_field0_qs; + logic [7:0] csr17_field0_wd; + logic csr17_field1_qs; + logic csr17_field1_wd; + logic csr18_we; + logic csr18_qs; + logic csr18_wd; + logic csr19_we; + logic csr19_qs; + logic csr19_wd; + logic csr20_we; + logic csr20_field0_qs; + logic csr20_field0_wd; + logic csr20_field1_qs; + logic csr20_field1_wd; + logic csr20_field2_qs; + + // Register instances + // R[csr0_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_csr0_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr0_regwen_we), + .wd (csr0_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (csr0_regwen_qs) + ); + + + // R[csr1]: V(False) + // Create REGWEN-gated WE signal + logic csr1_gated_we; + assign csr1_gated_we = csr1_we & csr0_regwen_qs; + // F[field0]: 7:0 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_csr1_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr1_gated_we), + .wd (csr1_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr1.field0.q), + .ds (), + + // to register interface (read) + .qs (csr1_field0_qs) + ); + + // F[field1]: 12:8 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_csr1_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr1_gated_we), + .wd (csr1_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr1.field1.q), + .ds (), + + // to register interface (read) + .qs (csr1_field1_qs) + ); + + + // R[csr2]: V(False) + // F[field0]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field0_wd), + + // from internal hardware + .de (hw2reg.csr2.field0.de), + .d (hw2reg.csr2.field0.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field0.q), + .ds (), + + // to register interface (read) + .qs (csr2_field0_qs) + ); + + // F[field1]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field1_wd), + + // from internal hardware + .de (hw2reg.csr2.field1.de), + .d (hw2reg.csr2.field1.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field1.q), + .ds (), + + // to register interface (read) + .qs (csr2_field1_qs) + ); + + // F[field2]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field2_wd), + + // from internal hardware + .de (hw2reg.csr2.field2.de), + .d (hw2reg.csr2.field2.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field2.q), + .ds (), + + // to register interface (read) + .qs (csr2_field2_qs) + ); + + // F[field3]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field3_wd), + + // from internal hardware + .de (hw2reg.csr2.field3.de), + .d (hw2reg.csr2.field3.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field3.q), + .ds (), + + // to register interface (read) + .qs (csr2_field3_qs) + ); + + // F[field4]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field4_wd), + + // from internal hardware + .de (hw2reg.csr2.field4.de), + .d (hw2reg.csr2.field4.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field4.q), + .ds (), + + // to register interface (read) + .qs (csr2_field4_qs) + ); + + // F[field5]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field5_wd), + + // from internal hardware + .de (hw2reg.csr2.field5.de), + .d (hw2reg.csr2.field5.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field5.q), + .ds (), + + // to register interface (read) + .qs (csr2_field5_qs) + ); + + // F[field6]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field6_wd), + + // from internal hardware + .de (hw2reg.csr2.field6.de), + .d (hw2reg.csr2.field6.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field6.q), + .ds (), + + // to register interface (read) + .qs (csr2_field6_qs) + ); + + // F[field7]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr2_field7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr2_we), + .wd (csr2_field7_wd), + + // from internal hardware + .de (hw2reg.csr2.field7.de), + .d (hw2reg.csr2.field7.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr2.field7.q), + .ds (), + + // to register interface (read) + .qs (csr2_field7_qs) + ); + + + // R[csr3]: V(False) + // Create REGWEN-gated WE signal + logic csr3_gated_we; + assign csr3_gated_we = csr3_we & csr0_regwen_qs; + // F[field0]: 3:0 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_csr3_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field0.q), + .ds (), + + // to register interface (read) + .qs (csr3_field0_qs) + ); + + // F[field1]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_csr3_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field1.q), + .ds (), + + // to register interface (read) + .qs (csr3_field1_qs) + ); + + // F[field2]: 10:8 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr3_field2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field2.q), + .ds (), + + // to register interface (read) + .qs (csr3_field2_qs) + ); + + // F[field3]: 13:11 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr3_field3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field3.q), + .ds (), + + // to register interface (read) + .qs (csr3_field3_qs) + ); + + // F[field4]: 16:14 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr3_field4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field4.q), + .ds (), + + // to register interface (read) + .qs (csr3_field4_qs) + ); + + // F[field5]: 19:17 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr3_field5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field5.q), + .ds (), + + // to register interface (read) + .qs (csr3_field5_qs) + ); + + // F[field6]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr3_field6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field6.q), + .ds (), + + // to register interface (read) + .qs (csr3_field6_qs) + ); + + // F[field7]: 23:21 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr3_field7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field7.q), + .ds (), + + // to register interface (read) + .qs (csr3_field7_qs) + ); + + // F[field8]: 25:24 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_csr3_field8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field8.q), + .ds (), + + // to register interface (read) + .qs (csr3_field8_qs) + ); + + // F[field9]: 27:26 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_csr3_field9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr3_gated_we), + .wd (csr3_field9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr3.field9.q), + .ds (), + + // to register interface (read) + .qs (csr3_field9_qs) + ); + + + // R[csr4]: V(False) + // Create REGWEN-gated WE signal + logic csr4_gated_we; + assign csr4_gated_we = csr4_we & csr0_regwen_qs; + // F[field0]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr4_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr4_gated_we), + .wd (csr4_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr4.field0.q), + .ds (), + + // to register interface (read) + .qs (csr4_field0_qs) + ); + + // F[field1]: 5:3 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr4_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr4_gated_we), + .wd (csr4_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr4.field1.q), + .ds (), + + // to register interface (read) + .qs (csr4_field1_qs) + ); + + // F[field2]: 8:6 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr4_field2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr4_gated_we), + .wd (csr4_field2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr4.field2.q), + .ds (), + + // to register interface (read) + .qs (csr4_field2_qs) + ); + + // F[field3]: 11:9 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr4_field3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr4_gated_we), + .wd (csr4_field3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr4.field3.q), + .ds (), + + // to register interface (read) + .qs (csr4_field3_qs) + ); + + + // R[csr5]: V(False) + // Create REGWEN-gated WE signal + logic csr5_gated_we; + assign csr5_gated_we = csr5_we & csr0_regwen_qs; + // F[field0]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr5_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr5_gated_we), + .wd (csr5_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr5.field0.q), + .ds (), + + // to register interface (read) + .qs (csr5_field0_qs) + ); + + // F[field1]: 4:3 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_csr5_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr5_gated_we), + .wd (csr5_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr5.field1.q), + .ds (), + + // to register interface (read) + .qs (csr5_field1_qs) + ); + + // F[field2]: 13:5 + prim_subreg #( + .DW (9), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (9'h0), + .Mubi (1'b0) + ) u_csr5_field2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr5_gated_we), + .wd (csr5_field2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr5.field2.q), + .ds (), + + // to register interface (read) + .qs (csr5_field2_qs) + ); + + // F[field3]: 18:14 + prim_subreg #( + .DW (5), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (5'h0), + .Mubi (1'b0) + ) u_csr5_field3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr5_gated_we), + .wd (csr5_field3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr5.field3.q), + .ds (), + + // to register interface (read) + .qs (csr5_field3_qs) + ); + + // F[field4]: 22:19 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_csr5_field4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr5_gated_we), + .wd (csr5_field4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr5.field4.q), + .ds (), + + // to register interface (read) + .qs (csr5_field4_qs) + ); + + + // R[csr6]: V(False) + // Create REGWEN-gated WE signal + logic csr6_gated_we; + assign csr6_gated_we = csr6_we & csr0_regwen_qs; + // F[field0]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr6_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field0.q), + .ds (), + + // to register interface (read) + .qs (csr6_field0_qs) + ); + + // F[field1]: 5:3 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr6_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field1.q), + .ds (), + + // to register interface (read) + .qs (csr6_field1_qs) + ); + + // F[field2]: 13:6 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_csr6_field2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field2.q), + .ds (), + + // to register interface (read) + .qs (csr6_field2_qs) + ); + + // F[field3]: 16:14 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_csr6_field3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field3.q), + .ds (), + + // to register interface (read) + .qs (csr6_field3_qs) + ); + + // F[field4]: 18:17 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_csr6_field4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field4.q), + .ds (), + + // to register interface (read) + .qs (csr6_field4_qs) + ); + + // F[field5]: 20:19 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_csr6_field5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field5.q), + .ds (), + + // to register interface (read) + .qs (csr6_field5_qs) + ); + + // F[field6]: 22:21 + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_csr6_field6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field6.q), + .ds (), + + // to register interface (read) + .qs (csr6_field6_qs) + ); + + // F[field7]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr6_field7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field7.q), + .ds (), + + // to register interface (read) + .qs (csr6_field7_qs) + ); + + // F[field8]: 24:24 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr6_field8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr6_gated_we), + .wd (csr6_field8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr6.field8.q), + .ds (), + + // to register interface (read) + .qs (csr6_field8_qs) + ); + + + // R[csr7]: V(False) + // Create REGWEN-gated WE signal + logic csr7_gated_we; + assign csr7_gated_we = csr7_we & csr0_regwen_qs; + // F[field0]: 7:0 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_csr7_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr7_gated_we), + .wd (csr7_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr7.field0.q), + .ds (), + + // to register interface (read) + .qs (csr7_field0_qs) + ); + + // F[field1]: 16:8 + prim_subreg #( + .DW (9), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (9'h0), + .Mubi (1'b0) + ) u_csr7_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr7_gated_we), + .wd (csr7_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr7.field1.q), + .ds (), + + // to register interface (read) + .qs (csr7_field1_qs) + ); + + + // R[csr8]: V(False) + // Create REGWEN-gated WE signal + logic csr8_gated_we; + assign csr8_gated_we = csr8_we & csr0_regwen_qs; + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_csr8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr8_gated_we), + .wd (csr8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr8.q), + .ds (), + + // to register interface (read) + .qs (csr8_qs) + ); + + + // R[csr9]: V(False) + // Create REGWEN-gated WE signal + logic csr9_gated_we; + assign csr9_gated_we = csr9_we & csr0_regwen_qs; + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_csr9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr9_gated_we), + .wd (csr9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr9.q), + .ds (), + + // to register interface (read) + .qs (csr9_qs) + ); + + + // R[csr10]: V(False) + // Create REGWEN-gated WE signal + logic csr10_gated_we; + assign csr10_gated_we = csr10_we & csr0_regwen_qs; + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_csr10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr10_gated_we), + .wd (csr10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr10.q), + .ds (), + + // to register interface (read) + .qs (csr10_qs) + ); + + + // R[csr11]: V(False) + // Create REGWEN-gated WE signal + logic csr11_gated_we; + assign csr11_gated_we = csr11_we & csr0_regwen_qs; + prim_subreg #( + .DW (32), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (32'h0), + .Mubi (1'b0) + ) u_csr11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr11_gated_we), + .wd (csr11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr11.q), + .ds (), + + // to register interface (read) + .qs (csr11_qs) + ); + + + // R[csr12]: V(False) + // Create REGWEN-gated WE signal + logic csr12_gated_we; + assign csr12_gated_we = csr12_we & csr0_regwen_qs; + prim_subreg #( + .DW (10), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (10'h0), + .Mubi (1'b0) + ) u_csr12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr12_gated_we), + .wd (csr12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr12.q), + .ds (), + + // to register interface (read) + .qs (csr12_qs) + ); + + + // R[csr13]: V(False) + // Create REGWEN-gated WE signal + logic csr13_gated_we; + assign csr13_gated_we = csr13_we & csr0_regwen_qs; + // F[field0]: 19:0 + prim_subreg #( + .DW (20), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (20'h0), + .Mubi (1'b0) + ) u_csr13_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr13_gated_we), + .wd (csr13_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr13.field0.q), + .ds (), + + // to register interface (read) + .qs (csr13_field0_qs) + ); + + // F[field1]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr13_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr13_gated_we), + .wd (csr13_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr13.field1.q), + .ds (), + + // to register interface (read) + .qs (csr13_field1_qs) + ); + + + // R[csr14]: V(False) + // Create REGWEN-gated WE signal + logic csr14_gated_we; + assign csr14_gated_we = csr14_we & csr0_regwen_qs; + // F[field0]: 7:0 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_csr14_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr14_gated_we), + .wd (csr14_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr14.field0.q), + .ds (), + + // to register interface (read) + .qs (csr14_field0_qs) + ); + + // F[field1]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr14_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr14_gated_we), + .wd (csr14_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr14.field1.q), + .ds (), + + // to register interface (read) + .qs (csr14_field1_qs) + ); + + + // R[csr15]: V(False) + // Create REGWEN-gated WE signal + logic csr15_gated_we; + assign csr15_gated_we = csr15_we & csr0_regwen_qs; + // F[field0]: 7:0 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_csr15_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr15_gated_we), + .wd (csr15_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr15.field0.q), + .ds (), + + // to register interface (read) + .qs (csr15_field0_qs) + ); + + // F[field1]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr15_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr15_gated_we), + .wd (csr15_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr15.field1.q), + .ds (), + + // to register interface (read) + .qs (csr15_field1_qs) + ); + + + // R[csr16]: V(False) + // Create REGWEN-gated WE signal + logic csr16_gated_we; + assign csr16_gated_we = csr16_we & csr0_regwen_qs; + // F[field0]: 7:0 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_csr16_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr16_gated_we), + .wd (csr16_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr16.field0.q), + .ds (), + + // to register interface (read) + .qs (csr16_field0_qs) + ); + + // F[field1]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr16_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr16_gated_we), + .wd (csr16_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr16.field1.q), + .ds (), + + // to register interface (read) + .qs (csr16_field1_qs) + ); + + + // R[csr17]: V(False) + // Create REGWEN-gated WE signal + logic csr17_gated_we; + assign csr17_gated_we = csr17_we & csr0_regwen_qs; + // F[field0]: 7:0 + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_csr17_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr17_gated_we), + .wd (csr17_field0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr17.field0.q), + .ds (), + + // to register interface (read) + .qs (csr17_field0_qs) + ); + + // F[field1]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr17_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr17_gated_we), + .wd (csr17_field1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr17.field1.q), + .ds (), + + // to register interface (read) + .qs (csr17_field1_qs) + ); + + + // R[csr18]: V(False) + // Create REGWEN-gated WE signal + logic csr18_gated_we; + assign csr18_gated_we = csr18_we & csr0_regwen_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr18_gated_we), + .wd (csr18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr18.q), + .ds (), + + // to register interface (read) + .qs (csr18_qs) + ); + + + // R[csr19]: V(False) + // Create REGWEN-gated WE signal + logic csr19_gated_we; + assign csr19_gated_we = csr19_we & csr0_regwen_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr19_gated_we), + .wd (csr19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.csr19.q), + .ds (), + + // to register interface (read) + .qs (csr19_qs) + ); + + + // R[csr20]: V(False) + // F[field0]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr20_field0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr20_we), + .wd (csr20_field0_wd), + + // from internal hardware + .de (hw2reg.csr20.field0.de), + .d (hw2reg.csr20.field0.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr20.field0.q), + .ds (), + + // to register interface (read) + .qs (csr20_field0_qs) + ); + + // F[field1]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr20_field1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (csr20_we), + .wd (csr20_field1_wd), + + // from internal hardware + .de (hw2reg.csr20.field1.de), + .d (hw2reg.csr20.field1.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr20.field1.q), + .ds (), + + // to register interface (read) + .qs (csr20_field1_qs) + ); + + // F[field2]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_csr20_field2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.csr20.field2.de), + .d (hw2reg.csr20.field2.d), + + // to internal hardware + .qe (), + .q (reg2hw.csr20.field2.q), + .ds (), + + // to register interface (read) + .qs (csr20_field2_qs) + ); + + + + logic [20:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == FLASH_CTRL_CSR0_REGWEN_OFFSET); + addr_hit[ 1] = (reg_addr == FLASH_CTRL_CSR1_OFFSET); + addr_hit[ 2] = (reg_addr == FLASH_CTRL_CSR2_OFFSET); + addr_hit[ 3] = (reg_addr == FLASH_CTRL_CSR3_OFFSET); + addr_hit[ 4] = (reg_addr == FLASH_CTRL_CSR4_OFFSET); + addr_hit[ 5] = (reg_addr == FLASH_CTRL_CSR5_OFFSET); + addr_hit[ 6] = (reg_addr == FLASH_CTRL_CSR6_OFFSET); + addr_hit[ 7] = (reg_addr == FLASH_CTRL_CSR7_OFFSET); + addr_hit[ 8] = (reg_addr == FLASH_CTRL_CSR8_OFFSET); + addr_hit[ 9] = (reg_addr == FLASH_CTRL_CSR9_OFFSET); + addr_hit[10] = (reg_addr == FLASH_CTRL_CSR10_OFFSET); + addr_hit[11] = (reg_addr == FLASH_CTRL_CSR11_OFFSET); + addr_hit[12] = (reg_addr == FLASH_CTRL_CSR12_OFFSET); + addr_hit[13] = (reg_addr == FLASH_CTRL_CSR13_OFFSET); + addr_hit[14] = (reg_addr == FLASH_CTRL_CSR14_OFFSET); + addr_hit[15] = (reg_addr == FLASH_CTRL_CSR15_OFFSET); + addr_hit[16] = (reg_addr == FLASH_CTRL_CSR16_OFFSET); + addr_hit[17] = (reg_addr == FLASH_CTRL_CSR17_OFFSET); + addr_hit[18] = (reg_addr == FLASH_CTRL_CSR18_OFFSET); + addr_hit[19] = (reg_addr == FLASH_CTRL_CSR19_OFFSET); + addr_hit[20] = (reg_addr == FLASH_CTRL_CSR20_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] & (|(FLASH_CTRL_PRIM_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(FLASH_CTRL_PRIM_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(FLASH_CTRL_PRIM_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(FLASH_CTRL_PRIM_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(FLASH_CTRL_PRIM_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(FLASH_CTRL_PRIM_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(FLASH_CTRL_PRIM_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(FLASH_CTRL_PRIM_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(FLASH_CTRL_PRIM_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(FLASH_CTRL_PRIM_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(FLASH_CTRL_PRIM_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(FLASH_CTRL_PRIM_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(FLASH_CTRL_PRIM_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(FLASH_CTRL_PRIM_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(FLASH_CTRL_PRIM_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(FLASH_CTRL_PRIM_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(FLASH_CTRL_PRIM_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(FLASH_CTRL_PRIM_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(FLASH_CTRL_PRIM_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(FLASH_CTRL_PRIM_PERMIT[19] & ~reg_be))) | + (addr_hit[20] & (|(FLASH_CTRL_PRIM_PERMIT[20] & ~reg_be))))); + end + + // Generate write-enables + assign csr0_regwen_we = addr_hit[0] & reg_we & !reg_error; + + assign csr0_regwen_wd = reg_wdata[0]; + assign csr1_we = addr_hit[1] & reg_we & !reg_error; + + assign csr1_field0_wd = reg_wdata[7:0]; + + assign csr1_field1_wd = reg_wdata[12:8]; + assign csr2_we = addr_hit[2] & reg_we & !reg_error; + + assign csr2_field0_wd = reg_wdata[0]; + + assign csr2_field1_wd = reg_wdata[1]; + + assign csr2_field2_wd = reg_wdata[2]; + + assign csr2_field3_wd = reg_wdata[3]; + + assign csr2_field4_wd = reg_wdata[4]; + + assign csr2_field5_wd = reg_wdata[5]; + + assign csr2_field6_wd = reg_wdata[6]; + + assign csr2_field7_wd = reg_wdata[7]; + assign csr3_we = addr_hit[3] & reg_we & !reg_error; + + assign csr3_field0_wd = reg_wdata[3:0]; + + assign csr3_field1_wd = reg_wdata[7:4]; + + assign csr3_field2_wd = reg_wdata[10:8]; + + assign csr3_field3_wd = reg_wdata[13:11]; + + assign csr3_field4_wd = reg_wdata[16:14]; + + assign csr3_field5_wd = reg_wdata[19:17]; + + assign csr3_field6_wd = reg_wdata[20]; + + assign csr3_field7_wd = reg_wdata[23:21]; + + assign csr3_field8_wd = reg_wdata[25:24]; + + assign csr3_field9_wd = reg_wdata[27:26]; + assign csr4_we = addr_hit[4] & reg_we & !reg_error; + + assign csr4_field0_wd = reg_wdata[2:0]; + + assign csr4_field1_wd = reg_wdata[5:3]; + + assign csr4_field2_wd = reg_wdata[8:6]; + + assign csr4_field3_wd = reg_wdata[11:9]; + assign csr5_we = addr_hit[5] & reg_we & !reg_error; + + assign csr5_field0_wd = reg_wdata[2:0]; + + assign csr5_field1_wd = reg_wdata[4:3]; + + assign csr5_field2_wd = reg_wdata[13:5]; + + assign csr5_field3_wd = reg_wdata[18:14]; + + assign csr5_field4_wd = reg_wdata[22:19]; + assign csr6_we = addr_hit[6] & reg_we & !reg_error; + + assign csr6_field0_wd = reg_wdata[2:0]; + + assign csr6_field1_wd = reg_wdata[5:3]; + + assign csr6_field2_wd = reg_wdata[13:6]; + + assign csr6_field3_wd = reg_wdata[16:14]; + + assign csr6_field4_wd = reg_wdata[18:17]; + + assign csr6_field5_wd = reg_wdata[20:19]; + + assign csr6_field6_wd = reg_wdata[22:21]; + + assign csr6_field7_wd = reg_wdata[23]; + + assign csr6_field8_wd = reg_wdata[24]; + assign csr7_we = addr_hit[7] & reg_we & !reg_error; + + assign csr7_field0_wd = reg_wdata[7:0]; + + assign csr7_field1_wd = reg_wdata[16:8]; + assign csr8_we = addr_hit[8] & reg_we & !reg_error; + + assign csr8_wd = reg_wdata[31:0]; + assign csr9_we = addr_hit[9] & reg_we & !reg_error; + + assign csr9_wd = reg_wdata[31:0]; + assign csr10_we = addr_hit[10] & reg_we & !reg_error; + + assign csr10_wd = reg_wdata[31:0]; + assign csr11_we = addr_hit[11] & reg_we & !reg_error; + + assign csr11_wd = reg_wdata[31:0]; + assign csr12_we = addr_hit[12] & reg_we & !reg_error; + + assign csr12_wd = reg_wdata[9:0]; + assign csr13_we = addr_hit[13] & reg_we & !reg_error; + + assign csr13_field0_wd = reg_wdata[19:0]; + + assign csr13_field1_wd = reg_wdata[20]; + assign csr14_we = addr_hit[14] & reg_we & !reg_error; + + assign csr14_field0_wd = reg_wdata[7:0]; + + assign csr14_field1_wd = reg_wdata[8]; + assign csr15_we = addr_hit[15] & reg_we & !reg_error; + + assign csr15_field0_wd = reg_wdata[7:0]; + + assign csr15_field1_wd = reg_wdata[8]; + assign csr16_we = addr_hit[16] & reg_we & !reg_error; + + assign csr16_field0_wd = reg_wdata[7:0]; + + assign csr16_field1_wd = reg_wdata[8]; + assign csr17_we = addr_hit[17] & reg_we & !reg_error; + + assign csr17_field0_wd = reg_wdata[7:0]; + + assign csr17_field1_wd = reg_wdata[8]; + assign csr18_we = addr_hit[18] & reg_we & !reg_error; + + assign csr18_wd = reg_wdata[0]; + assign csr19_we = addr_hit[19] & reg_we & !reg_error; + + assign csr19_wd = reg_wdata[0]; + assign csr20_we = addr_hit[20] & reg_we & !reg_error; + + assign csr20_field0_wd = reg_wdata[0]; + + assign csr20_field1_wd = reg_wdata[1]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = csr0_regwen_we; + reg_we_check[1] = csr1_gated_we; + reg_we_check[2] = csr2_we; + reg_we_check[3] = csr3_gated_we; + reg_we_check[4] = csr4_gated_we; + reg_we_check[5] = csr5_gated_we; + reg_we_check[6] = csr6_gated_we; + reg_we_check[7] = csr7_gated_we; + reg_we_check[8] = csr8_gated_we; + reg_we_check[9] = csr9_gated_we; + reg_we_check[10] = csr10_gated_we; + reg_we_check[11] = csr11_gated_we; + reg_we_check[12] = csr12_gated_we; + reg_we_check[13] = csr13_gated_we; + reg_we_check[14] = csr14_gated_we; + reg_we_check[15] = csr15_gated_we; + reg_we_check[16] = csr16_gated_we; + reg_we_check[17] = csr17_gated_we; + reg_we_check[18] = csr18_gated_we; + reg_we_check[19] = csr19_gated_we; + reg_we_check[20] = csr20_we; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (1'b1) + addr_hit[0]: begin + reg_rdata_next[0] = csr0_regwen_qs; + end + + addr_hit[1]: begin + reg_rdata_next[7:0] = csr1_field0_qs; + reg_rdata_next[12:8] = csr1_field1_qs; + end + + addr_hit[2]: begin + reg_rdata_next[0] = csr2_field0_qs; + reg_rdata_next[1] = csr2_field1_qs; + reg_rdata_next[2] = csr2_field2_qs; + reg_rdata_next[3] = csr2_field3_qs; + reg_rdata_next[4] = csr2_field4_qs; + reg_rdata_next[5] = csr2_field5_qs; + reg_rdata_next[6] = csr2_field6_qs; + reg_rdata_next[7] = csr2_field7_qs; + end + + addr_hit[3]: begin + reg_rdata_next[3:0] = csr3_field0_qs; + reg_rdata_next[7:4] = csr3_field1_qs; + reg_rdata_next[10:8] = csr3_field2_qs; + reg_rdata_next[13:11] = csr3_field3_qs; + reg_rdata_next[16:14] = csr3_field4_qs; + reg_rdata_next[19:17] = csr3_field5_qs; + reg_rdata_next[20] = csr3_field6_qs; + reg_rdata_next[23:21] = csr3_field7_qs; + reg_rdata_next[25:24] = csr3_field8_qs; + reg_rdata_next[27:26] = csr3_field9_qs; + end + + addr_hit[4]: begin + reg_rdata_next[2:0] = csr4_field0_qs; + reg_rdata_next[5:3] = csr4_field1_qs; + reg_rdata_next[8:6] = csr4_field2_qs; + reg_rdata_next[11:9] = csr4_field3_qs; + end + + addr_hit[5]: begin + reg_rdata_next[2:0] = csr5_field0_qs; + reg_rdata_next[4:3] = csr5_field1_qs; + reg_rdata_next[13:5] = csr5_field2_qs; + reg_rdata_next[18:14] = csr5_field3_qs; + reg_rdata_next[22:19] = csr5_field4_qs; + end + + addr_hit[6]: begin + reg_rdata_next[2:0] = csr6_field0_qs; + reg_rdata_next[5:3] = csr6_field1_qs; + reg_rdata_next[13:6] = csr6_field2_qs; + reg_rdata_next[16:14] = csr6_field3_qs; + reg_rdata_next[18:17] = csr6_field4_qs; + reg_rdata_next[20:19] = csr6_field5_qs; + reg_rdata_next[22:21] = csr6_field6_qs; + reg_rdata_next[23] = csr6_field7_qs; + reg_rdata_next[24] = csr6_field8_qs; + end + + addr_hit[7]: begin + reg_rdata_next[7:0] = csr7_field0_qs; + reg_rdata_next[16:8] = csr7_field1_qs; + end + + addr_hit[8]: begin + reg_rdata_next[31:0] = csr8_qs; + end + + addr_hit[9]: begin + reg_rdata_next[31:0] = csr9_qs; + end + + addr_hit[10]: begin + reg_rdata_next[31:0] = csr10_qs; + end + + addr_hit[11]: begin + reg_rdata_next[31:0] = csr11_qs; + end + + addr_hit[12]: begin + reg_rdata_next[9:0] = csr12_qs; + end + + addr_hit[13]: begin + reg_rdata_next[19:0] = csr13_field0_qs; + reg_rdata_next[20] = csr13_field1_qs; + end + + addr_hit[14]: begin + reg_rdata_next[7:0] = csr14_field0_qs; + reg_rdata_next[8] = csr14_field1_qs; + end + + addr_hit[15]: begin + reg_rdata_next[7:0] = csr15_field0_qs; + reg_rdata_next[8] = csr15_field1_qs; + end + + addr_hit[16]: begin + reg_rdata_next[7:0] = csr16_field0_qs; + reg_rdata_next[8] = csr16_field1_qs; + end + + addr_hit[17]: begin + reg_rdata_next[7:0] = csr17_field0_qs; + reg_rdata_next[8] = csr17_field1_qs; + end + + addr_hit[18]: begin + reg_rdata_next[0] = csr18_qs; + end + + addr_hit[19]: begin + reg_rdata_next[0] = csr19_qs; + end + + addr_hit[20]: begin + reg_rdata_next[0] = csr20_field0_qs; + reg_rdata_next[1] = csr20_field1_qs; + reg_rdata_next[2] = csr20_field2_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_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prog.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prog.sv new file mode 100644 index 0000000000000..aaa1514cfd1df --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_prog.sv @@ -0,0 +1,195 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Faux Flash Prog Control +// + +module flash_ctrl_prog import flash_ctrl_pkg::*; ( + input clk_i, + input rst_ni, + + // Control Interface + input op_start_i, + input [11:0] op_num_words_i, + output logic op_done_o, + output flash_ctrl_err_t op_err_o, + input [BusAddrW-1:0] op_addr_i, + input op_addr_oob_i, + input flash_prog_e op_type_i, + input [ProgTypes-1:0] type_avail_i, + output logic [BusAddrW-1:0] op_err_addr_o, + output logic cnt_err_o, + + // FIFO Interface + input data_rdy_i, + input [BusFullWidth-1:0] data_i, + output logic data_rd_o, + + // Flash Macro Interface + output logic flash_req_o, + output logic [BusAddrW-1:0] flash_addr_o, + output logic flash_ovfl_o, + output logic [BusFullWidth-1:0] flash_data_o, + output logic flash_last_o, // last beat of prog data + output flash_prog_e flash_type_o, + input flash_done_i, + input flash_mp_err_i, + input flash_prog_intg_err_i +); + + typedef enum logic { + StNorm = 'h0, + StErr = 'h1 + } state_e; + + state_e st_q, st_d; + logic [11:0] cnt; + logic cnt_hit; + logic [BusAddrW:0] int_addr; + logic txn_done; + + flash_ctrl_err_t op_err_q, op_err_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + st_q <= StNorm; + end else begin + st_q <= st_d; + end + end + + //always_ff @(posedge clk_i or negedge rst_ni) begin + // if (!rst_ni) begin + // cnt <= '0; + // end else if (op_start_i && op_done_o) begin + // cnt <= '0; + // end else if (data_rd_o) begin + // cnt <= cnt + 1'b1; + // end + //end + + prim_count #( + .Width(12) + ) u_cnt ( + .clk_i, + .rst_ni, + .clr_i(op_start_i && op_done_o), + .set_i('0), + .set_cnt_i('0), + .incr_en_i(data_rd_o), + .decr_en_i(1'b0), + .step_i(12'h1), + .commit_i(1'b1), + .cnt_o(cnt), + .cnt_after_commit_o(), + .err_o(cnt_err_o) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + op_err_addr_o <= '0; + end else if (~|op_err_q && |op_err_d) begin + op_err_addr_o <= flash_addr_o; + end + end + + assign txn_done = flash_req_o && flash_done_i; + assign cnt_hit = (cnt >= op_num_words_i); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + op_err_q <= '0; + end else if (op_start_i && op_done_o) begin + op_err_q <= '0; + end else begin + op_err_q <= op_err_d; + end + end + + // if the requested prog type is available + logic prog_type_avail; + assign prog_type_avail = type_avail_i[op_type_i]; + + // program resolution check + // if the incoming beat is larger than the maximum program resolution, error + // immediately and do not allow it to start. + localparam int WindowWidth = BusAddrW - BusPgmResWidth; + logic [WindowWidth-1:0] start_window, end_window; + logic [BusAddrW-1:0] end_addr; + logic pgm_res_err; + logic win_err; + assign end_addr = op_addr_i + BusAddrW'(op_num_words_i); + assign start_window = op_addr_i[BusAddrW-1:BusPgmResWidth]; + assign end_window = end_addr[BusAddrW-1:BusPgmResWidth]; + assign pgm_res_err = start_window != end_window; + assign win_err = pgm_res_err | op_addr_oob_i; + + // when error'd, continue to drain all program fifo contents like normal operation + // if this is not done, software may fill up the fifo without anyone + // draining the contents, leading to a lockup + always_comb begin + st_d = st_q; + flash_req_o = 1'b0; + data_rd_o = 1'b0; + op_done_o = 1'b0; + op_err_d = op_err_q; + + unique case (st_q) + + // Note the address counter is incremented on tx_done + // and cleared when the entire operation is complete. + StNorm: begin + + if (cnt_err_o) begin + // if count error'd don't bother doing anything else, just try to finish + st_d = StErr; + + end else if (op_start_i && prog_type_avail && !win_err) begin + // if the select operation type is not available, error + flash_req_o = data_rdy_i; + + if (txn_done) begin + op_err_d.mp_err = flash_mp_err_i; + op_err_d.prog_err = flash_prog_intg_err_i; + data_rd_o = 1'b1; + + if (cnt_hit) begin + op_done_o = 1'b1; + end else begin + st_d = |op_err_d ? StErr : StNorm; + end + end + + end else if (op_start_i && (!prog_type_avail || win_err)) begin + op_err_d.oob_err = op_addr_oob_i; + op_err_d.prog_type_err = !prog_type_avail; + op_err_d.prog_win_err = pgm_res_err; + st_d = StErr; + end + end + StErr: begin + data_rd_o = data_rdy_i; + + if (data_rdy_i && cnt_hit) begin + st_d = StNorm; + op_done_o = 1'b1; + end + end + default:; + endcase // unique case (st) + end + + assign flash_data_o = data_i; + assign int_addr = op_addr_i + BusAddrW'(cnt); + assign flash_addr_o = int_addr[0 +: BusAddrW]; + assign flash_ovfl_o = int_addr[BusAddrW]; + assign flash_last_o = flash_req_o & cnt_hit; + assign flash_type_o = op_type_i; + assign op_err_o = op_err_q | op_err_d; + + // unused signals + logic [BusPgmResWidth-1:0] unused_end_addr; + assign unused_end_addr = end_addr[BusPgmResWidth-1:0]; + +endmodule // flash_ctrl_prog diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_rd.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_rd.sv new file mode 100644 index 0000000000000..a06ebc2e17e3f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_rd.sv @@ -0,0 +1,185 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Faux Flash Read Control +// + +module flash_ctrl_rd import flash_ctrl_pkg::*; ( + input clk_i, + input rst_ni, + + // Software Interface + input op_start_i, + input [11:0] op_num_words_i, + output logic op_done_o, + flash_ctrl_err_t op_err_o, + input [BusAddrW-1:0] op_addr_i, + input op_addr_oob_i, + output logic [BusAddrW-1:0] op_err_addr_o, + output logic cnt_err_o, + + // FIFO Interface + input data_rdy_i, + output logic [BusFullWidth-1:0] data_o, + output logic data_wr_o, + + // Flash Macro Interface + output logic flash_req_o, + output logic [BusAddrW-1:0] flash_addr_o, + output logic flash_ovfl_o, + input [BusFullWidth-1:0] flash_data_i, + input flash_done_i, + input flash_rd_err_i, + input flash_mp_err_i +); + + typedef enum logic [1:0] { + StIdle, + StNorm, + StErr + } state_e; + + state_e st_q, st_d; + logic [11:0] cnt; + logic cnt_hit; + logic [BusAddrW:0] int_addr; + logic txn_done; + logic err_sel; //1 selects error data, 0 selects normal data + flash_ctrl_err_t op_err_q, op_err_d; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + st_q <= StIdle; + end else begin + st_q <= st_d; + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + op_err_q <= '0; + end else if (op_start_i && op_done_o) begin + op_err_q <= '0; + end else begin + op_err_q <= op_err_d; + end + end + + prim_count #( + .Width(12) + ) u_cnt ( + .clk_i, + .rst_ni, + .clr_i(op_start_i && op_done_o), + .set_i('0), + .set_cnt_i('0), + .incr_en_i(data_wr_o), + .decr_en_i(1'b0), + .step_i(12'h1), + .commit_i(1'b1), + .cnt_o(cnt), + .cnt_after_commit_o(), + .err_o(cnt_err_o) + ); + + //always_ff @(posedge clk_i or negedge rst_ni) begin + // if (!rst_ni) begin + // cnt <= '0; + // end else if (op_start_i && op_done_o) begin + // cnt <= '0; + // end else if (data_wr_o) begin + // cnt <= cnt + 1'b1; + // end + //end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + op_err_addr_o <= '0; + end else if (~|op_err_q && |op_err_d) begin + op_err_addr_o <= flash_addr_o; + end + end + + assign txn_done = flash_req_o & flash_done_i; + assign cnt_hit = (cnt >= op_num_words_i); + + + // when error'd, continue to complete existing read transaction but fill in with all 1's + // if this is not done, software may continue to attempt to read out of the fifo + // and eventually cause a bus deadlock as the fifo would be empty + // This scheme is similar to burst completion up an error + always_comb begin + st_d = st_q; + flash_req_o = 1'b0; + data_wr_o = 1'b0; + op_done_o = 1'b0; + op_err_d = op_err_q; + + unique case (st_q) + StIdle: begin + if (cnt_err_o) begin + // if counter error is encountered, just go to error state + st_d = StErr; + end else if (op_start_i) begin + op_err_d.oob_err = op_addr_oob_i; + st_d = |op_err_d ? StErr : StNorm; + end + end + + // Note the address counter is incremented on tx_done + // and cleared when the entire operation is complete. + StNorm: begin + flash_req_o = op_start_i & data_rdy_i; + + if (txn_done) begin + op_err_d.mp_err = flash_mp_err_i; + op_err_d.rd_err = flash_rd_err_i; + + data_wr_o = 1'b1; + + if (cnt_hit) begin + op_done_o = 1'b1; + st_d = StIdle; + end else begin + st_d = |op_err_d ? StErr : StNorm; + end + end + end + + StErr: begin + data_wr_o = data_rdy_i; + + if (data_rdy_i && cnt_hit) begin + st_d = StIdle; + op_done_o = 1'b1; + end + end + default:; + endcase // unique case (st) + end + + // overflow error detection is not here, but instead handled at memory protection + assign int_addr = op_addr_i + BusAddrW'(cnt); + assign flash_addr_o = int_addr[0 +: BusAddrW]; + assign flash_ovfl_o = int_addr[BusAddrW]; + // if error, return "empty" data + assign err_sel = data_wr_o & |op_err_o; + + // When there is no error, return flash data directly. + // When the error is a read error specifically, also return flash data as the integrity is + // natively handled by the phy. + // All other errors do not result in an actual transaction to the flash, and therefore must use + // the locally available error value. + logic [BusFullWidth-1:0] inv_data_integ; + tlul_data_integ_enc u_bus_intg ( + .data_i({BusWidth{1'b1}}), + .data_intg_o(inv_data_integ) + ); + + assign data_o = ~err_sel | (err_sel & op_err_o.rd_err) ? flash_data_i : inv_data_integ; + + assign op_err_o = op_err_q | op_err_d; + + +endmodule // flash_ctrl_rd diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_reg_pkg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_reg_pkg.sv new file mode 100644 index 0000000000000..17d0af89e5d4b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_reg_pkg.sv @@ -0,0 +1,1540 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 flash_ctrl_reg_pkg; + + // Param list + parameter int RegNumBanks = 2; + parameter int RegPagesPerBank = 16; + parameter int RegBusPgmResBytes = 64; + parameter int RegPageWidth = 4; + parameter int RegBankWidth = 1; + parameter int NumRegions = 8; + parameter int NumInfoTypes = 3; + parameter int NumInfos0 = 10; + parameter int NumInfos1 = 1; + parameter int NumInfos2 = 2; + parameter int WordsPerPage = 256; + parameter int BytesPerWord = 8; + parameter int BytesPerPage = 2048; + parameter int BytesPerBank = 32768; + parameter int unsigned ExecEn = 32'ha26a38f7; + parameter int MaxFifoDepth = 16; + parameter int MaxFifoWidth = 5; + parameter int NumAlerts = 5; + + // Address widths within the block + parameter int CoreAw = 9; + parameter int PrimAw = 7; + parameter int MemAw = 1; + + /////////////////////////////////////////////// + // Typedefs for registers for core interface // + /////////////////////////////////////////////// + + typedef struct packed { + struct packed { + logic q; + } corr_err; + struct packed { + logic q; + } op_done; + struct packed { + logic q; + } rd_lvl; + struct packed { + logic q; + } rd_full; + struct packed { + logic q; + } prog_lvl; + struct packed { + logic q; + } prog_empty; + } flash_ctrl_reg2hw_intr_state_reg_t; + + typedef struct packed { + struct packed { + logic q; + } corr_err; + struct packed { + logic q; + } op_done; + struct packed { + logic q; + } rd_lvl; + struct packed { + logic q; + } rd_full; + struct packed { + logic q; + } prog_lvl; + struct packed { + logic q; + } prog_empty; + } flash_ctrl_reg2hw_intr_enable_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } corr_err; + struct packed { + logic q; + logic qe; + } op_done; + struct packed { + logic q; + logic qe; + } rd_lvl; + struct packed { + logic q; + logic qe; + } rd_full; + struct packed { + logic q; + logic qe; + } prog_lvl; + struct packed { + logic q; + logic qe; + } prog_empty; + } flash_ctrl_reg2hw_intr_test_reg_t; + + typedef struct packed { + struct packed { + logic q; + logic qe; + } recov_prim_flash_alert; + struct packed { + logic q; + logic qe; + } fatal_prim_flash_alert; + struct packed { + logic q; + logic qe; + } fatal_err; + struct packed { + logic q; + logic qe; + } fatal_std_err; + struct packed { + logic q; + logic qe; + } recov_err; + } flash_ctrl_reg2hw_alert_test_reg_t; + + typedef struct packed { + logic [3:0] q; + } flash_ctrl_reg2hw_dis_reg_t; + + typedef struct packed { + logic [31:0] q; + } flash_ctrl_reg2hw_exec_reg_t; + + typedef struct packed { + logic q; + } flash_ctrl_reg2hw_init_reg_t; + + typedef struct packed { + struct packed { + logic [11:0] q; + } num; + struct packed { + logic [1:0] q; + } info_sel; + struct packed { + logic q; + } partition_sel; + struct packed { + logic q; + } erase_sel; + struct packed { + logic q; + } prog_sel; + struct packed { + logic [1:0] q; + } op; + struct packed { + logic q; + } start; + } flash_ctrl_reg2hw_control_reg_t; + + typedef struct packed { + logic [15:0] q; + } flash_ctrl_reg2hw_addr_reg_t; + + typedef struct packed { + struct packed { + logic q; + } repair; + struct packed { + logic q; + } normal; + } flash_ctrl_reg2hw_prog_type_en_reg_t; + + typedef struct packed { + logic q; + } flash_ctrl_reg2hw_erase_suspend_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + struct packed { + logic [3:0] q; + } en; + } flash_ctrl_reg2hw_mp_region_cfg_mreg_t; + + typedef struct packed { + struct packed { + logic [5:0] q; + } size; + struct packed { + logic [4:0] q; + } base; + } flash_ctrl_reg2hw_mp_region_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + } flash_ctrl_reg2hw_default_region_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + struct packed { + logic [3:0] q; + } en; + } flash_ctrl_reg2hw_bank0_info0_page_cfg_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + struct packed { + logic [3:0] q; + } en; + } flash_ctrl_reg2hw_bank0_info1_page_cfg_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + struct packed { + logic [3:0] q; + } en; + } flash_ctrl_reg2hw_bank0_info2_page_cfg_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + struct packed { + logic [3:0] q; + } en; + } flash_ctrl_reg2hw_bank1_info0_page_cfg_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + struct packed { + logic [3:0] q; + } en; + } flash_ctrl_reg2hw_bank1_info1_page_cfg_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } he_en; + struct packed { + logic [3:0] q; + } ecc_en; + struct packed { + logic [3:0] q; + } scramble_en; + struct packed { + logic [3:0] q; + } erase_en; + struct packed { + logic [3:0] q; + } prog_en; + struct packed { + logic [3:0] q; + } rd_en; + struct packed { + logic [3:0] q; + } en; + } flash_ctrl_reg2hw_bank1_info2_page_cfg_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } ecc_dis; + struct packed { + logic [3:0] q; + } scramble_dis; + } flash_ctrl_reg2hw_hw_info_cfg_override_reg_t; + + typedef struct packed { + logic q; + } flash_ctrl_reg2hw_mp_bank_cfg_shadowed_mreg_t; + + typedef struct packed { + struct packed { + logic q; + } fifo_err; + struct packed { + logic q; + } ctrl_cnt_err; + struct packed { + logic q; + } phy_fsm_err; + struct packed { + logic q; + } storage_err; + struct packed { + logic q; + } arb_fsm_err; + struct packed { + logic q; + } lcmgr_intg_err; + struct packed { + logic q; + } lcmgr_err; + struct packed { + logic q; + } prog_intg_err; + struct packed { + logic q; + } reg_intg_err; + } flash_ctrl_reg2hw_std_fault_status_reg_t; + + typedef struct packed { + struct packed { + logic q; + } host_gnt_err; + struct packed { + logic q; + } arb_err; + struct packed { + logic q; + } spurious_ack; + struct packed { + logic q; + } phy_storage_err; + struct packed { + logic q; + } phy_relbl_err; + struct packed { + logic q; + } seed_err; + struct packed { + logic q; + } prog_type_err; + struct packed { + logic q; + } prog_win_err; + struct packed { + logic q; + } prog_err; + struct packed { + logic q; + } rd_err; + struct packed { + logic q; + } mp_err; + struct packed { + logic q; + } op_err; + } flash_ctrl_reg2hw_fault_status_reg_t; + + typedef struct packed { + logic [7:0] q; + } flash_ctrl_reg2hw_ecc_single_err_cnt_mreg_t; + + typedef struct packed { + struct packed { + logic q; + } alert_trig; + struct packed { + logic q; + } alert_ack; + } flash_ctrl_reg2hw_phy_alert_cfg_reg_t; + + typedef struct packed { + logic [31:0] q; + } flash_ctrl_reg2hw_scratch_reg_t; + + typedef struct packed { + struct packed { + logic [4:0] q; + } rd; + struct packed { + logic [4:0] q; + } prog; + } flash_ctrl_reg2hw_fifo_lvl_reg_t; + + typedef struct packed { + logic q; + } flash_ctrl_reg2hw_fifo_rst_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } prog_empty; + struct packed { + logic d; + logic de; + } prog_lvl; + struct packed { + logic d; + logic de; + } rd_full; + struct packed { + logic d; + logic de; + } rd_lvl; + struct packed { + logic d; + logic de; + } op_done; + struct packed { + logic d; + logic de; + } corr_err; + } flash_ctrl_hw2reg_intr_state_reg_t; + + typedef struct packed { + logic d; + } flash_ctrl_hw2reg_ctrl_regwen_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } start; + } flash_ctrl_hw2reg_control_reg_t; + + typedef struct packed { + logic d; + logic de; + } flash_ctrl_hw2reg_erase_suspend_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } done; + struct packed { + logic d; + logic de; + } err; + } flash_ctrl_hw2reg_op_status_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } rd_full; + struct packed { + logic d; + logic de; + } rd_empty; + struct packed { + logic d; + logic de; + } prog_full; + struct packed { + logic d; + logic de; + } prog_empty; + struct packed { + logic d; + logic de; + } init_wip; + struct packed { + logic d; + logic de; + } initialized; + } flash_ctrl_hw2reg_status_reg_t; + + typedef struct packed { + logic [10:0] d; + } flash_ctrl_hw2reg_debug_state_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } op_err; + struct packed { + logic d; + logic de; + } mp_err; + struct packed { + logic d; + logic de; + } rd_err; + struct packed { + logic d; + logic de; + } prog_err; + struct packed { + logic d; + logic de; + } prog_win_err; + struct packed { + logic d; + logic de; + } prog_type_err; + struct packed { + logic d; + logic de; + } update_err; + struct packed { + logic d; + logic de; + } macro_err; + } flash_ctrl_hw2reg_err_code_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } reg_intg_err; + struct packed { + logic d; + logic de; + } prog_intg_err; + struct packed { + logic d; + logic de; + } lcmgr_err; + struct packed { + logic d; + logic de; + } lcmgr_intg_err; + struct packed { + logic d; + logic de; + } arb_fsm_err; + struct packed { + logic d; + logic de; + } storage_err; + struct packed { + logic d; + logic de; + } phy_fsm_err; + struct packed { + logic d; + logic de; + } ctrl_cnt_err; + struct packed { + logic d; + logic de; + } fifo_err; + } flash_ctrl_hw2reg_std_fault_status_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } op_err; + struct packed { + logic d; + logic de; + } mp_err; + struct packed { + logic d; + logic de; + } rd_err; + struct packed { + logic d; + logic de; + } prog_err; + struct packed { + logic d; + logic de; + } prog_win_err; + struct packed { + logic d; + logic de; + } prog_type_err; + struct packed { + logic d; + logic de; + } seed_err; + struct packed { + logic d; + logic de; + } phy_relbl_err; + struct packed { + logic d; + logic de; + } phy_storage_err; + struct packed { + logic d; + logic de; + } spurious_ack; + struct packed { + logic d; + logic de; + } arb_err; + struct packed { + logic d; + logic de; + } host_gnt_err; + } flash_ctrl_hw2reg_fault_status_reg_t; + + typedef struct packed { + logic [15:0] d; + logic de; + } flash_ctrl_hw2reg_err_addr_reg_t; + + typedef struct packed { + logic [7:0] d; + logic de; + } flash_ctrl_hw2reg_ecc_single_err_cnt_mreg_t; + + typedef struct packed { + logic [15:0] d; + logic de; + } flash_ctrl_hw2reg_ecc_single_err_addr_mreg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } init_wip; + struct packed { + logic d; + logic de; + } prog_normal_avail; + struct packed { + logic d; + logic de; + } prog_repair_avail; + } flash_ctrl_hw2reg_phy_status_reg_t; + + typedef struct packed { + struct packed { + logic [4:0] d; + } prog; + struct packed { + logic [4:0] d; + } rd; + } flash_ctrl_hw2reg_curr_fifo_lvl_reg_t; + + // Register -> HW type for core interface + typedef struct packed { + flash_ctrl_reg2hw_intr_state_reg_t intr_state; // [1265:1260] + flash_ctrl_reg2hw_intr_enable_reg_t intr_enable; // [1259:1254] + flash_ctrl_reg2hw_intr_test_reg_t intr_test; // [1253:1242] + flash_ctrl_reg2hw_alert_test_reg_t alert_test; // [1241:1232] + flash_ctrl_reg2hw_dis_reg_t dis; // [1231:1228] + flash_ctrl_reg2hw_exec_reg_t exec; // [1227:1196] + flash_ctrl_reg2hw_init_reg_t init; // [1195:1195] + flash_ctrl_reg2hw_control_reg_t control; // [1194:1175] + flash_ctrl_reg2hw_addr_reg_t addr; // [1174:1159] + flash_ctrl_reg2hw_prog_type_en_reg_t prog_type_en; // [1158:1157] + flash_ctrl_reg2hw_erase_suspend_reg_t erase_suspend; // [1156:1156] + flash_ctrl_reg2hw_mp_region_cfg_mreg_t [7:0] mp_region_cfg; // [1155:932] + flash_ctrl_reg2hw_mp_region_mreg_t [7:0] mp_region; // [931:844] + flash_ctrl_reg2hw_default_region_reg_t default_region; // [843:820] + flash_ctrl_reg2hw_bank0_info0_page_cfg_mreg_t [9:0] bank0_info0_page_cfg; // [819:540] + flash_ctrl_reg2hw_bank0_info1_page_cfg_mreg_t [0:0] bank0_info1_page_cfg; // [539:512] + flash_ctrl_reg2hw_bank0_info2_page_cfg_mreg_t [1:0] bank0_info2_page_cfg; // [511:456] + flash_ctrl_reg2hw_bank1_info0_page_cfg_mreg_t [9:0] bank1_info0_page_cfg; // [455:176] + flash_ctrl_reg2hw_bank1_info1_page_cfg_mreg_t [0:0] bank1_info1_page_cfg; // [175:148] + flash_ctrl_reg2hw_bank1_info2_page_cfg_mreg_t [1:0] bank1_info2_page_cfg; // [147:92] + flash_ctrl_reg2hw_hw_info_cfg_override_reg_t hw_info_cfg_override; // [91:84] + flash_ctrl_reg2hw_mp_bank_cfg_shadowed_mreg_t [1:0] mp_bank_cfg_shadowed; // [83:82] + flash_ctrl_reg2hw_std_fault_status_reg_t std_fault_status; // [81:73] + flash_ctrl_reg2hw_fault_status_reg_t fault_status; // [72:61] + flash_ctrl_reg2hw_ecc_single_err_cnt_mreg_t [1:0] ecc_single_err_cnt; // [60:45] + flash_ctrl_reg2hw_phy_alert_cfg_reg_t phy_alert_cfg; // [44:43] + flash_ctrl_reg2hw_scratch_reg_t scratch; // [42:11] + flash_ctrl_reg2hw_fifo_lvl_reg_t fifo_lvl; // [10:1] + flash_ctrl_reg2hw_fifo_rst_reg_t fifo_rst; // [0:0] + } flash_ctrl_core_reg2hw_t; + + // HW -> register type for core interface + typedef struct packed { + flash_ctrl_hw2reg_intr_state_reg_t intr_state; // [186:175] + flash_ctrl_hw2reg_ctrl_regwen_reg_t ctrl_regwen; // [174:174] + flash_ctrl_hw2reg_control_reg_t control; // [173:172] + flash_ctrl_hw2reg_erase_suspend_reg_t erase_suspend; // [171:170] + flash_ctrl_hw2reg_op_status_reg_t op_status; // [169:166] + flash_ctrl_hw2reg_status_reg_t status; // [165:154] + flash_ctrl_hw2reg_debug_state_reg_t debug_state; // [153:143] + flash_ctrl_hw2reg_err_code_reg_t err_code; // [142:127] + flash_ctrl_hw2reg_std_fault_status_reg_t std_fault_status; // [126:109] + flash_ctrl_hw2reg_fault_status_reg_t fault_status; // [108:85] + flash_ctrl_hw2reg_err_addr_reg_t err_addr; // [84:68] + flash_ctrl_hw2reg_ecc_single_err_cnt_mreg_t [1:0] ecc_single_err_cnt; // [67:50] + flash_ctrl_hw2reg_ecc_single_err_addr_mreg_t [1:0] ecc_single_err_addr; // [49:16] + flash_ctrl_hw2reg_phy_status_reg_t phy_status; // [15:10] + flash_ctrl_hw2reg_curr_fifo_lvl_reg_t curr_fifo_lvl; // [9:0] + } flash_ctrl_core_hw2reg_t; + + // Register offsets for core interface + parameter logic [CoreAw-1:0] FLASH_CTRL_INTR_STATE_OFFSET = 9'h 0; + parameter logic [CoreAw-1:0] FLASH_CTRL_INTR_ENABLE_OFFSET = 9'h 4; + parameter logic [CoreAw-1:0] FLASH_CTRL_INTR_TEST_OFFSET = 9'h 8; + parameter logic [CoreAw-1:0] FLASH_CTRL_ALERT_TEST_OFFSET = 9'h c; + parameter logic [CoreAw-1:0] FLASH_CTRL_DIS_OFFSET = 9'h 10; + parameter logic [CoreAw-1:0] FLASH_CTRL_EXEC_OFFSET = 9'h 14; + parameter logic [CoreAw-1:0] FLASH_CTRL_INIT_OFFSET = 9'h 18; + parameter logic [CoreAw-1:0] FLASH_CTRL_CTRL_REGWEN_OFFSET = 9'h 1c; + parameter logic [CoreAw-1:0] FLASH_CTRL_CONTROL_OFFSET = 9'h 20; + parameter logic [CoreAw-1:0] FLASH_CTRL_ADDR_OFFSET = 9'h 24; + parameter logic [CoreAw-1:0] FLASH_CTRL_PROG_TYPE_EN_OFFSET = 9'h 28; + parameter logic [CoreAw-1:0] FLASH_CTRL_ERASE_SUSPEND_OFFSET = 9'h 2c; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_0_OFFSET = 9'h 30; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_1_OFFSET = 9'h 34; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_2_OFFSET = 9'h 38; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_3_OFFSET = 9'h 3c; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_4_OFFSET = 9'h 40; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_5_OFFSET = 9'h 44; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_6_OFFSET = 9'h 48; + parameter logic [CoreAw-1:0] FLASH_CTRL_REGION_CFG_REGWEN_7_OFFSET = 9'h 4c; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_0_OFFSET = 9'h 50; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_1_OFFSET = 9'h 54; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_2_OFFSET = 9'h 58; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_3_OFFSET = 9'h 5c; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_4_OFFSET = 9'h 60; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_5_OFFSET = 9'h 64; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_6_OFFSET = 9'h 68; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_CFG_7_OFFSET = 9'h 6c; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_0_OFFSET = 9'h 70; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_1_OFFSET = 9'h 74; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_2_OFFSET = 9'h 78; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_3_OFFSET = 9'h 7c; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_4_OFFSET = 9'h 80; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_5_OFFSET = 9'h 84; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_6_OFFSET = 9'h 88; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_REGION_7_OFFSET = 9'h 8c; + parameter logic [CoreAw-1:0] FLASH_CTRL_DEFAULT_REGION_OFFSET = 9'h 90; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_0_OFFSET = 9'h 94; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_1_OFFSET = 9'h 98; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_2_OFFSET = 9'h 9c; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_3_OFFSET = 9'h a0; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_4_OFFSET = 9'h a4; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_5_OFFSET = 9'h a8; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_6_OFFSET = 9'h ac; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_7_OFFSET = 9'h b0; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_8_OFFSET = 9'h b4; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_REGWEN_9_OFFSET = 9'h b8; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0_OFFSET = 9'h bc; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_1_OFFSET = 9'h c0; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_2_OFFSET = 9'h c4; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_3_OFFSET = 9'h c8; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_4_OFFSET = 9'h cc; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_5_OFFSET = 9'h d0; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_6_OFFSET = 9'h d4; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_7_OFFSET = 9'h d8; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_8_OFFSET = 9'h dc; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_9_OFFSET = 9'h e0; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO1_REGWEN_OFFSET = 9'h e4; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO1_PAGE_CFG_OFFSET = 9'h e8; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO2_REGWEN_0_OFFSET = 9'h ec; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO2_REGWEN_1_OFFSET = 9'h f0; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO2_PAGE_CFG_0_OFFSET = 9'h f4; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1_OFFSET = 9'h f8; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_0_OFFSET = 9'h fc; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_1_OFFSET = 9'h 100; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_2_OFFSET = 9'h 104; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_3_OFFSET = 9'h 108; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_4_OFFSET = 9'h 10c; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_5_OFFSET = 9'h 110; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_6_OFFSET = 9'h 114; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_7_OFFSET = 9'h 118; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_8_OFFSET = 9'h 11c; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_REGWEN_9_OFFSET = 9'h 120; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0_OFFSET = 9'h 124; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1_OFFSET = 9'h 128; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_2_OFFSET = 9'h 12c; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_3_OFFSET = 9'h 130; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_4_OFFSET = 9'h 134; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_5_OFFSET = 9'h 138; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_6_OFFSET = 9'h 13c; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_7_OFFSET = 9'h 140; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_8_OFFSET = 9'h 144; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_9_OFFSET = 9'h 148; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO1_REGWEN_OFFSET = 9'h 14c; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO1_PAGE_CFG_OFFSET = 9'h 150; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO2_REGWEN_0_OFFSET = 9'h 154; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO2_REGWEN_1_OFFSET = 9'h 158; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO2_PAGE_CFG_0_OFFSET = 9'h 15c; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK1_INFO2_PAGE_CFG_1_OFFSET = 9'h 160; + parameter logic [CoreAw-1:0] FLASH_CTRL_HW_INFO_CFG_OVERRIDE_OFFSET = 9'h 164; + parameter logic [CoreAw-1:0] FLASH_CTRL_BANK_CFG_REGWEN_OFFSET = 9'h 168; + parameter logic [CoreAw-1:0] FLASH_CTRL_MP_BANK_CFG_SHADOWED_OFFSET = 9'h 16c; + parameter logic [CoreAw-1:0] FLASH_CTRL_OP_STATUS_OFFSET = 9'h 170; + parameter logic [CoreAw-1:0] FLASH_CTRL_STATUS_OFFSET = 9'h 174; + parameter logic [CoreAw-1:0] FLASH_CTRL_DEBUG_STATE_OFFSET = 9'h 178; + parameter logic [CoreAw-1:0] FLASH_CTRL_ERR_CODE_OFFSET = 9'h 17c; + parameter logic [CoreAw-1:0] FLASH_CTRL_STD_FAULT_STATUS_OFFSET = 9'h 180; + parameter logic [CoreAw-1:0] FLASH_CTRL_FAULT_STATUS_OFFSET = 9'h 184; + parameter logic [CoreAw-1:0] FLASH_CTRL_ERR_ADDR_OFFSET = 9'h 188; + parameter logic [CoreAw-1:0] FLASH_CTRL_ECC_SINGLE_ERR_CNT_OFFSET = 9'h 18c; + parameter logic [CoreAw-1:0] FLASH_CTRL_ECC_SINGLE_ERR_ADDR_0_OFFSET = 9'h 190; + parameter logic [CoreAw-1:0] FLASH_CTRL_ECC_SINGLE_ERR_ADDR_1_OFFSET = 9'h 194; + parameter logic [CoreAw-1:0] FLASH_CTRL_PHY_ALERT_CFG_OFFSET = 9'h 198; + parameter logic [CoreAw-1:0] FLASH_CTRL_PHY_STATUS_OFFSET = 9'h 19c; + parameter logic [CoreAw-1:0] FLASH_CTRL_SCRATCH_OFFSET = 9'h 1a0; + parameter logic [CoreAw-1:0] FLASH_CTRL_FIFO_LVL_OFFSET = 9'h 1a4; + parameter logic [CoreAw-1:0] FLASH_CTRL_FIFO_RST_OFFSET = 9'h 1a8; + parameter logic [CoreAw-1:0] FLASH_CTRL_CURR_FIFO_LVL_OFFSET = 9'h 1ac; + + // Reset values for hwext registers and their fields for core interface + parameter logic [5:0] FLASH_CTRL_INTR_TEST_RESVAL = 6'h 0; + parameter logic [0:0] FLASH_CTRL_INTR_TEST_PROG_EMPTY_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_INTR_TEST_PROG_LVL_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_INTR_TEST_RD_FULL_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_INTR_TEST_RD_LVL_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_INTR_TEST_OP_DONE_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_INTR_TEST_CORR_ERR_RESVAL = 1'h 0; + parameter logic [4:0] FLASH_CTRL_ALERT_TEST_RESVAL = 5'h 0; + parameter logic [0:0] FLASH_CTRL_ALERT_TEST_RECOV_ERR_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_ALERT_TEST_FATAL_STD_ERR_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_ALERT_TEST_FATAL_ERR_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_ALERT_TEST_FATAL_PRIM_FLASH_ALERT_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_ALERT_TEST_RECOV_PRIM_FLASH_ALERT_RESVAL = 1'h 0; + parameter logic [0:0] FLASH_CTRL_CTRL_REGWEN_RESVAL = 1'h 1; + parameter logic [0:0] FLASH_CTRL_CTRL_REGWEN_EN_RESVAL = 1'h 1; + parameter logic [10:0] FLASH_CTRL_DEBUG_STATE_RESVAL = 11'h 0; + parameter logic [12:0] FLASH_CTRL_CURR_FIFO_LVL_RESVAL = 13'h 0; + parameter logic [4:0] FLASH_CTRL_CURR_FIFO_LVL_PROG_RESVAL = 5'h 0; + parameter logic [4:0] FLASH_CTRL_CURR_FIFO_LVL_RD_RESVAL = 5'h 0; + + // Window parameters for core interface + parameter logic [CoreAw-1:0] FLASH_CTRL_PROG_FIFO_OFFSET = 9'h 1b0; + parameter int unsigned FLASH_CTRL_PROG_FIFO_SIZE = 'h 4; + parameter int unsigned FLASH_CTRL_PROG_FIFO_IDX = 0; + parameter logic [CoreAw-1:0] FLASH_CTRL_RD_FIFO_OFFSET = 9'h 1b4; + parameter int unsigned FLASH_CTRL_RD_FIFO_SIZE = 'h 4; + parameter int unsigned FLASH_CTRL_RD_FIFO_IDX = 1; + + // Register index for core interface + typedef enum int { + FLASH_CTRL_INTR_STATE, + FLASH_CTRL_INTR_ENABLE, + FLASH_CTRL_INTR_TEST, + FLASH_CTRL_ALERT_TEST, + FLASH_CTRL_DIS, + FLASH_CTRL_EXEC, + FLASH_CTRL_INIT, + FLASH_CTRL_CTRL_REGWEN, + FLASH_CTRL_CONTROL, + FLASH_CTRL_ADDR, + FLASH_CTRL_PROG_TYPE_EN, + FLASH_CTRL_ERASE_SUSPEND, + FLASH_CTRL_REGION_CFG_REGWEN_0, + FLASH_CTRL_REGION_CFG_REGWEN_1, + FLASH_CTRL_REGION_CFG_REGWEN_2, + FLASH_CTRL_REGION_CFG_REGWEN_3, + FLASH_CTRL_REGION_CFG_REGWEN_4, + FLASH_CTRL_REGION_CFG_REGWEN_5, + FLASH_CTRL_REGION_CFG_REGWEN_6, + FLASH_CTRL_REGION_CFG_REGWEN_7, + FLASH_CTRL_MP_REGION_CFG_0, + FLASH_CTRL_MP_REGION_CFG_1, + FLASH_CTRL_MP_REGION_CFG_2, + FLASH_CTRL_MP_REGION_CFG_3, + FLASH_CTRL_MP_REGION_CFG_4, + FLASH_CTRL_MP_REGION_CFG_5, + FLASH_CTRL_MP_REGION_CFG_6, + FLASH_CTRL_MP_REGION_CFG_7, + FLASH_CTRL_MP_REGION_0, + FLASH_CTRL_MP_REGION_1, + FLASH_CTRL_MP_REGION_2, + FLASH_CTRL_MP_REGION_3, + FLASH_CTRL_MP_REGION_4, + FLASH_CTRL_MP_REGION_5, + FLASH_CTRL_MP_REGION_6, + FLASH_CTRL_MP_REGION_7, + FLASH_CTRL_DEFAULT_REGION, + FLASH_CTRL_BANK0_INFO0_REGWEN_0, + FLASH_CTRL_BANK0_INFO0_REGWEN_1, + FLASH_CTRL_BANK0_INFO0_REGWEN_2, + FLASH_CTRL_BANK0_INFO0_REGWEN_3, + FLASH_CTRL_BANK0_INFO0_REGWEN_4, + FLASH_CTRL_BANK0_INFO0_REGWEN_5, + FLASH_CTRL_BANK0_INFO0_REGWEN_6, + FLASH_CTRL_BANK0_INFO0_REGWEN_7, + FLASH_CTRL_BANK0_INFO0_REGWEN_8, + FLASH_CTRL_BANK0_INFO0_REGWEN_9, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_1, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_2, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_3, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_4, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_5, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_6, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_7, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_8, + FLASH_CTRL_BANK0_INFO0_PAGE_CFG_9, + FLASH_CTRL_BANK0_INFO1_REGWEN, + FLASH_CTRL_BANK0_INFO1_PAGE_CFG, + FLASH_CTRL_BANK0_INFO2_REGWEN_0, + FLASH_CTRL_BANK0_INFO2_REGWEN_1, + FLASH_CTRL_BANK0_INFO2_PAGE_CFG_0, + FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1, + FLASH_CTRL_BANK1_INFO0_REGWEN_0, + FLASH_CTRL_BANK1_INFO0_REGWEN_1, + FLASH_CTRL_BANK1_INFO0_REGWEN_2, + FLASH_CTRL_BANK1_INFO0_REGWEN_3, + FLASH_CTRL_BANK1_INFO0_REGWEN_4, + FLASH_CTRL_BANK1_INFO0_REGWEN_5, + FLASH_CTRL_BANK1_INFO0_REGWEN_6, + FLASH_CTRL_BANK1_INFO0_REGWEN_7, + FLASH_CTRL_BANK1_INFO0_REGWEN_8, + FLASH_CTRL_BANK1_INFO0_REGWEN_9, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_2, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_3, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_4, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_5, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_6, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_7, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_8, + FLASH_CTRL_BANK1_INFO0_PAGE_CFG_9, + FLASH_CTRL_BANK1_INFO1_REGWEN, + FLASH_CTRL_BANK1_INFO1_PAGE_CFG, + FLASH_CTRL_BANK1_INFO2_REGWEN_0, + FLASH_CTRL_BANK1_INFO2_REGWEN_1, + FLASH_CTRL_BANK1_INFO2_PAGE_CFG_0, + FLASH_CTRL_BANK1_INFO2_PAGE_CFG_1, + FLASH_CTRL_HW_INFO_CFG_OVERRIDE, + FLASH_CTRL_BANK_CFG_REGWEN, + FLASH_CTRL_MP_BANK_CFG_SHADOWED, + FLASH_CTRL_OP_STATUS, + FLASH_CTRL_STATUS, + FLASH_CTRL_DEBUG_STATE, + FLASH_CTRL_ERR_CODE, + FLASH_CTRL_STD_FAULT_STATUS, + FLASH_CTRL_FAULT_STATUS, + FLASH_CTRL_ERR_ADDR, + FLASH_CTRL_ECC_SINGLE_ERR_CNT, + FLASH_CTRL_ECC_SINGLE_ERR_ADDR_0, + FLASH_CTRL_ECC_SINGLE_ERR_ADDR_1, + FLASH_CTRL_PHY_ALERT_CFG, + FLASH_CTRL_PHY_STATUS, + FLASH_CTRL_SCRATCH, + FLASH_CTRL_FIFO_LVL, + FLASH_CTRL_FIFO_RST, + FLASH_CTRL_CURR_FIFO_LVL + } flash_ctrl_core_id_e; + + // Register width information to check illegal writes for core interface + parameter logic [3:0] FLASH_CTRL_CORE_PERMIT [108] = '{ + 4'b 0001, // index[ 0] FLASH_CTRL_INTR_STATE + 4'b 0001, // index[ 1] FLASH_CTRL_INTR_ENABLE + 4'b 0001, // index[ 2] FLASH_CTRL_INTR_TEST + 4'b 0001, // index[ 3] FLASH_CTRL_ALERT_TEST + 4'b 0001, // index[ 4] FLASH_CTRL_DIS + 4'b 1111, // index[ 5] FLASH_CTRL_EXEC + 4'b 0001, // index[ 6] FLASH_CTRL_INIT + 4'b 0001, // index[ 7] FLASH_CTRL_CTRL_REGWEN + 4'b 1111, // index[ 8] FLASH_CTRL_CONTROL + 4'b 0011, // index[ 9] FLASH_CTRL_ADDR + 4'b 0001, // index[ 10] FLASH_CTRL_PROG_TYPE_EN + 4'b 0001, // index[ 11] FLASH_CTRL_ERASE_SUSPEND + 4'b 0001, // index[ 12] FLASH_CTRL_REGION_CFG_REGWEN_0 + 4'b 0001, // index[ 13] FLASH_CTRL_REGION_CFG_REGWEN_1 + 4'b 0001, // index[ 14] FLASH_CTRL_REGION_CFG_REGWEN_2 + 4'b 0001, // index[ 15] FLASH_CTRL_REGION_CFG_REGWEN_3 + 4'b 0001, // index[ 16] FLASH_CTRL_REGION_CFG_REGWEN_4 + 4'b 0001, // index[ 17] FLASH_CTRL_REGION_CFG_REGWEN_5 + 4'b 0001, // index[ 18] FLASH_CTRL_REGION_CFG_REGWEN_6 + 4'b 0001, // index[ 19] FLASH_CTRL_REGION_CFG_REGWEN_7 + 4'b 1111, // index[ 20] FLASH_CTRL_MP_REGION_CFG_0 + 4'b 1111, // index[ 21] FLASH_CTRL_MP_REGION_CFG_1 + 4'b 1111, // index[ 22] FLASH_CTRL_MP_REGION_CFG_2 + 4'b 1111, // index[ 23] FLASH_CTRL_MP_REGION_CFG_3 + 4'b 1111, // index[ 24] FLASH_CTRL_MP_REGION_CFG_4 + 4'b 1111, // index[ 25] FLASH_CTRL_MP_REGION_CFG_5 + 4'b 1111, // index[ 26] FLASH_CTRL_MP_REGION_CFG_6 + 4'b 1111, // index[ 27] FLASH_CTRL_MP_REGION_CFG_7 + 4'b 0011, // index[ 28] FLASH_CTRL_MP_REGION_0 + 4'b 0011, // index[ 29] FLASH_CTRL_MP_REGION_1 + 4'b 0011, // index[ 30] FLASH_CTRL_MP_REGION_2 + 4'b 0011, // index[ 31] FLASH_CTRL_MP_REGION_3 + 4'b 0011, // index[ 32] FLASH_CTRL_MP_REGION_4 + 4'b 0011, // index[ 33] FLASH_CTRL_MP_REGION_5 + 4'b 0011, // index[ 34] FLASH_CTRL_MP_REGION_6 + 4'b 0011, // index[ 35] FLASH_CTRL_MP_REGION_7 + 4'b 0111, // index[ 36] FLASH_CTRL_DEFAULT_REGION + 4'b 0001, // index[ 37] FLASH_CTRL_BANK0_INFO0_REGWEN_0 + 4'b 0001, // index[ 38] FLASH_CTRL_BANK0_INFO0_REGWEN_1 + 4'b 0001, // index[ 39] FLASH_CTRL_BANK0_INFO0_REGWEN_2 + 4'b 0001, // index[ 40] FLASH_CTRL_BANK0_INFO0_REGWEN_3 + 4'b 0001, // index[ 41] FLASH_CTRL_BANK0_INFO0_REGWEN_4 + 4'b 0001, // index[ 42] FLASH_CTRL_BANK0_INFO0_REGWEN_5 + 4'b 0001, // index[ 43] FLASH_CTRL_BANK0_INFO0_REGWEN_6 + 4'b 0001, // index[ 44] FLASH_CTRL_BANK0_INFO0_REGWEN_7 + 4'b 0001, // index[ 45] FLASH_CTRL_BANK0_INFO0_REGWEN_8 + 4'b 0001, // index[ 46] FLASH_CTRL_BANK0_INFO0_REGWEN_9 + 4'b 1111, // index[ 47] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_0 + 4'b 1111, // index[ 48] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_1 + 4'b 1111, // index[ 49] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_2 + 4'b 1111, // index[ 50] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_3 + 4'b 1111, // index[ 51] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_4 + 4'b 1111, // index[ 52] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_5 + 4'b 1111, // index[ 53] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_6 + 4'b 1111, // index[ 54] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_7 + 4'b 1111, // index[ 55] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_8 + 4'b 1111, // index[ 56] FLASH_CTRL_BANK0_INFO0_PAGE_CFG_9 + 4'b 0001, // index[ 57] FLASH_CTRL_BANK0_INFO1_REGWEN + 4'b 1111, // index[ 58] FLASH_CTRL_BANK0_INFO1_PAGE_CFG + 4'b 0001, // index[ 59] FLASH_CTRL_BANK0_INFO2_REGWEN_0 + 4'b 0001, // index[ 60] FLASH_CTRL_BANK0_INFO2_REGWEN_1 + 4'b 1111, // index[ 61] FLASH_CTRL_BANK0_INFO2_PAGE_CFG_0 + 4'b 1111, // index[ 62] FLASH_CTRL_BANK0_INFO2_PAGE_CFG_1 + 4'b 0001, // index[ 63] FLASH_CTRL_BANK1_INFO0_REGWEN_0 + 4'b 0001, // index[ 64] FLASH_CTRL_BANK1_INFO0_REGWEN_1 + 4'b 0001, // index[ 65] FLASH_CTRL_BANK1_INFO0_REGWEN_2 + 4'b 0001, // index[ 66] FLASH_CTRL_BANK1_INFO0_REGWEN_3 + 4'b 0001, // index[ 67] FLASH_CTRL_BANK1_INFO0_REGWEN_4 + 4'b 0001, // index[ 68] FLASH_CTRL_BANK1_INFO0_REGWEN_5 + 4'b 0001, // index[ 69] FLASH_CTRL_BANK1_INFO0_REGWEN_6 + 4'b 0001, // index[ 70] FLASH_CTRL_BANK1_INFO0_REGWEN_7 + 4'b 0001, // index[ 71] FLASH_CTRL_BANK1_INFO0_REGWEN_8 + 4'b 0001, // index[ 72] FLASH_CTRL_BANK1_INFO0_REGWEN_9 + 4'b 1111, // index[ 73] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_0 + 4'b 1111, // index[ 74] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_1 + 4'b 1111, // index[ 75] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_2 + 4'b 1111, // index[ 76] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_3 + 4'b 1111, // index[ 77] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_4 + 4'b 1111, // index[ 78] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_5 + 4'b 1111, // index[ 79] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_6 + 4'b 1111, // index[ 80] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_7 + 4'b 1111, // index[ 81] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_8 + 4'b 1111, // index[ 82] FLASH_CTRL_BANK1_INFO0_PAGE_CFG_9 + 4'b 0001, // index[ 83] FLASH_CTRL_BANK1_INFO1_REGWEN + 4'b 1111, // index[ 84] FLASH_CTRL_BANK1_INFO1_PAGE_CFG + 4'b 0001, // index[ 85] FLASH_CTRL_BANK1_INFO2_REGWEN_0 + 4'b 0001, // index[ 86] FLASH_CTRL_BANK1_INFO2_REGWEN_1 + 4'b 1111, // index[ 87] FLASH_CTRL_BANK1_INFO2_PAGE_CFG_0 + 4'b 1111, // index[ 88] FLASH_CTRL_BANK1_INFO2_PAGE_CFG_1 + 4'b 0001, // index[ 89] FLASH_CTRL_HW_INFO_CFG_OVERRIDE + 4'b 0001, // index[ 90] FLASH_CTRL_BANK_CFG_REGWEN + 4'b 0001, // index[ 91] FLASH_CTRL_MP_BANK_CFG_SHADOWED + 4'b 0001, // index[ 92] FLASH_CTRL_OP_STATUS + 4'b 0001, // index[ 93] FLASH_CTRL_STATUS + 4'b 0011, // index[ 94] FLASH_CTRL_DEBUG_STATE + 4'b 0001, // index[ 95] FLASH_CTRL_ERR_CODE + 4'b 0011, // index[ 96] FLASH_CTRL_STD_FAULT_STATUS + 4'b 0011, // index[ 97] FLASH_CTRL_FAULT_STATUS + 4'b 0011, // index[ 98] FLASH_CTRL_ERR_ADDR + 4'b 0011, // index[ 99] FLASH_CTRL_ECC_SINGLE_ERR_CNT + 4'b 0011, // index[100] FLASH_CTRL_ECC_SINGLE_ERR_ADDR_0 + 4'b 0011, // index[101] FLASH_CTRL_ECC_SINGLE_ERR_ADDR_1 + 4'b 0001, // index[102] FLASH_CTRL_PHY_ALERT_CFG + 4'b 0001, // index[103] FLASH_CTRL_PHY_STATUS + 4'b 1111, // index[104] FLASH_CTRL_SCRATCH + 4'b 0011, // index[105] FLASH_CTRL_FIFO_LVL + 4'b 0001, // index[106] FLASH_CTRL_FIFO_RST + 4'b 0011 // index[107] FLASH_CTRL_CURR_FIFO_LVL + }; + + /////////////////////////////////////////////// + // Typedefs for registers for prim interface // + /////////////////////////////////////////////// + + typedef struct packed { + struct packed { + logic [4:0] q; + } field1; + struct packed { + logic [7:0] q; + } field0; + } flash_ctrl_reg2hw_csr1_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field7; + struct packed { + logic q; + } field6; + struct packed { + logic q; + } field5; + struct packed { + logic q; + } field4; + struct packed { + logic q; + } field3; + struct packed { + logic q; + } field2; + struct packed { + logic q; + } field1; + struct packed { + logic q; + } field0; + } flash_ctrl_reg2hw_csr2_reg_t; + + typedef struct packed { + struct packed { + logic [1:0] q; + } field9; + struct packed { + logic [1:0] q; + } field8; + struct packed { + logic [2:0] q; + } field7; + struct packed { + logic q; + } field6; + struct packed { + logic [2:0] q; + } field5; + struct packed { + logic [2:0] q; + } field4; + struct packed { + logic [2:0] q; + } field3; + struct packed { + logic [2:0] q; + } field2; + struct packed { + logic [3:0] q; + } field1; + struct packed { + logic [3:0] q; + } field0; + } flash_ctrl_reg2hw_csr3_reg_t; + + typedef struct packed { + struct packed { + logic [2:0] q; + } field3; + struct packed { + logic [2:0] q; + } field2; + struct packed { + logic [2:0] q; + } field1; + struct packed { + logic [2:0] q; + } field0; + } flash_ctrl_reg2hw_csr4_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } field4; + struct packed { + logic [4:0] q; + } field3; + struct packed { + logic [8:0] q; + } field2; + struct packed { + logic [1:0] q; + } field1; + struct packed { + logic [2:0] q; + } field0; + } flash_ctrl_reg2hw_csr5_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field8; + struct packed { + logic q; + } field7; + struct packed { + logic [1:0] q; + } field6; + struct packed { + logic [1:0] q; + } field5; + struct packed { + logic [1:0] q; + } field4; + struct packed { + logic [2:0] q; + } field3; + struct packed { + logic [7:0] q; + } field2; + struct packed { + logic [2:0] q; + } field1; + struct packed { + logic [2:0] q; + } field0; + } flash_ctrl_reg2hw_csr6_reg_t; + + typedef struct packed { + struct packed { + logic [8:0] q; + } field1; + struct packed { + logic [7:0] q; + } field0; + } flash_ctrl_reg2hw_csr7_reg_t; + + typedef struct packed { + logic [31:0] q; + } flash_ctrl_reg2hw_csr8_reg_t; + + typedef struct packed { + logic [31:0] q; + } flash_ctrl_reg2hw_csr9_reg_t; + + typedef struct packed { + logic [31:0] q; + } flash_ctrl_reg2hw_csr10_reg_t; + + typedef struct packed { + logic [31:0] q; + } flash_ctrl_reg2hw_csr11_reg_t; + + typedef struct packed { + logic [9:0] q; + } flash_ctrl_reg2hw_csr12_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field1; + struct packed { + logic [19:0] q; + } field0; + } flash_ctrl_reg2hw_csr13_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field1; + struct packed { + logic [7:0] q; + } field0; + } flash_ctrl_reg2hw_csr14_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field1; + struct packed { + logic [7:0] q; + } field0; + } flash_ctrl_reg2hw_csr15_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field1; + struct packed { + logic [7:0] q; + } field0; + } flash_ctrl_reg2hw_csr16_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field1; + struct packed { + logic [7:0] q; + } field0; + } flash_ctrl_reg2hw_csr17_reg_t; + + typedef struct packed { + logic q; + } flash_ctrl_reg2hw_csr18_reg_t; + + typedef struct packed { + logic q; + } flash_ctrl_reg2hw_csr19_reg_t; + + typedef struct packed { + struct packed { + logic q; + } field2; + struct packed { + logic q; + } field1; + struct packed { + logic q; + } field0; + } flash_ctrl_reg2hw_csr20_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } field0; + struct packed { + logic d; + logic de; + } field1; + struct packed { + logic d; + logic de; + } field2; + struct packed { + logic d; + logic de; + } field3; + struct packed { + logic d; + logic de; + } field4; + struct packed { + logic d; + logic de; + } field5; + struct packed { + logic d; + logic de; + } field6; + struct packed { + logic d; + logic de; + } field7; + } flash_ctrl_hw2reg_csr2_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } field0; + struct packed { + logic d; + logic de; + } field1; + struct packed { + logic d; + logic de; + } field2; + } flash_ctrl_hw2reg_csr20_reg_t; + + // Register -> HW type for prim interface + typedef struct packed { + flash_ctrl_reg2hw_csr1_reg_t csr1; // [325:313] + flash_ctrl_reg2hw_csr2_reg_t csr2; // [312:305] + flash_ctrl_reg2hw_csr3_reg_t csr3; // [304:277] + flash_ctrl_reg2hw_csr4_reg_t csr4; // [276:265] + flash_ctrl_reg2hw_csr5_reg_t csr5; // [264:242] + flash_ctrl_reg2hw_csr6_reg_t csr6; // [241:217] + flash_ctrl_reg2hw_csr7_reg_t csr7; // [216:200] + flash_ctrl_reg2hw_csr8_reg_t csr8; // [199:168] + flash_ctrl_reg2hw_csr9_reg_t csr9; // [167:136] + flash_ctrl_reg2hw_csr10_reg_t csr10; // [135:104] + flash_ctrl_reg2hw_csr11_reg_t csr11; // [103:72] + flash_ctrl_reg2hw_csr12_reg_t csr12; // [71:62] + flash_ctrl_reg2hw_csr13_reg_t csr13; // [61:41] + flash_ctrl_reg2hw_csr14_reg_t csr14; // [40:32] + flash_ctrl_reg2hw_csr15_reg_t csr15; // [31:23] + flash_ctrl_reg2hw_csr16_reg_t csr16; // [22:14] + flash_ctrl_reg2hw_csr17_reg_t csr17; // [13:5] + flash_ctrl_reg2hw_csr18_reg_t csr18; // [4:4] + flash_ctrl_reg2hw_csr19_reg_t csr19; // [3:3] + flash_ctrl_reg2hw_csr20_reg_t csr20; // [2:0] + } flash_ctrl_prim_reg2hw_t; + + // HW -> register type for prim interface + typedef struct packed { + flash_ctrl_hw2reg_csr2_reg_t csr2; // [21:6] + flash_ctrl_hw2reg_csr20_reg_t csr20; // [5:0] + } flash_ctrl_prim_hw2reg_t; + + // Register offsets for prim interface + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR0_REGWEN_OFFSET = 7'h 0; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR1_OFFSET = 7'h 4; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR2_OFFSET = 7'h 8; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR3_OFFSET = 7'h c; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR4_OFFSET = 7'h 10; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR5_OFFSET = 7'h 14; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR6_OFFSET = 7'h 18; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR7_OFFSET = 7'h 1c; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR8_OFFSET = 7'h 20; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR9_OFFSET = 7'h 24; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR10_OFFSET = 7'h 28; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR11_OFFSET = 7'h 2c; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR12_OFFSET = 7'h 30; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR13_OFFSET = 7'h 34; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR14_OFFSET = 7'h 38; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR15_OFFSET = 7'h 3c; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR16_OFFSET = 7'h 40; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR17_OFFSET = 7'h 44; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR18_OFFSET = 7'h 48; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR19_OFFSET = 7'h 4c; + parameter logic [PrimAw-1:0] FLASH_CTRL_CSR20_OFFSET = 7'h 50; + + // Register index for prim interface + typedef enum int { + FLASH_CTRL_CSR0_REGWEN, + FLASH_CTRL_CSR1, + FLASH_CTRL_CSR2, + FLASH_CTRL_CSR3, + FLASH_CTRL_CSR4, + FLASH_CTRL_CSR5, + FLASH_CTRL_CSR6, + FLASH_CTRL_CSR7, + FLASH_CTRL_CSR8, + FLASH_CTRL_CSR9, + FLASH_CTRL_CSR10, + FLASH_CTRL_CSR11, + FLASH_CTRL_CSR12, + FLASH_CTRL_CSR13, + FLASH_CTRL_CSR14, + FLASH_CTRL_CSR15, + FLASH_CTRL_CSR16, + FLASH_CTRL_CSR17, + FLASH_CTRL_CSR18, + FLASH_CTRL_CSR19, + FLASH_CTRL_CSR20 + } flash_ctrl_prim_id_e; + + // Register width information to check illegal writes for prim interface + parameter logic [3:0] FLASH_CTRL_PRIM_PERMIT [21] = '{ + 4'b 0001, // index[ 0] FLASH_CTRL_CSR0_REGWEN + 4'b 0011, // index[ 1] FLASH_CTRL_CSR1 + 4'b 0001, // index[ 2] FLASH_CTRL_CSR2 + 4'b 1111, // index[ 3] FLASH_CTRL_CSR3 + 4'b 0011, // index[ 4] FLASH_CTRL_CSR4 + 4'b 0111, // index[ 5] FLASH_CTRL_CSR5 + 4'b 1111, // index[ 6] FLASH_CTRL_CSR6 + 4'b 0111, // index[ 7] FLASH_CTRL_CSR7 + 4'b 1111, // index[ 8] FLASH_CTRL_CSR8 + 4'b 1111, // index[ 9] FLASH_CTRL_CSR9 + 4'b 1111, // index[10] FLASH_CTRL_CSR10 + 4'b 1111, // index[11] FLASH_CTRL_CSR11 + 4'b 0011, // index[12] FLASH_CTRL_CSR12 + 4'b 0111, // index[13] FLASH_CTRL_CSR13 + 4'b 0011, // index[14] FLASH_CTRL_CSR14 + 4'b 0011, // index[15] FLASH_CTRL_CSR15 + 4'b 0011, // index[16] FLASH_CTRL_CSR16 + 4'b 0011, // index[17] FLASH_CTRL_CSR17 + 4'b 0001, // index[18] FLASH_CTRL_CSR18 + 4'b 0001, // index[19] FLASH_CTRL_CSR19 + 4'b 0001 // index[20] FLASH_CTRL_CSR20 + }; + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_region_cfg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_region_cfg.sv new file mode 100644 index 0000000000000..af75e5a29834f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_ctrl_region_cfg.sv @@ -0,0 +1,171 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash control region configuration processing +// +// There are two main purpose of this module: +// 1. strip the error conditions away from reg packages (see #8282) +// 2. generate shadow update and storage errors + +module flash_ctrl_region_cfg + import flash_ctrl_pkg::*; + import flash_ctrl_reg_pkg::*; +( + input clk_i, + input rst_ni, + input lc_ctrl_pkg::lc_tx_t lc_creator_seed_sw_rw_en_i, + input lc_ctrl_pkg::lc_tx_t lc_owner_seed_sw_rw_en_i, + input lc_ctrl_pkg::lc_tx_t lc_iso_part_sw_wr_en_i, + input lc_ctrl_pkg::lc_tx_t lc_iso_part_sw_rd_en_i, + input sw_bank_cfg_t [NumBanks-1:0] bank_cfg_i, + input sw_region_t [MpRegions-1:0] region_i, + input sw_region_cfg_t [MpRegions-1:0] region_cfg_i, + input sw_default_cfg_t default_cfg_i, + input sw_info_cfg_t [NumInfos0-1:0] bank0_info0_cfg_i, + input sw_info_cfg_t [NumInfos1-1:0] bank0_info1_cfg_i, + input sw_info_cfg_t [NumInfos2-1:0] bank0_info2_cfg_i, + input sw_info_cfg_t [NumInfos0-1:0] bank1_info0_cfg_i, + input sw_info_cfg_t [NumInfos1-1:0] bank1_info1_cfg_i, + input sw_info_cfg_t [NumInfos2-1:0] bank1_info2_cfg_i, + + output bank_cfg_t [NumBanks-1:0] bank_cfg_o, + output mp_region_cfg_t [MpRegions:0] region_cfgs_o, + output info_page_cfg_t [NumBanks-1:0][InfoTypes-1:0][InfosPerBank-1:0] info_page_cfgs_o +); + + import prim_mubi_pkg::mubi4_t; + + ////////////////////////////////////// + // Life cycle synchronizer + ////////////////////////////////////// + + lc_ctrl_pkg::lc_tx_t lc_creator_seed_sw_rw_en; + lc_ctrl_pkg::lc_tx_t lc_owner_seed_sw_rw_en; + lc_ctrl_pkg::lc_tx_t lc_iso_part_sw_rd_en; + lc_ctrl_pkg::lc_tx_t lc_iso_part_sw_wr_en; + + // synchronize enables into local domain + prim_lc_sync #( + .NumCopies(1) + ) u_lc_creator_seed_sw_rw_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_creator_seed_sw_rw_en_i), + .lc_en_o({lc_creator_seed_sw_rw_en}) + ); + + prim_lc_sync #( + .NumCopies(1) + ) u_lc_owner_seed_sw_rw_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_owner_seed_sw_rw_en_i), + .lc_en_o({lc_owner_seed_sw_rw_en}) + ); + + prim_lc_sync #( + .NumCopies(1) + ) u_lc_iso_part_sw_rd_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_iso_part_sw_rd_en_i), + .lc_en_o({lc_iso_part_sw_rd_en}) + ); + + prim_lc_sync #( + .NumCopies(1) + ) u_lc_iso_part_sw_wr_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_iso_part_sw_wr_en_i), + .lc_en_o({lc_iso_part_sw_wr_en}) + ); + + ////////////////////////////////////// + // Bank speicfic configuration + ////////////////////////////////////// + for (genvar i = 0; i < NumBanks; i++) begin : gen_bank_cfg + assign bank_cfg_o[i].q = bank_cfg_i[i].q; + end + + ////////////////////////////////////// + // Data partition regions + ////////////////////////////////////// + // extra region is the default region + for (genvar i = 0; i < MpRegions; i++) begin : gen_mp_regions + assign region_cfgs_o[i].base = region_i[i].base.q; + assign region_cfgs_o[i].size = region_i[i].size.q; + assign region_cfgs_o[i].en = mubi4_t'(region_cfg_i[i].en.q); + assign region_cfgs_o[i].rd_en = mubi4_t'(region_cfg_i[i].rd_en.q); + assign region_cfgs_o[i].prog_en = mubi4_t'(region_cfg_i[i].prog_en.q); + assign region_cfgs_o[i].erase_en = mubi4_t'(region_cfg_i[i].erase_en.q); + assign region_cfgs_o[i].scramble_en = mubi4_t'(region_cfg_i[i].scramble_en.q); + assign region_cfgs_o[i].ecc_en = mubi4_t'(region_cfg_i[i].ecc_en.q); + assign region_cfgs_o[i].he_en = mubi4_t'(region_cfg_i[i].he_en.q); + end + + //default region + assign region_cfgs_o[MpRegions].base = '0; + assign region_cfgs_o[MpRegions].size = NumBanks * PagesPerBank; + assign region_cfgs_o[MpRegions].en = prim_mubi_pkg::MuBi4True; + assign region_cfgs_o[MpRegions].rd_en = mubi4_t'(default_cfg_i.rd_en.q); + assign region_cfgs_o[MpRegions].prog_en = mubi4_t'(default_cfg_i.prog_en.q); + assign region_cfgs_o[MpRegions].erase_en = mubi4_t'(default_cfg_i.erase_en.q); + assign region_cfgs_o[MpRegions].scramble_en = mubi4_t'(default_cfg_i.scramble_en.q); + assign region_cfgs_o[MpRegions].ecc_en = mubi4_t'(default_cfg_i.ecc_en.q); + assign region_cfgs_o[MpRegions].he_en = mubi4_t'(default_cfg_i.he_en.q); + + ////////////////////////////////////// + // Info partition properties configuration + ////////////////////////////////////// + sw_info_cfg_t [NumBanks-1:0][InfoTypes-1:0][InfosPerBank-1:0] sw_info_cfgs; + info_page_cfg_t [NumBanks-1:0][InfoTypes-1:0][InfosPerBank-1:0] info_cfgs; + localparam int InfoBits = $bits(sw_info_cfg_t) * InfosPerBank; + + // transform from unique names reg output to structure + // Not all types have the maximum number of banks, so those are packed to 0 + assign sw_info_cfgs[0][0] = InfoBits'(bank0_info0_cfg_i); + assign sw_info_cfgs[0][1] = InfoBits'(bank0_info1_cfg_i); + assign sw_info_cfgs[0][2] = InfoBits'(bank0_info2_cfg_i); + assign sw_info_cfgs[1][0] = InfoBits'(bank1_info0_cfg_i); + assign sw_info_cfgs[1][1] = InfoBits'(bank1_info1_cfg_i); + assign sw_info_cfgs[1][2] = InfoBits'(bank1_info2_cfg_i); + + // strip error indications + for (genvar i = 0; i < NumBanks; i++) begin : gen_info_cfg_bank + for (genvar j = 0; j < InfoTypes; j++) begin : gen_info_cfg_type + for (genvar k = 0; k < InfosPerBank; k++) begin : gen_info_cfg_page + assign info_cfgs[i][j][k].en = mubi4_t'(sw_info_cfgs[i][j][k].en.q); + assign info_cfgs[i][j][k].rd_en = mubi4_t'(sw_info_cfgs[i][j][k].rd_en.q); + assign info_cfgs[i][j][k].prog_en = mubi4_t'(sw_info_cfgs[i][j][k].prog_en.q); + assign info_cfgs[i][j][k].erase_en = mubi4_t'(sw_info_cfgs[i][j][k].erase_en.q); + assign info_cfgs[i][j][k].scramble_en = mubi4_t'(sw_info_cfgs[i][j][k].scramble_en.q); + assign info_cfgs[i][j][k].ecc_en = mubi4_t'(sw_info_cfgs[i][j][k].ecc_en.q); + assign info_cfgs[i][j][k].he_en = mubi4_t'(sw_info_cfgs[i][j][k].he_en.q); + end + end + end + + import lc_ctrl_pkg::lc_tx_test_true_strict; + + // qualify software settings with creator / owner privileges + for(genvar i = 0; i < NumBanks; i++) begin : gen_info_priv_bank + for (genvar j = 0; j < InfoTypes; j++) begin : gen_info_priv_type + flash_ctrl_info_cfg # ( + .Bank(i), + .InfoSel(j) + ) u_info_cfg ( + .clk_i, + .rst_ni, + .cfgs_i(info_cfgs[i][j]), + .creator_seed_priv_i(lc_tx_test_true_strict(lc_creator_seed_sw_rw_en)), + .owner_seed_priv_i(lc_tx_test_true_strict(lc_owner_seed_sw_rw_en)), + .iso_flash_wr_en_i(lc_tx_test_true_strict(lc_iso_part_sw_wr_en)), + .iso_flash_rd_en_i(lc_tx_test_true_strict(lc_iso_part_sw_rd_en)), + .cfgs_o(info_page_cfgs_o[i][j]) + ); + end + end + +endmodule // flash_ctrl_reg_wrap diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp.sv new file mode 100644 index 0000000000000..8fea1679c9866 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp.sv @@ -0,0 +1,377 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Memory Properties +// + +`include "prim_assert.sv" + +module flash_mp +import prim_mubi_pkg::mubi4_t; +import flash_ctrl_pkg::*; +import flash_ctrl_reg_pkg::*; ( + input clk_i, + input rst_ni, + + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + + input mubi4_t flash_disable_i, + + // interface selection + input flash_sel_e if_sel_i, + + // configuration from sw + input mp_region_cfg_t [MpRegions:0] region_cfgs_i, + input bank_cfg_t [NumBanks-1:0] bank_cfgs_i, + input info_page_cfg_t [NumBanks-1:0][InfoTypes-1:0][InfosPerBank-1:0] info_page_cfgs_i, + input erase_suspend_i, + output logic erase_suspend_done_o, + + // interface signals to/from *_ctrl + input req_i, + input flash_lcmgr_phase_e phase_i, + input [AllPagesW-1:0] req_addr_i, + input flash_part_e req_part_i, + input [InfoTypesWidth-1:0] info_sel_i, + input addr_ovfl_i, + input rd_i, + input prog_i, + input pg_erase_i, + input bk_erase_i, + output logic rd_done_o, + output logic prog_done_o, + output logic erase_done_o, + output logic error_o, + + // hardware interface override + input mubi4_t hw_info_scramble_dis_i, + input mubi4_t hw_info_ecc_dis_i, + + // interface signals to/from flash_phy + output logic req_o, + output logic rd_o, + output logic prog_o, + output logic scramble_en_o, + output logic ecc_en_o, + output logic he_en_o, + output logic pg_erase_o, + output logic bk_erase_o, + output logic erase_suspend_o, + input rd_done_i, + input prog_done_i, + input erase_done_i +); + + import prim_mubi_pkg::mubi4_test_true_strict; + + // Total number of regions including default region + localparam int TotalRegions = MpRegions+1; + + // bank + page address + logic [AllPagesW-1:0] bank_page_addr; + // bank address + logic [BankW-1:0] bank_addr; + // page address + logic [PageW-1:0] page_addr; + + assign bank_page_addr = req_addr_i; + assign bank_addr = req_addr_i[AllPagesW-1 -: BankW]; + assign page_addr = req_addr_i[PageW-1:0]; + + logic [NumBanks-1:0] bk_erase_en; + logic data_rd_en; + logic data_prog_en; + logic data_pg_erase_en; + logic data_bk_erase_en; + logic data_scramble_en; + logic data_ecc_en; + logic data_he_en; + logic info_rd_en; + logic info_prog_en; + logic info_pg_erase_en; + logic info_bk_erase_en; + logic info_scramble_en; + logic info_ecc_en; + logic info_he_en; + + // Memory properties handling for hardware interface + logic hw_sel; + assign hw_sel = if_sel_i == HwSel; + + logic data_part_sel; + logic info_part_sel; + assign data_part_sel = req_part_i == FlashPartData; + assign info_part_sel = req_part_i == FlashPartInfo; + + + //////////////////////////////////////// + // Check address out of bounds + // Applies for all partitions + //////////////////////////////////////// + logic addr_invalid; + logic bank_invalid; + logic [PageW-1:0] end_addr; + + // when number of banks are power of 2, invalid bank is handled by addr_ovfl_i + if (NumBanks % 2 > 0) begin : gen_bank_check + assign bank_invalid = bank_addr > NumBanks; + end else begin : gen_no_bank_check + logic [BankW-1:0] unused_bank_addr; + assign unused_bank_addr = bank_addr; + assign bank_invalid = '0; + end + + // address is invalid if: + // the address extends beyond the end of the partition in question + // the bank selection is invalid + // if the address overflowed the control counters + assign end_addr = data_part_sel ? DataPartitionEndAddr : + InfoPartitionEndAddr[info_sel_i]; + + assign addr_invalid = req_i & + (page_addr > end_addr | + bank_invalid | + addr_ovfl_i + ); + + //////////////////////////////////////// + // Check data partition access + //////////////////////////////////////// + logic invalid_data_txn; + data_region_attr_t sw_data_attrs [TotalRegions]; + mp_region_cfg_t sw_sel_cfg; + mp_region_cfg_t hw_sel_cfg; + + // wrap software configurations into software attributes + for(genvar i = 0; i < TotalRegions; i++) begin : gen_region_attrs + assign sw_data_attrs[i].phase = PhaseInvalid; + assign sw_data_attrs[i].cfg = region_cfgs_i[i]; + end + + flash_mp_data_region_sel #( + .Regions(TotalRegions) + ) u_sw_sel ( + .req_i(req_i & ~hw_sel), + .phase_i(PhaseInvalid), + .addr_i(bank_page_addr), + .region_attrs_i(sw_data_attrs), + .sel_cfg_o(sw_sel_cfg) + ); + + flash_mp_data_region_sel #( + .Regions(HwDataRules) + ) u_hw_sel ( + .req_i(req_i & hw_sel), + .phase_i(phase_i), + .addr_i(bank_page_addr), + .region_attrs_i(HwDataAttr), + .sel_cfg_o(hw_sel_cfg) + ); + + // select between hardware and software interfaces + mp_region_cfg_t data_region_cfg; + assign data_region_cfg = hw_sel ? hw_sel_cfg : sw_sel_cfg; + + // tie off unused signals + logic [31:0] unused_region_base; + logic [31:0] unused_region_size; + assign unused_region_base = 32'(data_region_cfg.base); + assign unused_region_size = 32'(data_region_cfg.size); + + // check for bank erase + // bank erase allowed for only data partition and software interface + always_comb begin + for (int unsigned i = 0; i < NumBanks; i++) begin: bank_comps + bk_erase_en[i] = (bank_addr == i[BankW-1:0]) & bank_cfgs_i[i].q & ~hw_sel; + end + end + + logic data_en; + assign data_en = data_part_sel & + ~addr_invalid & + mubi4_test_true_strict(data_region_cfg.en); + + assign data_rd_en = data_en & rd_i & + mubi4_test_true_strict(data_region_cfg.rd_en); + + assign data_prog_en = data_en & prog_i & + mubi4_test_true_strict(data_region_cfg.prog_en); + + assign data_pg_erase_en = data_en & pg_erase_i & + mubi4_test_true_strict(data_region_cfg.erase_en); + + assign data_bk_erase_en = bk_erase_i & |bk_erase_en; + + assign data_scramble_en = data_en & (rd_i | prog_i) & + mubi4_test_true_strict(data_region_cfg.scramble_en); + + assign data_ecc_en = data_en & (rd_i | prog_i) & + mubi4_test_true_strict(data_region_cfg.ecc_en); + + assign data_he_en = data_en & + mubi4_test_true_strict(data_region_cfg.he_en); + + assign invalid_data_txn = req_i & data_part_sel & + ~(data_rd_en | + data_prog_en | + data_pg_erase_en | + data_bk_erase_en + ); + + //////////////////////////////////////// + // Check info partition access + //////////////////////////////////////// + + // hardware interface permission check + info_page_cfg_t hw_page_cfg_pre, hw_page_cfg; + + // rule match used for assertions only + logic [HwInfoRules-1:0] unused_rule_match; + + // software interface permission check + logic [InfoPageW-1:0] info_page_addr; + info_page_cfg_t page_cfg; + logic info_en; + logic invalid_info_txn; + + // select appropriate hw page configuration based on phase and page matching + always_comb begin + hw_page_cfg_pre = '0; + unused_rule_match = '0; + if (hw_sel && req_i) begin + for (int unsigned i = 0; i < HwInfoRules; i++) begin: hw_info_region_comps + // select the appropriate hardware page + if (bank_page_addr == HwInfoPageAttr[i].page.addr && + info_sel_i == HwInfoPageAttr[i].page.sel && + phase_i == HwInfoPageAttr[i].phase) begin + unused_rule_match[i] = 1'b1; + hw_page_cfg_pre = HwInfoPageAttr[i].cfg; + end + end + end + + hw_page_cfg = hw_page_cfg_pre; + hw_page_cfg.scramble_en = prim_mubi_pkg::mubi4_and_hi(hw_page_cfg_pre.scramble_en, + mubi4_t'(~hw_info_scramble_dis_i)); + hw_page_cfg.ecc_en = prim_mubi_pkg::mubi4_and_hi(hw_page_cfg_pre.ecc_en, + mubi4_t'(~hw_info_ecc_dis_i)); + end + + // select appropriate page configuration + assign info_page_addr = req_addr_i[InfoPageW-1:0]; + assign page_cfg = hw_sel ? hw_page_cfg : info_page_cfgs_i[bank_addr][info_sel_i][info_page_addr]; + + // final operation + assign info_en = info_part_sel & + ~addr_invalid & + mubi4_test_true_strict(page_cfg.en); + assign info_rd_en = info_en & rd_i & mubi4_test_true_strict(page_cfg.rd_en); + assign info_prog_en = info_en & prog_i & mubi4_test_true_strict(page_cfg.prog_en); + assign info_pg_erase_en = info_en & pg_erase_i & mubi4_test_true_strict(page_cfg.erase_en); + // when info is selected for bank erase, the page configuration does not matter + assign info_bk_erase_en = info_part_sel & bk_erase_i & |bk_erase_en; + assign info_scramble_en = info_en & (rd_i | prog_i) & + mubi4_test_true_strict(page_cfg.scramble_en); + + assign info_ecc_en = info_en & (rd_i | prog_i) & mubi4_test_true_strict(page_cfg.ecc_en); + assign info_he_en = info_en & mubi4_test_true_strict(page_cfg.he_en); + + // check for invalid transactions + assign invalid_info_txn = req_i & info_part_sel & + ~(info_rd_en | info_prog_en | info_pg_erase_en | + info_bk_erase_en); + + + //////////////////////////////////////// + // Combine all check results + //////////////////////////////////////// + assign rd_o = req_i & (data_rd_en | info_rd_en); + assign prog_o = req_i & (data_prog_en | info_prog_en); + assign pg_erase_o = req_i & (data_pg_erase_en | info_pg_erase_en); + assign bk_erase_o = req_i & (data_bk_erase_en | info_bk_erase_en); + assign scramble_en_o = req_i & (data_scramble_en | info_scramble_en); + assign ecc_en_o = req_i & (data_ecc_en | info_ecc_en); + assign he_en_o = req_i & (data_he_en | info_he_en); + assign req_o = rd_o | prog_o | pg_erase_o | bk_erase_o; + + logic txn_err; + logic no_allowed_txn; + // if flash_disable is true, transaction is always invalid + assign no_allowed_txn = req_i & + ((prim_mubi_pkg::mubi4_test_true_loose(flash_disable_i)) | + (addr_invalid | invalid_data_txn | invalid_info_txn)); + + // return done and error the next cycle + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + txn_err <= 1'b0; + end else if (txn_err) begin + txn_err <= 1'b0; + end else if (no_allowed_txn) begin + txn_err <= 1'b1; + end + end + + assign rd_done_o = rd_done_i | txn_err; + assign prog_done_o = prog_done_i | txn_err; + assign erase_done_o = erase_done_i | txn_err; + assign error_o = txn_err; + + // if no ongoing erase operation, immediately return + // if ongoing erase operation, wait for flash phy return + logic erase_valid; + assign erase_valid = pg_erase_o | bk_erase_o; + assign erase_suspend_o = erase_valid & erase_suspend_i; + assign erase_suspend_done_o = erase_suspend_i & ~erase_valid | + erase_suspend_o & erase_done_o; + + + ////////////////////////////////////////////// + // Assertions, Assumptions, and Coverpoints // + ////////////////////////////////////////////// + + // Bank erase enable should always be one-hot. We cannot erase multiple banks + // at the same time + `ASSERT(bkEraseEnOnehot_A, (req_o & bk_erase_o) |-> $onehot(bk_erase_en)) + // Requests can only happen one at a time + `ASSERT(requestTypesOnehot_A, req_o |-> $onehot({rd_o, prog_o, pg_erase_o, bk_erase_o})) + // Info / data errors are mutually exclusive + `ASSERT(invalidReqOnehot_A, req_o |-> $onehot0({invalid_data_txn, invalid_info_txn})) + // Cannot match more than one info rule at a time + `ASSERT(hwInfoRuleOnehot_A, req_i & hw_sel |-> $onehot0(unused_rule_match)) + // An input request should lead to an output request if there are no errors + `ASSERT(InReqOutReq_A, req_i |-> req_o | no_allowed_txn) + // An Info request should not lead to data requests + `ASSERT(InfoReqToData_A, req_i & info_part_sel |-> ~|{data_en, + data_rd_en, + data_prog_en, + data_pg_erase_en}) + // A data request should not lead to info requests + `ASSERT(DataReqToInfo_A, req_i & data_part_sel |-> + ~|{info_en, + info_rd_en, + info_prog_en, + info_pg_erase_en, + info_bk_erase_en}) + + // If a bank erase request only selects data, then info should be erased + `ASSERT(BankEraseData_A, req_i & bk_erase_i & |bk_erase_en & data_part_sel |-> data_bk_erase_en & + ~info_bk_erase_en) + + // If a bank erase request also selects the info partition, then both data + // and info must be erased + `ASSERT(BankEraseInfo_A, req_i & bk_erase_i & |bk_erase_en & info_part_sel |-> &{data_bk_erase_en, + info_bk_erase_en}) + + // When no transactions are allowed, the output request should always be 0. + // The assertion is disabled during escalation since req_o takes a few cycles to + // go to 0 if escalation is asserted mid transaction. + `ASSERT(NoReqWhenErr_A, no_allowed_txn |-> ~req_o, + clk_i, !rst_ni || lc_ctrl_pkg::lc_tx_test_true_loose(lc_escalate_en_i)) + + // This signal is only used in the assertion above. + lc_ctrl_pkg::lc_tx_t unused_escalate_en; + assign unused_escalate_en = lc_escalate_en_i; + +endmodule // flash_erase_ctrl diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp_data_region_sel.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp_data_region_sel.sv new file mode 100644 index 0000000000000..c159b524c42eb --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_mp_data_region_sel.sv @@ -0,0 +1,58 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Memory Properties +// + +`include "prim_assert.sv" + +module flash_mp_data_region_sel import flash_ctrl_pkg::*; #( + parameter int Regions = 4 +) ( + input req_i, + input flash_lcmgr_phase_e phase_i, + input [AllPagesW-1:0] addr_i, + input data_region_attr_t region_attrs_i [Regions], + output mp_region_cfg_t sel_cfg_o +); + import prim_mubi_pkg::mubi4_test_true_strict; + + // There could be multiple region matches due to region overlap + // Lower indices always have priority + logic [AllPagesW:0] region_end[Regions]; + logic [Regions-1:0] region_match; + logic [Regions-1:0] region_sel; + + // decode for software interface region + assign region_sel[0] = region_match[0]; + for (genvar i = 1; i < Regions; i++) begin: gen_region_priority + assign region_sel[i] = region_match[i] & ~|region_match[i-1:0]; + end + + // check for region match + always_comb begin + for (int i = 0; i < Regions; i++) begin: gen_region_comps + region_end[i] = {1'b0, region_attrs_i[i].cfg.base} + region_attrs_i[i].cfg.size; + + // region matches if address within range and if the partition matches + region_match[i] = addr_i >= region_attrs_i[i].cfg.base & + {1'b0, addr_i} < region_end[i] & + phase_i == region_attrs_i[i].phase & + mubi4_test_true_strict(region_attrs_i[i].cfg.en) & + req_i; + end + end + + // select appropriate region configuration + always_comb begin + sel_cfg_o = '0; + for (int i = 0; i < Regions; i++) begin: gen_region_sel + if (region_sel[i]) begin + sel_cfg_o = region_attrs_i[i].cfg; + end + end + end + + +endmodule // flash_mp_data_region_sel diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy.sv new file mode 100644 index 0000000000000..cfe3845ece6b1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy.sv @@ -0,0 +1,401 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Module +// +// +// Flash phy represents the top level open source wrapper for a proprietary flash +// module. +// The top level flash_phy is only responsible for dispatching transactions and +// correctly collecting the responses in order. + +module flash_phy + import flash_ctrl_pkg::*; + import prim_mubi_pkg::mubi4_t; +#( + parameter bit SecScrambleEn = 1'b1 +) +( + input clk_i, + input rst_ni, + input host_req_i, + input [BusAddrW-1:0] host_addr_i, + output logic host_req_rdy_o, + output logic host_req_done_o, + output logic [BusFullWidth-1:0] host_rdata_o, + output logic host_rderr_o, + input flash_req_t flash_ctrl_i, + output flash_rsp_t flash_ctrl_o, + input tlul_pkg::tl_h2d_t tl_i, + output tlul_pkg::tl_d2h_t tl_o, + input mubi4_t scanmode_i, + input scan_en_i, + input scan_rst_ni, + input flash_power_ready_h_i, + input flash_power_down_h_i, + inout [1:0] flash_test_mode_a_io, + inout flash_test_voltage_h_io, + input mubi4_t flash_bist_enable_i, + input lc_ctrl_pkg::lc_tx_t lc_nvm_debug_en_i, + input ast_pkg::ast_obs_ctrl_t obs_ctrl_i, + output logic [7:0] fla_obs_o, + output logic fatal_prim_flash_alert_o, + output logic recov_prim_flash_alert_o +); + + import prim_mubi_pkg::MuBi4False; + + // Flash macro outstanding refers to how many reads we allow a macro to move ahead of an + // in order blocking read. Since the data cannot be returned out of order, this simply + // does the reads in advance and store them in a FIFO + localparam int FlashMacroOustanding = 1; + localparam int SeqFifoDepth = FlashMacroOustanding * NumBanks; + + // flash_phy forwards incoming host transactions to the appropriate bank. However, depending + // on the transaction type, the completion times may differ (for example, a transaction + // requiring de-scramble will take significantly longer than one that hits in the read buffers). + // This implies that it is possible for flash_phy to forward one transaction to bank N and another + // to bank N+1 only for bank N+1 to finish its transaction first. + // + // This suggests that even though transactions are received in-order, they can complete out of + // order. Thus it is the responsibility of the flash_phy to sequence the responses correctly. + // For banks that have finished ahead of time, it is also important to hold their output until + // consumption by the host. + // + // The sequence fifo below holds the correct response order, while each flash_phy_core is + // paired with a small passthrough response FIFO to hold the data if necessary. + // If one bank finishes "ahead" of schedule, the response FIFO will hold the response, and no new + // transactions will be issued to that bank until the response is consumed by the host. + + // host to flash_phy interface + logic [BankW-1:0] host_bank_sel; + logic [BankW-1:0] rsp_bank_sel; + logic [NumBanks-1:0] host_req_rdy; + logic [NumBanks-1:0] host_req_done; + logic [NumBanks-1:0] host_rsp_avail; + logic [NumBanks-1:0] host_rsp_vld; + logic [NumBanks-1:0] host_rsp_ack; + logic [BusFullWidth-1:0] host_rsp_data [NumBanks]; + logic [NumBanks-1:0] host_rsp_err; + logic seq_fifo_rdy; + logic seq_fifo_pending; + + // flash_ctrl to flash_phy interface + logic [BankW-1:0] ctrl_bank_sel; + logic [NumBanks-1:0] rd_done; + logic [NumBanks-1:0] prog_done; + logic [NumBanks-1:0] erase_done; + logic init_busy; + logic [ProgTypes-1:0] prog_type_avail; + + // common interface + logic [BusFullWidth-1:0] rd_data_host [NumBanks]; + logic [BusFullWidth-1:0] rd_data_ctrl [NumBanks]; + logic [NumBanks-1:0] rd_err; + logic [NumBanks-1:0] spurious_acks; + + // fsm error per bank + logic [NumBanks-1:0] fsm_err; + + // integrity error per bank + logic [NumBanks-1:0] prog_intg_err; + logic [NumBanks-1:0] relbl_ecc_err; + logic [NumBanks-1:0] intg_ecc_err; + + // consistency error per bank + logic [NumBanks-1:0] arb_err; + logic [NumBanks-1:0] host_gnt_err; + + // fifo error per bank + logic [NumBanks-1:0] rsp_fifo_err; + logic [NumBanks-1:0] core_fifo_err; + + // outstanding count error per bank + logic [NumBanks-1:0] cnt_err; + + // arbiter error from scrambling module + logic scramble_arb_err; + + // select which bank each is operating on + assign host_bank_sel = host_req_i ? host_addr_i[BusAddrW-1 -: BankW] : '0; + assign ctrl_bank_sel = flash_ctrl_i.addr[BusAddrW-1 -: BankW]; + + // accept transaction if bank is ready and previous response NOT pending + assign host_req_rdy_o = host_req_rdy[host_bank_sel] & host_rsp_avail[host_bank_sel] & + seq_fifo_rdy; + + assign host_req_done_o = seq_fifo_pending & host_rsp_vld[rsp_bank_sel]; + assign host_rderr_o = host_rsp_err[rsp_bank_sel]; + assign host_rdata_o = host_rsp_data[rsp_bank_sel]; + + // all banks are assumed to be the same in terms of prog_type support + assign flash_ctrl_o.prog_type_avail = prog_type_avail; + assign flash_ctrl_o.rd_done = rd_done[ctrl_bank_sel]; + assign flash_ctrl_o.prog_done = prog_done[ctrl_bank_sel]; + assign flash_ctrl_o.erase_done = erase_done[ctrl_bank_sel]; + assign flash_ctrl_o.rd_data = rd_data_ctrl[ctrl_bank_sel]; + assign flash_ctrl_o.rd_err = rd_err[ctrl_bank_sel]; + assign flash_ctrl_o.init_busy = init_busy; + assign flash_ctrl_o.prog_intg_err = |prog_intg_err; + assign flash_ctrl_o.storage_relbl_err = |relbl_ecc_err; + assign flash_ctrl_o.storage_intg_err = |intg_ecc_err; + assign flash_ctrl_o.fsm_err = |fsm_err; + assign flash_ctrl_o.spurious_ack = |spurious_acks; + assign flash_ctrl_o.arb_err = |arb_err | scramble_arb_err; + assign flash_ctrl_o.host_gnt_err = |{host_gnt_err, cnt_err} ; + assign flash_ctrl_o.fifo_err = |{rsp_fifo_err, core_fifo_err}; + + + // This fifo holds the expected return order + prim_fifo_sync #( + .Width (BankW), + .Pass (0), + .Depth (SeqFifoDepth) + ) u_bank_sequence_fifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(host_req_i & host_req_rdy_o), + .wready_o(seq_fifo_rdy), + .wdata_i (host_bank_sel), + .depth_o (), + .full_o (), + .rvalid_o(seq_fifo_pending), + .rready_i(host_req_done_o), + .rdata_o (rsp_bank_sel), + .err_o () + ); + + // Generate host scramble_en indication, broadcasted to all banks + localparam int TotalRegions = MpRegions + 1; + logic host_scramble_en, host_ecc_en; + data_region_attr_t region_attrs [TotalRegions]; + mp_region_cfg_t region_cfg, unused_cfg; + + for(genvar i = 0; i < TotalRegions; i++) begin : gen_region_attrs + assign region_attrs[i].phase = PhaseInvalid; + assign region_attrs[i].cfg = flash_ctrl_i.region_cfgs[i]; + end + + // the region decode only accepts page address + flash_mp_data_region_sel #( + .Regions(TotalRegions) + ) u_region_sel ( + .req_i(host_req_i), + .phase_i(PhaseInvalid), + .addr_i(host_addr_i[BusAddrW-1 -: AllPagesW]), + .region_attrs_i(region_attrs), + .sel_cfg_o(region_cfg) + ); + + // most attributes are unused + assign unused_cfg = region_cfg; + + // only scramble/ecc attributes are looked at + import prim_mubi_pkg::mubi4_test_true_strict; + import prim_mubi_pkg::mubi4_and_hi; + + assign host_scramble_en = mubi4_test_true_strict( + mubi4_and_hi(region_cfg.scramble_en, region_cfg.en)); + assign host_ecc_en = mubi4_test_true_strict(mubi4_and_hi(region_cfg.ecc_en, region_cfg.en)); + + // Prim flash to flash_phy_core connections + flash_phy_pkg::scramble_req_t [NumBanks-1:0] scramble_req; + flash_phy_pkg::scramble_rsp_t [NumBanks-1:0] scramble_rsp; + flash_phy_pkg::flash_phy_prim_flash_req_t [NumBanks-1:0] prim_flash_req; + flash_phy_pkg::flash_phy_prim_flash_rsp_t [NumBanks-1:0] prim_flash_rsp; + logic [NumBanks-1:0] ecc_single_err; + logic [NumBanks-1:0][BusAddrW-1:0] ecc_addr; + + assign flash_ctrl_o.ecc_single_err = ecc_single_err; + assign flash_ctrl_o.ecc_addr = ecc_addr; + + // One extra copy for the flash scrambling module. + mubi4_t [NumBanks:0] flash_disable; + prim_mubi4_sync #( + .NumCopies(NumBanks+1), + .AsyncOn(0) + ) u_disable_buf ( + .clk_i, + .rst_ni, + .mubi_i(flash_ctrl_i.flash_disable), + .mubi_o(flash_disable) + ); + + + for (genvar bank = 0; bank < NumBanks; bank++) begin : gen_flash_cores + + // pop if the response came from the appropriate fifo + assign host_rsp_ack[bank] = host_req_done_o & (rsp_bank_sel == bank); + + prim_fifo_sync #( + .Width (BusFullWidth + 1), + .Pass (1'b1), + .Depth (FlashMacroOustanding), + .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN + ) u_host_rsp_fifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(host_req_done[bank]), + .wready_o(host_rsp_avail[bank]), + .wdata_i ({rd_err[bank], rd_data_host[bank]}), + .depth_o (), + .full_o (), + .rvalid_o(host_rsp_vld[bank]), + .rready_i(host_rsp_ack[bank]), + .rdata_o ({host_rsp_err[bank], host_rsp_data[bank]}), + .err_o (rsp_fifo_err[bank]) + ); + + logic host_req; + logic ctrl_req; + assign host_req = host_req_i & (host_bank_sel == bank) & host_rsp_avail[bank]; + assign ctrl_req = flash_ctrl_i.req & (ctrl_bank_sel == bank); + assign ecc_addr[bank][BusBankAddrW +: BankW] = bank; + + flash_phy_core u_core ( + .clk_i, + .rst_ni, + // integrity error is either from host or from controller + .req_i(ctrl_req), + .scramble_en_i(flash_ctrl_i.scramble_en), + .ecc_en_i(flash_ctrl_i.ecc_en), + .he_en_i(flash_ctrl_i.he_en), + // host request must be suppressed if response fifo cannot hold more + // otherwise the flash_phy_core and flash_phy will get out of sync + .host_req_i(host_req), + .host_scramble_en_i(host_scramble_en), + .host_ecc_en_i(host_ecc_en), + .host_addr_i(host_addr_i[0 +: BusBankAddrW]), + .rd_i(flash_ctrl_i.rd), + .prog_i(flash_ctrl_i.prog), + .pg_erase_i(flash_ctrl_i.pg_erase), + .bk_erase_i(flash_ctrl_i.bk_erase), + .erase_suspend_req_i(flash_ctrl_i.erase_suspend), + .part_i(flash_ctrl_i.part), + .info_sel_i(flash_ctrl_i.info_sel), + .addr_i(flash_ctrl_i.addr[0 +: BusBankAddrW]), + .prog_data_i(flash_ctrl_i.prog_data), + .prog_last_i(flash_ctrl_i.prog_last), + .prog_type_i(flash_ctrl_i.prog_type), + .rd_buf_en_i(flash_ctrl_i.rd_buf_en), + .host_req_rdy_o(host_req_rdy[bank]), + .host_req_done_o(host_req_done[bank]), + .rd_done_o(rd_done[bank]), + .prog_done_o(prog_done[bank]), + .erase_done_o(erase_done[bank]), + .rd_data_host_o(rd_data_host[bank]), + .rd_data_ctrl_o(rd_data_ctrl[bank]), + .rd_err_o(rd_err[bank]), + .flash_disable_i(flash_disable[bank]), + .scramble_req_o(scramble_req[bank]), + .scramble_rsp_i(scramble_rsp[bank]), + .prim_flash_req_o(prim_flash_req[bank]), + .prim_flash_rsp_i(prim_flash_rsp[bank]), + .ecc_single_err_o(ecc_single_err[bank]), + .ecc_addr_o(ecc_addr[bank][BusBankAddrW-1:0]), + .fsm_err_o(fsm_err[bank]), + .prog_intg_err_o(prog_intg_err[bank]), + .relbl_ecc_err_o(relbl_ecc_err[bank]), + .intg_ecc_err_o(intg_ecc_err[bank]), + .spurious_ack_o(spurious_acks[bank]), + .arb_err_o(arb_err[bank]), + .host_gnt_err_o(host_gnt_err[bank]), + .fifo_err_o(core_fifo_err[bank]), + .cnt_err_o(cnt_err[bank]) + ); + end // block: gen_flash_banks + + // shared scrambling module + // SEC_CM: MEM.SCRAMBLE + flash_phy_scramble #( + .SecScrambleEn(SecScrambleEn) + ) u_scramble ( + .clk_i, + .rst_ni, + // both escalation and integrity error cause the scramble keys to change + .disable_i(prim_mubi_pkg::mubi4_test_true_loose(flash_disable[NumBanks])), + .addr_key_i(flash_ctrl_i.addr_key), + .data_key_i(flash_ctrl_i.data_key), + .rand_addr_key_i(flash_ctrl_i.rand_addr_key), + .rand_data_key_i(flash_ctrl_i.rand_data_key), + .scramble_req_i(scramble_req), + .scramble_rsp_o(scramble_rsp), + .arb_err_o(scramble_arb_err) // fatal error from redundant arbiter logic + ); + + // life cycle handling + logic tdo; + lc_ctrl_pkg::lc_tx_t [FlashLcDftLast-1:0] lc_nvm_debug_en; + + assign flash_ctrl_o.jtag_rsp.tdo = tdo & + lc_ctrl_pkg::lc_tx_test_true_strict(lc_nvm_debug_en[FlashLcTdoSel]); + + prim_lc_sync #( + .NumCopies(int'(FlashLcDftLast)) + ) u_lc_nvm_debug_en_sync ( + .clk_i, + .rst_ni, + .lc_en_i(lc_nvm_debug_en_i), + .lc_en_o(lc_nvm_debug_en) + ); + + import lc_ctrl_pkg::lc_tx_test_true_strict; + // if nvm debug is enabled, flash_bist_enable controls entry to flash test mode. + // if nvm debug is disabled, flash_bist_enable is always turned off. + mubi4_t bist_enable_qual; + assign bist_enable_qual = (lc_tx_test_true_strict(lc_nvm_debug_en[FlashBistSel])) ? + flash_bist_enable_i : + MuBi4False; + + prim_flash #( + .NumBanks(NumBanks), + .InfosPerBank(InfosPerBank), + .InfoTypes(InfoTypes), + .InfoTypesWidth(InfoTypesWidth), + .PagesPerBank(PagesPerBank), + .WordsPerPage(WordsPerPage), + .DataWidth(flash_phy_pkg::FullDataWidth) + ) u_flash ( + .clk_i, + .rst_ni, + .tl_i, + .tl_o, + .flash_req_i(prim_flash_req), + .flash_rsp_o(prim_flash_rsp), + .prog_type_avail_o(prog_type_avail), + .init_busy_o(init_busy), + .tck_i(flash_ctrl_i.jtag_req.tck & lc_tx_test_true_strict(lc_nvm_debug_en[FlashLcTckSel])), + .tdi_i(flash_ctrl_i.jtag_req.tdi & lc_tx_test_true_strict(lc_nvm_debug_en[FlashLcTdiSel])), + .tms_i(flash_ctrl_i.jtag_req.tms & lc_tx_test_true_strict(lc_nvm_debug_en[FlashLcTmsSel])), + .tdo_o(tdo), + .bist_enable_i(bist_enable_qual), + .obs_ctrl_i, + .fla_obs_o, + .scanmode_i, + .scan_en_i, + .scan_rst_ni, + .flash_power_ready_h_i, + .flash_power_down_h_i, + .flash_test_mode_a_io, + .flash_test_voltage_h_io, + .flash_err_o(flash_ctrl_o.macro_err), + .fatal_alert_o(fatal_prim_flash_alert_o), + .recov_alert_o(recov_prim_flash_alert_o) + ); + logic unused_alert; + assign unused_alert = flash_ctrl_i.alert_trig & flash_ctrl_i.alert_ack; + + logic unused_trst_n; + assign unused_trst_n = flash_ctrl_i.jtag_req.trst_n; + assign flash_ctrl_o.jtag_rsp.tdo_oe = 1'b1; + + ////////////////////////////////////////////// + // Assertions, Assumptions, and Coverpoints // + ///////////////////////////////////////////// + + // Add some assertions regarding response ordering + +endmodule // flash_phy diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_core.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_core.sv new file mode 100644 index 0000000000000..1437764f2f6eb --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_core.sv @@ -0,0 +1,604 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Core Module +// +// +// This module wraps every single flash bank and contains most of the region attribute, +// scramble, ECC, security and arbitration logic. + +module flash_phy_core + import flash_phy_pkg::*; + import prim_mubi_pkg::mubi4_t; +#( + parameter int unsigned ArbCnt = 5 +) ( + input clk_i, + input rst_ni, + input host_req_i, // host request - read only + input host_scramble_en_i, + input host_ecc_en_i, + input [BusBankAddrW-1:0] host_addr_i, + input req_i, // controller request + input scramble_en_i, + input ecc_en_i, + input he_en_i, + input rd_i, + input prog_i, + input pg_erase_i, + input bk_erase_i, + input erase_suspend_req_i, + input flash_ctrl_pkg::flash_part_e part_i, + input [InfoTypesWidth-1:0] info_sel_i, + input [BusBankAddrW-1:0] addr_i, + input [BusFullWidth-1:0] prog_data_i, + input prog_last_i, + input flash_ctrl_pkg::flash_prog_e prog_type_i, + input rd_buf_en_i, + input prim_mubi_pkg::mubi4_t flash_disable_i, + output scramble_req_t scramble_req_o, + input scramble_rsp_t scramble_rsp_i, + input flash_phy_prim_flash_rsp_t prim_flash_rsp_i, + output flash_phy_prim_flash_req_t prim_flash_req_o, + output logic host_req_rdy_o, + output logic host_req_done_o, + output logic rd_done_o, + output logic prog_done_o, + output logic erase_done_o, + output logic [BusFullWidth-1:0] rd_data_host_o, + output logic [BusFullWidth-1:0] rd_data_ctrl_o, + output logic rd_err_o, + output logic ecc_single_err_o, + output logic [BusBankAddrW-1:0] ecc_addr_o, + output logic fsm_err_o, + output logic prog_intg_err_o, + output logic relbl_ecc_err_o, + output logic intg_ecc_err_o, + output logic spurious_ack_o, + output logic arb_err_o, + output logic host_gnt_err_o, + output logic fifo_err_o, + output logic cnt_err_o +); + + + localparam int CntWidth = $clog2(ArbCnt + 1); + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 5 -m 6 -n 10 \ + // -s 3884146959 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: -- + // 5: |||||||||||||||||||| (46.67%) + // 6: ||||||||||||||||| (40.00%) + // 7: ||||| (13.33%) + // 8: -- + // 9: -- + // 10: -- + // + // Minimum Hamming distance: 5 + // Maximum Hamming distance: 7 + // Minimum Hamming weight: 4 + // Maximum Hamming weight: 8 + // + localparam int StateWidth = 10; + typedef enum logic [StateWidth-1:0] { + StIdle = 10'b1011011110, + StCtrlRead = 10'b0010100110, + StCtrlProg = 10'b1111101101, + StCtrl = 10'b1101000010, + StDisable = 10'b0000111011 + } state_e; + + state_e state_q, state_d; + + // request signals to flash macro + logic [PhyLastOp-1:0] reqs; + + // host select for address + logic host_sel; + + // controller response valid + logic ctrl_rsp_vld; + + // ack to phy operations from flash macro + logic ack; + + // done to phy operations from flash macro + logic done; + + // ack from flash_phy_prog to controller + logic prog_ack; + + // ack from flash_phy_erase to controller + logic erase_ack; + + // interface with flash macro + logic [BusBankAddrW-1:0] muxed_addr; + flash_ctrl_pkg::flash_part_e muxed_part; + logic muxed_scramble_en; + logic muxed_ecc_en; + + // entire read stage is idle, inclusive of all stages + logic rd_stage_idle; + + // the read stage is ready to accept a new transaction + logic rd_stage_rdy; + + // the read stage has valid response + logic rd_stage_data_valid; + + // arbitration counter + // If controller side has lost arbitration ArbCnt times, favor it once + logic [CntWidth-1:0] arb_cnt; + logic inc_arb_cnt; + + // scramble / de-scramble connections + logic calc_ack; + logic op_ack; + logic [DataWidth-1:0] scramble_mask; + + logic host_gnt; + logic ctrl_gnt; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + arb_cnt <= '0; + end else if (ctrl_rsp_vld) begin + arb_cnt <= '0; + end else if (inc_arb_cnt) begin + arb_cnt <= arb_cnt + 1'b1; + end + end + + import prim_mubi_pkg::mubi4_test_false_strict; + import prim_mubi_pkg::mubi4_test_true_loose; + + // SEC_CM: PHY.FSM.SPARSE + `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, StIdle) + + typedef enum logic [2:0] { + HostDisableIdx, + CtrlDisableIdx, + FsmDisableIdx, + ProgFsmDisableIdx, + LastDisableIdx + } phy_core_disable_e; + + prim_mubi_pkg::mubi4_t [LastDisableIdx-1:0] flash_disable; + prim_mubi4_sync #( + .NumCopies(int'(LastDisableIdx)), + .AsyncOn(0) + ) u_disable_buf ( + .clk_i, + .rst_ni, + .mubi_i(flash_disable_i), + .mubi_o(flash_disable) + ); + + // Oustanding width is slightly larger to ensure a faulty increment is able to reach + // the higher value. For example if RspOrderDepth were 3, a clog2 of 3 would still be 2 + // and not allow the counter to increment to 4. + localparam int OutstandingRdWidth = $clog2(RspOrderDepth+2); + logic [OutstandingRdWidth-1:0] host_outstanding; + logic ctrl_fsm_idle; + logic host_req; + // SEC_CM: PHY_HOST_GRANT.CTRL.CONSISTENCY + // A host transaction was granted to the muxed partition, this is illegal + logic host_gnt_err_event; + assign host_gnt_err_event = (host_gnt && muxed_part != flash_ctrl_pkg::FlashPartData); + // Controller fsm became non idle when there are pending host transactions, this is + // illegal. + logic host_outstanding_err_event; + assign host_outstanding_err_event = |host_outstanding & !ctrl_fsm_idle; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + host_gnt_err_o <= '0; + end else if (host_gnt_err_event | host_outstanding_err_event) begin + host_gnt_err_o <= 1'b1; + end + end + + // When host grant errors occur, also create in band error responses. + // The error condition is held until all existing host transactions are + // processed. + logic host_gnt_rd_err; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + host_gnt_rd_err <= '0; + end else if (host_outstanding == '0) begin + host_gnt_rd_err <= '0; + end else if (host_gnt_err_event) begin + host_gnt_rd_err <= 1'b1; + end + end + + // When host outstanding errors occur, also create in band error responses. + // The error condition is held until all existing host and controller + // transactions are processed. + logic host_outstanding_rd_err; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + host_outstanding_rd_err <= '0; + end else if (host_outstanding == '0 && ctrl_fsm_idle) begin + host_outstanding_rd_err <= '0; + end else if (host_outstanding_err_event) begin + host_outstanding_rd_err <= 1'b1; + end + end + + // SEC_CM: PHY_HOST_GRANT.CTRL.CONSISTENCY + prim_count #( + .Width(OutstandingRdWidth), + .ResetValue('0) + ) u_host_outstanding_cnt ( + .clk_i, + .rst_ni, + .clr_i('0), + .set_i('0), + .set_cnt_i('0), + .incr_en_i(host_gnt && !host_req_done_o && (host_outstanding <= RspOrderDepth)), + .decr_en_i(!host_gnt && host_req_done_o && |host_outstanding), + .step_i(OutstandingRdWidth'(1'b1)), + .commit_i(1'b1), + .cnt_o(host_outstanding), + .cnt_after_commit_o(), + .err_o(cnt_err_o) + ); + + // If host_outstanding is non-zero, the controller fsm must be idle.. + // This assertion needs to be disabled for sec_cm testing + `ASSERT(HostTransIdleChk_A, |host_outstanding |-> ctrl_fsm_idle) + + //always_ff @(posedge clk_i or negedge rst_ni) begin + // if (!rst_ni) begin + // host_outstanding <= '0; + // end else if (host_gnt && !host_req_done_o && (host_outstanding <= RspOrderDepth)) begin + // host_outstanding <= host_outstanding + 1'b1; + // end else if (!host_gnt && host_req_done_o && |host_outstanding) begin + // host_outstanding <= host_outstanding - 1'b1; + // end + //end + + `ASSERT(RdTxnCheck_A, host_outstanding <= RspOrderDepth) + + // The host request is suppressed under a variety of conditions: + // 1. If a controller transaction is already ongoing. + // 2. If a grant or outstanding error has already been observed but not yet + // fully processed. + assign host_req = host_req_i & (arb_cnt < ArbCnt[CntWidth-1:0]) & ctrl_fsm_idle & + !host_gnt_rd_err & !host_outstanding_rd_err & + mubi4_test_false_strict(flash_disable[HostDisableIdx]); + assign host_sel = host_req; + assign host_gnt = host_req & host_req_rdy_o; + assign host_req_done_o = |host_outstanding & rd_stage_data_valid; + + // controller request can only win after the entire read pipeline + // clears + logic ctrl_req; + assign ctrl_req = req_i & rd_stage_idle & + !host_gnt_rd_err & !host_outstanding_rd_err & + mubi4_test_false_strict(flash_disable[CtrlDisableIdx]); + + logic [1:0] data_tie_off [2]; + assign data_tie_off = '{default: '0}; + + // SEC_CM: PHY_ARBITER.CTRL.REDUN + logic phy_req; + logic phy_rdy; + + prim_arbiter_tree_dup #( + .N(2), + .DW(2), + .EnDataPort('0), + .FixedArb(1) + ) u_host_arb ( + .clk_i, + .rst_ni, + .req_chk_i('0), + .req_i({ctrl_req, host_req}), + .data_i(data_tie_off), + .gnt_o({ctrl_gnt, host_req_rdy_o}), + .idx_o(), + .valid_o(phy_req), + .data_o(), + .ready_i(phy_rdy), + .err_o(arb_err_o) + ); + + assign phy_rdy = phy_req & host_req ? rd_stage_rdy : rd_stage_idle; + + + // if request happens at the same time as a host grant, increment count + assign inc_arb_cnt = req_i & host_gnt; + + logic fsm_err; + always_comb begin + state_d = state_q; + reqs = '0; + ctrl_rsp_vld = '0; + fsm_err = '0; + ctrl_fsm_idle = '0; + + unique case (state_q) + StIdle: begin + ctrl_fsm_idle = 1'b1; + if (mubi4_test_true_loose(flash_disable[FsmDisableIdx])) begin + state_d = StDisable; + end else if (ctrl_gnt && rd_i) begin + state_d = StCtrlRead; + end else if (ctrl_gnt && prog_i) begin + state_d = StCtrlProg; + end else if (ctrl_gnt) begin + state_d = StCtrl; + end + end + + // Controller reads are very slow. + StCtrlRead: begin + if (rd_stage_data_valid) begin + ctrl_rsp_vld = 1'b1; + state_d = StIdle; + end + end + + // Controller program data may be packed based on + // address alignment + StCtrlProg: begin + reqs[PhyProg] = 1'b1; + if (prog_ack) begin + ctrl_rsp_vld = 1'b1; + state_d = StIdle; + end + end + + // other controller operations directly interface with flash + StCtrl: begin + reqs[PhyPgErase] = pg_erase_i; + reqs[PhyBkErase] = bk_erase_i; + if (erase_ack) begin + ctrl_rsp_vld = 1'b1; + state_d = StIdle; + end + end + + StDisable: begin + ctrl_fsm_idle = 1'b1; + state_d = StDisable; + end + + default: begin + ctrl_fsm_idle = 1'b1; + fsm_err = 1'b1; + end + + endcase // unique case (state_q) + end // always_comb + + // determine spurious acks + // SEC_CM: PHY_ACK.CTRL.CONSISTENCY + assign spurious_ack_o = (ctrl_fsm_idle & ctrl_rsp_vld) | + ((host_outstanding == '0) & host_req_done_o); + + // transactions coming from flash controller are always data type + assign muxed_addr = host_sel ? host_addr_i : addr_i; + assign muxed_part = host_sel ? flash_ctrl_pkg::FlashPartData : part_i; + assign muxed_scramble_en = host_sel ? host_scramble_en_i : scramble_en_i; + assign muxed_ecc_en = host_sel ? host_ecc_en_i : ecc_en_i; + assign rd_done_o = ctrl_rsp_vld & rd_i; + assign prog_done_o = ctrl_rsp_vld & prog_i; + assign erase_done_o = ctrl_rsp_vld & (pg_erase_i | bk_erase_i); + + //////////////////////// + // read pipeline + //////////////////////// + + logic flash_rd_req; + logic [FullDataWidth-1:0] flash_rdata; + logic rd_calc_req; + logic [BankAddrW-1:0] rd_calc_addr; + logic rd_op_req; + logic [DataWidth-1:0] rd_scrambled_data; + logic [DataWidth-1:0] rd_descrambled_data; + + // if host grant is encountered, transactions return in-band + // error until all transactions are flushed. + logic phy_rd_err; + assign rd_err_o = phy_rd_err; + + + // After host_gnt_rd_err asserts, no more host requests + // are granted until all transactions are flushed. This means + // the last outstanding transaction is by definition the "error". + // + // If ctrl_fsm_idle inexplicably goes low while there are host transactions + // the transaction handling may be irreversibly broken. + // The host_oustanding_rd_err makes a best effort attempt to cleanly + // recover. It responds with in-band error controller transactions until the + // all pending transactions are flushed. + logic arb_host_gnt_err; + assign arb_host_gnt_err = (host_gnt_rd_err & host_outstanding == 1'b1) | + (host_outstanding_rd_err); + + flash_phy_rd u_rd ( + .clk_i, + .rst_ni, + .buf_en_i(rd_buf_en_i), + //.req_i(reqs[PhyRead] | host_req), + .req_i(phy_req & (rd_i | host_req)), + .descramble_i(muxed_scramble_en), + .ecc_i(muxed_ecc_en), + .prog_i(reqs[PhyProg]), + .pg_erase_i(reqs[PhyPgErase]), + .bk_erase_i(reqs[PhyBkErase]), + .addr_i(muxed_addr), + .part_i(muxed_part), + // info select cannot be generated by the host + .info_sel_i(info_sel_i), + .rdy_o(rd_stage_rdy), + .data_valid_o(rd_stage_data_valid), + .data_err_o(phy_rd_err), + .data_host_o(rd_data_host_o), + .data_ctrl_o(rd_data_ctrl_o), + .idle_o(rd_stage_idle), + // a catastrophic arbitration error has been observed, just dump + // dump returns until all transactions are flushed. + .arb_err_i(arb_host_gnt_err), + .req_o(flash_rd_req), + .ack_i(ack), + .done_i(done), + .data_i(arb_host_gnt_err ? {FullDataWidth{1'b1}} : flash_rdata), + //scramble unit interface + .calc_req_o(rd_calc_req), + .calc_addr_o(rd_calc_addr), + .descramble_req_o(rd_op_req), + .scrambled_data_o(rd_scrambled_data), + .calc_ack_i(calc_ack), + .descramble_ack_i(op_ack), + .mask_i(scramble_mask), + .descrambled_data_i(rd_descrambled_data), + .ecc_single_err_o, + .ecc_addr_o, + .relbl_ecc_err_o, + .intg_ecc_err_o, + .fifo_err_o + ); + + //////////////////////// + // program pipeline + //////////////////////// + + logic [FullDataWidth-1:0] prog_full_data; + logic [DataWidth-1:0] prog_scrambled_data; + logic [DataWidth-1:0] prog_data; + logic prog_last; + logic flash_prog_req; + logic prog_calc_req; + logic prog_op_req; + logic prog_fsm_err; + + if (WidthMultiple == 1) begin : gen_single_prog_data + assign flash_prog_req = reqs[PhyProg]; + assign prog_data = prog_data_i[BusWidth-1:0]; + assign prog_fsm_err = '0; + end else begin : gen_prog_data + + // SEC_CM: MEM.INTEGRITY + flash_phy_prog u_prog ( + .clk_i, + .rst_ni, + .req_i(reqs[PhyProg]), + .disable_i(flash_disable[ProgFsmDisableIdx]), + .scramble_i(muxed_scramble_en), + .ecc_i(muxed_ecc_en), + .sel_i(addr_i[0 +: WordSelW]), + .data_i(prog_data_i), + .last_i(prog_last_i), + .ack_i(ack), + .done_i(done), + .calc_ack_i(calc_ack), + .scramble_ack_i(op_ack), + .mask_i(scramble_mask), + .scrambled_data_i(prog_scrambled_data), + .calc_req_o(prog_calc_req), + .scramble_req_o(prog_op_req), + .req_o(flash_prog_req), + .last_o(prog_last), + .ack_o(prog_ack), + .block_data_o(prog_data), + .data_o(prog_full_data), + .fsm_err_o(prog_fsm_err), + .intg_err_o(prog_intg_err_o) + ); + end + + assign fsm_err_o = fsm_err | prog_fsm_err; + + //////////////////////// + // erase pipeline + //////////////////////// + + logic flash_pg_erase_req; + logic flash_bk_erase_req; + logic erase_suspend_req; + flash_phy_erase u_erase ( + .clk_i, + .rst_ni, + .pg_erase_req_i(reqs[PhyPgErase]), + .bk_erase_req_i(reqs[PhyBkErase]), + .suspend_req_i(erase_suspend_req_i), + .ack_o(erase_ack), + .pg_erase_req_o(flash_pg_erase_req), + .bk_erase_req_o(flash_bk_erase_req), + .suspend_req_o(erase_suspend_req), + .ack_i(ack), + .done_i(done) + ); + + //////////////////////// + // bundle data to send to shared scrambling module + //////////////////////// + + assign scramble_req_o.calc_req = prog_calc_req | rd_calc_req; + assign scramble_req_o.op_req = prog_op_req | rd_op_req; + assign scramble_req_o.op_type = prog_op_req ? ScrambleOp : DeScrambleOp; + assign scramble_req_o.addr = prog_calc_req ? muxed_addr[BusBankAddrW-1:LsbAddrBit] : + rd_calc_addr; + assign scramble_req_o.plain_data = prog_data; + assign scramble_req_o.scrambled_data = rd_scrambled_data; + assign calc_ack = scramble_rsp_i.calc_ack; + assign op_ack = scramble_rsp_i.op_ack; + assign scramble_mask = scramble_rsp_i.mask; + assign rd_descrambled_data = scramble_rsp_i.plain_data; + assign prog_scrambled_data = scramble_rsp_i.scrambled_data; + + //////////////////////// + // Actual connection to flash phy + //////////////////////// + + // Connections to the actual flash macro wrapper + assign prim_flash_req_o = '{ + rd_req: flash_rd_req, + prog_req: flash_prog_req, + prog_last: prog_last, + prog_type: prog_type_i, + pg_erase_req: flash_pg_erase_req, + bk_erase_req: flash_bk_erase_req, + erase_suspend_req: erase_suspend_req, + // high endurance enable does not cause changes to + // transaction protocol and is forwarded directly to the wrapper + he: he_en_i, + addr: muxed_addr[BusBankAddrW-1:LsbAddrBit], + part: muxed_part, + info_sel: info_sel_i, + prog_full_data: prog_full_data + }; + + assign ack = prim_flash_rsp_i.ack; + assign done = prim_flash_rsp_i.done; + assign flash_rdata = prim_flash_rsp_i.rdata; + + ///////////////////////////////// + // Assertions + ///////////////////////////////// + + // requests to flash must always be one hot + `ASSERT(OneHotReqs_A, $onehot0(reqs)) + `ASSERT_INIT(NoRemainder_A, AddrBitsRemain == 0) + `ASSERT_INIT(Pow2Multiple_A, $onehot(WidthMultiple)) + + // once arb count maxes, the host request should be masked + `ASSERT(ArbCntMax_A, arb_cnt == ArbCnt |-> !inc_arb_cnt) + + // once arb count maxes, the host request needs to be masked until the arb count is cleared + `ASSERT(CtrlPrio_A, arb_cnt == ArbCnt |-> (!host_req throughout (ctrl_rsp_vld[->1]))) + +endmodule // flash_phy_core diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_erase.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_erase.sv new file mode 100644 index 0000000000000..42bcbe6ebb963 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_erase.sv @@ -0,0 +1,87 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Erase Module +// Translates the controller's req/ack interface to the interface expected by the flash wrapper +// Longer term the controller protocol can be changed to match. + +module flash_phy_erase import flash_phy_pkg::*; ( + input clk_i, + input rst_ni, + + // interface with controller + input pg_erase_req_i, + input bk_erase_req_i, + input suspend_req_i, + output logic ack_o, + + // interface with flash + output logic pg_erase_req_o, + output logic bk_erase_req_o, + output logic suspend_req_o, + input ack_i, + input done_i +); + + typedef enum logic [1:0] { + StEraseIdle, + StEraseBusy, + StEraseSuspend + } erase_state_e; + + erase_state_e state_d, state_q; + + logic req_valid; + logic suspend_valid; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + state_q <= StEraseIdle; + end else begin + state_q <= state_d; + end + end + + always_comb begin + req_valid = 1'b0; + suspend_valid = 1'b0; + ack_o = 1'b0; + state_d = state_q; + + unique case (state_q) + StEraseIdle: begin + req_valid = 1'b1; + + if ((pg_erase_req_o || bk_erase_req_o) && ack_i) begin + state_d = StEraseBusy; + end + end + + StEraseBusy: begin + suspend_valid = '1; + + if (suspend_req_i && ack_i) begin + state_d = StEraseSuspend; + end else if (done_i) begin + ack_o = 1'b1; + state_d = StEraseIdle; + end + end + + StEraseSuspend: begin + if (done_i) begin + ack_o = 1'b1; + state_d = StEraseIdle; + end + end + + default:; + endcase // unique case (state_q) + end + + assign pg_erase_req_o = pg_erase_req_i & req_valid; + assign bk_erase_req_o = bk_erase_req_i & req_valid; + assign suspend_req_o = suspend_req_i & suspend_valid; + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_pkg.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_pkg.sv new file mode 100644 index 0000000000000..41593bd3e2d77 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_pkg.sv @@ -0,0 +1,156 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash phy module package +// + +package flash_phy_pkg; + + // flash phy parameters + parameter int unsigned NumBanks = flash_ctrl_pkg::NumBanks; + parameter int unsigned InfosPerBank = flash_ctrl_pkg::InfosPerBank; + parameter int unsigned PagesPerBank = flash_ctrl_pkg::PagesPerBank; + parameter int unsigned WordsPerPage = flash_ctrl_pkg::WordsPerPage; + parameter int unsigned BankW = flash_ctrl_pkg::BankW; + parameter int unsigned PageW = flash_ctrl_pkg::PageW; + parameter int unsigned WordW = flash_ctrl_pkg::WordW; + parameter int unsigned BankAddrW = flash_ctrl_pkg::BankAddrW; + parameter int unsigned DataWidth = flash_ctrl_pkg::DataWidth; + parameter int unsigned EccWidth = 8; + parameter int unsigned MetaDataWidth = flash_ctrl_pkg::MetaDataWidth; + parameter int unsigned WidthMultiple = flash_ctrl_pkg::WidthMultiple; + parameter int unsigned NumBuf = 4; // number of flash read buffers + parameter int unsigned RspOrderDepth = 2; // this should be DataWidth / BusWidth + // will switch to this after bus widening + parameter int unsigned PlainIntgWidth = MetaDataWidth - EccWidth; + parameter int unsigned PlainDataWidth = DataWidth + PlainIntgWidth; + //parameter int unsigned ScrDataWidth = DataWidth + EccWidth; + parameter int unsigned FullDataWidth = DataWidth + MetaDataWidth; + parameter int unsigned InfoTypes = flash_ctrl_pkg::InfoTypes; + parameter int unsigned InfoTypesWidth = flash_ctrl_pkg::InfoTypesWidth; + + // flash ctrl / bus parameters + parameter int unsigned BusWidth = flash_ctrl_pkg::BusWidth; + parameter int unsigned BusFullWidth = flash_ctrl_pkg::BusFullWidth; + parameter int unsigned BusBankAddrW = flash_ctrl_pkg::BusBankAddrW; + parameter int unsigned BusWordW = flash_ctrl_pkg::BusWordW; + parameter int unsigned ProgTypes = flash_ctrl_pkg::ProgTypes; + + // address bits remain must be 0 + parameter int unsigned AddrBitsRemain = DataWidth % BusWidth; + + // base index + // This is the lsb position of the prim flash address when looking at the bus address + parameter int unsigned LsbAddrBit = $clog2(WidthMultiple); + parameter int unsigned WordSelW = WidthMultiple == 1 ? 1 : LsbAddrBit; + + // scramble / de-scramble parameters + // Number of cycles the gf_mult is given to complete + parameter int unsigned KeySize = 128; + parameter int unsigned GfMultCycles = 2; + // If this value is greater than 1, constraints must be updated for multicycle paths + parameter int unsigned CipherCycles = 2; + + // GF(2) irreducible polynomial for flash XEX scrambling scheme. + // We use the NIST 800-38B recommendation for block cipher modes of operation. + // See Section "5.3 Subkeys" on page 6: + // https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38B.pdf + // Specifically, we use the polynomial: x^64 + x^4 + x^3 + x + 1. Note, the + // MSB get clipped off below. + parameter bit[DataWidth-1:0] ScrambleIPoly = DataWidth'(1'b1) << 4 | + DataWidth'(1'b1) << 3 | + DataWidth'(1'b1) << 1 | + DataWidth'(1'b1) << 0; + + // Read buffer metadata + typedef enum logic [1:0] { + Invalid = 2'h0, + Wip = 2'h1, + Valid = 2'h2, + Undef = 2'h3 + } rd_buf_attr_e; + + typedef struct packed { + logic [PlainDataWidth-1:0] data; + logic [BankAddrW-1:0] addr; // all address bits preserved to pick return portion + logic part; + logic [InfoTypesWidth-1:0] info_sel; + rd_buf_attr_e attr; + logic err; + } rd_buf_t; + + typedef struct packed { + logic [NumBuf-1:0] buf_sel; + logic [WordSelW-1:0] word_sel; + logic intg_ecc_en; + } rsp_fifo_entry_t; + + parameter int RspOrderFifoWidth = $bits(rsp_fifo_entry_t); + + typedef struct packed { + logic [BankAddrW-1:0] addr; + logic descramble; + logic ecc; + } rd_attr_t; + + // Flash Operations Supported + typedef enum logic [1:0] { + PhyProg, + PhyPgErase, + PhyBkErase, + PhyLastOp + } flash_phy_op_e; + + // Flash Operations Selected + typedef enum logic [1:0] { + None = 2'h0, + Host = 2'h1, + Ctrl = 2'h2 + } flash_phy_op_sel_e; + + typedef enum logic { + ScrambleOp = 1'b0, + DeScrambleOp = 1'b1 + } cipher_ops_e; + + // Connections to prim_flash + typedef struct packed { + logic rd_req; + logic prog_req; + logic prog_last; + flash_ctrl_pkg::flash_prog_e prog_type; + logic pg_erase_req; + logic bk_erase_req; + logic erase_suspend_req; + logic he; + logic [BankAddrW-1:0] addr; + flash_ctrl_pkg::flash_part_e part; + logic [InfoTypesWidth-1:0] info_sel; + logic [FullDataWidth-1:0] prog_full_data; + } flash_phy_prim_flash_req_t; + + typedef struct packed { + logic ack; + logic done; + logic [FullDataWidth-1:0] rdata; + } flash_phy_prim_flash_rsp_t; + + typedef struct packed { + logic calc_req; + logic op_req; + cipher_ops_e op_type; + logic [BankAddrW-1:0] addr; + logic [DataWidth-1:0] plain_data; + logic [DataWidth-1:0] scrambled_data; + } scramble_req_t; + + typedef struct packed { + logic calc_ack; + logic op_ack; + logic [DataWidth-1:0] mask; + logic [DataWidth-1:0] plain_data; + logic [DataWidth-1:0] scrambled_data; + } scramble_rsp_t; + +endpackage // flash_phy_pkg diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_prog.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_prog.sv new file mode 100644 index 0000000000000..fe0e622c03dbc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_prog.sv @@ -0,0 +1,390 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Prog Module +// +// This module implements the flash phy program operation +// +// The flash phy prog module is mainly responsible for packing incoming data +// transactions into appropriate flash word sizes. +// +// This is done primarily for two reasons +// - Reduce program stress on the flash +// Flash modules usually have a limit to how many times adjacent words can be programmed. +// If a programming beat is longer than a flash word, it would be best to compact those +// beats into multiples of the flash word size to improve performance and reduce +// unnecessary programmings +// +// - Observe minimum block cipher sizes for scrambling / descrambling and ECC. +// Scrambling algorithms and ECC work on a specific chunk of data. When these features +// are enabled, the phy controller needs to ensure there is enough data to satisfy that +// request. + +module flash_phy_prog import flash_phy_pkg::*; ( + input clk_i, + input rst_ni, + input prim_mubi_pkg::mubi4_t disable_i, + input req_i, + input scramble_i, + input ecc_i, + input [WordSelW-1:0] sel_i, + input [BusFullWidth-1:0] data_i, + input last_i, + input ack_i, // ack means request has been accepted by flash + input done_i, // done means requested transaction has completed + input calc_ack_i, + input scramble_ack_i, + input [DataWidth-1:0] mask_i, + input [DataWidth-1:0] scrambled_data_i, + output logic calc_req_o, + output logic scramble_req_o, + output logic req_o, + output logic last_o, // last beat of an incoming transaction + output logic ack_o, + // block data does not contain ecc / metadata portion + output logic [DataWidth-1:0] block_data_o, + output logic [FullDataWidth-1:0] data_o, + output logic fsm_err_o, + output logic intg_err_o +); + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 5 -m 11 -n 11 \ + // -s 2968771430 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: -- + // 4: -- + // 5: |||||||||||||||||||| (40.00%) + // 6: ||||||||||||||||| (34.55%) + // 7: |||||| (12.73%) + // 8: ||||| (10.91%) + // 9: (1.82%) + // 10: -- + // 11: -- + // + // Minimum Hamming distance: 5 + // Maximum Hamming distance: 9 + // Minimum Hamming weight: 2 + // Maximum Hamming weight: 8 + // + localparam int StateWidth = 11; + typedef enum logic [StateWidth-1:0] { + StIdle = 11'b11111111110, + StPrePack = 11'b00001110111, + StPackData = 11'b10100100011, + StPostPack = 11'b11010000101, + StCalcPlainEcc = 11'b01101011011, + StReqFlash = 11'b01010110010, + StWaitFlash = 11'b00100111000, + StCalcMask = 11'b00000001110, + StScrambleData = 11'b00011101001, + StCalcEcc = 11'b00111010100, + StDisabled = 11'b10001000000 + } state_e; + state_e state_d, state_q; + + typedef enum logic [1:0] { + Filler, + Actual + } data_sel_e; + + // The currently observed data beat + logic [WordSelW-1:0] idx; + logic [WordSelW-1:0] idx_sub_one; + logic pack_valid; + logic [BusWidth-1:0] pack_data; + logic align_next; + data_sel_e data_sel; + + localparam int MaxIdx = WidthMultiple - 1; + + logic [WidthMultiple-1:0][BusWidth-1:0] packed_data; + logic plain_ecc_en; + + // selects empty data or real data + assign pack_data = (data_sel == Actual) ? data_i[BusWidth-1:0] : {BusWidth{1'b1}}; + + logic data_intg_ok; + logic data_err; + + // use the tlul integrity module directly for bus integrity + // SEC_CM: MEM.BUS.INTEGRITY + tlul_data_integ_dec u_data_intg_chk ( + .data_intg_i(data_i), + .data_err_o(data_err) + ); + assign data_intg_ok = ~data_err; + + logic data_invalid_q, data_invalid_d; + // hold on integrity failure indication until reset + assign data_invalid_d = data_invalid_q | + (pack_valid & ~data_intg_ok); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + data_invalid_q <= '0; + end else begin + data_invalid_q <= data_invalid_d; + end + end + + // indication to upper layer presence of error + assign intg_err_o = data_invalid_q; + + // if integrity failure is seen, fake communication with flash + // and simply terminate + logic ack, done; + assign ack = ack_i | data_invalid_q; + assign done = done_i | data_invalid_q; + + // next idx will be aligned + assign idx_sub_one = idx - 1'b1; + assign align_next = (idx > '0) ? (idx_sub_one == sel_i) : 1'b0; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + idx <= '0; + end else if (pack_valid && idx == MaxIdx) begin + // when a flash word is packed full, return index to 0 + idx <= '0; + end else if (pack_valid) begin + // increment otherwise + idx <= idx + 1'b1; + end + end + + + // SEC_CM: PHY_PROG.FSM.SPARSE + `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, StIdle) + + // If the first beat of an incoming transaction is not aligned to word boundary (for example + // if each flash word is 4 bus words wide, and the first word to program starts at index 1), + // the fsm pre-packs the flash word with empty words until the supplied index. + // Once at the index, real data supplied from the flash controller is packed until the last + // beat of data. At the last beat of data, if it is not also aligned (index 3 in this example), + // more empty words are packed at the end to fill out the word. + // + always_comb begin + state_d = state_q; + + pack_valid = 1'b0; + data_sel = Filler; + plain_ecc_en = 1'b0; + req_o = 1'b0; + ack_o = 1'b0; + last_o = 1'b0; + calc_req_o = 1'b0; + scramble_req_o = 1'b0; + fsm_err_o = 1'b0; + + unique case (state_q) + StIdle: begin + // if first beat of a transaction is not aligned, prepack with empty bits + if (prim_mubi_pkg::mubi4_test_true_loose(disable_i)) begin + // only disable during idle state to ensure program is able to gracefully complete + // this is important as we do not want to accidentally disturb any electrical procedure + // internal to the flash macro + state_d = StDisabled; + end else if (req_i && |sel_i) begin + state_d = StPrePack; + end else if (req_i) begin + state_d = StPackData; + end + end + + StPrePack: begin + // pack until currently supplied data + pack_valid = (idx < sel_i); + if (idx == align_next) begin + state_d = StPackData; + end + end + + StPackData: begin + pack_valid = req_i; + data_sel = Actual; + + if (req_i && idx == MaxIdx) begin + // last beat of a flash word + state_d = StCalcPlainEcc; + end else if (req_i && last_i) begin + // last beat is not aligned with the last entry of flash word + state_d = StPostPack; + end else if (req_i) begin + ack_o = 1'b1; + end + end + + StPostPack: begin + // supply filler data + pack_valid = 1'b1; + data_sel = Filler; + + // finish packing remaining entries + if (idx == MaxIdx) begin + state_d = StCalcPlainEcc; + end + end + + StCalcPlainEcc: begin + plain_ecc_en = 1'b1; + state_d = scramble_i ? StCalcMask : StReqFlash; + end + + StCalcMask: begin + calc_req_o = 1'b1; + + if (calc_ack_i) begin + state_d = StScrambleData; + end + end + + StScrambleData: begin + scramble_req_o = 1'b1; + + if (scramble_ack_i) begin + state_d = StCalcEcc; + end + end + + StCalcEcc: begin + state_d = StReqFlash; + end + + StReqFlash: begin + // only request flash if data integrity was valid + req_o = ~data_invalid_q; + last_o = last_i; + + // if this is the last beat of the program burst + // - wait for done + // if this is NOT the last beat + // - ack the upstream request and accept more beats + if (last_i) begin + state_d = ack ? StWaitFlash : StReqFlash; + end else begin + ack_o = ack; + state_d = ack ? StIdle : StReqFlash; + end + end + + StWaitFlash: begin + if (done) begin + ack_o = 1'b1; + state_d = StIdle; + end + end + + StDisabled: begin + state_d = StDisabled; + end + + default: begin + fsm_err_o = 1'b1; + end + + endcase // unique case (state_q) + + end + + logic [DataWidth-1:0] mask_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + packed_data <= '0; + mask_q <= '0; + end else if (req_o && ack) begin + packed_data <= '0; + end else if (calc_req_o && calc_ack_i) begin + packed_data <= packed_data ^ mask_i; + mask_q <= mask_i; + end else if (scramble_req_o && scramble_ack_i) begin + packed_data <= scrambled_data_i[DataWidth-1:0] ^ mask_q; + end else if (pack_valid) begin + packed_data[idx] <= pack_data; + end + end + + assign block_data_o = packed_data; + + // ECC handling + localparam int PlainDataEccWidth = DataWidth + 8; + + logic [FullDataWidth-1:0] ecc_data; + logic [PlainDataEccWidth-1:0] plain_data_w_ecc; + logic [PlainIntgWidth-1:0] plain_data_ecc; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + plain_data_ecc <= '1; + end else if (plain_ecc_en) begin + plain_data_ecc <= plain_data_w_ecc[DataWidth +: PlainIntgWidth]; + end + end + + logic [PlainDataWidth-1:0] ecc_data_in; + assign ecc_data_in = {plain_data_ecc, packed_data}; + + // reliability ECC calculation + prim_secded_hamming_76_68_enc u_enc ( + .data_i(ecc_data_in), + .data_o(ecc_data) + ); + + // integrity ECC calculation + // This instance can technically be merged with the instance above, but is + // kept separate for the sake of convenience + // The plain data ecc is calculated continuously from packed data (which changes + // from packed data to masked/scrambled data based on software configuration). + // The actual plain data ECC is explicitly captured during this process when + // it is required. + prim_secded_hamming_72_64_enc u_plain_enc ( + .data_i(packed_data), + .data_o(plain_data_w_ecc) + ); + + logic unused_data; + assign unused_data = |plain_data_w_ecc; + + // pad the remaining bits with '1' if ecc is not used. + assign data_o = ecc_i ? ecc_data : {{EccWidth{1'b1}}, ecc_data_in}; + + ///////////////////////////////// + // Assertions + ///////////////////////////////// + +`ifdef INC_ASSERT + logic txn_done; + logic [15:0] done_cnt_d, done_cnt_q; + + assign txn_done = req_i && ack_o && last_i; + assign done_cnt_d = txn_done ? '0 : (done ? done_cnt_q + 16'h1 : done_cnt_q); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + done_cnt_q <= '0; + end else begin + done_cnt_q <= done_cnt_d; + end + end + + // We can only observe one done per transaction. + `ASSERT(OneDonePerTxn_A, txn_done |-> done_cnt_d == '0) + +`endif + + // Prepack state can only pack up to WidthMultiple - 1 + `ASSERT(PrePackRule_A, state_q == StPrePack && pack_valid |-> idx < MaxIdx) + + // Postpack states should never pack the first index (as it would be aligned in that case) + `ASSERT(PostPackRule_A, state_q == StPostPack && pack_valid |-> idx != '0) + + // The metadata width must always be greater than the ecc width + `ASSERT_INIT(WidthCheck_A, MetaDataWidth >= EccWidth) + +endmodule // flash_phy_prog diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd.sv new file mode 100644 index 0000000000000..cb8e55316e252 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd.sv @@ -0,0 +1,851 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Read Module +// +// This module implements the flash phy read pipeline. +// The read pipeline consists of read buffers, the actual flash read stage, the +// descrambling stage, and finally the response. +// +// Note this module backpressures the front end, but cannot handle any back end +// back pressuring at the response stage. It is thus assumed it will tell the +// upstream to stop issuing instructions, however once issued, the upstream will +// always accept the response. +// +// Support for descramble stage +// The allocate and descramble indication received at read stage are saved. +// When the read completes, depending on the 'descramble' indication saved, the +// data is either stored into FIFO (reg + skid) between read and descramble stage, +// or forwarded directly to the buffer (no de-scramble) +// +// If the storage element between read and de-scramble stages are completely full +// for any reason, then the read stage cannot start. +// +// When the read stage begins, the galois multiply portion of the de-scramble is +// also kicked off. When the galois multiply stage AND read stage completes, the +// de-scramble is then kicked off. + +module flash_phy_rd + import flash_phy_pkg::*; + import prim_mubi_pkg::mubi4_t; +( + input clk_i, + input rst_ni, + + // configuration interface from flash controller + input buf_en_i, + + // interface with arbitration unit + input req_i, + input descramble_i, + input ecc_i, + input prog_i, + input pg_erase_i, + input bk_erase_i, + input [BusBankAddrW-1:0] addr_i, + input flash_ctrl_pkg::flash_part_e part_i, + input [InfoTypesWidth-1:0] info_sel_i, + output logic rdy_o, + output logic data_valid_o, + output logic data_err_o, + output logic relbl_ecc_err_o, + output logic intg_ecc_err_o, + output logic [BusFullWidth-1:0] data_host_o, + output logic [BusFullWidth-1:0] data_ctrl_o, + output logic idle_o, // the entire read pipeline is idle + input arb_err_i, // a catastrophic arbitration error was observed + + // interface with scramble unit + output logic calc_req_o, + output logic descramble_req_o, + output logic [BankAddrW-1:0] calc_addr_o, + output logic [DataWidth-1:0] scrambled_data_o, + input calc_ack_i, + input descramble_ack_i, + input [DataWidth-1:0] mask_i, + input [DataWidth-1:0] descrambled_data_i, + + // interface to actual flash primitive + output logic req_o, + input ack_i, // request has been accepted + input done_i, // actual data return + input [FullDataWidth-1:0] data_i, + + // error status reporting + // only single bit error is shown here as multi-bit errors are + // actual data errors and reflected in-band through data_err_o + output logic ecc_single_err_o, + output logic [BusBankAddrW-1:0] ecc_addr_o, + + // fifo error + output logic fifo_err_o + ); + + ///////////////////////////////// + // Read buffers + ///////////////////////////////// + + // internal buffer enable + logic buf_en_q; + + // muxed de-scrambled and plain-data + logic [PlainDataWidth-1:0] muxed_data; + logic muxed_err; + + // muxed data valid signal that takes scrambling into consideration + logic data_valid; + + // A buffer allocate is invoked when a new transaction arrives. + // Alloc only happens if the new transaction does not match an existing entry. + logic [NumBuf-1:0] alloc; + + // A buffer update is invoked after the completion of the de-scramble stage. + // This updates the buffer that was allocated when a new transaction was initiated. + logic [NumBuf-1:0] update; + + rd_buf_t read_buf [NumBuf]; + logic [NumBuf-1:0] buf_invalid; + logic [NumBuf-1:0] buf_valid; + logic [NumBuf-1:0] buf_wip; + + // The new transaction matches an already allocated buffer. + // The buffer may be valid or work in progress. + logic [NumBuf-1:0] buf_match; + logic no_match; + + // This net tracks which buffers have a dependency to items currently in the rsp_order_fifo + logic [NumBuf-1:0] buf_dependency; + + // all buffers have a current dependency to an entry in rsp_order_fifo + logic all_buf_dependency; + + // There is a stateful operation aimed at valid buffer, that buffer must be flushed + logic [NumBuf-1:0] data_hazard; + + // The next buffer allocated is determined in the following way: + // If there is an invalid buffer, use that lowest one + // If there are no invalid buffers, pick a valid buffer + // Work in progress buffer is NEVER replaced. + // There should only be one work in progress buffer at a time + logic [NumBuf-1:0] buf_invalid_alloc; + logic [NumBuf-1:0] buf_valid_alloc; + logic [NumBuf-1:0] buf_alloc; + + // flash word address + logic [BankAddrW-1:0] flash_word_addr; + assign flash_word_addr = addr_i[BusBankAddrW-1:LsbAddrBit]; + + for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_states + assign buf_valid[i] = read_buf[i].attr == Valid; + assign buf_wip[i] = read_buf[i].attr == Wip; + + // if a buffer is valid and contains an error, it should be considered + // invalid as long as there are no pending responses already waiting + // on that buffer. + assign buf_invalid[i] = (read_buf[i].attr == Invalid) | + (read_buf[i].attr == Valid & + read_buf[i].err & + ~buf_dependency[i]); + end + + assign buf_invalid_alloc[0] = buf_invalid[0]; + for (genvar i = 1; i < NumBuf; i++) begin: gen_inv_alloc_bufs + assign buf_invalid_alloc[i] = buf_invalid[i] & ~|buf_invalid[i-1:0]; + end + + // a prim arbiter is used to somewhat fairly select among the valid buffers + logic [1:0] dummy_data [NumBuf]; + for (genvar i = 0; i < NumBuf; i++) begin: gen_dummy + assign dummy_data[i] = '0; + end + + prim_arbiter_tree #( + .N(NumBuf), + .DW(2), + .EnDataPort(1'b0) + ) u_valid_random ( + .clk_i, + .rst_ni, + .req_chk_i(1'b0), // Valid is allowed to drop without ready. + // If there is an invalid buffer, always allocate from that one first + // If all buffers have a dependency to an in-flight transaction, do not + // allocate and wait for the dependencies to end. + // If none of the above are true, THEN pick a buffer from the current valid + // buffers that DO NOT have an ongoing dependency. + .req_i(|buf_invalid_alloc | all_buf_dependency ? '0 : buf_valid & ~buf_dependency), + .data_i(dummy_data), + .gnt_o(buf_valid_alloc), + .idx_o(), + .valid_o(), + .data_o(), + .ready_i(req_o & ack_i & no_match) + ); + + // which buffer to allocate upon a new transaction + assign buf_alloc = |buf_invalid_alloc ? buf_invalid_alloc : buf_valid_alloc; + + // do not attempt to generate match unless the transaction is relevant + for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_match + logic part_match; + logic info_sel_match; + + assign part_match = read_buf[i].part == part_i; + assign info_sel_match = read_buf[i].info_sel == info_sel_i; + + assign buf_match[i] = req_i & + buf_en_q & + (buf_valid[i] | buf_wip[i]) & + (read_buf[i].addr == flash_word_addr) & + ~read_buf[i].err & + part_match & + info_sel_match; + + // A data hazard should never happen to a wip buffer because it implies + // that a read is in progress, so a hazard operation cannot start. + // If bank erase, all buffers must be flushed. + // If page erase, only if the buffer lands in the same page. + // If program, only if it's the same flash word. + logic word_addr_match; + logic page_addr_match; + + assign word_addr_match = (read_buf[i].addr == flash_word_addr) & + part_match & + info_sel_match; + + // the read buffer address in on flash word boundary + // while the incoming address in on the bus word boundary + assign page_addr_match = (read_buf[i].addr[WordW +: PageW] == addr_i[BusWordW +: PageW]) & + part_match & + info_sel_match; + + assign data_hazard[i] = buf_valid[i] & + (bk_erase_i | + (prog_i & word_addr_match) | + (pg_erase_i & page_addr_match)); + + end + + assign no_match = ~|buf_match; + + // if new request does not match anything, allocate + assign alloc = no_match ? {NumBuf{req_i & buf_en_q}} & buf_alloc : '0; + + // read buffers + // allocate sets state to Wip + // update sets state to valid + // wipe sets state to invalid - this comes from prog + for (genvar i = 0; i < NumBuf; i++) begin: gen_bufs + flash_phy_rd_buffers u_rd_buf ( + .clk_i, + .rst_ni, + .en_i(buf_en_q), + .alloc_i(rdy_o & alloc[i]), + .update_i(update[i]), + .err_i(muxed_err), + .wipe_i(data_hazard[i]), + .addr_i(flash_word_addr), + .part_i(part_i), + .info_sel_i(info_sel_i), + .data_i(muxed_data), + .out_o(read_buf[i]) + ); + end + + // The buffer enable is allowed to change when the entire read pipeline is idle + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + buf_en_q <= 1'b0; + end else if (idle_o) begin + buf_en_q <= buf_en_i; + end + end + + ///////////////////////////////// + // Flash read stage + ///////////////////////////////// + + // Flash read stage determines if the transactions are accepted. + // + // The response fifo is written to when a transaction initiates a flash read OR when a match + // is hit. The information written is just the allocated buffer that would have satisfied the + // transaction, as well as bits that indicate which part of the buffer is the right return data + // + // This allows a hit transaction to match in-order, and unblock later transactions to begin + // reading from the flash primitive + + rsp_fifo_entry_t rsp_fifo_wdata, rsp_fifo_rdata; + logic rsp_fifo_rdy; + logic rsp_fifo_vld; + + // saved attributes on flash read + logic [NumBuf-1:0] alloc_q; + rd_attr_t rd_attrs; + + // read complete + // since done is broadcast to all the modules, need to know we are actually active + logic rd_start; + logic rd_busy; + logic rd_done; + + assign rd_start = req_o & ack_i; + assign rd_done = rd_busy & done_i; + + // scramble stage ready + logic scramble_stage_rdy; + + // mask calculation done + logic calc_req_done; + + // if buffer allocated, that is the return source + // if buffer matched, that is the return source + assign rsp_fifo_wdata.buf_sel = |alloc ? buf_alloc : buf_match; + + logic rsp_order_fifo_wr; + assign rsp_order_fifo_wr = req_i && rdy_o; + + logic rsp_order_fifo_rd; + assign rsp_order_fifo_rd = rsp_fifo_vld & data_valid_o; + + flash_phy_rd_buf_dep u_rd_buf_dep ( + .clk_i, + .rst_ni, + .en_i(buf_en_q), + .fifo_wr_i(rsp_order_fifo_wr), + .fifo_rd_i(rsp_order_fifo_rd), + .wr_buf_i(rsp_fifo_wdata.buf_sel), + .rd_buf_i(rsp_fifo_rdata.buf_sel), + .dependency_o(buf_dependency), + .all_dependency_o(all_buf_dependency) + ); + + // If width is the same, word_sel is unused + if (WidthMultiple == 1) begin : gen_single_word_sel + assign rsp_fifo_wdata.word_sel = '0; + end else begin : gen_word_sel + assign rsp_fifo_wdata.word_sel = addr_i[0 +: LsbAddrBit]; + end + + // store the ecc configuration for this transaction until + // response is ready to be sent. + assign rsp_fifo_wdata.intg_ecc_en = ecc_i; + + // response order FIFO + logic rsp_order_fifo_err; + prim_fifo_sync #( + .Width (RspOrderFifoWidth), + .Pass (0), + .Depth (RspOrderDepth), + .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN + ) u_rsp_order_fifo ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(rsp_order_fifo_wr), + .wready_o(rsp_fifo_rdy), + .wdata_i (rsp_fifo_wdata), + .depth_o (), + .full_o (), + .rvalid_o(rsp_fifo_vld), + .rready_i(data_valid_o), // pop when a match has been found + .rdata_o (rsp_fifo_rdata), + .err_o (rsp_order_fifo_err) + ); + + // Consider converting this to a FIFO for better matching + // The rd_busy flag is effectively a "full" flag anyways of a single + // entry. + logic flash_rdy; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + alloc_q <= '0; + rd_attrs <= '0; + rd_busy <= '0; + end else if (rd_start) begin + rd_busy <= 1'b1; + alloc_q <= alloc; + rd_attrs.addr <= addr_i[BusBankAddrW-1:LsbAddrBit]; + rd_attrs.descramble <= descramble_i; + rd_attrs.ecc <= ecc_i; + + end else if (rd_done) begin + rd_busy <= 1'b0; + end + end + + // flash is ready to accept another transaction + assign flash_rdy = ~rd_busy | rd_done; + + // read stages are ready when both the response fifo and the + // data / mask fifos have space for new entries + logic rd_stages_rdy; + assign rd_stages_rdy = rsp_fifo_rdy & scramble_stage_rdy; + + // When buffer enable changes, we want to hold off new requests + // until the request is absorbed. buf_en_q is allowed to change + // only when the entire read pipeline is idle, however, during that + // same cycle there could be a new incoming request. + // + // We back pressure here instead of waiting for a period of idle + no + // request because it potentially means a storm of accesses could + // prevent the buffer enable from taking effect. + logic no_buf_en_change; + assign no_buf_en_change = (buf_en_q == buf_en_i); + + // If no buffers matched, accept only if flash is ready and there is space + // If buffer is matched, accept as long as there is space in the rsp fifo + // If all buffers are currently allocated or have a dependency, wait until + // at least 1 dependency has cleared. + assign rdy_o = (no_match ? ack_i & flash_rdy & rd_stages_rdy : rd_stages_rdy) & + ~all_buf_dependency & no_buf_en_change & + // If the current read requires descrambling, wait for the + // mask calculation to finish before accepting the next request. + (calc_req_o ? calc_req_done : 1'b1); + + // issue a transaction to flash only if there is space in read stages, + // there is no buffer match and flash is not currently busy. + assign req_o = req_i & no_buf_en_change & flash_rdy & rd_stages_rdy & no_match & + // If the current read requires descrambling, wait for the + // mask calculation to finish before accepting the next request. + (calc_req_o ? calc_req_done : 1'b1); + + ///////////////////////////////// + // Handling Reliability ECC + ///////////////////////////////// + + // only uncorrectable errors are passed on to the fabric + logic data_err; + + // scrambled data must pass through ECC first + logic valid_ecc; + logic ecc_multi_err; + logic ecc_single_err; + logic [PlainDataWidth-1:0] data_ecc_chk; + logic [PlainDataWidth-1:0] data_int; + logic data_erased; + + // this ECC check is for reliability ECC + assign valid_ecc = rd_done && rd_attrs.ecc; + + // When all bits are 1, the data has been erased + // This check is only valid when read data returns. + assign data_erased = rd_done & (data_i == {FullDataWidth{1'b1}}); + + prim_secded_hamming_76_68_dec u_dec ( + .data_i(data_i), + .data_o(data_ecc_chk), + .syndrome_o(), + .err_o({ecc_multi_err, ecc_single_err}) + ); + + // send out error indication when ecc is enabled + assign data_err = valid_ecc & ecc_multi_err; + + // reliability ECC errors cause both in-band and out-of-band errors + assign relbl_ecc_err_o = data_err; + + // If there is a detected multi-bit error or a single bit error, always return the + // ECC corrected result (even though it is possibly wrong). + // There is no data error of any kind (specifically when multi_err is disabled), just + // return the raw data so that it can be debugged. + assign data_int = data_err | ecc_single_err_o ? + data_ecc_chk : + data_i[PlainDataWidth-1:0]; + + // send out error indication when ecc is enabled + assign ecc_single_err_o = valid_ecc & ecc_single_err; + + // ecc address return is always the full flash word + assign ecc_addr_o = {rd_attrs.addr, {LsbAddrBit{1'b0}}}; + + ///////////////////////////////// + // De-scrambling stage + ///////////////////////////////// + + // Even on ECC error, progress through the stage normally + + logic fifo_data_ready; + logic fifo_data_valid; + logic fifo_forward_pop; + logic rd_and_mask_fifo_pop; + logic mask_valid; + logic [PlainDataWidth-1:0] fifo_data; + logic [DataWidth-1:0] mask; + logic addr_xor_fifo_rdy; + logic [BankAddrW-1:0] fifo_addr_xor; + logic data_fifo_rdy; + logic mask_fifo_rdy; + logic descram; + logic dropmsk; + logic forward; + logic descram_q; + logic dropmsk_q; + logic forward_q; + logic hint_forward; + logic hint_dropmsk; + logic hint_descram; + logic data_err_q; + logic [NumBuf-1:0] alloc_q2; + logic [1:0] unused_rd_depth, unused_mask_depth, unused_addr_xor_depth; + + assign scramble_stage_rdy = data_fifo_rdy & mask_fifo_rdy & addr_xor_fifo_rdy; + + // descramble is only required if the location is scramble enabled AND it is not erased. + assign descram = rd_done & rd_attrs.descramble & ~data_erased; + + // If the location is scramble enabled but has been erased, we'll need to drop the computed mask. + assign dropmsk = rd_done & rd_attrs.descramble & data_erased; + + // data is forwarded whenever it does not require descrambling and there are no entries in the + // FIFO to ensure the current read cannot run ahead of the descramble. + assign forward = rd_done & ~descram & ~fifo_data_valid; + + assign hint_descram = fifo_data_valid & descram_q; + assign hint_dropmsk = fifo_data_valid & dropmsk_q; + assign hint_forward = fifo_data_valid & forward_q; + + // Data is consumed when: + // 1. If the location is scramble enabled: + // a) When descrambling completes. + // b) As soon as the mask computation finishes, in case the mask is to be dropped. + // 2. If the location is not scramble enabled: + // - As soon as the data is ready from the FIFO. For the forwarding case, see below. + assign fifo_data_ready = hint_descram ? descramble_req_o & descramble_ack_i : + hint_dropmsk ? mask_valid : fifo_data_valid; + + // In the case of forwarding, the storage FIFOs are bypassed but still pushed. Once the forwarded + // entries arrive at the output of the read FIFO, we need to drop them. If a mask has been + // computed that is not used (e.g. because of erasing a location that is scramble enabled), wait + // for the mask computation to be done and then drop the forwarded data together with the + // corresponding mask. + assign fifo_forward_pop = hint_forward & (hint_dropmsk ? mask_valid : 1'b1); + + assign rd_and_mask_fifo_pop = fifo_data_ready | fifo_forward_pop; + + // See comment above on how FIFO popping can be improved in the future + logic rd_stage_fifo_err; + prim_fifo_sync #( + .Width (PlainDataWidth + 4 + NumBuf), + .Pass (0), + .Depth (2), + .OutputZeroIfEmpty (1), + .Secure (1'b1) // SEC_CM: FIFO.CTR.REDUN + ) u_rd_storage ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(rd_done), + .wready_o(data_fifo_rdy), + .wdata_i ({alloc_q, descram, dropmsk, forward, data_err, data_int}), + .depth_o (unused_rd_depth), + .full_o (), + .rvalid_o(fifo_data_valid), + .rready_i(rd_and_mask_fifo_pop), + .rdata_o ({alloc_q2, descram_q, dropmsk_q, forward_q, data_err_q, fifo_data}), + .err_o (rd_stage_fifo_err) + ); + + // storage for mask calculations + prim_fifo_sync #( + .Width (DataWidth), + .Pass (0), + .Depth (2), + .OutputZeroIfEmpty (1) + ) u_mask_storage ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(calc_req_done), + .wready_o(mask_fifo_rdy), + .wdata_i (mask_i), + .depth_o (unused_mask_depth), + .full_o (), + .rvalid_o(mask_valid), + .rready_i(rd_and_mask_fifo_pop), + .rdata_o (mask), + .err_o () + ); + + prim_fifo_sync #( + .Width (BankAddrW), + .Pass (0), + .Depth (RspOrderDepth), + .OutputZeroIfEmpty (1) + ) u_addr_xor_storage ( + .clk_i, + .rst_ni, + .clr_i (1'b0), + .wvalid_i(rsp_order_fifo_wr), + .wready_o(addr_xor_fifo_rdy), + .wdata_i (flash_word_addr), + .depth_o (unused_addr_xor_depth), + .full_o (), + .rvalid_o(), + .rready_i(data_valid_o), + .rdata_o (fifo_addr_xor), + .err_o () + ); + + // generate the mask calculation request + // mask calculation is done in parallel to the read stage + // calc_req_o is done after req_o is accepted so that most of the + // cycle can be allocated to mask calculation logic. req_o, + // unlike calc_req_o, asserts the same cycle the transaction is + // received, so much of the timing may have already been lost to + // transaction routing. + logic calc_req_start; + assign calc_req_start = req_o & ack_i & descramble_i; + assign calc_req_done = calc_req_o & calc_ack_i; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + calc_req_o <= '0; + end else if (calc_req_start) begin + calc_req_o <= 1'b1; + end else if (calc_req_done) begin + calc_req_o <= 1'b0; + end + end + + // operand to gf_mult + assign calc_addr_o = rd_attrs.addr; + + // generate the descramble request whenever both stages are available + // and there is a need to descramble + assign descramble_req_o = fifo_data_valid & mask_valid & hint_descram; + + // scrambled data to de-scramble + assign scrambled_data_o = fifo_data[DataWidth-1:0] ^ mask; + + // muxed responses + // When "forward" is true, there is nothing ahead in the pipeline, directly feed data + // and error forward. + // When "forward" is not true, take the output from the descramble stage, which is + // dependent on the scramble hint. + assign muxed_data = forward ? data_int : + hint_descram ? {fifo_data[PlainDataWidth-1 -: PlainIntgWidth], + descrambled_data_i ^ mask} : + fifo_data; + assign muxed_err = forward ? data_err : + ~hint_forward ? data_err_q : '0; + + // muxed data valid + // if no de-scramble required, return data on read complete + // if data is all empty (erased), also return data on read complete + // if descramble is required, return data when descrambler finishes + // if descramble is not required, but there are transactions ahead, return from fifo when ready + assign data_valid = forward | ~hint_forward & fifo_data_ready; + + + ///////////////////////////////// + // Response + ///////////////////////////////// + + logic flash_rsp_match; + logic [NumBuf-1:0] buf_rsp_match; + logic [PlainDataWidth-1:0] buf_rsp_data; + logic [BankAddrW-1:0] buf_addr_xor; + logic buf_rsp_err; + + + // update buffers + // When forwarding, update entry stored in alloc_q + // When de-scrambling however, the contents of alloc_q may have already updated to the next read, + // so a different pointer is used. + assign update = forward ? alloc_q : + ~hint_forward & fifo_data_ready ? alloc_q2 : '0; + + // match in flash response when allocated buffer is the same as top of response fifo + // if read buffers are not enabled, do not check buffer selection + assign flash_rsp_match = rsp_fifo_vld & data_valid & + (~buf_en_q | rsp_fifo_rdata.buf_sel == update); + + // match in buf response when there is a valid buffer that is the same as top of response fifo + for (genvar i = 0; i < NumBuf; i++) begin: gen_buf_rsp_match + assign buf_rsp_match[i] = buf_en_q & rsp_fifo_vld & + (rsp_fifo_rdata.buf_sel[i] & buf_valid[i]); + end + + // select among the buffers + always_comb begin + buf_rsp_data = muxed_data; + buf_rsp_err = '0; + buf_addr_xor = '0; + for (int i = 0; i < NumBuf; i++) begin + if (buf_rsp_match[i]) begin + buf_rsp_data = read_buf[i].data; + buf_addr_xor = read_buf[i].addr; + buf_rsp_err = buf_rsp_err | read_buf[i].err; + end + end + end + + logic [PlainDataWidth-1:0] data_out_muxed; + assign data_out_muxed = |buf_rsp_match ? buf_rsp_data : muxed_data; + + logic [BusFullWidth-1:0] data_out_intg; + if (WidthMultiple == 1) begin : gen_width_one_rd + // When multiple is 1, just pass the read through directly + logic unused_word_sel; + + // use the tlul integrity module directly for bus integrity + // SEC_CM: MEM.BUS.INTEGRITY + tlul_data_integ_enc u_bus_intg ( + .data_i(data_out_muxed[DataWidth-1:0]), + .data_intg_o(data_out_intg) + ); + + assign unused_word_sel = rsp_fifo_rdata.word_sel; + + end else begin : gen_rd + // Re-arrange data into packed array to pick the correct one + logic [WidthMultiple-1:0][BusWidth-1:0] bus_words_packed; + logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg; + logic [WidthMultiple-1:0][BusFullWidth-1:0] bus_words_packed_intg_buf; + assign bus_words_packed = data_out_muxed[DataWidth-1:0]; + + for (genvar i = 0; i < WidthMultiple; i++) begin: gen_bus_words_intg + // use the tlul integrity module directly for bus integrity + // SEC_CM: MEM.BUS.INTEGRITY + tlul_data_integ_enc u_bus_intg ( + .data_i(bus_words_packed[i]), + .data_intg_o(bus_words_packed_intg[i]) + ); + + // This primitive is used to place a size-only constraint on the + // buffers to act as a synthesis optimization barrier. + prim_buf #( + .Width(BusFullWidth) + ) u_prim_buf_intg ( + .in_i(bus_words_packed_intg[i]), + .out_o(bus_words_packed_intg_buf[i]) + ); + end + // Mux based on selected word. + assign data_out_intg = bus_words_packed_intg_buf[rsp_fifo_rdata.word_sel]; + + end + + // On a data_err_o, send back '1 with data integrity tag on top of this data. + logic [BusFullWidth-1:0] inv_data_integ; + tlul_data_integ_enc u_bus_inv_data_intg ( + .data_i({BusWidth{1'b1}}), + .data_intg_o(inv_data_integ) + ); + + logic [BusFullWidth-1:0] data_out_pre_xor; + assign data_out_pre_xor = data_err_o ? inv_data_integ : data_out_intg; + + assign data_ctrl_o = data_out_pre_xor; + + logic [BusBankAddrW-1:0] addr_xor_muxed; + logic [BusBankAddrW-1:0] fifo_addr_xor_muxed; + logic [BusBankAddrW-1:0] buf_addr_xor_muxed; + + assign fifo_addr_xor_muxed = {fifo_addr_xor, rsp_fifo_rdata.word_sel}; + assign buf_addr_xor_muxed = {buf_addr_xor, rsp_fifo_rdata.word_sel}; + + assign addr_xor_muxed = |buf_rsp_match ? buf_addr_xor_muxed : fifo_addr_xor_muxed; + + logic [BusWidth-1:0] data_out_xor; + logic [BusWidth-1:0] data_out_xor_buf; + assign data_out_xor = + data_out_pre_xor[BusWidth-1:0] ^ {{(BusWidth-BusBankAddrW){1'b0}}, addr_xor_muxed}; + + // Buffer to ensure that synthesis tool does not optimize the XOR. + prim_buf #( + .Width(BusWidth) + ) u_prim_buf_data_xor_out ( + .in_i(data_out_xor), + .out_o(data_out_xor_buf) + ); + + assign data_host_o = {data_out_pre_xor[BusFullWidth-1:BusWidth], data_out_xor_buf}; + + // add plaintext decoding here + // plaintext error + logic intg_err_pre, intg_err; + logic [DataWidth-1:0] unused_data; + logic [3:0] unused_intg; + logic [3:0] truncated_intg; + + prim_secded_hamming_72_64_enc u_plain_enc ( + .data_i(data_out_muxed[DataWidth-1:0]), + .data_o({unused_intg, truncated_intg, unused_data}) + ); + assign intg_err_pre = rsp_fifo_rdata.intg_ecc_en ? + truncated_intg != data_out_muxed[DataWidth +: PlainIntgWidth] : + '0; + + prim_sec_anchor_buf #( + .Width(1) + ) u_intg_buf ( + .in_i(intg_err_pre), + .out_o(intg_err) + ); + + // whenever the response is coming from the buffer, the error is never set + assign data_valid_o = flash_rsp_match | (|buf_rsp_match); + + // integrity and reliability ECC errors always cause in band errors + assign data_err_o = data_valid_o & (muxed_err | intg_err | (|buf_rsp_match & buf_rsp_err)) | + arb_err_i; + + // integrity ECC error can also cause out of band alert + assign intg_ecc_err_o = data_valid_o & intg_err; + + // the entire read pipeline is idle when there are no responses to return and no + assign idle_o = ~rsp_fifo_vld; + + // if any fifo shows an integrity error + assign fifo_err_o = |{rsp_order_fifo_err, rd_stage_fifo_err}; + + ///////////////////////////////// + // Assertions + ///////////////////////////////// + + // The buffers are flip flop based, do not allow too many of them + `ASSERT_INIT(MaxBufs_A, NumBuf <= 8) + + // match should happen only to 1 buffer + `ASSERT(OneHotMatch_A, $onehot0(buf_match)) + + // allocate should happen only to 1 buffer at time + `ASSERT(OneHotAlloc_A, $onehot0(alloc)) + + // update should happen only to 1 buffer at time + `ASSERT(OneHotUpdate_A, $onehot0(update)) + + // buffer response match should happen only to 1 buffer at time + `ASSERT(OneHotRspMatch_A, $onehot0(buf_rsp_match)) + + // alloc and update should be mutually exclusive for a buffer + `ASSERT(ExclusiveOps_A, (alloc & update) == 0 ) + + // valid and wip are mutually exclusive + `ASSERT(ExclusiveState_A, (buf_valid & buf_wip) == 0) + + // data_hazard and wip should be mutually exclusive + `ASSERT(ExclusiveProgHazard_A, (data_hazard & buf_wip) == 0) + + // unless the pipeline is idle, we should not have non-read transactions + `ASSERT(IdleCheck_A, !idle_o |-> {prog_i,pg_erase_i,bk_erase_i} == '0) + + // Whenever forward is true, hint_descram should always be 0 + `ASSERT(ForwardCheck_A, forward |-> hint_descram == '0) + + // Whenever response is coming from buffer, ecc error cannot be set + `ASSERT(BufferMatchEcc_A, |buf_rsp_match |-> muxed_err == '0) + + // The read storage depth and mask depth should always be the same after popping + //`ASSERT(FifoSameDepth_A, rd_and_mask_fifo_pop |=> unused_rd_depth == unused_mask_depth) + + ///////////////////////////////// + // Functional coverage points to add + ///////////////////////////////// + + // exercise both flash_read and de-scramble stages at the same time + // - make sure accesses can be consecutive or random + // exercise back to back transactions, and transactions with varying delays + // exercise data hazard where erase / program requires buffer eviction + +endmodule // flash_phy_core diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buf_dep.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buf_dep.sv new file mode 100644 index 0000000000000..736f840c87554 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buf_dep.sv @@ -0,0 +1,128 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Read Buffers Dependency +// +// This module handles the dependency between response order FIFO +// and the buffers. +// Basically, it ensures that if an item queued up in the response +// FIFO is waiting for a specific buffer, that buffer is not de-allocated +// to serve a new request. +// + +module flash_phy_rd_buf_dep import flash_phy_pkg::*;( + input clk_i, + input rst_ni, + input en_i, + input fifo_wr_i, + input fifo_rd_i, + input [NumBuf-1:0] wr_buf_i, + input [NumBuf-1:0] rd_buf_i, + output logic [NumBuf-1:0] dependency_o, + output logic all_dependency_o +); + + // The following logic determines the dependency between entries in the read buffer + // with items currently queued up for response. + localparam int NumBufWidth = $clog2(NumBuf); + + // also need to add an assertion to check for overflows + localparam int BufDepCntWidth = $clog2(RspOrderDepth + 1); + logic [NumBuf-1:0][BufDepCntWidth-1:0] buf_dependency_cnt; + + // The logic below can be more simplified in an always_comb loop, + // but the `i` assignment causes some lint tools to be mildly unhappy. + // This separarate creation seems to be more tool friendly. + logic [NumBuf-1:0][NumBufWidth-1:0] buf_mux_cnt; + for(genvar i = 0; i < NumBuf; i++) begin : gen_cnt_assign + assign buf_mux_cnt[i] = i; + end + + // the dep buf select needs to be different between increment and decrement + // When incrementing, we are looking at the wdata of the rsp_order_fifo + // When decrementing, we are looking at the rdata of the rsp_order_fifo + logic [NumBufWidth-1:0] incr_buf_sel; + logic [NumBufWidth-1:0] decr_buf_sel; + always_comb begin + incr_buf_sel = '0; + decr_buf_sel = '0; + for (int unsigned i = 0; i < NumBuf; i++) begin + if (wr_buf_i[i]) begin + incr_buf_sel = buf_mux_cnt[i]; + end + if (rd_buf_i[i]) begin + decr_buf_sel = buf_mux_cnt[i]; + end + end + end // always_comb + + logic [BufDepCntWidth-1:0] curr_incr_cnt, curr_decr_cnt; + assign curr_incr_cnt = buf_dependency_cnt[incr_buf_sel]; + assign curr_decr_cnt = buf_dependency_cnt[decr_buf_sel]; + + logic cnt_incr, cnt_decr; + assign cnt_incr = en_i & fifo_wr_i & (curr_incr_cnt < RspOrderDepth); + assign cnt_decr = en_i & fifo_rd_i & (curr_decr_cnt > '0); + + //assign cnt_decr = fifo_rd_i & (rsp_fifo_vld & data_valid_o) & (curr_decr_cnt > '0); + + logic fin_cnt_incr, fin_cnt_decr; + assign fin_cnt_incr = (incr_buf_sel == decr_buf_sel) ? cnt_incr && !cnt_decr : cnt_incr; + assign fin_cnt_decr = (incr_buf_sel == decr_buf_sel) ? !cnt_incr && cnt_decr : cnt_decr; + + // This tells us which buffer currently has a dependency to an item in the rsp_order_fifo + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + buf_dependency_cnt <= '0; + end else begin + if (fin_cnt_incr) begin + buf_dependency_cnt[incr_buf_sel] <= curr_incr_cnt + 1'b1; + end + if (fin_cnt_decr) begin + buf_dependency_cnt[decr_buf_sel] <= curr_decr_cnt - 1'b1; + end + end + end + + // per buffer dependency determination + always_comb begin + dependency_o = '0; + for (int i = 0; i < NumBuf; i++) begin + dependency_o[i] = |buf_dependency_cnt[i]; + end + end + + // all buffer entries currently have a dependency + assign all_dependency_o = &dependency_o; + + + // If there are more buffers than there are number of response fifo entries, we an never have + // a fully dependent condition + `ASSERT(BufferDepRsp_A, NumBuf > RspOrderDepth |-> ~all_dependency_o) + + // We should never attempt to increment when at max value + `ASSERT(BufferIncrOverFlow_A, en_i & fifo_wr_i |-> curr_incr_cnt < RspOrderDepth) + + // We should never attempt to decrement when at min value + `ASSERT(BufferDecrUnderRun_A, en_i & fifo_rd_i |-> (curr_decr_cnt > '0)) + + // The total number of dependent buffers cannot never exceed the size of response queue + `ifdef INC_ASSERT + //VCS coverage off + // pragma coverage off + logic [31:0] assert_cnt; + always_comb begin + assert_cnt = '0; + for (int unsigned i = 0; i < NumBuf; i++) begin + assert_cnt = assert_cnt + dependency_o[i]; + end + end + //VCS coverage on + // pragma coverage on + + `ASSERT(DepBufferRspOrder_A, fifo_wr_i |=> assert_cnt <= RspOrderDepth) + `endif + + +endmodule // flash_phy_rd_buf_dep diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buffers.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buffers.sv new file mode 100644 index 0000000000000..7052b240c63f3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_rd_buffers.sv @@ -0,0 +1,70 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Read Buffers +// +// This module implements the read buffers +// These buffers are straightforward flip flop storage. +// There are 3 inputs, alloc, upate and wipe. +// +// Alloc happens when a buffer is allocated, the state transitions to WIP. +// +// Update happens when a buffer has already been allocated, and is now being updated with data, the +// state transitions to VALID. +// +// Wipe happens when a buffer is wiped due to a program being issued to the same location, the +// state transitions to INVALID +// +// Basically...this is a tag ram + data ram combined into one +// + +module flash_phy_rd_buffers import flash_phy_pkg::*; ( + input clk_i, + input rst_ni, + input en_i, + input alloc_i, + input update_i, + input err_i, + input wipe_i, + input [BankAddrW-1:0] addr_i, + input part_i, + input [InfoTypesWidth-1:0] info_sel_i, + input [PlainDataWidth-1:0] data_i, + output rd_buf_t out_o +); + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + out_o.data <= '0; + out_o.addr <= '0; + out_o.part <= flash_ctrl_pkg::FlashPartData; + out_o.info_sel <= '0; + out_o.attr <= Invalid; + out_o.err <= '0; + end else if (!en_i && out_o.attr != Invalid) begin + out_o.attr <= Invalid; + out_o.err <= '0; + end else if (wipe_i && en_i) begin + out_o.attr <= Invalid; + out_o.err <= '0; + end else if (alloc_i && en_i) begin + out_o.addr <= addr_i; + out_o.part <= part_i; + out_o.info_sel <= info_sel_i; + out_o.attr <= Wip; + out_o.err <= '0; + end else if (update_i && en_i) begin + out_o.data <= data_i; + out_o.attr <= Valid; + out_o.err <= err_i; + end + end + + // If a buffer receives an update command, it MUST be work in progress + `ASSERT(UpdateCheck_A, update_i & en_i |-> out_o.attr == Wip) + + // If a buffer receives an allocate command, it MUST NOT be work in progress + `ASSERT(AllocCheck_A, alloc_i & en_i |-> out_o.attr != Wip) + +endmodule // flash_phy_rd_buffers diff --git a/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_scramble.sv b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_scramble.sv new file mode 100644 index 0000000000000..3ea297c5d56bc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/flash_ctrl/rtl/flash_phy_scramble.sv @@ -0,0 +1,239 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Flash Phy Scramble Module +// +// This module implements the flash scramble / de-scramble operation +// This operation is actually XEX. However the components are broken +// in two and separately manipulated by the program and read pipelines. +// + +module flash_phy_scramble import flash_phy_pkg::*; #( + parameter bit SecScrambleEn = 1'b1 +) ( + input clk_i, + input rst_ni, + input disable_i, + input [KeySize-1:0] addr_key_i, + input [KeySize-1:0] data_key_i, + input [KeySize-1:0] rand_addr_key_i, + input [KeySize-1:0] rand_data_key_i, + input scramble_req_t [NumBanks-1:0] scramble_req_i, + output scramble_rsp_t [NumBanks-1:0] scramble_rsp_o, + output logic arb_err_o +); + + /////////////////////////// + // input arbitration logic + /////////////////////////// + + localparam int OpDataWidth = 2*DataWidth + $bits(cipher_ops_e); + logic calc_req, calc_ack, op_req, op_ack; + logic [NumBanks-1:0] calc_req_banks, calc_ack_banks, op_req_banks, op_ack_banks; + logic [BankAddrW-1:0] calc_addr_in_banks[NumBanks]; + logic [OpDataWidth-1:0] op_data_in_banks[NumBanks]; + logic [BankAddrW-1:0] calc_addr_in; + logic [DataWidth-1:0] calc_mask; + logic [OpDataWidth-1:0] op_data_in; + cipher_ops_e op_type; + logic [DataWidth-1:0] plain_data_in, plain_data_out, scrambled_data_in, scrambled_data_out; + for (genvar k = 0; k < NumBanks; k++) begin : gen_scramble_assign + // Inputs for GF mult + assign calc_req_banks[k] = scramble_req_i[k].calc_req; + assign calc_addr_in_banks[k] = scramble_req_i[k].addr; + // Outputs for GF mult + assign scramble_rsp_o[k].calc_ack = calc_ack_banks[k]; + assign scramble_rsp_o[k].mask = calc_mask; + + + // Inputs for scrambling primitive + assign op_req_banks[k] = scramble_req_i[k].op_req; + assign op_data_in_banks[k] = {scramble_req_i[k].op_type, + scramble_req_i[k].plain_data, + scramble_req_i[k].scrambled_data}; + // Outputs for scrambling primitive + assign scramble_rsp_o[k].op_ack = op_ack_banks[k]; + assign scramble_rsp_o[k].plain_data = plain_data_out; + assign scramble_rsp_o[k].scrambled_data = scrambled_data_out; + end + + // SEC_CM: PHY_ARBITER.CTRL.REDUN + logic [NumBanks-1:0] local_err; + prim_arbiter_tree_dup #( + .N(NumBanks), + .DW(BankAddrW), + .EnDataPort(1) + ) u_prim_arbiter_tree_calc ( + .clk_i, + .rst_ni, + .req_chk_i(1'b1), + .req_i (calc_req_banks), + .data_i (calc_addr_in_banks), + .gnt_o (calc_ack_banks), + .idx_o (), + .valid_o (calc_req), + .data_o (calc_addr_in), + .ready_i (calc_ack), + .err_o (local_err[0]) + ); + + // SEC_CM: PHY_ARBITER.CTRL.REDUN + prim_arbiter_tree_dup #( + .N(NumBanks), + .DW(OpDataWidth), + .EnDataPort(1) + ) u_prim_arbiter_tree_op ( + .clk_i, + .rst_ni, + .req_chk_i(1'b1), + .req_i (op_req_banks), + .data_i (op_data_in_banks), + .gnt_o (op_ack_banks), + .idx_o (), + .valid_o (op_req), + .data_o (op_data_in), + .ready_i (op_ack), + .err_o (local_err[1]) + ); + + assign arb_err_o = |local_err; + + assign {op_type, + plain_data_in, + scrambled_data_in} = op_data_in; + + /////////////////////////// + // GF multiplier + /////////////////////////// + + localparam int AddrPadWidth = DataWidth - BankAddrW; + localparam int UnusedWidth = KeySize - AddrPadWidth; + + // unused portion of addr_key + logic [KeySize-1:0] muxed_addr_key; + + logic addr_key_sel; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + addr_key_sel <= '0; + end else if (!calc_req || calc_req && calc_ack) begin + addr_key_sel <= disable_i; + end + end + + assign muxed_addr_key = addr_key_sel ? rand_addr_key_i : addr_key_i; + + logic [UnusedWidth-1:0] unused_key; + assign unused_key = muxed_addr_key[KeySize-1 -: UnusedWidth]; + + // Galois Multiply portion + // Note: Degree of IPoly and width parameters must match (leading MSB of IPoly is dropped). + if (SecScrambleEn) begin : gen_gf_mult + prim_gf_mult # ( + .Width(DataWidth), + .StagesPerCycle(DataWidth / GfMultCycles), + .IPoly(ScrambleIPoly) + ) u_mult ( + .clk_i, + .rst_ni, + .req_i(calc_req), + .operand_a_i({muxed_addr_key[DataWidth +: AddrPadWidth], calc_addr_in}), + .operand_b_i(muxed_addr_key[DataWidth-1:0]), + .ack_o(calc_ack), + .prod_o(calc_mask) + ); + end else begin : gen_no_gf_mult + assign calc_mask = '0; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + calc_ack <= '0; + end else if (calc_req && calc_ack) begin + calc_ack <= '0; + end else if (calc_req && !calc_ack) begin + calc_ack <= '1; + end + end + end + + /////////////////////////// + // cipher + /////////////////////////// + + logic dec; + logic [DataWidth-1:0] data; + assign dec = op_type == DeScrambleOp; + + // Do not allow the key to change during a transaction. + // While this may be desirable for security reasons, it creates + // timing issues for physical design + logic data_key_sel; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + data_key_sel <= '0; + end else if (!op_req || op_req && op_ack) begin + data_key_sel <= disable_i; + end + end + + // the prim_prince valid_o is a flopped version of valid_i + // As a result, when op_req stays high due to multiple transactions + // in-flight, the receiving logic can misinterpret the 'ack' if we just + // tie it to valid_o. + // Add a little bit of shimming logic here to properly create the ack + logic cipher_valid_in_d, cipher_valid_in_q; + logic cipher_valid_out; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + cipher_valid_in_q <= '0; + end else begin + cipher_valid_in_q <= cipher_valid_in_d; + end + end + + assign cipher_valid_in_d = op_ack ? '0 : op_req & !cipher_valid_out; + assign op_ack = cipher_valid_in_q & cipher_valid_out; + + if (SecScrambleEn) begin : gen_prince + prim_prince # ( + .DataWidth(DataWidth), + .KeyWidth(KeySize), + // Use improved key schedule proposed by https://eprint.iacr.org/2014/656.pdf (see appendix). + .UseOldKeySched(1'b0), + .HalfwayDataReg(1'b1), + // No key register is needed half way, since the data_key_i and operation op_type inputs + // remain constant until one data block has been processed. + .HalfwayKeyReg (1'b0) + ) u_cipher ( + .clk_i, + .rst_ni, + .valid_i(cipher_valid_in_d), + .data_i(dec ? scrambled_data_in : plain_data_in), + .key_i(data_key_sel ? rand_data_key_i : data_key_i), + .dec_i(dec), + .data_o(data), + .valid_o(cipher_valid_out) + ); + + end else begin : gen_no_prince + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + cipher_valid_out <= '0; + end else begin + cipher_valid_out <= cipher_valid_in_d; + end + end + assign data = dec ? scrambled_data_in : plain_data_in; + end + + // if decrypt, output the unscrambled data, feed input through otherwise + assign plain_data_out = dec ? data : scrambled_data_in; + + // if encrypt, output the scrambled data, feed input through otherwise + assign scrambled_data_out = dec ? plain_data_in : data; + + + +endmodule // flash_phy_scramble diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/BUILD b/hw/top_englishbreakfast/ip_autogen/pinmux/BUILD new file mode 100644 index 0000000000000..dda56de039e27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/pinmux/README.md b/hw/top_englishbreakfast/ip_autogen/pinmux/README.md new file mode 100644 index 0000000000000..d247e97a2c295 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/README.md @@ -0,0 +1,29 @@ +# Pinmux Technical Specification + + +# Overview + +This document specifies the functionality of the pin multiplexer (`pinmux`) peripheral. +This module conforms to the [OpenTitan guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability). +See that document for integration overview within the broader OpenTitan top level system. +The module provides a mechanism to reconfigure the peripheral-to-pin mapping at runtime, which greatly enhances the system flexibility. +In addition to that, the `pinmux` also allows the user to control pad attributes (such as pull-up, pull-down, open-drain, drive-strength, keeper and inversion), and it contains features that facilitate low-power modes of the system. +For example, the sleep behavior of each pad can be programmed individually, and the module contains additional pattern detectors that can listen on any IO and wake up the system if a specific pattern has been detected. + +## Features + +- Configurable number of chip bidirectional IOs + +- Configurable number of peripheral inputs and outputs + +- Programmable mapping from peripheral outputs (and output enables) to top-level outputs (and output enables) + +- Programmable mapping from top-level inputs to peripheral inputs + +- Programmable control of chip pad attributes like output drive-strength, pull-up, pull-down and virtual open-drain + +- Programmable pattern detectors to detect wakeup conditions during sleep mode + +- Programmable sleep mode behavior + +- Support for life-cycle-based JTAG (TAP) isolation and muxing diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux.hjson b/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux.hjson new file mode 100644 index 0000000000000..2afd499e814c3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux.hjson @@ -0,0 +1,1153 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +{ + name: "pinmux", + human_name: "Pin Multiplexer", + one_line_desc: "Multiplexes between on-chip hardware blocks and pins, and can be configured at runtime", + one_paragraph_desc: ''' + Pin Multiplexer connects on-chip hardware blocks to IC pins and controls the attributes of the pin drivers (such as pull-up/down, open-drain, and drive strength). + Large parts of its functionality can be controlled by software through registers. + Further features include per-pin programmable sleep behavior and wakeup pattern detectors as well as support for life-cycle-based JTAG (TAP) isolation and muxing. + ''' + // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. + cip_id: "18", + design_spec: "../doc", + dv_doc: "../doc/dv", + hw_checklist: "../doc/checklist", + sw_checklist: "/sw/device/lib/dif/dif_pinmux", + version: "1.1.0", + life_stage: "L1", + design_stage: "D3", + verification_stage: "V2S", + dif_stage: "S2", + notes: "Use FPV to perform block level verification.", + clocking: [ + {clock: "clk_i", reset: "rst_ni", primary: true}, + {clock: "clk_aon_i", reset: "rst_aon_ni"}, + {reset: "rst_sys_ni"} + ] + bus_interfaces: [ + { protocol: "tlul", direction: "device" } + ], + regwidth: "32", + scan: "true", + + alert_list: [ + { name: "fatal_fault", + desc: ''' + This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. + ''' + } + ], + + wakeup_list: [ + { name: "pin_wkup_req", + desc: "pin wake request" + }, + { name: "usb_wkup_req", + desc: "usb wake request" + }, + ], + + inter_signal_list: [ + // Life cycle inputs + { struct: "lc_tx" + type: "uni" + name: "lc_hw_debug_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg", + desc: ''' + Debug enable qualifier coming from life cycle controller, used for HW strap qualification. + ''' + } + { struct: "lc_tx" + type: "uni" + name: "lc_dft_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg", + desc: ''' + Test enable qualifier coming from life cycle controller, used for HW strap qualification. + ''' + } + { struct: "lc_tx" + type: "uni" + name: "lc_escalate_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg", + desc: ''' + Escalation enable signal coming from life cycle controller, used for invalidating + the latched lc_hw_debug_en state inside the strap sampling logic. + ''',} + + { struct: "lc_tx" + type: "uni" + name: "lc_check_byp_en" + act: "rcv" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg", + desc: ''' + Check bypass enable signal coming from life cycle controller, used for invalidating + the latched lc_hw_debug_en state inside the strap sampling logic. This signal is asserted + whenever the life cycle controller performs a life cycle transition. Its main use is + to skip any background checks inside the life cycle partition of the OTP controller while + a life cycle transition is in progress. + ''',} + + { struct: "lc_tx" + type: "uni" + name: "pinmux_hw_debug_en" + act: "req" + default: "lc_ctrl_pkg::Off" + package: "lc_ctrl_pkg", + desc: ''' + This is the latched version of lc_hw_debug_en_i. We use it exclusively to gate the JTAG + signals and TAP side of the RV_DM so that RV_DM can remain live during an NDM reset cycle. + ''',} + + // JTAG TAPs + { struct: "jtag" + type: "req_rsp" + name: "lc_jtag" + act: "req" + package: "jtag_pkg" + desc: ''' + Qualified JTAG signals for life cycle controller TAP. + ''',} + + { struct: "jtag" + type: "req_rsp" + name: "rv_jtag" + act: "req" + package: "jtag_pkg" + desc: ''' + Qualified JTAG signals for RISC-V processor TAP. + ''',} + + { struct: "jtag" + type: "req_rsp" + name: "dft_jtag" + act: "req" + package: "jtag_pkg" + desc: ''' + Qualified JTAG signals for DFT TAP. + ''',} + + // Testmode signals to AST + { struct: "dft_strap_test_req", + type: "uni", + name: "dft_strap_test", + act: "req", + package: "pinmux_pkg", + desc: ''' + Sampled DFT strap values, going to the DFT TAP. + ''', + default: "'0" + } + // DFT indication to stop tap strap sampling + { struct: "logic", + type: "uni", + name: "dft_hold_tap_sel", + act: "rcv", + package: "", + desc: ''' + TAP selection hold indication, asserted by the DFT TAP during boundary scan. + ''', + default: "'0" + } + // Define pwr mgr <-> pinmux signals + { struct: "logic", + type: "uni", + name: "sleep_en", + act: "rcv", + package: "", + desc: ''' + Level signal that is asserted when the power manager enters sleep. + ''', + default: "1'b0" + }, + { struct: "logic", + type: "uni", + name: "strap_en", + act: "rcv", + package: "", + desc: ''' + This signal is pulsed high by the power manager after reset in order to sample the HW straps. + ''', + default: "1'b0" + }, + { struct: "logic", + type: "uni", + name: "strap_en_override", + act: "rcv", + desc: ''' + This signal transitions from 0 -> 1 by the lc_ctrl manager after volatile RAW_UNLOCK in order to re-sample the HW straps. + The signal must stay at 1 until reset. + Note that this is only used in test chips when SecVolatileRawUnlockEn = 1. + Otherwise this signal is unused. + ''', + default: "1'b0" + }, + { struct: "logic", + type: "uni", + name: "pin_wkup_req", + act: "req", + package: "", + desc: ''' + Wakeup request from wakeup detectors, to the power manager, running on the AON clock. + ''', + default: "1'b0" + }, + { name: "usbdev_dppullup_en", + type: "uni", + act: "rcv", + package: "", + desc: ''' + Pullup enable signal coming from the USB IP. + ''', + struct: "logic", + width: "1" + }, + { name: "usbdev_dnpullup_en", + type: "uni", + act: "rcv", + package: "", + desc: ''' + Pullup enable signal coming from the USB IP. + ''', + struct: "logic", + width: "1" + }, + { name: "usb_dppullup_en", + type: "uni", + act: "req", + package: "", + desc: ''' + Pullup enable signal going to USB PHY, needs to be maintained in low-power mode. + ''', + struct: "logic", + width: "1" + default: "1'b0" + }, + { name: "usb_dnpullup_en", + type: "uni", + act: "req", + package: "", + desc: ''' + Pullup enable signal going to USB PHY, needs to be maintained in low-power mode. + ''', + struct: "logic", + width: "1" + default: "1'b0" + }, + { struct: "logic", + type: "uni", + name: "usb_wkup_req", + act: "req", + package: "", + desc: ''' + Wakeup request from USB wakeup detector, going to the power manager, running on the AON clock. + ''', + default: "1'b0" + }, + { name: "usbdev_suspend_req", + type: "uni", + act: "rcv", + package: "", + desc: ''' + Indicates whether USB is in suspended state, coming from the USB device. + ''', + struct: "logic", + width: "1" + }, + { name: "usbdev_wake_ack", + type: "uni", + act: "rcv", + package: "", + desc: ''' + Acknowledges the USB wakeup request, coming from the USB device. + ''', + struct: "logic", + width: "1" + }, + { name: "usbdev_bus_not_idle", + type: "uni", + act: "req", + package: "", + desc: ''' + Event signal that indicates that the USB was not idle while monitoring. + ''', + struct: "logic", + width: "1", + default: "1'b0" + }, + { name: "usbdev_bus_reset", + type: "uni", + act: "req", + package: "", + desc: ''' + Event signal that indicates that the USB issued a Bus Reset while monitoring. + ''', + struct: "logic", + width: "1", + default: "1'b0" + }, + { name: "usbdev_sense_lost", + type: "uni", + act: "req", + package: "", + desc: ''' + Event signal that indicates that USB SENSE signal was lost while monitoring. + ''', + struct: "logic", + width: "1", + default: "1'b0" + }, + { name: "usbdev_wake_detect_active", + type: "uni", + act: "req", + package: "", + desc: ''' + State debug information. + ''', + struct: "logic", + width: 1, + default: "1'b0" + }, + ] + + param_list: [ + // Secure parameters + { name: "SecVolatileRawUnlockEn", + type: "bit", + default: "1'b0", + desc: ''' + Disable (0) or enable (1) volatile RAW UNLOCK capability. + If enabled, the strap_en_override_i input can be used to re-sample the straps at runtime. + + IMPORTANT NOTE: This should only be used in test chips. The parameter must be set + to 0 in production tapeouts since this weakens the security posture of the RAW + UNLOCK mechanism. + ''' + local: "false", + expose: "true" + }, + { name: "NMioPeriphIn", + desc: "Number of muxed peripheral inputs", + type: "int", + default: "38", + local: "true" + }, + { name: "NMioPeriphOut", + desc: "Number of muxed peripheral outputs", + type: "int", + default: "35", + local: "true" + }, + { name: "NMioPads", + desc: "Number of muxed IO pads", + type: "int", + default: "47", + local: "true" + }, + { name: "NDioPads", + desc: "Number of dedicated IO pads", + type: "int", + default: "14", + local: "true" + }, + { name: "NWkupDetect", + desc: "Number of wakeup detectors", + type: "int", + default: "8", + local: "true" + }, + { name: "WkupCntWidth", + desc: "Number of wakeup counter bits", + type: "int", + default: "8", + local: "true" + }, + // Since the target-specific top-levels often have slightly + // different debug signal positions, we need a way to pass + // this info from the target specific top-level into the pinmux + // logic. The parameter struct below serves this purpose. + { name: "TargetCfg", + desc: "Target specific pinmux configuration.", + type: "pinmux_pkg::target_cfg_t", + default: "pinmux_pkg::DefaultTargetCfg", + local: "false", + expose: "true" + }, + ], + countermeasures: [ + { name: "BUS.INTEGRITY", + desc: "End-to-end bus integrity scheme." + } + { name: "LC_DFT_EN.INTERSIG.MUBI", + desc: "The life cycle DFT enable signal is multibit encoded." + } + { name: "LC_HW_DEBUG_EN.INTERSIG.MUBI", + desc: "The life cycle hardware debug enable signal is multibit encoded." + } + { name: "LC_CHECK_BYP_EN.INTERSIG.MUBI", + desc: "The life cycle check bypass signal is multibit encoded." + } + { name: "LC_ESCALATE_EN.INTERSIG.MUBI", + desc: "The life cycle check bypass signal is multibit encoded." + } + { name: "PINMUX_HW_DEBUG_EN.INTERSIG.MUBI", + desc: '''In order to support the NDM reset feature in RV_DM, + the pinmux latches the LC_HW_DEBUG_EN signal so that it can survive + the NDM reset, and sends that signal on to the RV_DM for use in + gating circuitry. This signal is also multibit encoded + ''' + } + { name: "TAP.MUX.LC_GATED", + desc: '''The TAP selection mux/demux in the strap sampling module + is gated by life cycle signals so that the RV_DM can only + be selected during when LC_HW_DEBUG_EN is asserted, and + the DFT TAP can only be selected when LC_DFT_EN is asserted. + ''' + } + ] + + registers: [ +////////////////////////// +// MIO Inputs // +////////////////////////// + { multireg: { name: "MIO_PERIPH_INSEL_REGWEN", + desc: "Register write enable for MIO peripheral input selects.", + count: "NMioPeriphIn", + compact: "false", + swaccess: "rw0c", + hwaccess: "none", + cname: "MIO_PERIPH_INSEL", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Register write enable bit. + If this is cleared to 0, the corresponding MIO_PERIPH_INSEL + is not writable anymore. + ''', + resval: "1", + } + ] + } + }, + { multireg: { name: "MIO_PERIPH_INSEL", + desc: "For each peripheral input, this selects the muxable pad input.", + count: "NMioPeriphIn", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "MIO_PERIPH_INSEL_REGWEN", + regwen_multi: "true", + cname: "IN", + fields: [ + { bits: "5:0", + name: "IN", + desc: ''' + 0: tie constantly to zero, 1: tie constantly to 1, + >=2: MIO pads (i.e., add 2 to the native MIO pad index). + ''' + resval: 0, + } + ] + } + }, + +////////////////////////// +// MIO Outputs // +////////////////////////// + { multireg: { name: "MIO_OUTSEL_REGWEN", + desc: "Register write enable for MIO output selects.", + count: "NMioPads", + compact: "false", + swaccess: "rw0c", + hwaccess: "none", + cname: "MIO_OUTSEL", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Register write enable bit. + If this is cleared to 0, the corresponding MIO_OUTSEL + is not writable anymore. + ''', + resval: "1", + } + ] + } + }, + { multireg: { name: "MIO_OUTSEL", + desc: "For each muxable pad, this selects the peripheral output.", + count: "NMioPads", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "MIO_OUTSEL_REGWEN", + regwen_multi: "true", + cname: "OUT", + fields: [ + { bits: "5:0", + name: "OUT", + desc: ''' + 0: tie constantly to zero, 1: tie constantly to 1, 2: high-Z, + >=3: peripheral outputs (i.e., add 3 to the native peripheral pad index). + ''' + resval: 2, + } + ] + // Random writes to this field may result in pad drive conflicts, + // which in turn leads to propagating Xes and assertion failures. + tags: ["excl:CsrAllTests:CsrExclWrite"] + } + }, + +////////////////////////// +// MIO PAD attributes // +////////////////////////// + { multireg: { name: "MIO_PAD_ATTR_REGWEN", + desc: "Register write enable for MIO PAD attributes.", + count: "NMioPads", + compact: "false", + swaccess: "rw0c", + hwaccess: "none", + cname: "MIO_PAD", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Register write enable bit. + If this is cleared to 0, the corresponding !!MIO_PAD_ATTR + is not writable anymore. + ''', + resval: "1", + } + ] + } + }, + { multireg: { name: "MIO_PAD_ATTR", + desc: ''' + Muxed pad attributes. + This register has WARL behavior since not each pad type may support + all attributes. + The muxed pad that is used for TAP strap 0 has a different reset value, with `pull_en` set to 1. + ''', + count: "NMioPads", + compact: "false", + swaccess: "rw", + hwaccess: "hrw", + hwext: "true", + hwqe: "true", + regwen: "MIO_PAD_ATTR_REGWEN", + regwen_multi: "true", + cname: "MIO_PAD", + resval: 0 + fields: [ + { bits: "0", + name: "invert", + desc: "Invert input and output levels." + }, + { bits: "1", + name: "virtual_od_en", + desc: "Enable virtual open drain." + }, + { bits: "2", + name: "pull_en", + desc: "Enable pull-up or pull-down resistor." + }, + { bits: "3", + name: "pull_select", + desc: "Pull select (0: pull-down, 1: pull-up)." + enum: [ + { value: "0", + name: "pull_down", + desc: "Select the pull-down resistor." + }, + { value: "1", + name: "pull_up", + desc: "Select the pull-up resistor." + } + ] + }, + { bits: "4", + name: "keeper_en", + desc: "Enable keeper termination. This weakly drives the previous pad output value when output is disabled, similar to a verilog `trireg`." + }, + { bits: "5", + name: "schmitt_en", + desc: "Enable the schmitt trigger." + }, + { bits: "6", + name: "od_en", + desc: "Enable open drain." + }, + { bits: "7", + name: "input_disable", + desc: ''' + Disable input drivers. + Setting this to 1 for pads that are not used as input can reduce their leakage current. + ''' + }, + { bits: "17:16", + name: "slew_rate", + desc: "Slew rate (0x0: slowest, 0x3: fastest)." + }, + { bits: "23:20", + name: "drive_strength", + desc: "Drive strength (0x0: weakest, 0xf: strongest)" + } + ], + // these CSRs have WARL behavior and may not + // read back the same value that was written to them. + // further, they have hardware side effects since they drive the + // pad attributes, and hence no random data should be written to them. + // Additionally, their reset value is defined by the RTL implementation and may not equal `resval` for all instances (#24621). + tags: ["excl:CsrAllTests:CsrExclAll"] + } + }, + +////////////////////////// +// DIO PAD attributes // +////////////////////////// + { multireg: { name: "DIO_PAD_ATTR_REGWEN", + desc: "Register write enable for DIO PAD attributes.", + count: "NDioPads", + compact: "false", + swaccess: "rw0c", + hwaccess: "none", + cname: "DIO_PAD", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Register write enable bit. + If this is cleared to 0, the corresponding !!DIO_PAD_ATTR + is not writable anymore. + ''', + resval: "1", + } + ] + } + }, + { multireg: { name: "DIO_PAD_ATTR", + desc: ''' + Dedicated pad attributes. + This register has WARL behavior since not each pad type may support + all attributes. + ''', + count: "NDioPads", + compact: "false", + swaccess: "rw", + hwaccess: "hrw", + hwext: "true", + hwqe: "true", + regwen: "DIO_PAD_ATTR_REGWEN", + regwen_multi: "true", + cname: "DIO_PAD", + resval: 0, + fields: [ + { bits: "0", + name: "invert", + desc: "Invert input and output levels." + }, + { bits: "1", + name: "virtual_od_en", + desc: "Enable virtual open drain." + }, + { bits: "2", + name: "pull_en", + desc: "Enable pull-up or pull-down resistor." + }, + { bits: "3", + name: "pull_select", + desc: "Pull select (0: pull-down, 1: pull-up)." + enum: [ + { value: "0", + name: "pull_down", + desc: "Select the pull-down resistor." + }, + { value: "1", + name: "pull_up", + desc: "Select the pull-up resistor." + } + ] + }, + { bits: "4", + name: "keeper_en", + desc: "Enable keeper termination. This weakly drives the previous pad output value when output is disabled, similar to a verilog `trireg`." + }, + { bits: "5", + name: "schmitt_en", + desc: "Enable the schmitt trigger." + }, + { bits: "6", + name: "od_en", + desc: "Enable open drain." + }, + { bits: "7", + name: "input_disable", + desc: ''' + Disable input drivers. + Setting this to 1 for pads that are not used as input can reduce their leakage current. + ''' + }, + { bits: "17:16", + name: "slew_rate", + desc: "Slew rate (0x0: slowest, 0x3: fastest)." + }, + { bits: "23:20", + name: "drive_strength", + desc: "Drive strength (0x0: weakest, 0xf: strongest)" + } + ], + // these CSRs have WARL behavior and may not + // read back the same value that was written to them. + // further, they have hardware side effects since they drive the + // pad attributes, and hence no random data should be written to them. + tags: ["excl:CsrAllTests:CsrExclWrite"] + } + }, + +////////////////////////// +// MIO PAD sleep mode // +////////////////////////// + { multireg: { name: "MIO_PAD_SLEEP_STATUS", + desc: "Register indicating whether the corresponding pad is in sleep mode.", + count: "NMioPads", + swaccess: "rw0c", + hwaccess: "hrw", + cname: "MIO_PAD", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + This register is set to 1 if the deep sleep mode of the corresponding + pad has been enabled (!!MIO_PAD_SLEEP_EN) upon deep sleep entry. + The sleep mode of the corresponding pad will remain active until SW + clears this bit. + ''', + resval: "0", + } + ] + } + }, + { multireg: { name: "MIO_PAD_SLEEP_REGWEN", + desc: "Register write enable for MIO sleep value configuration.", + count: "NMioPads", + compact: "false", + swaccess: "rw0c", + hwaccess: "none", + cname: "MIO_PAD", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Register write enable bit. + If this is cleared to 0, the corresponding !!MIO_PAD_SLEEP_MODE + is not writable anymore. + ''', + resval: "1", + } + ] + } + }, + { multireg: { name: "MIO_PAD_SLEEP_EN", + desc: '''Enables the sleep mode of the corresponding muxed pad. + ''' + count: "NMioPads", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "MIO_PAD_SLEEP_REGWEN", + regwen_multi: "true", + cname: "OUT", + fields: [ + { bits: "0", + name: "EN", + resval: 0, + desc: ''' + Deep sleep mode enable. + If this bit is set to 1 the corresponding pad will enable the sleep behavior + specified in !!MIO_PAD_SLEEP_MODE upon deep sleep entry, and the corresponding bit + in !!MIO_PAD_SLEEP_STATUS will be set to 1. + The pad remains in deep sleep mode until the corresponding bit in + !!MIO_PAD_SLEEP_STATUS is cleared by SW. + Note that if an always on peripheral is connected to a specific MIO pad, + the corresponding !!MIO_PAD_SLEEP_EN bit should be set to 0. + ''' + } + ] + } + }, + { multireg: { name: "MIO_PAD_SLEEP_MODE", + desc: '''Defines sleep behavior of the corresponding muxed pad. + ''' + count: "NMioPads", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "MIO_PAD_SLEEP_REGWEN", + regwen_multi: "true", + cname: "OUT", + fields: [ + { bits: "1:0", + name: "OUT", + resval: 2, + desc: "Value to drive in deep sleep." + enum: [ + { value: "0", + name: "Tie-Low", + desc: "The pad is driven actively to zero in deep sleep mode." + }, + { value: "1", + name: "Tie-High", + desc: "The pad is driven actively to one in deep sleep mode." + }, + { value: "2", + name: "High-Z", + desc: ''' + The pad is left undriven in deep sleep mode. Note that the actual + driving behavior during deep sleep will then depend on the pull-up/-down + configuration of in !!MIO_PAD_ATTR. + ''' + }, + { value: "3", + name: "Keep", + desc: "Keep last driven value (including high-Z)." + }, + ] + } + ] + } + }, +////////////////////////// +// DIO PAD sleep mode // +////////////////////////// + { multireg: { name: "DIO_PAD_SLEEP_STATUS", + desc: "Register indicating whether the corresponding pad is in sleep mode.", + count: "NDioPads", + swaccess: "rw0c", + hwaccess: "hrw", + cname: "DIO_PAD", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + This register is set to 1 if the deep sleep mode of the corresponding + pad has been enabled (!!DIO_PAD_SLEEP_MODE) upon deep sleep entry. + The sleep mode of the corresponding pad will remain active until SW + clears this bit. + ''', + resval: "0", + } + ] + } + }, + { multireg: { name: "DIO_PAD_SLEEP_REGWEN", + desc: "Register write enable for DIO sleep value configuration.", + count: "NDioPads", + compact: "false", + swaccess: "rw0c", + hwaccess: "none", + cname: "DIO_PAD", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Register write enable bit. + If this is cleared to 0, the corresponding !!DIO_PAD_SLEEP_MODE + is not writable anymore. + ''', + resval: "1", + } + ] + } + }, + { multireg: { name: "DIO_PAD_SLEEP_EN", + desc: '''Enables the sleep mode of the corresponding dedicated pad. + ''' + count: "NDioPads", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "DIO_PAD_SLEEP_REGWEN", + regwen_multi: "true", + cname: "OUT", + fields: [ + { bits: "0", + name: "EN", + resval: 0, + desc: ''' + Deep sleep mode enable. + If this bit is set to 1 the corresponding pad will enable the sleep behavior + specified in !!DIO_PAD_SLEEP_MODE upon deep sleep entry, and the corresponding bit + in !!DIO_PAD_SLEEP_STATUS will be set to 1. + The pad remains in deep sleep mode until the corresponding bit in + !!DIO_PAD_SLEEP_STATUS is cleared by SW. + Note that if an always on peripheral is connected to a specific DIO pad, + the corresponding !!DIO_PAD_SLEEP_EN bit should be set to 0. + ''' + } + ] + } + }, + { multireg: { name: "DIO_PAD_SLEEP_MODE", + desc: '''Defines sleep behavior of the corresponding dedicated pad. + ''' + count: "NDioPads", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "DIO_PAD_SLEEP_REGWEN", + regwen_multi: "true", + cname: "OUT", + fields: [ + { bits: "1:0", + name: "OUT", + resval: 2, + desc: "Value to drive in deep sleep." + enum: [ + { value: "0", + name: "Tie-Low", + desc: "The pad is driven actively to zero in deep sleep mode." + }, + { value: "1", + name: "Tie-High", + desc: "The pad is driven actively to one in deep sleep mode." + }, + { value: "2", + name: "High-Z", + desc: ''' + The pad is left undriven in deep sleep mode. Note that the actual + driving behavior during deep sleep will then depend on the pull-up/-down + configuration of in !!DIO_PAD_ATTR. + ''' + }, + { value: "3", + name: "Keep", + desc: "Keep last driven value (including high-Z)." + }, + ] + } + ] + } + }, +//////////////////////// +// Wakeup detectors // +//////////////////////// + { multireg: { name: "WKUP_DETECTOR_REGWEN", + desc: "Register write enable for wakeup detectors.", + count: "NWkupDetect", + compact: "false", + swaccess: "rw0c", + hwaccess: "none", + cname: "WKUP_DETECTOR", + fields: [ + { bits: "0", + name: "EN", + desc: ''' + Register write enable bit. + If this is cleared to 0, the corresponding WKUP_DETECTOR + configuration is not writable anymore. + ''', + resval: "1", + } + ] + } + }, + { multireg: { name: "WKUP_DETECTOR_EN", + desc: ''' + Enables for the wakeup detectors. + Note that these registers are synced to the always-on clock. + The first write access always completes immediately. + However, read/write accesses following a write will block until that write has completed. + ''' + count: "NWkupDetect", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "WKUP_DETECTOR_REGWEN", + regwen_multi: "true", + cname: "DETECTOR", + async: "clk_aon_i", + fields: [ + { bits: "0:0", + name: "EN", + resval: 0, + desc: ''' + Setting this bit activates the corresponding wakeup detector. + The behavior is as specified in !!WKUP_DETECTOR, + !!WKUP_DETECTOR_CNT_TH and !!WKUP_DETECTOR_PADSEL. + ''' + // In CSR tests, we do not touch the chip IOs. Thet are either pulled low or + // or undriven. + // + // Random writes to the wkup detect CSRs may result in the case where the + // wakeup gets enabled and signaled due to a pin being low for a programmed + // time, which results in wkup_cause register to mismatch, OR, result in + // assertion error due to a pin programmed for wakeup detection is undriven + // Also exclude write for csr_hw_reset, otherwise, X may be detected and propagating. + tags: ["excl:CsrAllTests:CsrExclWrite"] + } + ] + } + + }, + { multireg: { name: "WKUP_DETECTOR", + desc: ''' + Configuration of wakeup condition detectors. + Note that these registers are synced to the always-on clock. + The first write access always completes immediately. + However, read/write accesses following a write will block until that write has completed. + + Note that the wkup detector should be disabled by setting !!WKUP_DETECTOR_EN_0 before changing the detection mode. + The reason for that is that the pulse width counter is NOT cleared upon a mode change while the detector is enabled. + ''' + count: "NWkupDetect", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "WKUP_DETECTOR_REGWEN", + regwen_multi: "true", + cname: "DETECTOR", + async: "clk_aon_i", + fields: [ + { bits: "2:0", + name: "MODE", + resval: 0, + desc: "Wakeup detection mode. Out of range values default to Posedge." + enum: [ + { value: "0", + name: "Posedge", + desc: "Trigger a wakeup request when observing a positive edge." + }, + { value: "1", + name: "Negedge", + desc: "Trigger a wakeup request when observing a negative edge." + }, + { value: "2", + name: "Edge", + desc: "Trigger a wakeup request when observing an edge in any direction." + }, + { value: "3", + name: "TimedHigh", + desc: ''' + Trigger a wakeup request when pin is driven HIGH for a certain amount + of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH. + ''' + }, + { value: "4", + name: "TimedLow", + desc: ''' + Trigger a wakeup request when pin is driven LOW for a certain amount + of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH. + ''' + }, + + ] + } + { bits: "3", + name: "FILTER", + resval: 0, + desc: '''0: signal filter disabled, 1: signal filter enabled. the signal must + be stable for 4 always-on clock cycles before the value is being forwarded. + can be used for debouncing. + ''' + } + { bits: "4", + name: "MIODIO", + resval: 0, + desc: '''0: select index !!WKUP_DETECTOR_PADSEL from MIO pads, + 1: select index !!WKUP_DETECTOR_PADSEL from DIO pads. + ''' + } + ] + } + + }, + { multireg: { name: "WKUP_DETECTOR_CNT_TH", + desc: ''' + Counter thresholds for wakeup condition detectors. + Note that these registers are synced to the always-on clock. + The first write access always completes immediately. + However, read/write accesses following a write will block until that write has completed. + ''' + count: "NWkupDetect", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "WKUP_DETECTOR_REGWEN", + regwen_multi: "true", + cname: "DETECTOR", + async: "clk_aon_i", + fields: [ + { bits: "WkupCntWidth-1:0", + name: "TH", + resval: 0, + desc: '''Counter threshold for TimedLow and TimedHigh wakeup detector modes (see !!WKUP_DETECTOR). + The threshold is in terms of always-on clock cycles. + ''' + } + ] + } + + }, + { multireg: { name: "WKUP_DETECTOR_PADSEL", + desc: ''' + Pad selects for pad wakeup condition detectors. + This register is NOT synced to the AON domain since the muxing mechanism is implemented in the same way as the pinmux muxing matrix. + ''' + count: "NWkupDetect", + compact: "false", + swaccess: "rw", + hwaccess: "hro", + regwen: "WKUP_DETECTOR_REGWEN", + regwen_multi: "true", + cname: "DETECTOR", + fields: [ + { bits: "5:0", + name: "SEL", + resval: 0, + desc: '''Selects a specific MIO or DIO pad (depending on !!WKUP_DETECTOR configuration). + In case of MIO, the pad select index is the same as used for !!MIO_PERIPH_INSEL, meaning that index + 0 and 1 just select constants 0 and 1, and the MIO pads live at indices >= 2. In case of DIO pads, + the pad select index corresponds 1:1 to the DIO pad to be selected. + ''' + } + ] + } + + }, + { multireg: { name: "WKUP_CAUSE", + desc: ''' + Cause registers for wakeup detectors. + Note that these registers are synced to the always-on clock. + The first write access always completes immediately. + However, read/write accesses following a write will block until that write has completed. + ''' + count: "NWkupDetect", + swaccess: "rw0c", + hwaccess: "hrw", + cname: "DETECTOR", + async: "clk_aon_i", + fields: [ + { bits: "0", + name: "CAUSE", + resval: 0, + desc: '''Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. + ''' + } + ] + } + + }, + ], +} diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_fpv_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_fpv_testplan.hjson new file mode 100644 index 0000000000000..c7b93e78e2883 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_fpv_testplan.hjson @@ -0,0 +1,883 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "pinmux" + import_testplans: ["hw/dv/tools/dvsim/testplans/fpv_csr_testplan.hjson"] + testpoints: [ + // `mio_to_periph_o` tests. + // Symbolic variable `periph_sel_i` is used to select a specific `mio_to_periph_o` pin. + { + name: InSel0_A + desc: '''When register `periph_insel` is set to 0, which means the selected input is constant + zero, the corresponding `mio_to_periph_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: InSel1_A + desc: '''When register `periph_insel` is set to 1, which means the selected input is constant + one, the corresponding `mio_to_periph_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: InSelN_A + desc: '''When register `periph_insel` is set to any value between 2 and + (2 + number of MioPads) and the select index is not jtag, the corresponding + `mio_to_periph_o` must be equal to the related `mio_in_i` value.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: InSelOOB_A + desc: '''When register `periph_insel` is set to any value larger than + (2 + number of MioPads), the corresponding `mio_to_periph_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `mio_to_periph_o` backward tests + // Symbolic variable `periph_sel_i` is used to select a specific `mio_to_periph_o` pin. + { + name: MioToPeriph0Backward_A + desc: '''`mio_to_periph_o` should output 0 only if one of the following conditions meets: + - Register `periph_insel` is set to 0. + - The corresponding `mio_in_i` is 0. + - Jtag is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: MioToPeriph1Backward_A + desc: '''`mio_to_periph_o` should output 1 only if one of the following conditions meets: + - Register `periph_insel` is set to 1. + - The corresponding `mio_in_i` is 1. + - Jtag is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `dio_to_periph_o` tests + // Symbolic variable `dio_sel_i` is used to select a specific `dio_to_periph_o` pin. + { + name: DioInSelN_A + desc: "This assertion checks that `dio_to_periph_o` is directly connected to `dio_in_i`." + stage: V1 + tests: ["pinmux_assert"] + } + + // `mio_out_o` not in sleep_mode tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_out_o` pin. + { + name: OutSel0_A + desc: '''When register `mio_outsel` is set to 0 and is not in sleep mode or jtag, which means + the selected output is constant zero, the corresponding `mio_out_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSel1_A + desc: '''When register `mio_outsel` is set to 1 and is not in sleep mode or jtag, which means + the selected output is constant one, the corresponding `mio_out_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSel2_A + desc: '''When register `mio_outsel` is set to 2 and is not in sleep mode or jtag, which means + the selected output is driving high-Z, the corresponding `mio_out_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSelN_A + desc: '''When register `mio_outsel` is set to any value between 3 and + (3 + Number of periph out) and is not in sleep mode or jtag, the corresponding + `mio_out_o` must be equal to the related `periph_to_mio_i` value.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSelOOB_A + desc: '''When register `mio_outsel` is set to any value larger than + (3 + Number of periph out) and is not in sleep mode, the corresponding `mio_out_o` must + be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `mio_out_o` backward tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_out_o` pin. + { + name: MioOut0Backward_A + desc: '''`mio_out_o` should output 0 only if one of the following conditions meets: + - Register `mio_insel` is set to 0 or 2. + - The corresponding `periph_to_mio_i` is 0. + - Sleep mode is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: MioOut1Backward_A + desc: '''`mio_out_o` should output 1 only if one of the following conditions meets: + - Register `mio_insel` is set to 1. + - The corresponding `periph_to_mio_i` is 1. + - Sleep mode is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `mio_oe_o` not in sleep_mode tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_out_o` pin. + { + name: OutSelOe0_A + desc: '''When register `mio_outsel` is set to 0 and is not in sleep mode or jtag, the + corresponding `mio_oe_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSelOe1_A + desc: '''When register `mio_outsel` is set to 1 and is not in sleep mode or jtag, the + corresponding `mio_oe_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSelOe2_A + desc: '''When register `mio_outsel` is set to 2 and is not in sleep mode or jtag, which + indicates driving high-Z to the selected output, the corresponding `mio_oe_o` must + be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSelOeN_A + desc: '''When register `mio_outsel` is set to any value between 3 and + (3 + Number of periph out) and is not in sleep mode or jtag, the corresponding + `mio_oe_o` must be equal to the related `periph_to_mio_oe_i` value.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: OutSelOeOOB_A + desc: '''When register `mio_outsel` is set to any value larger than + (3 + Number of periph out) and is not in sleep mode, the corresponding `mio_oe_o` must + be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `mio_oe_o` backward tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_oe_o` pin. + { + name: MioOe0Backward_A + desc: '''`mio_oe_o` should output 0 only if one of the following conditions meets: + - Register `mio_insel` is set to 2. + - The corresponding `periph_to_mio_oe_i` is 0. + - Sleep mode is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: MioOe1Backward_A + desc: '''`mio_oe_o` should output 1 only if one of the following conditions meets: + - Register `mio_insel` is set to 0 or 1. + - The corresponding `periph_to_mio_oe_i` is 1. + - Sleep mode is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `mio_out_o` in sleep mode tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_out_o` pin. + { + name: MioSleepMode0_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 0, which means the pad is driven zero in deep sleep mode. + If, in the meantime, register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_out_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioSleepMode1_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 1, which means the pad is driven one in deep sleep mode. + In the meantime, if register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_out_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioSleepMode2_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 2, which means the pad is driven high-Z in deep sleep mode. + In the meantime, if register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_out_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioSleepMode3_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 3, which means the pad keeps last driven value in deep sleep + mode. + In the meantime, if register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_out_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioSleepStable_A + desc: '''If not at posedge of `sleep_en_i`, and in the meantime register + `mio_pad_sleep_status` is not written via TLUL interface to clear the sleep status, the + corresponding `mio_out_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `mio_oe_o` in sleep mode tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_oe_o` pin. + { + name: MioOeSleepMode0_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 0, which means the pad is driven zero in deep sleep mode. + In the meantime, if register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_oe_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioOeSleepMode1_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 1, which means the pad is driven one in deep sleep mode. + In the meantime, if register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_oe_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioOeSleepMode2_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 2, which means the pad is driven high-Z in deep sleep mode. + In the meantime, if register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_oe_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioOeSleepMode3_A + desc: '''At posedge of `sleep_en_i`, if register `mio_pad_sleep_en` is 1 and + `mio_pad_sleep_mode` is 3, which means the pad keeps last driven value in deep sleep + mode. + In the meantime, if register `mio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `mio_oe_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioOeSleepStable_A + desc: '''If not at posedge of `sleep_en_i`, and in the meantime, if register + `mio_pad_sleep_status` is not written via TLUL interface to clear the sleep status, the + corresponding `mio_oe_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `mio_out_o` sleep mode related backward tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_out_o` pin. + { + name: MioSleep0Backward_A + desc: '''`mio_out_o` should output 0 only if one of the following conditions meets: + - In sleep mode, register `mio_pad_sleep_mode` is set to 0 or 2. + - In sleep mode, previous `mio_out_o` is 0 and `mio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `mio_out_o` is 0 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: MioSleep1Backward_A + desc: '''`mio_out_o` should output 1 only if one of the following conditions meets: + - In sleep mode, register `mio_pad_sleep_mode` is set to 1. + - In sleep mode, previous `mio_out_o` is 1 and `mio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `mio_out_o` is 1 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `mio_oe_o` sleep mode related backward tests + // Symbolic variable `mio_sel_i` is used to select a specific `mio_oe_o` pin. + { + name: MioOeSleep0Backward_A + desc: '''`mio_oe_o` should output 0 only if one of the following conditions meets: + - In sleep mode, register `mio_pad_sleep_mode` is set to 2. + - In sleep mode, previous `mio_oe_o` is 0 and `mio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `mio_oe_o` is 0 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: MioOeSleep1Backward_A + desc: '''`mio_oe_o` should output 1 only if one of the following conditions meets: + - In sleep mode, register `mio_pad_sleep_mode` is set to 0 or 1. + - In sleep mode, previous `mio_oe_o` is 1 and `mio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `mio_oe_o` is 1 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `dio_out_o` not in sleep mode tests + // Symbolic variable `dio_sel_i` is used to select a specific `dio_out_o` pin. + { + name: DOutSelN_A + desc: "`dio_out_o` is connected to `periph_to_dio_i` if not in sleep mode." + stage: V1 + tests: ["pinmux_assert"] + } + + // `dio_oe_o` not in sleep mode tests + // Symbolic variable `dio_sel_i` is used to select a specific `dio_oe_o` pin. + { + name: DOutSelOeN_A + desc: "`dio_oe_o` is connected to `periph_to_dio_oe_i` if not in sleep mode." + stage: V1 + tests: ["pinmux_assert"] + } + + // `dio_out_o` in sleep mode tests + // Symbolic variable `dio_sel_i` is used to select a specific `dio_out_o` pin. + { + name: DioSleepMode0_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 0, which means the pad is driven zero in deep sleep mode. + In the meantime, if register `dio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_out_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioSleepMode1_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 1, which means the pad is driven one in deep sleep mode. + In the meantime, if register `dmio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_out_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioSleepMode2_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 2, which means the pad is driven high-Z in deep sleep mode. + In the meantime, if register `dio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_out_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioSleepMode3_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 3, which means the pad keeps last driven value in deep sleep + mode. + In the meantime, if register `dio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_out_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioSleepStable_A + desc: '''If not at posedge of `sleep_en_i`, and in the meantime, if register + `dio_pad_sleep_status` is not written via TLUL interface to clear the sleep status, the + corresponding `dio_out_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `dio_oe_o` in sleep mode tests + // Symbolic variable `dio_sel_i` is used to select a specific `dio_oe_o` pin. + { + name: DioOeSleepMode0_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 0, which means the pad is driven zero in deep sleep mode. + In the meantime, if register `dio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_oe_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioOeSleepMode1_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 1, which means the pad is driven one in deep sleep mode. + In the meantime, if register `dio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_oe_o` must be 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioOeSleepMode2_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 2, which means the pad is driven high-Z in deep sleep mode. + In the meantime, if register `dio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_oe_o` must be 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioOeSleepMode3_A + desc: '''At posedge of `sleep_en_i`, if register `dio_pad_sleep_en` is 1 and + `dio_pad_sleep_mode` is 3, which means the pad keeps last driven value in deep sleep + mode. + In the meantime, if register `dio_pad_sleep_status` is not written via TLUL interface + to clear the sleep status, the corresponding `dio_oe_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DioOeSleepStable_A + desc: '''If not at posedge of `sleep_en_i`, and in the meantime, if register + `dio_pad_sleep_status` is not written via TLUL interface to clear the sleep status, the + corresponding `dio_oe_o` should be stable. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `dio_out_o` backward tests + // Symbolic variable `dio_sel_i` is used to select a specific `dio_out_o` pin. + { + name: Dio0Backward_A + desc: '''`dio_out_o` should output 0 only if one of the following conditions meets: + - The corresponding `periph_to_dio_i` is 0. + - In sleep mode, register `dio_pad_sleep_mode` is set to 0 or 2. + - In sleep mode, previous `dio_out_o` is 0 and `dio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `dio_out_o` is 0 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: Dio1Backward_A + desc: '''`dio_out_o` should output 1 only if one of the following conditions meets: + - The corresponding `periph_to_dio_i` is 1. + - In sleep mode, register `dio_pad_sleep_mode` is set to 1. + - In sleep mode, previous `dio_out_o` is 1 and `dio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `dio_out_o` is 1 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `dio_oe_o` backward tests + // Symbolic variable `dio_sel_i` is used to select a specific `dio_oe_o` pin. + { + name: DioOe0Backward_A + desc: '''`dio_oe_o` should output 0 only if one of the following conditions meets: + - The corresponding `periph_to_dio_i` is 0. + - In sleep mode, register `dio_pad_sleep_mode` is set to 2. + - In sleep mode, previous `dio_oe_o` is 0 and `dio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `dio_oe_o` is 0 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: DioOe1Backward_A + desc: '''`dio_oe_o` should output 1 only if one of the following conditions meets: + - The corresponding `periph_to_dio_i` is 1. + - In sleep mode, register `dio_pad_sleep_mode` is set to 0 or 1. + - In sleep mode, previous `dio_oe_o` is 1 and `dio_pad_sleep_mode` is set to 3. + - In sleep mode, previous `dio_oe_o` is 1 and input `sleep_en_i` is not at posedge. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `mio_pad_attr_o` tests + { + name: MioAttrO_A + desc: '''`mio_attr_o` should be equal to corresponding `mio_pad_attr` register value and + TargetCfg's mio_pad_type configuration.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: MioJtagAttrO_A + desc: "If jtag is enabled, the jtag `mio_attr_o` index should be equal to 0." + stage: V1 + tests: ["pinmux_assert"] + } + + // `dio_pad_attr_o` tests + { + name: DioAttrO_A + desc: '''`dio_attr_o` should be equal to corresponding `dio_pad_attr` register value and + TargetCfg's dio_pad_type configuration.''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `pin_wkup_req_o` tests + // Symbolic variable `wkup_sel_i` is used to select a specific wkup_cause. + // Variable `final_pin_val` is created to capture selected wakeup pins based on register + // `wkup_detector_padsel` and `wkup_detector.filter`. + { + name: WkupPosedge_A + desc: '''When register `wkup_detector_en` is set to 1 and `wkup_detector.mode` is set to 0, + which means rising edge is used to detect wakeup. If variable `final_pin_val` is at + posedge then `wkup_cause` register's `de` attribute should be set to 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: WkupNegedge_A + desc: '''When register `wkup_detector_en` is set to 1 and `wkup_detector.mode` is set to 1, + which means falling edge is used to detect wakeup. If variable `final_pin_val` is at + negedge, then `wkup_cause` register's `de` attribute should be set to 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: WkupEdge_A + desc: '''When register `wkup_detector_en` is set to 1 and `wkup_detector.mode` is set to 2, + which means either rising or falling edge is used to detect wakeup. If variable + `final_pin_val` is at posedge or negedge, then `wkup_cause` register's `de` attribute + should be set to 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: WkupTimedHigh_A + desc: '''When register `wkup_detector_en` is set to 1 and `wkup_detector.mode` is set to 3, + which means postive pulse cycles are used to detect wakeup. If variable `final_pin_val` + stays high longer than the threshold, then `wkup_cause` register's `de` attribute + should be set to 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: WkupTimedLow_A + desc: '''When register `wkup_detector_en` is set to 1 and `wkup_detector.mode` is set to 4, + which means negative pulse cycles are used to detect wakeup. If variable `final_pin_val` + stays low longer than the threshold, then `wkup_cause` register's `de` attribute should + be set to 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: WkupCauseQ_A + desc: '''When `wkup_cause` register's `de` attribute is set to 1 and user is not writing to + `wkup_cause` at the same cycle, then `wkup_cause.q` should be set to 1.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: AonWkupO_A + desc: '''When register `wkup_cause` is 1, `pin_wkup_req_o` should also be 1. + `pin_wkup_req_o` is 0 only when all `wkup_cause` registers are 0.''' + stage: V1 + tests: ["pinmux_assert"] + } + + // `pin_wkup_req_o` backward tests + { + name: WkupCause0_A + desc: "Register `wkup_cause` is 0 only when none of the above wakeup conditions is met." + stage: V2 + tests: ["pinmux_assert"] + } + { + name: WkupCause1_A + desc: "Register `wkup_cause` is 1 when at least one of the above wakeup conditions is met." + stage: V2 + tests: ["pinmux_assert"] + } + + // `lc_jtag_o` tests + { + name: LcJtagWoScanmode_A + desc: '''Not in scanmode, when tap_strap select LC_tap, `lc_jtag_o` must be equal to the + corresponding `mio_in_i` pins based on the `TargetCfg` configuration.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: LcJtagWScanmode_A + desc: '''In scanmode, when tap_strap select LC_tap, `lc_jtag_o` must be equal to the + corresponding `mio_in_i` pins based on the `TargetCfg` configuration except the + `jtag_trst` pin, which must be equal to `rst_ni`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: LcJtagODefault_A + desc: "`lc_jtag_o` should stay 0 if tap_strap did not select LC_tap." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: LcJtagOBackward_A + desc: '''`lc_jtag_o` pins are equal to the corresponding `mio_in_i` inputs if one of the + following conditions are met: + - Lc Jtag is disabled and the corresponding pins are 0. + - Lc Jtag is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `rv_jtag_o` tests + { + name: RvJtagWoScanmode_A + desc: '''Not in scanmode, when tap_strap select RV_tap and `lc_hw_debug_en_i` input is On for + the past two clock cycles due to the synchronizer, then `rv_jtag_o` must be equal to + the corresponding `mio_in_i` pins based on the `TargetCfg` configuration.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: RvJtagWScanmode_A + desc: '''In scanmode, When tap_strap select RV_tap and `lc_hw_debug_en_i` is On for the past + two clock cycles due to the synchronizer, then `rv_jtag_o` must be equal to the + corresponding `mio_in_i` pins based on the `TargetCfg` configuration except the + `jtag_trst` pin, which must be equal to `rst_ni`. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: RvJtagODefault_A + desc: '''`rv_jtag_o` should stay 0 if tap_strap did not select RV_tap or `lc_hw_debug_en_i` + input is Off for the past two clock cycles due to the synchronizer.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: RvJtagOBackward_A + desc: '''`rv_jtag_o` pins are equal to the corresponding `mio_in_i` inputs if one of the + following conditions are met: + - Rv Jtag is disabled and the corresponding pins are 0. + - Rv Jtag is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + // `dft_jtag_o` tests + { + name: DftJtagWoScanmode_A + desc: '''Not in scanmode, when tap_strap select DFT_tap and `lc_dft_en_i` is On for the past + two clock cycles due to the synchronizer, `lc_jtag_o` must be equal to the + corresponding `mio_in_i` pins based on the `TargetCfg` configuration.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DftJtagWScanmode_A + desc: '''In scanmode, when tap_strap select DFT_tap and `lc_dft_en_i` is On for the past + two clock cycles due to the synchronizer, `lc_jtag_o` must be equal to the + corresponding `mio_in_i` pins based on the `TargetCfg` configuration except the + `jtag_trst` pin, which must be equal to `rst_ni`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DftJtagODefault_A + desc: '''`dft_jtag_o` should stay 0 if tap_strap did not select DFT_tap or the `lc_dft_en_i` + input is Off for the past two clock cycles due to the synchronizer.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DftJtagOBackward_A + desc: '''`dft_jtag_o` pins are equal to the corresponding `mio_in_i` inputs if one of the + following conditions are met: + - Dft Jtag is disabled and the corresponding pins are 0. + - Dft Jtag is enabled. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + { + name: DftJtagO1Backward_A + desc: '''`dft_jtag_o` pins are ones if one of the following conditions are met: + - Dft Jtag is enabled and the corresponding pins are 1. + ''' + stage: V2 + tests: ["pinmux_assert"] + } + + { + name: TapStrap_A + desc: '''If `dft_hold_tap_sel_i` is 0 and `lc_dft_en_i` is On for the past two clock cycles + due to the synchronizer, or `strap_en_i` is 1. + And in the meantime, if `lc_hw_debug_en_i` is On for the past two clock cycles due to + the synchronizer, then tap_strap must be equal to the past value of corresponding + `mio_in_i`. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: TapStrap0_A + desc: '''If `dft_hold_tap_sel_i` is 0 and `lc_dft_en_i` is On for the past two clock cycles + due to the synchronizer, or `strap_en_i` is 1. + Then tap_strap[0] must be equal to the past value of corresponding `mio_in_i`. + ''' + stage: V1 + tests: ["pinmux_assert"] + } + + // Jtag pinmux output tests + { + name: LcJtagI_A + desc: '''When Lc tap is selected, the corresponding `mio_out_o` and `mio_out_oe` should be + equal to `lc_jtag_i`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: RvJtagI_A + desc: '''When Rv tap is selected and `lc_hw_debug_en_i` is On for the past two clock cycles + due to the synchronizer, the corresponding `mio_out_o` and `mio_out_oe` should be equal + to `rv_jtag_i`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DftJtagI_A + desc: '''When Dft tap is selected and `lc_dft_en_i` is On for the past two clock cycles + due to the synchronizer, the corresponding `mio_out_o` and `mio_out_oe` should be equal + to `dft_jtag_i`.''' + stage: V1 + tests: ["pinmux_assert"] + } + + // Dft `strap_test_o` tests + { + name: DftStrapTestO_A + desc: '''When `lc_dft_en_i` is On for the past two clock cycles due to the synchronizer, + `dft_strap_test_o.valid` must be 1, and `dft_strap_test_o.straps` should be equal to + the corresponding `mio_in_i` index.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DftStrapTestOValidStable_A + desc: "`dft_strap_test_o.valid` once set to 1 will stay high until reset." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: DftStrapTestOStrapStable_A + desc: "`dft_strap_test_o.valid` once set, `dft_strap_test_o.straps` should stay stable." + stage: V1 + tests: ["pinmux_assert"] + } + + // USB related IOs. + // Current plan is to only check connectivity via assertions because usbdev design is fully + // verified separately in a DV testbench. + { + name: UsbSleepEnI_A + desc: "`sleep_en_i` should be connected directly to usbdev's `low_power_alw_i`." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbDppullupEnUpwrI_A + desc: '''`usb_dppullup_en_upwr_i` should be connected directly to usbdev's + `usb_dppullup_en_upwr_i`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbDnpullupEnUpwrI_A + desc: '''`usb_dnpullup_en_upwr_i` should be connected directly to usbdev's + `usb_dnpullup_en_upwr_i`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbDppullupEnO_A + desc: '''`usb_dppullup_en_o` should be connected directly to usbdev's + `usb_dppullup_en_o`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbDnpullupEnO_A + desc: '''`usb_dnpullup_en_o` should be connected directly to usbdev's + `usb_dnpullup_en_o`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbOutOfRstI_A + desc: "`usb_out_of_rst_i` should be connected directly to usbdev's `usb_out_of_rst_upwr_i`." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbAonWakeEnUpwrI_A + desc: '''`usb_aon_wake_en_i` should be connected directly to usbdev's + `usb_aon_wake_en_upwr_i`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbAonWakeAckUpwrI_A + desc: '''`usb_aon_wake_ack_i` should be connected directly to usbdev's + `usb_aon_woken_upwr_i`.''' + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbSuspendI_A + desc: "`usb_suspend_i` should be connected directly to usbdev's `usb_suspended_upwr_i`." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbWkupReqO_A + desc: "`usb_wkup_req_o` should be connected directly to usbdev's `wake_rep_alw_o`." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbBusResetO_A + desc: "`usb_bus_reset_o` should be connected directly to usbdev's `bus_reset_alw_o`." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbSenseLostO_A + desc: "`usb_sense_lost_o` should be connected directly to usbdev's `bus_lost_alw_o`." + stage: V1 + tests: ["pinmux_assert"] + } + { + name: UsbStateDebugO_A + desc: "`usb_state_debug_o` should be connected directly to usbdev's `bus_debug_o`." + stage: V1 + tests: ["pinmux_assert"] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_sec_cm_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_sec_cm_testplan.hjson new file mode 100644 index 0000000000000..61987929469c8 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/data/pinmux_sec_cm_testplan.hjson @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// .../pinmux/data/pinmux.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: +// .../pinmux/data/pinmux_testplan.hjson +{ + testpoints: [ + { + name: sec_cm_bus_integrity + desc: "Verify the countermeasure(s) BUS.INTEGRITY." + stage: V2S + tests: [] + } + { + name: sec_cm_lc_dft_en_intersig_mubi + desc: "Verify the countermeasure(s) LC_DFT_EN.INTERSIG.MUBI." + stage: V2S + tests: [] + } + { + name: sec_cm_lc_hw_debug_en_intersig_mubi + desc: "Verify the countermeasure(s) LC_HW_DEBUG_EN.INTERSIG.MUBI." + stage: V2S + tests: [] + } + { + name: sec_cm_lc_check_byp_en_intersig_mubi + desc: "Verify the countermeasure(s) LC_CHECK_BYP_EN.INTERSIG.MUBI." + stage: V2S + tests: [] + } + { + name: sec_cm_lc_escalate_en_intersig_mubi + desc: "Verify the countermeasure(s) LC_ESCALATE_EN.INTERSIG.MUBI." + stage: V2S + tests: [] + } + { + name: sec_cm_pinmux_hw_debug_en_intersig_mubi + desc: "Verify the countermeasure(s) PINMUX_HW_DEBUG_EN.INTERSIG.MUBI." + stage: V2S + tests: [] + } + { + name: sec_cm_tap_mux_lc_gated + desc: "Verify the countermeasure(s) TAP.MUX.LC_GATED." + stage: V2S + tests: [] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/data/top_englishbreakfast_pinmux.ipconfig.hjson b/hw/top_englishbreakfast/ip_autogen/pinmux/data/top_englishbreakfast_pinmux.ipconfig.hjson new file mode 100644 index 0000000000000..82e1a32e6028c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/data/top_englishbreakfast_pinmux.ipconfig.hjson @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + instance_name: top_englishbreakfast_pinmux + param_values: + { + n_wkup_detect: 8 + wkup_cnt_width: 8 + n_mio_pads: 47 + n_mio_periph_in: 38 + n_mio_periph_out: 35 + n_dio_pads: 14 + n_dio_periph_in: 12 + n_dio_periph_out: 12 + enable_usb_wakeup: true + enable_strap_sampling: true + top_pkg_vlnv: lowrisc:constants:top_englishbreakfast_top_pkg + scan_role_pkg_vlnv: lowrisc:systems:top_englishbreakfast_scan_role_pkg + topname: englishbreakfast + } +} diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/defs.bzl b/hw/top_englishbreakfast/ip_autogen/pinmux/defs.bzl new file mode 100644 index 0000000000000..2c612740eac3a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +load("//rules/opentitan:hw.bzl", "opentitan_ip") + +PINMUX = opentitan_ip( + name = "pinmux", + hjson = "//hw/top_englishbreakfast/ip_autogen/pinmux:data/pinmux.hjson", +) diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/checklist.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/checklist.md new file mode 100644 index 0000000000000..37f48b1992dea --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/checklist.md @@ -0,0 +1,267 @@ +# Pinmux Checklist + +This checklist is for [Hardware Stage](../../../../../doc/project_governance/development_stages.md) transitions for the [Pinmux 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 | [Pinmux spec](../README.md) +Documentation | [CSR_DEFINED][] | Done | +RTL | [CLKRST_CONNECTED][] | Done | +RTL | [IP_TOP][] | Done | +RTL | [IP_INSTANTIABLE][] | Done | +RTL | [PHYSICAL_MACROS_DEFINED_80][] | Done | +RTL | [FUNC_IMPLEMENTED][] | Done | +RTL | [ASSERT_KNOWN_ADDED][] | Done | Primary I/Os are exempted from KNOWN assertions since the chip-level testbench may drive X'es onto some of these signals. +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][] | Done | +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][] | N/A | + +[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][] | N/A | +Security | [SEC_CM_SHADOW_REGS][] | N/A | +Security | [SEC_CM_RTL_REVIEWED][] | N/A | +Security | [SEC_CM_COUNCIL_REVIEWED][] | N/A | This block only contains the bus-integrity CM. + +[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][] | Done | +RTL | [TODO_COMPLETE][] | Done | +Code Quality | [LINT_COMPLETE][] | Done | +Code Quality | [CDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Code Quality | [RDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Review | [REVIEW_RTL][] | Done | Note that the USB wakeup detector submodule `u_usbdev_aon_wake` is excluded in this review as it will be reviewed as part of the USB sign-off process. +Review | [REVIEW_DELETED_FF][] | Waived | No block-level flow available - waived to top-level signoff. +Review | [REVIEW_SW_CHANGE][] | Done | +Review | [REVIEW_SW_ERRATA][] | Done | +Review | Reviewer(s) | Done | msf@ tjaychen@ chencindy@ awill@ +Review | Signoff date | Done | 2022-08-17 + +[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 | +Documentation | [TESTPLAN_COMPLETED][] | Done | +Testbench | [TB_TOP_CREATED][] | Done | +Testbench | [PRELIMINARY_ASSERTION_CHECKS_ADDED][]| Done | +Testbench | [SIM_TB_ENV_CREATED][] | N/A | +Testbench | [SIM_RAL_MODEL_GEN_AUTOMATED][] | N/A | This block uses FPV +Testbench | [CSR_CHECK_GEN_AUTOMATED][] | Done | +Testbench | [TB_GEN_AUTOMATED][] | Done | +Tests | [SIM_SMOKE_TEST_PASSING][] | N/A | +Tests | [SIM_CSR_MEM_TEST_SUITE_PASSING][] | N/A | +Tests | [FPV_MAIN_ASSERTIONS_PROVEN][] | Done | +Tool Setup | [SIM_ALT_TOOL_SETUP][] | N/A | +Regression | [SIM_SMOKE_REGRESSION_SETUP][] | N/A | +Regression | [SIM_NIGHTLY_REGRESSION_SETUP][] | N/A | +Regression | [FPV_REGRESSION_SETUP][] | Done | +Coverage | [SIM_COVERAGE_MODEL_ADDED][] | N/A | +Code Quality | [TB_LINT_SETUP][] | Done | +Integration | [PRE_VERIFIED_SUB_MODULES_V1][] | Waived | usbdev will be verified by a separate DV testbench. +Review | [DESIGN_SPEC_REVIEWED][] | Not Started | +Review | [TESTPLAN_REVIEWED][] | Done | +Review | [STD_TEST_CATEGORIES_PLANNED][] | N/A | +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][] | N/A | +Tests | [SIM_ALL_TESTS_PASSING][] | N/A | +Tests | [FPV_ALL_ASSERTIONS_WRITTEN][] | Done | +Tests | [FPV_ALL_ASSUMPTIONS_REVIEWED][] | Done | +Tests | [SIM_FW_SIMULATED][] | N/A | +Regression | [SIM_NIGHTLY_REGRESSION_V2][] | N/A | +Coverage | [SIM_CODE_COVERAGE_V2][] | N/A | +Coverage | [SIM_FUNCTIONAL_COVERAGE_V2][] | N/A | +Coverage | [FPV_CODE_COVERAGE_V2][] | Done | +Coverage | [FPV_COI_COVERAGE_V2][] | Done | +Integration | [PRE_VERIFIED_SUB_MODULES_V2][] | Waived | usbdev will be verified by a separate DV testbench. +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 | The testplan has been generated, but there is no DV environment to test these CMs. The CMs (bus integrity and LC gated TAP muxing/demuxing) are tested with the FPV testbench instead. +Tests | [FPV_SEC_CM_PROVEN][] | Done | The SEC_CM behavior has been proven with formal. +Tests | [SIM_SEC_CM_VERIFIED][] | N/A | This module only has an FPV testbench. +Coverage | [SIM_COVERAGE_REVIEWED][] | N/A | This module only has an FPV testbench. +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_pendingg diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/README.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/README.md new file mode 100644 index 0000000000000..c96f03d0f50b2 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/README.md @@ -0,0 +1,35 @@ +# PINMUX DV document + +* **DV**: + * TODO: Add a UVM testbench to reuse auto-generated common tests for TLUL and alerts. + +* **FPV**: + * Verify all the PINMUX outputs by writing assumptions and assertions with a FPV based testbench + * Verify TileLink device protocol compliance with a FPV based testbench + +* [Design & verification stage](../../../../../README.md) + * [HW development stages](../../../../../../doc/project_governance/development_stages.md) +* [FPV dashboard](https://reports.opentitan.org/hw/top_englishbreakfast/formal/summary.html) + +For detailed information on PINMUX design features, please see the +[PINMUX design specification](../../README.md). + +PINMUX FPV testbench has been constructed based on the [formal architecture](../../../../../formal/README.md). + +![Block diagram](fpv.svg) + +* The `../fpv/tb/pinmux_bind.sv` binds the `tlul_assert` [assertions](../../../../../ip/tlul/doc/TlulProtocolChecker.md) with pinmux to ensure TileLink interface protocol compliance. +* The `../fpv/tb/pinmux_bind.sv` also binds the `pinmux_csr_assert_fpv` to assert the TileLink writes and reads correctly. + +* The `../fpv/tb/pinmux_bind_fpv.sv` binds module `pinmux_assert_fpv` with the pinmux RTL. +The assertion file ensures all pinmux's outputs are verified based on the [testplan](#testplan). + +In the pinmux design, it includes usbdev logic because it operates on an always-on domain. +Pinmux FPV assertions will only cover the connectivities between usbdev IOs and pinmux IOs. +All functional checks will be implemented in the usbdev testbench. + +Due to the large number of peripheral, muxed, dedicated IOs, and wakeup causes, symbolic variables are used to reduce the number of repeated assertions code. +In the pinmux_assert_fpv module, we declared four symbolic variables (`mio_sel_i`, `periph_sel_i`, `dio_sel_i`, `wkup_sel_i`) to represent the index for muxed IOs, peripheral IOs, dedicated IOs, and wakeup causes. +Detailed explanation is listed in the [Symbolic Variables](../../../../../formal/README.md#symbolic-variables) section. + +[Testplan](../../data/pinmux_fpv_testplan.hjson) diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/fpv.svg b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/fpv.svg new file mode 100644 index 0000000000000..0061e7fd012f5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/dv/fpv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/generic_pad_wrapper.svg b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/generic_pad_wrapper.svg new file mode 100644 index 0000000000000..bd95569d8ea00 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/generic_pad_wrapper.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/interfaces.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/interfaces.md new file mode 100644 index 0000000000000..60912cebf6113 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/interfaces.md @@ -0,0 +1,97 @@ +# Hardware Interfaces + + +Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`pinmux`** has the following hardware interfaces defined +- Primary Clock: **`clk_i`** +- Other Clocks: **`clk_aon_i`** +- Bus Device Interfaces (TL-UL): **`tl`** +- Bus Host Interfaces (TL-UL): *none* +- Peripheral Pins for Chip IO: *none* +- Interrupts: *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 | +|:--------------------------|:-------------------------------|:--------|:------|--------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| lc_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Debug enable qualifier coming from life cycle controller, used for HW strap qualification. | +| lc_dft_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Test enable qualifier coming from life cycle controller, used for HW strap qualification. | +| lc_escalate_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Escalation enable signal coming from life cycle controller, used for invalidating the latched lc_hw_debug_en state inside the strap sampling logic. | +| lc_check_byp_en | lc_ctrl_pkg::lc_tx | uni | rcv | 1 | Check bypass enable signal coming from life cycle controller, used for invalidating the latched lc_hw_debug_en state inside the strap sampling logic. This signal is asserted whenever the life cycle controller performs a life cycle transition. Its main use is to skip any background checks inside the life cycle partition of the OTP controller while a life cycle transition is in progress. | +| pinmux_hw_debug_en | lc_ctrl_pkg::lc_tx | uni | req | 1 | This is the latched version of lc_hw_debug_en_i. We use it exclusively to gate the JTAG signals and TAP side of the RV_DM so that RV_DM can remain live during an NDM reset cycle. | +| lc_jtag | jtag_pkg::jtag | req_rsp | req | 1 | Qualified JTAG signals for life cycle controller TAP. | +| rv_jtag | jtag_pkg::jtag | req_rsp | req | 1 | Qualified JTAG signals for RISC-V processor TAP. | +| dft_jtag | jtag_pkg::jtag | req_rsp | req | 1 | Qualified JTAG signals for DFT TAP. | +| dft_strap_test | pinmux_pkg::dft_strap_test_req | uni | req | 1 | Sampled DFT strap values, going to the DFT TAP. | +| dft_hold_tap_sel | logic | uni | rcv | 1 | TAP selection hold indication, asserted by the DFT TAP during boundary scan. | +| sleep_en | logic | uni | rcv | 1 | Level signal that is asserted when the power manager enters sleep. | +| strap_en | logic | uni | rcv | 1 | This signal is pulsed high by the power manager after reset in order to sample the HW straps. | +| strap_en_override | logic | uni | rcv | 1 | This signal transitions from 0 -> 1 by the lc_ctrl manager after volatile RAW_UNLOCK in order to re-sample the HW straps. The signal must stay at 1 until reset. Note that this is only used in test chips when SecVolatileRawUnlockEn = 1. Otherwise this signal is unused. | +| pin_wkup_req | logic | uni | req | 1 | Wakeup request from wakeup detectors, to the power manager, running on the AON clock. | +| usbdev_dppullup_en | logic | uni | rcv | 1 | Pullup enable signal coming from the USB IP. | +| usbdev_dnpullup_en | logic | uni | rcv | 1 | Pullup enable signal coming from the USB IP. | +| usb_dppullup_en | logic | uni | req | 1 | Pullup enable signal going to USB PHY, needs to be maintained in low-power mode. | +| usb_dnpullup_en | logic | uni | req | 1 | Pullup enable signal going to USB PHY, needs to be maintained in low-power mode. | +| usb_wkup_req | logic | uni | req | 1 | Wakeup request from USB wakeup detector, going to the power manager, running on the AON clock. | +| usbdev_suspend_req | logic | uni | rcv | 1 | Indicates whether USB is in suspended state, coming from the USB device. | +| usbdev_wake_ack | logic | uni | rcv | 1 | Acknowledges the USB wakeup request, coming from the USB device. | +| usbdev_bus_not_idle | logic | uni | req | 1 | Event signal that indicates that the USB was not idle while monitoring. | +| usbdev_bus_reset | logic | uni | req | 1 | Event signal that indicates that the USB issued a Bus Reset while monitoring. | +| usbdev_sense_lost | logic | uni | req | 1 | Event signal that indicates that USB SENSE signal was lost while monitoring. | +| usbdev_wake_detect_active | logic | uni | req | 1 | State debug information. | +| tl | tlul_pkg::tl | req_rsp | rsp | 1 | | + +## 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 | +|:----------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| PINMUX.BUS.INTEGRITY | End-to-end bus integrity scheme. | +| PINMUX.LC_DFT_EN.INTERSIG.MUBI | The life cycle DFT enable signal is multibit encoded. | +| PINMUX.LC_HW_DEBUG_EN.INTERSIG.MUBI | The life cycle hardware debug enable signal is multibit encoded. | +| PINMUX.LC_CHECK_BYP_EN.INTERSIG.MUBI | The life cycle check bypass signal is multibit encoded. | +| PINMUX.LC_ESCALATE_EN.INTERSIG.MUBI | The life cycle check bypass signal is multibit encoded. | +| PINMUX.PINMUX_HW_DEBUG_EN.INTERSIG.MUBI | In order to support the NDM reset feature in RV_DM, the pinmux latches the LC_HW_DEBUG_EN signal so that it can survive the NDM reset, and sends that signal on to the RV_DM for use in gating circuitry. This signal is also multibit encoded | +| PINMUX.TAP.MUX.LC_GATED | The TAP selection mux/demux in the strap sampling module is gated by life cycle signals so that the RV_DM can only be selected during when LC_HW_DEBUG_EN is asserted, and the DFT TAP can only be selected when LC_DFT_EN is asserted. | + + + + +## Parameters + +The following table lists the main parameters used throughout the `pinmux` design. +Note that the `pinmux` is generated based on the system configuration, and hence these parameters are placed into a package. +The pinout and `pinmux` mappings are listed under [Pinout and Pinmux Mapping](#pinout-and-pinmux-mapping) for specific top-level configurations. + +Parameter | Description +---------------|--------------- +`NPeriphOut` | Number of peripheral outputs. +`NPeriphIn` | Number of peripheral input. +`NMioPads` | Number of muxed bidirectional pads. +`NDioPads` | Number of dedicated pads. + +## Primary IO Signals + +The table below lists the primary `pinmux` IO signals to/from the pad ring. +The number of dedicated and muxed IOs is parametric, and hence the signals are stacked in packed arrays. + +Signal | Direction | Type | Description +---------------------------------------|-----------|------------------------------------|--------------- +`periph_to_mio_i[NPeriphOut-1:0]` | `input` | packed `logic` | Signals from `NPeriphOut` muxed peripheral outputs coming into the `pinmux`. +`periph_to_mio_oe_i[NPeriphOut-1:0]` | `input` | packed `logic` | Signals from `NPeriphOut` muxed peripheral output enables coming into the `pinmux`. +`mio_to_periph_o[NPeriphIn-1:0]` | `output` | packed `logic` | Signals to `NPeriphIn` muxed peripherals coming from the `pinmux`. +`periph_to_dio_i[NDioPads-1:0]` | `input` | packed `logic` | Signals from `NDioPads` dedicated peripheral outputs coming into the `pinmux`. +`periph_to_dio_oe_i[NDioPads-1:0]` | `input` | packed `logic` | Signals from `NDioPads` dedicated peripheral output enables coming into the `pinmux`. +`dio_to_periph_o[NDioPads-1:0]` | `output` | packed `logic` | Signals to `NDioPads` dedicated peripherals coming from the `pinmux`. +`mio_attr_o[NMioPads-1:0]` | `output` | prim_pad_wrapper_pkg::pad_attr_t | Packed array containing the pad attributes of all muxed IOs. +`mio_out_o[NMioPads-1:0]` | `output` | packed `logic` | Signals to `NMioPads` bidirectional muxed pads as output data. +`mio_oe_o[NMioPads-1:0]` | `output` | packed `logic` | Signals to `NMioPads` bidirectional muxed pads as output enables. +`mio_in_i[NMioPads-1:0]` | `input` | packed `logic` | Signals from `NMioPads` bidirectional muxed pads as input data. +`dio_attr_o[NDioPads-1:0]` | `output` | prim_pad_wrapper_pkg::pad_attr_t | Packed array containing the pad attributes of all dedicated IOs. +`dio_out_o[NDioPads-1:0]` | `output` | packed `logic` | Signals to `NDioPads` bidirectional dedicated pads as output data. +`dio_oe_o[NDioPads-1:0]` | `output` | packed `logic` | Signals to `NDioPads` bidirectional dedicated pads as output enables. +`dio_in_i[NDioPads-1:0]` | `input` | packed `logic` | Signals from `NDioPads` bidirectional dedicated pads as input data. diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_muxing_matrix.svg b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_muxing_matrix.svg new file mode 100644 index 0000000000000..0cd96b99002d7 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_muxing_matrix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_overview_block_diagram.svg b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_overview_block_diagram.svg new file mode 100644 index 0000000000000..895eec6e6da41 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinmux_overview_block_diagram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinout_cw305.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinout_cw305.md new file mode 100644 index 0000000000000..2f753506fc96d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/pinout_cw305.md @@ -0,0 +1,107 @@ +# "CW305" Target : Pinout and Pinmux Connectivity + +## Pinout Table + +|

Pad Name

|

Type

|

Bank

|

Connection

|

Special Function

|

Pinmux Insel Constant / Muxed Output Index

|

Description

| +|:-------------------------------------------------:|:-----------------------------------------:|:---------------------------------------:|:---------------------------------------------:|:---------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:| +|

POR_N

|

InputStd

|

VCC

|

manual

|

-

|

- / -

|

System reset

| +|

USB_P

|

BidirTol

|

VCC

|

manual

|

-

|

- / -

|

USB P signal

| +|

USB_N

|

BidirTol

|

VCC

|

manual

|

-

|

- / -

|

USB N signal

| +|

SPI_DEV_D0

|

BidirStd

|

VIOA

|

direct

|

tdi

|

- / -

|

SPI device data / JTAG tdi signal, overlaid on SPI_DEV.

| +|

SPI_DEV_D1

|

BidirStd

|

VIOA

|

direct

|

tdo

|

- / -

|

SPI device data / JTAG tdo signal, overlaid on SPI_DEV.

| +|

SPI_DEV_CLK

|

InputStd

|

VIOA

|

direct

|

tck

|

- / -

|

SPI device clock / JTAG tck signal, overlaid on SPI_DEV.

| +|

SPI_DEV_CS_L

|

InputStd

|

VIOA

|

direct

|

tms

|

- / -

|

SPI device chip select / JTAG tms signal, overlaid on SPI_DEV.

| +|

IOA0

|

BidirStd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa0 / kTopEnglishbreakfastPinmuxMioOutIoa0

|

Muxed IO pad

| +|

IOA1

|

BidirStd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa1 / kTopEnglishbreakfastPinmuxMioOutIoa1

|

Muxed IO pad

| +|

IOA2

|

BidirStd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa2 / kTopEnglishbreakfastPinmuxMioOutIoa2

|

Muxed IO pad

| +|

IOA3

|

BidirStd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa3 / kTopEnglishbreakfastPinmuxMioOutIoa3

|

Muxed IO pad

| +|

IOA4

|

BidirStd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa4 / kTopEnglishbreakfastPinmuxMioOutIoa4

|

Muxed IO pad

| +|

IOA5

|

BidirStd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa5 / kTopEnglishbreakfastPinmuxMioOutIoa5

|

Muxed IO pad

| +|

IOA6

|

BidirOd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa6 / kTopEnglishbreakfastPinmuxMioOutIoa6

|

Muxed IO pad

| +|

IOA7

|

BidirOd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa7 / kTopEnglishbreakfastPinmuxMioOutIoa7

|

Muxed IO pad

| +|

IOA8

|

BidirOd

|

VIOA

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoa8 / kTopEnglishbreakfastPinmuxMioOutIoa8

|

Muxed IO pad

| +|

IOB0

|

BidirStd

|

VIOB

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIob0 / kTopEnglishbreakfastPinmuxMioOutIob0

|

Muxed IO pad

| +|

IOB1

|

BidirStd

|

VIOB

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIob1 / kTopEnglishbreakfastPinmuxMioOutIob1

|

Muxed IO pad

| +|

IOB2

|

BidirStd

|

VIOB

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIob2 / kTopEnglishbreakfastPinmuxMioOutIob2

|

Muxed IO pad

| +|

IOB3

|

BidirStd

|

VIOB

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIob3 / kTopEnglishbreakfastPinmuxMioOutIob3

|

Muxed IO pad

| +|

IOB4

|

BidirStd

|

VIOB

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIob4 / kTopEnglishbreakfastPinmuxMioOutIob4

|

Muxed IO pad

| +|

IOB5

|

BidirStd

|

VIOB

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIob5 / kTopEnglishbreakfastPinmuxMioOutIob5

|

Muxed IO pad

| +|

IOB6

|

BidirStd

|

VIOB

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIob6 / kTopEnglishbreakfastPinmuxMioOutIob6

|

Muxed IO pad

| +|

IOC0

|

BidirStd

|

VCC

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoc0 / kTopEnglishbreakfastPinmuxMioOutIoc0

|

Muxed IO pad

| +|

IOC1

|

BidirStd

|

VCC

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoc1 / kTopEnglishbreakfastPinmuxMioOutIoc1

|

Muxed IO pad

| +|

IOC2

|

BidirStd

|

VCC

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoc2 / kTopEnglishbreakfastPinmuxMioOutIoc2

|

Muxed IO pad

| +|

IOC3

|

BidirStd

|

VCC

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoc3 / kTopEnglishbreakfastPinmuxMioOutIoc3

|

Muxed IO pad

| +|

IOC4

|

BidirStd

|

VCC

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxInselIoc4 / kTopEnglishbreakfastPinmuxMioOutIoc4

|

Muxed IO pad

| +|

IOC5

|

BidirStd

|

VCC

|

muxed

|

tap1

|

kTopEnglishbreakfastPinmuxInselIoc5 / kTopEnglishbreakfastPinmuxMioOutIoc5

|

Muxed IO pad / TAP strap signal.

| +|

IOC8

|

BidirStd

|

VCC

|

muxed

|

tap0

|

kTopEnglishbreakfastPinmuxInselIoc8 / kTopEnglishbreakfastPinmuxMioOutIoc8

|

Muxed IO pad / TAP strap signal.

| +|

IOR4

|

BidirStd

|

VCC

|

muxed

|

trst_n

|

kTopEnglishbreakfastPinmuxInselIor4 / kTopEnglishbreakfastPinmuxMioOutIor4

|

Muxed IO pad / JTAG trst_n signal.

| +|

IO_CLK

|

InputStd

|

VCC

|

manual

|

-

|

- / -

|

Extra clock input for FPGA target

| +|

POR_BUTTON_N

|

InputStd

|

VCC

|

manual

|

-

|

- / -

|

POR from the push-button

| +|

IO_USB_SENSE0

|

BidirStd

|

VCC

|

manual

|

-

|

- / -

|

Manual USB signal for FPGA target

| +|

IO_USB_DNPULLUP0

|

BidirStd

|

VCC

|

manual

|

-

|

- / -

|

Manual USB signal for FPGA target

| +|

IO_USB_DPPULLUP0

|

BidirStd

|

VCC

|

manual

|

-

|

- / -

|

Manual USB signal for FPGA target

| +|

IO_CLKOUT

|

BidirStd

|

VCC

|

manual

|

-

|

- / -

|

Manual clock output for SCA setup

| +|

IO_TRIGGER

|

BidirStd

|

VCC

|

manual

|

-

|

- / -

|

Manual trigger output for SCA setup

| +## Pinmux Connectivity + +|

Module / Signal

|

Connection

|

Pad

|

Pinmux Outsel Constant / Peripheral Input Index

|

Description

| +|:--------------------------------------------------:|:---------------------------------------------:|:----------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------:| +|

spi_host0_sd[0]

|

direct

|

SPI_HOST_D0

|

- / -

|

| +|

spi_host0_sd[1]

|

direct

|

SPI_HOST_D1

|

- / -

|

| +|

spi_host0_sd[2]

|

direct

|

SPI_HOST_D2

|

- / -

|

| +|

spi_host0_sd[3]

|

direct

|

SPI_HOST_D3

|

- / -

|

| +|

spi_device_sd[0]

|

direct

|

SPI_DEV_D0

|

- / -

|

| +|

spi_device_sd[1]

|

direct

|

SPI_DEV_D1

|

- / -

|

| +|

spi_device_sd[2]

|

direct

|

SPI_DEV_D2

|

- / -

|

| +|

spi_device_sd[3]

|

direct

|

SPI_DEV_D3

|

- / -

|

| +|

usbdev_usb_dp

|

manual

|

-

|

- / -

|

| +|

usbdev_usb_dn

|

manual

|

-

|

- / -

|

| +|

gpio_gpio[0]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio0 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio0

|

| +|

gpio_gpio[1]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio1 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio1

|

| +|

gpio_gpio[2]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio2 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio2

|

| +|

gpio_gpio[3]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio3 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio3

|

| +|

gpio_gpio[4]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio4 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio4

|

| +|

gpio_gpio[5]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio5 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio5

|

| +|

gpio_gpio[6]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio6 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio6

|

| +|

gpio_gpio[7]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio7 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio7

|

| +|

gpio_gpio[8]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio8 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio8

|

| +|

gpio_gpio[9]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio9 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio9

|

| +|

gpio_gpio[10]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio10 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio10

|

| +|

gpio_gpio[11]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio11 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio11

|

| +|

gpio_gpio[12]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio12 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio12

|

| +|

gpio_gpio[13]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio13 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio13

|

| +|

gpio_gpio[14]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio14 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio14

|

| +|

gpio_gpio[15]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio15 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio15

|

| +|

gpio_gpio[16]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio16 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio16

|

| +|

gpio_gpio[17]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio17 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio17

|

| +|

gpio_gpio[18]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio18 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio18

|

| +|

gpio_gpio[19]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio19 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio19

|

| +|

gpio_gpio[20]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio20 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio20

|

| +|

gpio_gpio[21]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio21 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio21

|

| +|

gpio_gpio[22]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio22 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio22

|

| +|

gpio_gpio[23]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio23 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio23

|

| +|

gpio_gpio[24]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio24 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio24

|

| +|

gpio_gpio[25]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio25 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio25

|

| +|

gpio_gpio[26]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio26 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio26

|

| +|

gpio_gpio[27]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio27 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio27

|

| +|

gpio_gpio[28]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio28 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio28

|

| +|

gpio_gpio[29]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio29 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio29

|

| +|

gpio_gpio[30]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio30 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio30

|

| +|

gpio_gpio[31]

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselGpioGpio31 / kTopEnglishbreakfastPinmuxPeripheralInGpioGpio31

|

| +|

spi_device_sck

|

direct

|

SPI_DEV_CLK

|

- / -

|

| +|

spi_device_csb

|

direct

|

SPI_DEV_CS_L

|

- / -

|

| +|

uart0_rx

|

muxed

|

-

|

- / kTopEnglishbreakfastPinmuxPeripheralInUart0Rx

|

| +|

uart1_rx

|

muxed

|

-

|

- / kTopEnglishbreakfastPinmuxPeripheralInUart1Rx

|

| +|

flash_ctrl_tck

|

muxed

|

-

|

- / kTopEnglishbreakfastPinmuxPeripheralInFlashCtrlTck

|

| +|

flash_ctrl_tms

|

muxed

|

-

|

- / kTopEnglishbreakfastPinmuxPeripheralInFlashCtrlTms

|

| +|

flash_ctrl_tdi

|

muxed

|

-

|

- / kTopEnglishbreakfastPinmuxPeripheralInFlashCtrlTdi

|

| +|

usbdev_sense

|

muxed

|

-

|

- / kTopEnglishbreakfastPinmuxPeripheralInUsbdevSense

|

| +|

spi_host0_sck

|

direct

|

SPI_HOST_CLK

|

- / -

|

| +|

spi_host0_csb

|

direct

|

SPI_HOST_CS_L

|

- / -

|

| +|

uart0_tx

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselUart0Tx / -

|

| +|

uart1_tx

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselUart1Tx / -

|

| +|

flash_ctrl_tdo

|

muxed

|

-

|

kTopEnglishbreakfastPinmuxOutselFlashCtrlTdo / -

|

| diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/programmers_guide.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/programmers_guide.md new file mode 100644 index 0000000000000..6bff0cd858749 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/programmers_guide.md @@ -0,0 +1,115 @@ +# Programmer's Guide + +## Pad Attributes + +Software should determine and program the pad attributes at startup, or reprogram the attributes when the functionality requirements change at runtime. + +This can be achieved by writing to the [`MIO_PAD_ATTR_0`](registers.md#mio_pad_attr) and [`DIO_PAD_ATTR_0`](registers.md#dio_pad_attr) registers. +Note that the IO attributes should be configured before enabling muxed IOs going through the `pinmux` matrix in order to avoid undesired electrical behavior and/or contention at the pads. + +The pad attributes configuration can be locked down individually for each pad via the [`MIO_PAD_ATTR_REGWEN_0`](registers.md#mio_pad_attr_regwen) and [`DIO_PAD_ATTR_REGWEN_0`](registers.md#dio_pad_attr_regwen) registers. +The configuration can then not be altered anymore until the next system reset. + +The following pad attributes are supported by this register layout by default: + +ATTR Bits | Description | Access +----------|-----------------------------------------------|--------- +0 | Input/output inversion | WARL +1 | Virtual open drain enable | WARL +2 | Pull enable | WARL +3 | Pull select (0: down, 1: up) | WARL +4 | Keeper enable | WARL +5 | Schmitt trigger enable | WARL +6 | Open drain enable | WARL +8:7 | Slew rate (0x0: slowest, 0x3: fastest) | WARL +12:9 | Drive strength (0x0: weakest, 0xf: strongest) | WARL + +Since some of the pad attributes may not be implemented, SW can probe this capability by writing the CSRs and read them back to determine whether the value was legal. +This behavior is also referred to as "writes-any-reads-legal" or "WARL" in the RISC-V world. +For example, certain pads may only support two drive-strength bits, instead of four. +The unsupported drive-strength bits in the corresponding CSRs would then always read as zero, even if SW attempts to set them to 1. + +## Pinmux Configuration + +Upon POR, the `pinmux` state is such that all MIO outputs are high-Z, and all MIO peripheral inputs are tied off to 0. +Software should determine and program the `pinmux` mapping at startup, or reprogram it when the functionality requirements change at runtime. +This can be achieved by writing the following values to the [`PERIPH_INSEL_0`](registers.md#periph_insel_0) and [`MIO_OUTSEL_0`](registers.md#mio_outsel) registers. + +`periph_insel` Value | Selected Input Signal +----------------------|----------------------- +0 | Constant zero (default) +1 | Constant one +2 + k | Corresponding MIO input signal at index k + +The global default at reset is `0`, but the default of individual signals can be overridden at design time, if needed. + +`mio_outsel` Value | Selected Output signal +----------------------|----------------------- +0 | Constant zero (default) +1 | Constant one +2 | High-Z +3 + k | Corresponding peripheral output signal at index k + +The global default at reset is `2`, but the default of individual signals can be overridden at design time, if needed. + +Note that the `pinmux` configuration should be sequenced after any IO attribute-specific configuration in the [`MIO_PAD_ATTR_0`](registers.md#mio_pad_attr) and [`DIO_PAD_ATTR_0`](registers.md#dio_pad_attr) registers to avoid any unwanted electric behavior and/or contention. +If needed, each select signal can be individually locked down via [`MIO_PERIPH_INSEL_REGWEN_0`](registers.md#mio_periph_insel_regwen) or [`MIO_OUTSEL_REGWEN_0`](registers.md#mio_outsel_regwen). +The configuration can then not be altered anymore until the next system reset. + +## Sleep Features + +The sleep behavior of each individual MIO or DIO can be defined via the (registers.md#mio_pad_sleep_en), [`DIO_PAD_SLEEP_EN_0`](registers.md#dio_pad_sleep_en), [`MIO_PAD_SLEEP_MODE_0`](registers.md#mio_pad_sleep_mode) and [`DIO_PAD_SLEEP_MODE_0`](registers.md#dio_pad_sleep_mode)) registers. +Available sleep behaviors are: + +`dio/mio_pad_sleep_en` Value | `dio/mio_pad_sleep_mode` Value | Sleep Behavior +------------------------------|--------------------------------|----------------------- +0 | - | Drive (default) +1 | 0 | Tie-low +1 | 1 | Tie-high +1 | 2 | High-Z +1 | 3 | Keep last value + +Note that if the behavior is set to "Drive", the sleep mode will not be activated upon sleep entry. +Rather, the retention logic continues to drive the value coming from the peripheral side. +Also note that the sleep logic is located after the `pinmux` matrix, hence the sleep configuration is per MIO pad and not per MIO peripheral. + +Before sleep entry, SW should configure the appropriate sleep behavior of all MIOs/DIOs via [`MIO_PAD_SLEEP_MODE_0`](registers.md#mio_pad_sleep_mode), [`DIO_PAD_SLEEP_MODE_0`](registers.md#dio_pad_sleep_mode). +This configuration can be optionally locked down, in which case it cannot be modified again until POR. +The configured behavior is then activated for all pads that have sleep mode set to enabled (registers.md#mio_pad_sleep_en) and [`DIO_PAD_SLEEP_EN_0`](registers.md#dio_pad_sleep_en)) at once by the power manager during the sleep entry sequence. + +When exiting sleep, the task of disabling the sleep behavior is however up to SW. +I.e., it must clear the per-pad sleep status bits in registers [`MIO_PAD_SLEEP_STATUS_0`](registers.md#mio_pad_sleep_status) and [`DIO_PAD_SLEEP_STATUS_0`](registers.md#dio_pad_sleep_status) that have been set upon sleep entry. +The rationale for this is that it may not be desirable to disable sleep behavior on all pads at once due to some additional book keeping / re-initialization that needs to be performed while exiting sleep. + +## Wakeup Features + +The `pinmux` contains eight wakeup detectors. +These detectors can be individually enabled and disabled regardless of the sleep state. +This ensures that SW can set them up before and disable them after sleep in order to ensure that no events are missed during sleep entry and exit. + +For more information on the patterns supported by the wakeup detectors, see [wakeup detectors](theory_of_operation.md#wakeup-detectors). + +A typical programming sequence for the wakeup detectors looks as follows: + +1. Before initiating any sleep mode, SW should configure the wakeup detectors appropriately and enable them via the [`WKUP_DETECTOR_0`](registers.md#wkup_detector), [`WKUP_DETECTOR_CNT_TH_0`](registers.md#wkup_detector_cnt_th) and [`WKUP_DETECTOR_PADSEL_0`](registers.md#wkup_detector_padsel) registers. + +2. Optionally, lock the wakeup detector configuration via the [`WKUP_DETECTOR_REGWEN_0`](registers.md#wkup_detector_regwen) registers. + +3. During sleep, the wakeup detectors will trigger a wakeup request if a matching pattern has been observed. + A bit corresponding to the wakeup detector that has observed the pattern will be set in the [`WKUP_CAUSE`](registers.md#wkup_cause) register. + +4. When exiting sleep, SW should read the wake info register in the [power manager](../../pwrmgr/README.md) to determine the reason(s) for the wakeup request. + +5. If the wakeup request was due to a pin wakeup pattern detector, SW should inspect the [`WKUP_CAUSE`](registers.md#wkup_cause) registers in order to determine the exact cause. + +6. SW should in any case disable the wakeup detectors and clear the [`WKUP_CAUSE`](registers.md#wkup_cause) registers once it is safe to do so (in order to not miss any events). + Note that the [`WKUP_CAUSE`](registers.md#wkup_cause) registers reside in the slow AON clock domain, and hence clearing them takes a few uS to take effect. + If needed, a SW readback can be performed to ensure that the clear operation has completed successfully. + +## Pinout and Pinmux Mapping + +Please see the specific documentation for detailed pinout and pinmux mapping tables for [this top](../doc/targets.md). + +## Device Interface Functions (DIFs) + +- [Device Interface Functions](../../../../../sw/device/lib/dif/dif_pinmux.h) diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/registers.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/registers.md new file mode 100644 index 0000000000000..49bc869cb93e6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/registers.md @@ -0,0 +1,1813 @@ +# Registers + + +## Summary + +| Name | Offset | Length | Description | +|:----------------------------------------------------------------|:---------|---------:|:--------------------------------------------------------------------| +| pinmux.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_0`](#mio_periph_insel_regwen) | 0x4 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_1`](#mio_periph_insel_regwen) | 0x8 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_2`](#mio_periph_insel_regwen) | 0xc | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_3`](#mio_periph_insel_regwen) | 0x10 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_4`](#mio_periph_insel_regwen) | 0x14 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_5`](#mio_periph_insel_regwen) | 0x18 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_6`](#mio_periph_insel_regwen) | 0x1c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_7`](#mio_periph_insel_regwen) | 0x20 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_8`](#mio_periph_insel_regwen) | 0x24 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_9`](#mio_periph_insel_regwen) | 0x28 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_10`](#mio_periph_insel_regwen) | 0x2c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_11`](#mio_periph_insel_regwen) | 0x30 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_12`](#mio_periph_insel_regwen) | 0x34 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_13`](#mio_periph_insel_regwen) | 0x38 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_14`](#mio_periph_insel_regwen) | 0x3c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_15`](#mio_periph_insel_regwen) | 0x40 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_16`](#mio_periph_insel_regwen) | 0x44 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_17`](#mio_periph_insel_regwen) | 0x48 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_18`](#mio_periph_insel_regwen) | 0x4c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_19`](#mio_periph_insel_regwen) | 0x50 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_20`](#mio_periph_insel_regwen) | 0x54 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_21`](#mio_periph_insel_regwen) | 0x58 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_22`](#mio_periph_insel_regwen) | 0x5c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_23`](#mio_periph_insel_regwen) | 0x60 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_24`](#mio_periph_insel_regwen) | 0x64 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_25`](#mio_periph_insel_regwen) | 0x68 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_26`](#mio_periph_insel_regwen) | 0x6c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_27`](#mio_periph_insel_regwen) | 0x70 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_28`](#mio_periph_insel_regwen) | 0x74 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_29`](#mio_periph_insel_regwen) | 0x78 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_30`](#mio_periph_insel_regwen) | 0x7c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_31`](#mio_periph_insel_regwen) | 0x80 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_32`](#mio_periph_insel_regwen) | 0x84 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_33`](#mio_periph_insel_regwen) | 0x88 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_34`](#mio_periph_insel_regwen) | 0x8c | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_35`](#mio_periph_insel_regwen) | 0x90 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_36`](#mio_periph_insel_regwen) | 0x94 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_REGWEN_37`](#mio_periph_insel_regwen) | 0x98 | 4 | Register write enable for MIO peripheral input selects. | +| pinmux.[`MIO_PERIPH_INSEL_0`](#mio_periph_insel) | 0x9c | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_1`](#mio_periph_insel) | 0xa0 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_2`](#mio_periph_insel) | 0xa4 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_3`](#mio_periph_insel) | 0xa8 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_4`](#mio_periph_insel) | 0xac | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_5`](#mio_periph_insel) | 0xb0 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_6`](#mio_periph_insel) | 0xb4 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_7`](#mio_periph_insel) | 0xb8 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_8`](#mio_periph_insel) | 0xbc | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_9`](#mio_periph_insel) | 0xc0 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_10`](#mio_periph_insel) | 0xc4 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_11`](#mio_periph_insel) | 0xc8 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_12`](#mio_periph_insel) | 0xcc | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_13`](#mio_periph_insel) | 0xd0 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_14`](#mio_periph_insel) | 0xd4 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_15`](#mio_periph_insel) | 0xd8 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_16`](#mio_periph_insel) | 0xdc | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_17`](#mio_periph_insel) | 0xe0 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_18`](#mio_periph_insel) | 0xe4 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_19`](#mio_periph_insel) | 0xe8 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_20`](#mio_periph_insel) | 0xec | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_21`](#mio_periph_insel) | 0xf0 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_22`](#mio_periph_insel) | 0xf4 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_23`](#mio_periph_insel) | 0xf8 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_24`](#mio_periph_insel) | 0xfc | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_25`](#mio_periph_insel) | 0x100 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_26`](#mio_periph_insel) | 0x104 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_27`](#mio_periph_insel) | 0x108 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_28`](#mio_periph_insel) | 0x10c | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_29`](#mio_periph_insel) | 0x110 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_30`](#mio_periph_insel) | 0x114 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_31`](#mio_periph_insel) | 0x118 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_32`](#mio_periph_insel) | 0x11c | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_33`](#mio_periph_insel) | 0x120 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_34`](#mio_periph_insel) | 0x124 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_35`](#mio_periph_insel) | 0x128 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_36`](#mio_periph_insel) | 0x12c | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_PERIPH_INSEL_37`](#mio_periph_insel) | 0x130 | 4 | For each peripheral input, this selects the muxable pad input. | +| pinmux.[`MIO_OUTSEL_REGWEN_0`](#mio_outsel_regwen) | 0x134 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_1`](#mio_outsel_regwen) | 0x138 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_2`](#mio_outsel_regwen) | 0x13c | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_3`](#mio_outsel_regwen) | 0x140 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_4`](#mio_outsel_regwen) | 0x144 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_5`](#mio_outsel_regwen) | 0x148 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_6`](#mio_outsel_regwen) | 0x14c | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_7`](#mio_outsel_regwen) | 0x150 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_8`](#mio_outsel_regwen) | 0x154 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_9`](#mio_outsel_regwen) | 0x158 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_10`](#mio_outsel_regwen) | 0x15c | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_11`](#mio_outsel_regwen) | 0x160 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_12`](#mio_outsel_regwen) | 0x164 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_13`](#mio_outsel_regwen) | 0x168 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_14`](#mio_outsel_regwen) | 0x16c | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_15`](#mio_outsel_regwen) | 0x170 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_16`](#mio_outsel_regwen) | 0x174 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_17`](#mio_outsel_regwen) | 0x178 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_18`](#mio_outsel_regwen) | 0x17c | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_19`](#mio_outsel_regwen) | 0x180 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_20`](#mio_outsel_regwen) | 0x184 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_21`](#mio_outsel_regwen) | 0x188 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_22`](#mio_outsel_regwen) | 0x18c | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_23`](#mio_outsel_regwen) | 0x190 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_24`](#mio_outsel_regwen) | 0x194 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_25`](#mio_outsel_regwen) | 0x198 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_26`](#mio_outsel_regwen) | 0x19c | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_27`](#mio_outsel_regwen) | 0x1a0 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_28`](#mio_outsel_regwen) | 0x1a4 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_29`](#mio_outsel_regwen) | 0x1a8 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_30`](#mio_outsel_regwen) | 0x1ac | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_31`](#mio_outsel_regwen) | 0x1b0 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_32`](#mio_outsel_regwen) | 0x1b4 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_33`](#mio_outsel_regwen) | 0x1b8 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_34`](#mio_outsel_regwen) | 0x1bc | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_35`](#mio_outsel_regwen) | 0x1c0 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_36`](#mio_outsel_regwen) | 0x1c4 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_37`](#mio_outsel_regwen) | 0x1c8 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_38`](#mio_outsel_regwen) | 0x1cc | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_39`](#mio_outsel_regwen) | 0x1d0 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_40`](#mio_outsel_regwen) | 0x1d4 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_41`](#mio_outsel_regwen) | 0x1d8 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_42`](#mio_outsel_regwen) | 0x1dc | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_43`](#mio_outsel_regwen) | 0x1e0 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_44`](#mio_outsel_regwen) | 0x1e4 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_45`](#mio_outsel_regwen) | 0x1e8 | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_REGWEN_46`](#mio_outsel_regwen) | 0x1ec | 4 | Register write enable for MIO output selects. | +| pinmux.[`MIO_OUTSEL_0`](#mio_outsel) | 0x1f0 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_1`](#mio_outsel) | 0x1f4 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_2`](#mio_outsel) | 0x1f8 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_3`](#mio_outsel) | 0x1fc | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_4`](#mio_outsel) | 0x200 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_5`](#mio_outsel) | 0x204 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_6`](#mio_outsel) | 0x208 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_7`](#mio_outsel) | 0x20c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_8`](#mio_outsel) | 0x210 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_9`](#mio_outsel) | 0x214 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_10`](#mio_outsel) | 0x218 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_11`](#mio_outsel) | 0x21c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_12`](#mio_outsel) | 0x220 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_13`](#mio_outsel) | 0x224 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_14`](#mio_outsel) | 0x228 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_15`](#mio_outsel) | 0x22c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_16`](#mio_outsel) | 0x230 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_17`](#mio_outsel) | 0x234 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_18`](#mio_outsel) | 0x238 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_19`](#mio_outsel) | 0x23c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_20`](#mio_outsel) | 0x240 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_21`](#mio_outsel) | 0x244 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_22`](#mio_outsel) | 0x248 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_23`](#mio_outsel) | 0x24c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_24`](#mio_outsel) | 0x250 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_25`](#mio_outsel) | 0x254 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_26`](#mio_outsel) | 0x258 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_27`](#mio_outsel) | 0x25c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_28`](#mio_outsel) | 0x260 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_29`](#mio_outsel) | 0x264 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_30`](#mio_outsel) | 0x268 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_31`](#mio_outsel) | 0x26c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_32`](#mio_outsel) | 0x270 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_33`](#mio_outsel) | 0x274 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_34`](#mio_outsel) | 0x278 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_35`](#mio_outsel) | 0x27c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_36`](#mio_outsel) | 0x280 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_37`](#mio_outsel) | 0x284 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_38`](#mio_outsel) | 0x288 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_39`](#mio_outsel) | 0x28c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_40`](#mio_outsel) | 0x290 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_41`](#mio_outsel) | 0x294 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_42`](#mio_outsel) | 0x298 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_43`](#mio_outsel) | 0x29c | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_44`](#mio_outsel) | 0x2a0 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_45`](#mio_outsel) | 0x2a4 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_OUTSEL_46`](#mio_outsel) | 0x2a8 | 4 | For each muxable pad, this selects the peripheral output. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_0`](#mio_pad_attr_regwen) | 0x2ac | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_1`](#mio_pad_attr_regwen) | 0x2b0 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_2`](#mio_pad_attr_regwen) | 0x2b4 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_3`](#mio_pad_attr_regwen) | 0x2b8 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_4`](#mio_pad_attr_regwen) | 0x2bc | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_5`](#mio_pad_attr_regwen) | 0x2c0 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_6`](#mio_pad_attr_regwen) | 0x2c4 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_7`](#mio_pad_attr_regwen) | 0x2c8 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_8`](#mio_pad_attr_regwen) | 0x2cc | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_9`](#mio_pad_attr_regwen) | 0x2d0 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_10`](#mio_pad_attr_regwen) | 0x2d4 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_11`](#mio_pad_attr_regwen) | 0x2d8 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_12`](#mio_pad_attr_regwen) | 0x2dc | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_13`](#mio_pad_attr_regwen) | 0x2e0 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_14`](#mio_pad_attr_regwen) | 0x2e4 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_15`](#mio_pad_attr_regwen) | 0x2e8 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_16`](#mio_pad_attr_regwen) | 0x2ec | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_17`](#mio_pad_attr_regwen) | 0x2f0 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_18`](#mio_pad_attr_regwen) | 0x2f4 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_19`](#mio_pad_attr_regwen) | 0x2f8 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_20`](#mio_pad_attr_regwen) | 0x2fc | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_21`](#mio_pad_attr_regwen) | 0x300 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_22`](#mio_pad_attr_regwen) | 0x304 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_23`](#mio_pad_attr_regwen) | 0x308 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_24`](#mio_pad_attr_regwen) | 0x30c | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_25`](#mio_pad_attr_regwen) | 0x310 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_26`](#mio_pad_attr_regwen) | 0x314 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_27`](#mio_pad_attr_regwen) | 0x318 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_28`](#mio_pad_attr_regwen) | 0x31c | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_29`](#mio_pad_attr_regwen) | 0x320 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_30`](#mio_pad_attr_regwen) | 0x324 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_31`](#mio_pad_attr_regwen) | 0x328 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_32`](#mio_pad_attr_regwen) | 0x32c | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_33`](#mio_pad_attr_regwen) | 0x330 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_34`](#mio_pad_attr_regwen) | 0x334 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_35`](#mio_pad_attr_regwen) | 0x338 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_36`](#mio_pad_attr_regwen) | 0x33c | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_37`](#mio_pad_attr_regwen) | 0x340 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_38`](#mio_pad_attr_regwen) | 0x344 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_39`](#mio_pad_attr_regwen) | 0x348 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_40`](#mio_pad_attr_regwen) | 0x34c | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_41`](#mio_pad_attr_regwen) | 0x350 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_42`](#mio_pad_attr_regwen) | 0x354 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_43`](#mio_pad_attr_regwen) | 0x358 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_44`](#mio_pad_attr_regwen) | 0x35c | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_45`](#mio_pad_attr_regwen) | 0x360 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_REGWEN_46`](#mio_pad_attr_regwen) | 0x364 | 4 | Register write enable for MIO PAD attributes. | +| pinmux.[`MIO_PAD_ATTR_0`](#mio_pad_attr) | 0x368 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_1`](#mio_pad_attr) | 0x36c | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_2`](#mio_pad_attr) | 0x370 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_3`](#mio_pad_attr) | 0x374 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_4`](#mio_pad_attr) | 0x378 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_5`](#mio_pad_attr) | 0x37c | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_6`](#mio_pad_attr) | 0x380 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_7`](#mio_pad_attr) | 0x384 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_8`](#mio_pad_attr) | 0x388 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_9`](#mio_pad_attr) | 0x38c | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_10`](#mio_pad_attr) | 0x390 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_11`](#mio_pad_attr) | 0x394 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_12`](#mio_pad_attr) | 0x398 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_13`](#mio_pad_attr) | 0x39c | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_14`](#mio_pad_attr) | 0x3a0 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_15`](#mio_pad_attr) | 0x3a4 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_16`](#mio_pad_attr) | 0x3a8 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_17`](#mio_pad_attr) | 0x3ac | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_18`](#mio_pad_attr) | 0x3b0 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_19`](#mio_pad_attr) | 0x3b4 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_20`](#mio_pad_attr) | 0x3b8 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_21`](#mio_pad_attr) | 0x3bc | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_22`](#mio_pad_attr) | 0x3c0 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_23`](#mio_pad_attr) | 0x3c4 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_24`](#mio_pad_attr) | 0x3c8 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_25`](#mio_pad_attr) | 0x3cc | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_26`](#mio_pad_attr) | 0x3d0 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_27`](#mio_pad_attr) | 0x3d4 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_28`](#mio_pad_attr) | 0x3d8 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_29`](#mio_pad_attr) | 0x3dc | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_30`](#mio_pad_attr) | 0x3e0 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_31`](#mio_pad_attr) | 0x3e4 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_32`](#mio_pad_attr) | 0x3e8 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_33`](#mio_pad_attr) | 0x3ec | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_34`](#mio_pad_attr) | 0x3f0 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_35`](#mio_pad_attr) | 0x3f4 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_36`](#mio_pad_attr) | 0x3f8 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_37`](#mio_pad_attr) | 0x3fc | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_38`](#mio_pad_attr) | 0x400 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_39`](#mio_pad_attr) | 0x404 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_40`](#mio_pad_attr) | 0x408 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_41`](#mio_pad_attr) | 0x40c | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_42`](#mio_pad_attr) | 0x410 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_43`](#mio_pad_attr) | 0x414 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_44`](#mio_pad_attr) | 0x418 | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_45`](#mio_pad_attr) | 0x41c | 4 | Muxed pad attributes. | +| pinmux.[`MIO_PAD_ATTR_46`](#mio_pad_attr) | 0x420 | 4 | Muxed pad attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_0`](#dio_pad_attr_regwen) | 0x424 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_1`](#dio_pad_attr_regwen) | 0x428 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_2`](#dio_pad_attr_regwen) | 0x42c | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_3`](#dio_pad_attr_regwen) | 0x430 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_4`](#dio_pad_attr_regwen) | 0x434 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_5`](#dio_pad_attr_regwen) | 0x438 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_6`](#dio_pad_attr_regwen) | 0x43c | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_7`](#dio_pad_attr_regwen) | 0x440 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_8`](#dio_pad_attr_regwen) | 0x444 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_9`](#dio_pad_attr_regwen) | 0x448 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_10`](#dio_pad_attr_regwen) | 0x44c | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_11`](#dio_pad_attr_regwen) | 0x450 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_12`](#dio_pad_attr_regwen) | 0x454 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_REGWEN_13`](#dio_pad_attr_regwen) | 0x458 | 4 | Register write enable for DIO PAD attributes. | +| pinmux.[`DIO_PAD_ATTR_0`](#dio_pad_attr) | 0x45c | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_1`](#dio_pad_attr) | 0x460 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_2`](#dio_pad_attr) | 0x464 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_3`](#dio_pad_attr) | 0x468 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_4`](#dio_pad_attr) | 0x46c | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_5`](#dio_pad_attr) | 0x470 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_6`](#dio_pad_attr) | 0x474 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_7`](#dio_pad_attr) | 0x478 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_8`](#dio_pad_attr) | 0x47c | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_9`](#dio_pad_attr) | 0x480 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_10`](#dio_pad_attr) | 0x484 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_11`](#dio_pad_attr) | 0x488 | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_12`](#dio_pad_attr) | 0x48c | 4 | Dedicated pad attributes. | +| pinmux.[`DIO_PAD_ATTR_13`](#dio_pad_attr) | 0x490 | 4 | Dedicated pad attributes. | +| pinmux.[`MIO_PAD_SLEEP_STATUS_0`](#MIO_PAD_SLEEP_STATUS_0) | 0x494 | 4 | Register indicating whether the corresponding pad is in sleep mode. | +| pinmux.[`MIO_PAD_SLEEP_STATUS_1`](#MIO_PAD_SLEEP_STATUS_1) | 0x498 | 4 | Register indicating whether the corresponding pad is in sleep mode. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_0`](#mio_pad_sleep_regwen) | 0x49c | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_1`](#mio_pad_sleep_regwen) | 0x4a0 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_2`](#mio_pad_sleep_regwen) | 0x4a4 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_3`](#mio_pad_sleep_regwen) | 0x4a8 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_4`](#mio_pad_sleep_regwen) | 0x4ac | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_5`](#mio_pad_sleep_regwen) | 0x4b0 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_6`](#mio_pad_sleep_regwen) | 0x4b4 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_7`](#mio_pad_sleep_regwen) | 0x4b8 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_8`](#mio_pad_sleep_regwen) | 0x4bc | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_9`](#mio_pad_sleep_regwen) | 0x4c0 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_10`](#mio_pad_sleep_regwen) | 0x4c4 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_11`](#mio_pad_sleep_regwen) | 0x4c8 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_12`](#mio_pad_sleep_regwen) | 0x4cc | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_13`](#mio_pad_sleep_regwen) | 0x4d0 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_14`](#mio_pad_sleep_regwen) | 0x4d4 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_15`](#mio_pad_sleep_regwen) | 0x4d8 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_16`](#mio_pad_sleep_regwen) | 0x4dc | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_17`](#mio_pad_sleep_regwen) | 0x4e0 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_18`](#mio_pad_sleep_regwen) | 0x4e4 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_19`](#mio_pad_sleep_regwen) | 0x4e8 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_20`](#mio_pad_sleep_regwen) | 0x4ec | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_21`](#mio_pad_sleep_regwen) | 0x4f0 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_22`](#mio_pad_sleep_regwen) | 0x4f4 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_23`](#mio_pad_sleep_regwen) | 0x4f8 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_24`](#mio_pad_sleep_regwen) | 0x4fc | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_25`](#mio_pad_sleep_regwen) | 0x500 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_26`](#mio_pad_sleep_regwen) | 0x504 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_27`](#mio_pad_sleep_regwen) | 0x508 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_28`](#mio_pad_sleep_regwen) | 0x50c | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_29`](#mio_pad_sleep_regwen) | 0x510 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_30`](#mio_pad_sleep_regwen) | 0x514 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_31`](#mio_pad_sleep_regwen) | 0x518 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_32`](#mio_pad_sleep_regwen) | 0x51c | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_33`](#mio_pad_sleep_regwen) | 0x520 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_34`](#mio_pad_sleep_regwen) | 0x524 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_35`](#mio_pad_sleep_regwen) | 0x528 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_36`](#mio_pad_sleep_regwen) | 0x52c | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_37`](#mio_pad_sleep_regwen) | 0x530 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_38`](#mio_pad_sleep_regwen) | 0x534 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_39`](#mio_pad_sleep_regwen) | 0x538 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_40`](#mio_pad_sleep_regwen) | 0x53c | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_41`](#mio_pad_sleep_regwen) | 0x540 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_42`](#mio_pad_sleep_regwen) | 0x544 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_43`](#mio_pad_sleep_regwen) | 0x548 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_44`](#mio_pad_sleep_regwen) | 0x54c | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_45`](#mio_pad_sleep_regwen) | 0x550 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_REGWEN_46`](#mio_pad_sleep_regwen) | 0x554 | 4 | Register write enable for MIO sleep value configuration. | +| pinmux.[`MIO_PAD_SLEEP_EN_0`](#mio_pad_sleep_en) | 0x558 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_1`](#mio_pad_sleep_en) | 0x55c | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_2`](#mio_pad_sleep_en) | 0x560 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_3`](#mio_pad_sleep_en) | 0x564 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_4`](#mio_pad_sleep_en) | 0x568 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_5`](#mio_pad_sleep_en) | 0x56c | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_6`](#mio_pad_sleep_en) | 0x570 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_7`](#mio_pad_sleep_en) | 0x574 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_8`](#mio_pad_sleep_en) | 0x578 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_9`](#mio_pad_sleep_en) | 0x57c | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_10`](#mio_pad_sleep_en) | 0x580 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_11`](#mio_pad_sleep_en) | 0x584 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_12`](#mio_pad_sleep_en) | 0x588 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_13`](#mio_pad_sleep_en) | 0x58c | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_14`](#mio_pad_sleep_en) | 0x590 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_15`](#mio_pad_sleep_en) | 0x594 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_16`](#mio_pad_sleep_en) | 0x598 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_17`](#mio_pad_sleep_en) | 0x59c | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_18`](#mio_pad_sleep_en) | 0x5a0 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_19`](#mio_pad_sleep_en) | 0x5a4 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_20`](#mio_pad_sleep_en) | 0x5a8 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_21`](#mio_pad_sleep_en) | 0x5ac | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_22`](#mio_pad_sleep_en) | 0x5b0 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_23`](#mio_pad_sleep_en) | 0x5b4 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_24`](#mio_pad_sleep_en) | 0x5b8 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_25`](#mio_pad_sleep_en) | 0x5bc | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_26`](#mio_pad_sleep_en) | 0x5c0 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_27`](#mio_pad_sleep_en) | 0x5c4 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_28`](#mio_pad_sleep_en) | 0x5c8 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_29`](#mio_pad_sleep_en) | 0x5cc | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_30`](#mio_pad_sleep_en) | 0x5d0 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_31`](#mio_pad_sleep_en) | 0x5d4 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_32`](#mio_pad_sleep_en) | 0x5d8 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_33`](#mio_pad_sleep_en) | 0x5dc | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_34`](#mio_pad_sleep_en) | 0x5e0 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_35`](#mio_pad_sleep_en) | 0x5e4 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_36`](#mio_pad_sleep_en) | 0x5e8 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_37`](#mio_pad_sleep_en) | 0x5ec | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_38`](#mio_pad_sleep_en) | 0x5f0 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_39`](#mio_pad_sleep_en) | 0x5f4 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_40`](#mio_pad_sleep_en) | 0x5f8 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_41`](#mio_pad_sleep_en) | 0x5fc | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_42`](#mio_pad_sleep_en) | 0x600 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_43`](#mio_pad_sleep_en) | 0x604 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_44`](#mio_pad_sleep_en) | 0x608 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_45`](#mio_pad_sleep_en) | 0x60c | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_EN_46`](#mio_pad_sleep_en) | 0x610 | 4 | Enables the sleep mode of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_0`](#mio_pad_sleep_mode) | 0x614 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_1`](#mio_pad_sleep_mode) | 0x618 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_2`](#mio_pad_sleep_mode) | 0x61c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_3`](#mio_pad_sleep_mode) | 0x620 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_4`](#mio_pad_sleep_mode) | 0x624 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_5`](#mio_pad_sleep_mode) | 0x628 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_6`](#mio_pad_sleep_mode) | 0x62c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_7`](#mio_pad_sleep_mode) | 0x630 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_8`](#mio_pad_sleep_mode) | 0x634 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_9`](#mio_pad_sleep_mode) | 0x638 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_10`](#mio_pad_sleep_mode) | 0x63c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_11`](#mio_pad_sleep_mode) | 0x640 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_12`](#mio_pad_sleep_mode) | 0x644 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_13`](#mio_pad_sleep_mode) | 0x648 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_14`](#mio_pad_sleep_mode) | 0x64c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_15`](#mio_pad_sleep_mode) | 0x650 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_16`](#mio_pad_sleep_mode) | 0x654 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_17`](#mio_pad_sleep_mode) | 0x658 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_18`](#mio_pad_sleep_mode) | 0x65c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_19`](#mio_pad_sleep_mode) | 0x660 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_20`](#mio_pad_sleep_mode) | 0x664 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_21`](#mio_pad_sleep_mode) | 0x668 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_22`](#mio_pad_sleep_mode) | 0x66c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_23`](#mio_pad_sleep_mode) | 0x670 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_24`](#mio_pad_sleep_mode) | 0x674 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_25`](#mio_pad_sleep_mode) | 0x678 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_26`](#mio_pad_sleep_mode) | 0x67c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_27`](#mio_pad_sleep_mode) | 0x680 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_28`](#mio_pad_sleep_mode) | 0x684 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_29`](#mio_pad_sleep_mode) | 0x688 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_30`](#mio_pad_sleep_mode) | 0x68c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_31`](#mio_pad_sleep_mode) | 0x690 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_32`](#mio_pad_sleep_mode) | 0x694 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_33`](#mio_pad_sleep_mode) | 0x698 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_34`](#mio_pad_sleep_mode) | 0x69c | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_35`](#mio_pad_sleep_mode) | 0x6a0 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_36`](#mio_pad_sleep_mode) | 0x6a4 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_37`](#mio_pad_sleep_mode) | 0x6a8 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_38`](#mio_pad_sleep_mode) | 0x6ac | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_39`](#mio_pad_sleep_mode) | 0x6b0 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_40`](#mio_pad_sleep_mode) | 0x6b4 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_41`](#mio_pad_sleep_mode) | 0x6b8 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_42`](#mio_pad_sleep_mode) | 0x6bc | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_43`](#mio_pad_sleep_mode) | 0x6c0 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_44`](#mio_pad_sleep_mode) | 0x6c4 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_45`](#mio_pad_sleep_mode) | 0x6c8 | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`MIO_PAD_SLEEP_MODE_46`](#mio_pad_sleep_mode) | 0x6cc | 4 | Defines sleep behavior of the corresponding muxed pad. | +| pinmux.[`DIO_PAD_SLEEP_STATUS`](#DIO_PAD_SLEEP_STATUS) | 0x6d0 | 4 | Register indicating whether the corresponding pad is in sleep mode. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_0`](#dio_pad_sleep_regwen) | 0x6d4 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_1`](#dio_pad_sleep_regwen) | 0x6d8 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_2`](#dio_pad_sleep_regwen) | 0x6dc | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_3`](#dio_pad_sleep_regwen) | 0x6e0 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_4`](#dio_pad_sleep_regwen) | 0x6e4 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_5`](#dio_pad_sleep_regwen) | 0x6e8 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_6`](#dio_pad_sleep_regwen) | 0x6ec | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_7`](#dio_pad_sleep_regwen) | 0x6f0 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_8`](#dio_pad_sleep_regwen) | 0x6f4 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_9`](#dio_pad_sleep_regwen) | 0x6f8 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_10`](#dio_pad_sleep_regwen) | 0x6fc | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_11`](#dio_pad_sleep_regwen) | 0x700 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_12`](#dio_pad_sleep_regwen) | 0x704 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_REGWEN_13`](#dio_pad_sleep_regwen) | 0x708 | 4 | Register write enable for DIO sleep value configuration. | +| pinmux.[`DIO_PAD_SLEEP_EN_0`](#dio_pad_sleep_en) | 0x70c | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_1`](#dio_pad_sleep_en) | 0x710 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_2`](#dio_pad_sleep_en) | 0x714 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_3`](#dio_pad_sleep_en) | 0x718 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_4`](#dio_pad_sleep_en) | 0x71c | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_5`](#dio_pad_sleep_en) | 0x720 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_6`](#dio_pad_sleep_en) | 0x724 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_7`](#dio_pad_sleep_en) | 0x728 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_8`](#dio_pad_sleep_en) | 0x72c | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_9`](#dio_pad_sleep_en) | 0x730 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_10`](#dio_pad_sleep_en) | 0x734 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_11`](#dio_pad_sleep_en) | 0x738 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_12`](#dio_pad_sleep_en) | 0x73c | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_EN_13`](#dio_pad_sleep_en) | 0x740 | 4 | Enables the sleep mode of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_0`](#dio_pad_sleep_mode) | 0x744 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_1`](#dio_pad_sleep_mode) | 0x748 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_2`](#dio_pad_sleep_mode) | 0x74c | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_3`](#dio_pad_sleep_mode) | 0x750 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_4`](#dio_pad_sleep_mode) | 0x754 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_5`](#dio_pad_sleep_mode) | 0x758 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_6`](#dio_pad_sleep_mode) | 0x75c | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_7`](#dio_pad_sleep_mode) | 0x760 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_8`](#dio_pad_sleep_mode) | 0x764 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_9`](#dio_pad_sleep_mode) | 0x768 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_10`](#dio_pad_sleep_mode) | 0x76c | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_11`](#dio_pad_sleep_mode) | 0x770 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_12`](#dio_pad_sleep_mode) | 0x774 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`DIO_PAD_SLEEP_MODE_13`](#dio_pad_sleep_mode) | 0x778 | 4 | Defines sleep behavior of the corresponding dedicated pad. | +| pinmux.[`WKUP_DETECTOR_REGWEN_0`](#wkup_detector_regwen) | 0x77c | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_REGWEN_1`](#wkup_detector_regwen) | 0x780 | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_REGWEN_2`](#wkup_detector_regwen) | 0x784 | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_REGWEN_3`](#wkup_detector_regwen) | 0x788 | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_REGWEN_4`](#wkup_detector_regwen) | 0x78c | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_REGWEN_5`](#wkup_detector_regwen) | 0x790 | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_REGWEN_6`](#wkup_detector_regwen) | 0x794 | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_REGWEN_7`](#wkup_detector_regwen) | 0x798 | 4 | Register write enable for wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_0`](#wkup_detector_en) | 0x79c | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_1`](#wkup_detector_en) | 0x7a0 | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_2`](#wkup_detector_en) | 0x7a4 | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_3`](#wkup_detector_en) | 0x7a8 | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_4`](#wkup_detector_en) | 0x7ac | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_5`](#wkup_detector_en) | 0x7b0 | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_6`](#wkup_detector_en) | 0x7b4 | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_EN_7`](#wkup_detector_en) | 0x7b8 | 4 | Enables for the wakeup detectors. | +| pinmux.[`WKUP_DETECTOR_0`](#wkup_detector) | 0x7bc | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_1`](#wkup_detector) | 0x7c0 | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_2`](#wkup_detector) | 0x7c4 | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_3`](#wkup_detector) | 0x7c8 | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_4`](#wkup_detector) | 0x7cc | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_5`](#wkup_detector) | 0x7d0 | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_6`](#wkup_detector) | 0x7d4 | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_7`](#wkup_detector) | 0x7d8 | 4 | Configuration of wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_0`](#wkup_detector_cnt_th) | 0x7dc | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_1`](#wkup_detector_cnt_th) | 0x7e0 | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_2`](#wkup_detector_cnt_th) | 0x7e4 | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_3`](#wkup_detector_cnt_th) | 0x7e8 | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_4`](#wkup_detector_cnt_th) | 0x7ec | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_5`](#wkup_detector_cnt_th) | 0x7f0 | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_6`](#wkup_detector_cnt_th) | 0x7f4 | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_CNT_TH_7`](#wkup_detector_cnt_th) | 0x7f8 | 4 | Counter thresholds for wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_0`](#wkup_detector_padsel) | 0x7fc | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_1`](#wkup_detector_padsel) | 0x800 | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_2`](#wkup_detector_padsel) | 0x804 | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_3`](#wkup_detector_padsel) | 0x808 | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_4`](#wkup_detector_padsel) | 0x80c | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_5`](#wkup_detector_padsel) | 0x810 | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_6`](#wkup_detector_padsel) | 0x814 | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_DETECTOR_PADSEL_7`](#wkup_detector_padsel) | 0x818 | 4 | Pad selects for pad wakeup condition detectors. | +| pinmux.[`WKUP_CAUSE`](#WKUP_CAUSE) | 0x81c | 4 | Cause registers for wakeup detectors. | + +## ALERT_TEST +Alert Test Register +- Offset: `0x0` +- 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. | + +## MIO_PERIPH_INSEL_REGWEN +Register write enable for MIO peripheral input selects. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:---------------------------|:---------| +| MIO_PERIPH_INSEL_REGWEN_0 | 0x4 | +| MIO_PERIPH_INSEL_REGWEN_1 | 0x8 | +| MIO_PERIPH_INSEL_REGWEN_2 | 0xc | +| MIO_PERIPH_INSEL_REGWEN_3 | 0x10 | +| MIO_PERIPH_INSEL_REGWEN_4 | 0x14 | +| MIO_PERIPH_INSEL_REGWEN_5 | 0x18 | +| MIO_PERIPH_INSEL_REGWEN_6 | 0x1c | +| MIO_PERIPH_INSEL_REGWEN_7 | 0x20 | +| MIO_PERIPH_INSEL_REGWEN_8 | 0x24 | +| MIO_PERIPH_INSEL_REGWEN_9 | 0x28 | +| MIO_PERIPH_INSEL_REGWEN_10 | 0x2c | +| MIO_PERIPH_INSEL_REGWEN_11 | 0x30 | +| MIO_PERIPH_INSEL_REGWEN_12 | 0x34 | +| MIO_PERIPH_INSEL_REGWEN_13 | 0x38 | +| MIO_PERIPH_INSEL_REGWEN_14 | 0x3c | +| MIO_PERIPH_INSEL_REGWEN_15 | 0x40 | +| MIO_PERIPH_INSEL_REGWEN_16 | 0x44 | +| MIO_PERIPH_INSEL_REGWEN_17 | 0x48 | +| MIO_PERIPH_INSEL_REGWEN_18 | 0x4c | +| MIO_PERIPH_INSEL_REGWEN_19 | 0x50 | +| MIO_PERIPH_INSEL_REGWEN_20 | 0x54 | +| MIO_PERIPH_INSEL_REGWEN_21 | 0x58 | +| MIO_PERIPH_INSEL_REGWEN_22 | 0x5c | +| MIO_PERIPH_INSEL_REGWEN_23 | 0x60 | +| MIO_PERIPH_INSEL_REGWEN_24 | 0x64 | +| MIO_PERIPH_INSEL_REGWEN_25 | 0x68 | +| MIO_PERIPH_INSEL_REGWEN_26 | 0x6c | +| MIO_PERIPH_INSEL_REGWEN_27 | 0x70 | +| MIO_PERIPH_INSEL_REGWEN_28 | 0x74 | +| MIO_PERIPH_INSEL_REGWEN_29 | 0x78 | +| MIO_PERIPH_INSEL_REGWEN_30 | 0x7c | +| MIO_PERIPH_INSEL_REGWEN_31 | 0x80 | +| MIO_PERIPH_INSEL_REGWEN_32 | 0x84 | +| MIO_PERIPH_INSEL_REGWEN_33 | 0x88 | +| MIO_PERIPH_INSEL_REGWEN_34 | 0x8c | +| MIO_PERIPH_INSEL_REGWEN_35 | 0x90 | +| MIO_PERIPH_INSEL_REGWEN_36 | 0x94 | +| MIO_PERIPH_INSEL_REGWEN_37 | 0x98 | + + +### 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 | Register write enable bit. If this is cleared to 0, the corresponding MIO_PERIPH_INSEL is not writable anymore. | + +## MIO_PERIPH_INSEL +For each peripheral input, this selects the muxable pad input. +- Reset default: `0x0` +- Reset mask: `0x3f` +- Register enable: [`MIO_PERIPH_INSEL_REGWEN`](#mio_periph_insel_regwen) + +### Instances + +| Name | Offset | +|:--------------------|:---------| +| MIO_PERIPH_INSEL_0 | 0x9c | +| MIO_PERIPH_INSEL_1 | 0xa0 | +| MIO_PERIPH_INSEL_2 | 0xa4 | +| MIO_PERIPH_INSEL_3 | 0xa8 | +| MIO_PERIPH_INSEL_4 | 0xac | +| MIO_PERIPH_INSEL_5 | 0xb0 | +| MIO_PERIPH_INSEL_6 | 0xb4 | +| MIO_PERIPH_INSEL_7 | 0xb8 | +| MIO_PERIPH_INSEL_8 | 0xbc | +| MIO_PERIPH_INSEL_9 | 0xc0 | +| MIO_PERIPH_INSEL_10 | 0xc4 | +| MIO_PERIPH_INSEL_11 | 0xc8 | +| MIO_PERIPH_INSEL_12 | 0xcc | +| MIO_PERIPH_INSEL_13 | 0xd0 | +| MIO_PERIPH_INSEL_14 | 0xd4 | +| MIO_PERIPH_INSEL_15 | 0xd8 | +| MIO_PERIPH_INSEL_16 | 0xdc | +| MIO_PERIPH_INSEL_17 | 0xe0 | +| MIO_PERIPH_INSEL_18 | 0xe4 | +| MIO_PERIPH_INSEL_19 | 0xe8 | +| MIO_PERIPH_INSEL_20 | 0xec | +| MIO_PERIPH_INSEL_21 | 0xf0 | +| MIO_PERIPH_INSEL_22 | 0xf4 | +| MIO_PERIPH_INSEL_23 | 0xf8 | +| MIO_PERIPH_INSEL_24 | 0xfc | +| MIO_PERIPH_INSEL_25 | 0x100 | +| MIO_PERIPH_INSEL_26 | 0x104 | +| MIO_PERIPH_INSEL_27 | 0x108 | +| MIO_PERIPH_INSEL_28 | 0x10c | +| MIO_PERIPH_INSEL_29 | 0x110 | +| MIO_PERIPH_INSEL_30 | 0x114 | +| MIO_PERIPH_INSEL_31 | 0x118 | +| MIO_PERIPH_INSEL_32 | 0x11c | +| MIO_PERIPH_INSEL_33 | 0x120 | +| MIO_PERIPH_INSEL_34 | 0x124 | +| MIO_PERIPH_INSEL_35 | 0x128 | +| MIO_PERIPH_INSEL_36 | 0x12c | +| MIO_PERIPH_INSEL_37 | 0x130 | + + +### Fields + +```wavejson +{"reg": [{"name": "IN", "bits": 6, "attr": ["rw"], "rotate": 0}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:------------------------------------------------------------------------------------------------------------| +| 31:6 | | | | Reserved | +| 5:0 | rw | 0x0 | IN | 0: tie constantly to zero, 1: tie constantly to 1, >=2: MIO pads (i.e., add 2 to the native MIO pad index). | + +## MIO_OUTSEL_REGWEN +Register write enable for MIO output selects. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:---------------------|:---------| +| MIO_OUTSEL_REGWEN_0 | 0x134 | +| MIO_OUTSEL_REGWEN_1 | 0x138 | +| MIO_OUTSEL_REGWEN_2 | 0x13c | +| MIO_OUTSEL_REGWEN_3 | 0x140 | +| MIO_OUTSEL_REGWEN_4 | 0x144 | +| MIO_OUTSEL_REGWEN_5 | 0x148 | +| MIO_OUTSEL_REGWEN_6 | 0x14c | +| MIO_OUTSEL_REGWEN_7 | 0x150 | +| MIO_OUTSEL_REGWEN_8 | 0x154 | +| MIO_OUTSEL_REGWEN_9 | 0x158 | +| MIO_OUTSEL_REGWEN_10 | 0x15c | +| MIO_OUTSEL_REGWEN_11 | 0x160 | +| MIO_OUTSEL_REGWEN_12 | 0x164 | +| MIO_OUTSEL_REGWEN_13 | 0x168 | +| MIO_OUTSEL_REGWEN_14 | 0x16c | +| MIO_OUTSEL_REGWEN_15 | 0x170 | +| MIO_OUTSEL_REGWEN_16 | 0x174 | +| MIO_OUTSEL_REGWEN_17 | 0x178 | +| MIO_OUTSEL_REGWEN_18 | 0x17c | +| MIO_OUTSEL_REGWEN_19 | 0x180 | +| MIO_OUTSEL_REGWEN_20 | 0x184 | +| MIO_OUTSEL_REGWEN_21 | 0x188 | +| MIO_OUTSEL_REGWEN_22 | 0x18c | +| MIO_OUTSEL_REGWEN_23 | 0x190 | +| MIO_OUTSEL_REGWEN_24 | 0x194 | +| MIO_OUTSEL_REGWEN_25 | 0x198 | +| MIO_OUTSEL_REGWEN_26 | 0x19c | +| MIO_OUTSEL_REGWEN_27 | 0x1a0 | +| MIO_OUTSEL_REGWEN_28 | 0x1a4 | +| MIO_OUTSEL_REGWEN_29 | 0x1a8 | +| MIO_OUTSEL_REGWEN_30 | 0x1ac | +| MIO_OUTSEL_REGWEN_31 | 0x1b0 | +| MIO_OUTSEL_REGWEN_32 | 0x1b4 | +| MIO_OUTSEL_REGWEN_33 | 0x1b8 | +| MIO_OUTSEL_REGWEN_34 | 0x1bc | +| MIO_OUTSEL_REGWEN_35 | 0x1c0 | +| MIO_OUTSEL_REGWEN_36 | 0x1c4 | +| MIO_OUTSEL_REGWEN_37 | 0x1c8 | +| MIO_OUTSEL_REGWEN_38 | 0x1cc | +| MIO_OUTSEL_REGWEN_39 | 0x1d0 | +| MIO_OUTSEL_REGWEN_40 | 0x1d4 | +| MIO_OUTSEL_REGWEN_41 | 0x1d8 | +| MIO_OUTSEL_REGWEN_42 | 0x1dc | +| MIO_OUTSEL_REGWEN_43 | 0x1e0 | +| MIO_OUTSEL_REGWEN_44 | 0x1e4 | +| MIO_OUTSEL_REGWEN_45 | 0x1e8 | +| MIO_OUTSEL_REGWEN_46 | 0x1ec | + + +### 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 | Register write enable bit. If this is cleared to 0, the corresponding MIO_OUTSEL is not writable anymore. | + +## MIO_OUTSEL +For each muxable pad, this selects the peripheral output. +- Reset default: `0x2` +- Reset mask: `0x3f` +- Register enable: [`MIO_OUTSEL_REGWEN`](#mio_outsel_regwen) + +### Instances + +| Name | Offset | +|:--------------|:---------| +| MIO_OUTSEL_0 | 0x1f0 | +| MIO_OUTSEL_1 | 0x1f4 | +| MIO_OUTSEL_2 | 0x1f8 | +| MIO_OUTSEL_3 | 0x1fc | +| MIO_OUTSEL_4 | 0x200 | +| MIO_OUTSEL_5 | 0x204 | +| MIO_OUTSEL_6 | 0x208 | +| MIO_OUTSEL_7 | 0x20c | +| MIO_OUTSEL_8 | 0x210 | +| MIO_OUTSEL_9 | 0x214 | +| MIO_OUTSEL_10 | 0x218 | +| MIO_OUTSEL_11 | 0x21c | +| MIO_OUTSEL_12 | 0x220 | +| MIO_OUTSEL_13 | 0x224 | +| MIO_OUTSEL_14 | 0x228 | +| MIO_OUTSEL_15 | 0x22c | +| MIO_OUTSEL_16 | 0x230 | +| MIO_OUTSEL_17 | 0x234 | +| MIO_OUTSEL_18 | 0x238 | +| MIO_OUTSEL_19 | 0x23c | +| MIO_OUTSEL_20 | 0x240 | +| MIO_OUTSEL_21 | 0x244 | +| MIO_OUTSEL_22 | 0x248 | +| MIO_OUTSEL_23 | 0x24c | +| MIO_OUTSEL_24 | 0x250 | +| MIO_OUTSEL_25 | 0x254 | +| MIO_OUTSEL_26 | 0x258 | +| MIO_OUTSEL_27 | 0x25c | +| MIO_OUTSEL_28 | 0x260 | +| MIO_OUTSEL_29 | 0x264 | +| MIO_OUTSEL_30 | 0x268 | +| MIO_OUTSEL_31 | 0x26c | +| MIO_OUTSEL_32 | 0x270 | +| MIO_OUTSEL_33 | 0x274 | +| MIO_OUTSEL_34 | 0x278 | +| MIO_OUTSEL_35 | 0x27c | +| MIO_OUTSEL_36 | 0x280 | +| MIO_OUTSEL_37 | 0x284 | +| MIO_OUTSEL_38 | 0x288 | +| MIO_OUTSEL_39 | 0x28c | +| MIO_OUTSEL_40 | 0x290 | +| MIO_OUTSEL_41 | 0x294 | +| MIO_OUTSEL_42 | 0x298 | +| MIO_OUTSEL_43 | 0x29c | +| MIO_OUTSEL_44 | 0x2a0 | +| MIO_OUTSEL_45 | 0x2a4 | +| MIO_OUTSEL_46 | 0x2a8 | + + +### Fields + +```wavejson +{"reg": [{"name": "OUT", "bits": 6, "attr": ["rw"], "rotate": 0}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------------------------------------------------------------------------------------------------------------------| +| 31:6 | | | | Reserved | +| 5:0 | rw | 0x2 | OUT | 0: tie constantly to zero, 1: tie constantly to 1, 2: high-Z, >=3: peripheral outputs (i.e., add 3 to the native peripheral pad index). | + +## MIO_PAD_ATTR_REGWEN +Register write enable for MIO PAD attributes. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| MIO_PAD_ATTR_REGWEN_0 | 0x2ac | +| MIO_PAD_ATTR_REGWEN_1 | 0x2b0 | +| MIO_PAD_ATTR_REGWEN_2 | 0x2b4 | +| MIO_PAD_ATTR_REGWEN_3 | 0x2b8 | +| MIO_PAD_ATTR_REGWEN_4 | 0x2bc | +| MIO_PAD_ATTR_REGWEN_5 | 0x2c0 | +| MIO_PAD_ATTR_REGWEN_6 | 0x2c4 | +| MIO_PAD_ATTR_REGWEN_7 | 0x2c8 | +| MIO_PAD_ATTR_REGWEN_8 | 0x2cc | +| MIO_PAD_ATTR_REGWEN_9 | 0x2d0 | +| MIO_PAD_ATTR_REGWEN_10 | 0x2d4 | +| MIO_PAD_ATTR_REGWEN_11 | 0x2d8 | +| MIO_PAD_ATTR_REGWEN_12 | 0x2dc | +| MIO_PAD_ATTR_REGWEN_13 | 0x2e0 | +| MIO_PAD_ATTR_REGWEN_14 | 0x2e4 | +| MIO_PAD_ATTR_REGWEN_15 | 0x2e8 | +| MIO_PAD_ATTR_REGWEN_16 | 0x2ec | +| MIO_PAD_ATTR_REGWEN_17 | 0x2f0 | +| MIO_PAD_ATTR_REGWEN_18 | 0x2f4 | +| MIO_PAD_ATTR_REGWEN_19 | 0x2f8 | +| MIO_PAD_ATTR_REGWEN_20 | 0x2fc | +| MIO_PAD_ATTR_REGWEN_21 | 0x300 | +| MIO_PAD_ATTR_REGWEN_22 | 0x304 | +| MIO_PAD_ATTR_REGWEN_23 | 0x308 | +| MIO_PAD_ATTR_REGWEN_24 | 0x30c | +| MIO_PAD_ATTR_REGWEN_25 | 0x310 | +| MIO_PAD_ATTR_REGWEN_26 | 0x314 | +| MIO_PAD_ATTR_REGWEN_27 | 0x318 | +| MIO_PAD_ATTR_REGWEN_28 | 0x31c | +| MIO_PAD_ATTR_REGWEN_29 | 0x320 | +| MIO_PAD_ATTR_REGWEN_30 | 0x324 | +| MIO_PAD_ATTR_REGWEN_31 | 0x328 | +| MIO_PAD_ATTR_REGWEN_32 | 0x32c | +| MIO_PAD_ATTR_REGWEN_33 | 0x330 | +| MIO_PAD_ATTR_REGWEN_34 | 0x334 | +| MIO_PAD_ATTR_REGWEN_35 | 0x338 | +| MIO_PAD_ATTR_REGWEN_36 | 0x33c | +| MIO_PAD_ATTR_REGWEN_37 | 0x340 | +| MIO_PAD_ATTR_REGWEN_38 | 0x344 | +| MIO_PAD_ATTR_REGWEN_39 | 0x348 | +| MIO_PAD_ATTR_REGWEN_40 | 0x34c | +| MIO_PAD_ATTR_REGWEN_41 | 0x350 | +| MIO_PAD_ATTR_REGWEN_42 | 0x354 | +| MIO_PAD_ATTR_REGWEN_43 | 0x358 | +| MIO_PAD_ATTR_REGWEN_44 | 0x35c | +| MIO_PAD_ATTR_REGWEN_45 | 0x360 | +| MIO_PAD_ATTR_REGWEN_46 | 0x364 | + + +### 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 | Register write enable bit. If this is cleared to 0, the corresponding [`MIO_PAD_ATTR`](#mio_pad_attr) is not writable anymore. | + +## MIO_PAD_ATTR +Muxed pad attributes. +This register has WARL behavior since not each pad type may support +all attributes. +The muxed pad that is used for TAP strap 0 has a different reset value, with `pull_en` set to 1. +- Reset default: `0x0` +- Reset mask: `0xf300ff` +- Register enable: [`MIO_PAD_ATTR_REGWEN`](#mio_pad_attr_regwen) + +### Instances + +| Name | Offset | +|:----------------|:---------| +| MIO_PAD_ATTR_0 | 0x368 | +| MIO_PAD_ATTR_1 | 0x36c | +| MIO_PAD_ATTR_2 | 0x370 | +| MIO_PAD_ATTR_3 | 0x374 | +| MIO_PAD_ATTR_4 | 0x378 | +| MIO_PAD_ATTR_5 | 0x37c | +| MIO_PAD_ATTR_6 | 0x380 | +| MIO_PAD_ATTR_7 | 0x384 | +| MIO_PAD_ATTR_8 | 0x388 | +| MIO_PAD_ATTR_9 | 0x38c | +| MIO_PAD_ATTR_10 | 0x390 | +| MIO_PAD_ATTR_11 | 0x394 | +| MIO_PAD_ATTR_12 | 0x398 | +| MIO_PAD_ATTR_13 | 0x39c | +| MIO_PAD_ATTR_14 | 0x3a0 | +| MIO_PAD_ATTR_15 | 0x3a4 | +| MIO_PAD_ATTR_16 | 0x3a8 | +| MIO_PAD_ATTR_17 | 0x3ac | +| MIO_PAD_ATTR_18 | 0x3b0 | +| MIO_PAD_ATTR_19 | 0x3b4 | +| MIO_PAD_ATTR_20 | 0x3b8 | +| MIO_PAD_ATTR_21 | 0x3bc | +| MIO_PAD_ATTR_22 | 0x3c0 | +| MIO_PAD_ATTR_23 | 0x3c4 | +| MIO_PAD_ATTR_24 | 0x3c8 | +| MIO_PAD_ATTR_25 | 0x3cc | +| MIO_PAD_ATTR_26 | 0x3d0 | +| MIO_PAD_ATTR_27 | 0x3d4 | +| MIO_PAD_ATTR_28 | 0x3d8 | +| MIO_PAD_ATTR_29 | 0x3dc | +| MIO_PAD_ATTR_30 | 0x3e0 | +| MIO_PAD_ATTR_31 | 0x3e4 | +| MIO_PAD_ATTR_32 | 0x3e8 | +| MIO_PAD_ATTR_33 | 0x3ec | +| MIO_PAD_ATTR_34 | 0x3f0 | +| MIO_PAD_ATTR_35 | 0x3f4 | +| MIO_PAD_ATTR_36 | 0x3f8 | +| MIO_PAD_ATTR_37 | 0x3fc | +| MIO_PAD_ATTR_38 | 0x400 | +| MIO_PAD_ATTR_39 | 0x404 | +| MIO_PAD_ATTR_40 | 0x408 | +| MIO_PAD_ATTR_41 | 0x40c | +| MIO_PAD_ATTR_42 | 0x410 | +| MIO_PAD_ATTR_43 | 0x414 | +| MIO_PAD_ATTR_44 | 0x418 | +| MIO_PAD_ATTR_45 | 0x41c | +| MIO_PAD_ATTR_46 | 0x420 | + + +### Fields + +```wavejson +{"reg": [{"name": "invert", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "virtual_od_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "pull_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "pull_select", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "keeper_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "schmitt_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "od_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "input_disable", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 8}, {"name": "slew_rate", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 2}, {"name": "drive_strength", "bits": 4, "attr": ["rw"], "rotate": -90}, {"bits": 8}], "config": {"lanes": 1, "fontsize": 10, "vspace": 160}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------------------------------| +| 31:24 | | | Reserved | +| 23:20 | rw | 0x0 | [drive_strength](#mio_pad_attr--drive_strength) | +| 19:18 | | | Reserved | +| 17:16 | rw | 0x0 | [slew_rate](#mio_pad_attr--slew_rate) | +| 15:8 | | | Reserved | +| 7 | rw | 0x0 | [input_disable](#mio_pad_attr--input_disable) | +| 6 | rw | 0x0 | [od_en](#mio_pad_attr--od_en) | +| 5 | rw | 0x0 | [schmitt_en](#mio_pad_attr--schmitt_en) | +| 4 | rw | 0x0 | [keeper_en](#mio_pad_attr--keeper_en) | +| 3 | rw | 0x0 | [pull_select](#mio_pad_attr--pull_select) | +| 2 | rw | 0x0 | [pull_en](#mio_pad_attr--pull_en) | +| 1 | rw | 0x0 | [virtual_od_en](#mio_pad_attr--virtual_od_en) | +| 0 | rw | 0x0 | [invert](#mio_pad_attr--invert) | + +### MIO_PAD_ATTR . drive_strength +Drive strength (0x0: weakest, 0xf: strongest) + +### MIO_PAD_ATTR . slew_rate +Slew rate (0x0: slowest, 0x3: fastest). + +### MIO_PAD_ATTR . input_disable +Disable input drivers. +Setting this to 1 for pads that are not used as input can reduce their leakage current. + +### MIO_PAD_ATTR . od_en +Enable open drain. + +### MIO_PAD_ATTR . schmitt_en +Enable the schmitt trigger. + +### MIO_PAD_ATTR . keeper_en +Enable keeper termination. This weakly drives the previous pad output value when output is disabled, similar to a verilog `trireg`. + +### MIO_PAD_ATTR . pull_select +Pull select (0: pull-down, 1: pull-up). + +| Value | Name | Description | +|:--------|:----------|:-------------------------------| +| 0x0 | pull_down | Select the pull-down resistor. | +| 0x1 | pull_up | Select the pull-up resistor. | + + +### MIO_PAD_ATTR . pull_en +Enable pull-up or pull-down resistor. + +### MIO_PAD_ATTR . virtual_od_en +Enable virtual open drain. + +### MIO_PAD_ATTR . invert +Invert input and output levels. + +## DIO_PAD_ATTR_REGWEN +Register write enable for DIO PAD attributes. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| DIO_PAD_ATTR_REGWEN_0 | 0x424 | +| DIO_PAD_ATTR_REGWEN_1 | 0x428 | +| DIO_PAD_ATTR_REGWEN_2 | 0x42c | +| DIO_PAD_ATTR_REGWEN_3 | 0x430 | +| DIO_PAD_ATTR_REGWEN_4 | 0x434 | +| DIO_PAD_ATTR_REGWEN_5 | 0x438 | +| DIO_PAD_ATTR_REGWEN_6 | 0x43c | +| DIO_PAD_ATTR_REGWEN_7 | 0x440 | +| DIO_PAD_ATTR_REGWEN_8 | 0x444 | +| DIO_PAD_ATTR_REGWEN_9 | 0x448 | +| DIO_PAD_ATTR_REGWEN_10 | 0x44c | +| DIO_PAD_ATTR_REGWEN_11 | 0x450 | +| DIO_PAD_ATTR_REGWEN_12 | 0x454 | +| DIO_PAD_ATTR_REGWEN_13 | 0x458 | + + +### 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 | Register write enable bit. If this is cleared to 0, the corresponding [`DIO_PAD_ATTR`](#dio_pad_attr) is not writable anymore. | + +## DIO_PAD_ATTR +Dedicated pad attributes. +This register has WARL behavior since not each pad type may support +all attributes. +- Reset default: `0x0` +- Reset mask: `0xf300ff` +- Register enable: [`DIO_PAD_ATTR_REGWEN`](#dio_pad_attr_regwen) + +### Instances + +| Name | Offset | +|:----------------|:---------| +| DIO_PAD_ATTR_0 | 0x45c | +| DIO_PAD_ATTR_1 | 0x460 | +| DIO_PAD_ATTR_2 | 0x464 | +| DIO_PAD_ATTR_3 | 0x468 | +| DIO_PAD_ATTR_4 | 0x46c | +| DIO_PAD_ATTR_5 | 0x470 | +| DIO_PAD_ATTR_6 | 0x474 | +| DIO_PAD_ATTR_7 | 0x478 | +| DIO_PAD_ATTR_8 | 0x47c | +| DIO_PAD_ATTR_9 | 0x480 | +| DIO_PAD_ATTR_10 | 0x484 | +| DIO_PAD_ATTR_11 | 0x488 | +| DIO_PAD_ATTR_12 | 0x48c | +| DIO_PAD_ATTR_13 | 0x490 | + + +### Fields + +```wavejson +{"reg": [{"name": "invert", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "virtual_od_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "pull_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "pull_select", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "keeper_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "schmitt_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "od_en", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "input_disable", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 8}, {"name": "slew_rate", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 2}, {"name": "drive_strength", "bits": 4, "attr": ["rw"], "rotate": -90}, {"bits": 8}], "config": {"lanes": 1, "fontsize": 10, "vspace": 160}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:------------------------------------------------| +| 31:24 | | | Reserved | +| 23:20 | rw | 0x0 | [drive_strength](#dio_pad_attr--drive_strength) | +| 19:18 | | | Reserved | +| 17:16 | rw | 0x0 | [slew_rate](#dio_pad_attr--slew_rate) | +| 15:8 | | | Reserved | +| 7 | rw | 0x0 | [input_disable](#dio_pad_attr--input_disable) | +| 6 | rw | 0x0 | [od_en](#dio_pad_attr--od_en) | +| 5 | rw | 0x0 | [schmitt_en](#dio_pad_attr--schmitt_en) | +| 4 | rw | 0x0 | [keeper_en](#dio_pad_attr--keeper_en) | +| 3 | rw | 0x0 | [pull_select](#dio_pad_attr--pull_select) | +| 2 | rw | 0x0 | [pull_en](#dio_pad_attr--pull_en) | +| 1 | rw | 0x0 | [virtual_od_en](#dio_pad_attr--virtual_od_en) | +| 0 | rw | 0x0 | [invert](#dio_pad_attr--invert) | + +### DIO_PAD_ATTR . drive_strength +Drive strength (0x0: weakest, 0xf: strongest) + +### DIO_PAD_ATTR . slew_rate +Slew rate (0x0: slowest, 0x3: fastest). + +### DIO_PAD_ATTR . input_disable +Disable input drivers. +Setting this to 1 for pads that are not used as input can reduce their leakage current. + +### DIO_PAD_ATTR . od_en +Enable open drain. + +### DIO_PAD_ATTR . schmitt_en +Enable the schmitt trigger. + +### DIO_PAD_ATTR . keeper_en +Enable keeper termination. This weakly drives the previous pad output value when output is disabled, similar to a verilog `trireg`. + +### DIO_PAD_ATTR . pull_select +Pull select (0: pull-down, 1: pull-up). + +| Value | Name | Description | +|:--------|:----------|:-------------------------------| +| 0x0 | pull_down | Select the pull-down resistor. | +| 0x1 | pull_up | Select the pull-up resistor. | + + +### DIO_PAD_ATTR . pull_en +Enable pull-up or pull-down resistor. + +### DIO_PAD_ATTR . virtual_od_en +Enable virtual open drain. + +### DIO_PAD_ATTR . invert +Invert input and output levels. + +## MIO_PAD_SLEEP_STATUS_0 +Register indicating whether the corresponding pad is in sleep mode. +- Offset: `0x494` +- Reset default: `0x0` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "EN_0", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_1", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_2", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_3", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_4", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_5", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_6", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_7", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_8", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_9", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_10", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_11", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_12", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_13", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_14", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_15", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_16", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_17", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_18", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_19", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_20", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_21", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_22", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_23", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_24", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_25", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_26", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_27", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_28", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_29", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_30", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_31", "bits": 1, "attr": ["rw0c"], "rotate": -90}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31 | rw0c | 0x0 | EN_31 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 30 | rw0c | 0x0 | EN_30 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 29 | rw0c | 0x0 | EN_29 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 28 | rw0c | 0x0 | EN_28 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 27 | rw0c | 0x0 | EN_27 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 26 | rw0c | 0x0 | EN_26 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 25 | rw0c | 0x0 | EN_25 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 24 | rw0c | 0x0 | EN_24 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 23 | rw0c | 0x0 | EN_23 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 22 | rw0c | 0x0 | EN_22 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 21 | rw0c | 0x0 | EN_21 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 20 | rw0c | 0x0 | EN_20 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 19 | rw0c | 0x0 | EN_19 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 18 | rw0c | 0x0 | EN_18 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 17 | rw0c | 0x0 | EN_17 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 16 | rw0c | 0x0 | EN_16 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 15 | rw0c | 0x0 | EN_15 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 14 | rw0c | 0x0 | EN_14 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 13 | rw0c | 0x0 | EN_13 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 12 | rw0c | 0x0 | EN_12 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 11 | rw0c | 0x0 | EN_11 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 10 | rw0c | 0x0 | EN_10 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 9 | rw0c | 0x0 | EN_9 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 8 | rw0c | 0x0 | EN_8 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 7 | rw0c | 0x0 | EN_7 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 6 | rw0c | 0x0 | EN_6 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 5 | rw0c | 0x0 | EN_5 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 4 | rw0c | 0x0 | EN_4 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 3 | rw0c | 0x0 | EN_3 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 2 | rw0c | 0x0 | EN_2 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 1 | rw0c | 0x0 | EN_1 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 0 | rw0c | 0x0 | EN_0 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | + +## MIO_PAD_SLEEP_STATUS_1 +Register indicating whether the corresponding pad is in sleep mode. +- Offset: `0x498` +- Reset default: `0x0` +- Reset mask: `0x7fff` + +### Fields + +```wavejson +{"reg": [{"name": "EN_32", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_33", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_34", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_35", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_36", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_37", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_38", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_39", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_40", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_41", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_42", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_43", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_44", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_45", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_46", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 17}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------| +| 31:15 | | | | Reserved | +| 14 | rw0c | 0x0 | EN_46 | For MIO_PAD1 | +| 13 | rw0c | 0x0 | EN_45 | For MIO_PAD1 | +| 12 | rw0c | 0x0 | EN_44 | For MIO_PAD1 | +| 11 | rw0c | 0x0 | EN_43 | For MIO_PAD1 | +| 10 | rw0c | 0x0 | EN_42 | For MIO_PAD1 | +| 9 | rw0c | 0x0 | EN_41 | For MIO_PAD1 | +| 8 | rw0c | 0x0 | EN_40 | For MIO_PAD1 | +| 7 | rw0c | 0x0 | EN_39 | For MIO_PAD1 | +| 6 | rw0c | 0x0 | EN_38 | For MIO_PAD1 | +| 5 | rw0c | 0x0 | EN_37 | For MIO_PAD1 | +| 4 | rw0c | 0x0 | EN_36 | For MIO_PAD1 | +| 3 | rw0c | 0x0 | EN_35 | For MIO_PAD1 | +| 2 | rw0c | 0x0 | EN_34 | For MIO_PAD1 | +| 1 | rw0c | 0x0 | EN_33 | For MIO_PAD1 | +| 0 | rw0c | 0x0 | EN_32 | For MIO_PAD1 | + +## MIO_PAD_SLEEP_REGWEN +Register write enable for MIO sleep value configuration. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:------------------------|:---------| +| MIO_PAD_SLEEP_REGWEN_0 | 0x49c | +| MIO_PAD_SLEEP_REGWEN_1 | 0x4a0 | +| MIO_PAD_SLEEP_REGWEN_2 | 0x4a4 | +| MIO_PAD_SLEEP_REGWEN_3 | 0x4a8 | +| MIO_PAD_SLEEP_REGWEN_4 | 0x4ac | +| MIO_PAD_SLEEP_REGWEN_5 | 0x4b0 | +| MIO_PAD_SLEEP_REGWEN_6 | 0x4b4 | +| MIO_PAD_SLEEP_REGWEN_7 | 0x4b8 | +| MIO_PAD_SLEEP_REGWEN_8 | 0x4bc | +| MIO_PAD_SLEEP_REGWEN_9 | 0x4c0 | +| MIO_PAD_SLEEP_REGWEN_10 | 0x4c4 | +| MIO_PAD_SLEEP_REGWEN_11 | 0x4c8 | +| MIO_PAD_SLEEP_REGWEN_12 | 0x4cc | +| MIO_PAD_SLEEP_REGWEN_13 | 0x4d0 | +| MIO_PAD_SLEEP_REGWEN_14 | 0x4d4 | +| MIO_PAD_SLEEP_REGWEN_15 | 0x4d8 | +| MIO_PAD_SLEEP_REGWEN_16 | 0x4dc | +| MIO_PAD_SLEEP_REGWEN_17 | 0x4e0 | +| MIO_PAD_SLEEP_REGWEN_18 | 0x4e4 | +| MIO_PAD_SLEEP_REGWEN_19 | 0x4e8 | +| MIO_PAD_SLEEP_REGWEN_20 | 0x4ec | +| MIO_PAD_SLEEP_REGWEN_21 | 0x4f0 | +| MIO_PAD_SLEEP_REGWEN_22 | 0x4f4 | +| MIO_PAD_SLEEP_REGWEN_23 | 0x4f8 | +| MIO_PAD_SLEEP_REGWEN_24 | 0x4fc | +| MIO_PAD_SLEEP_REGWEN_25 | 0x500 | +| MIO_PAD_SLEEP_REGWEN_26 | 0x504 | +| MIO_PAD_SLEEP_REGWEN_27 | 0x508 | +| MIO_PAD_SLEEP_REGWEN_28 | 0x50c | +| MIO_PAD_SLEEP_REGWEN_29 | 0x510 | +| MIO_PAD_SLEEP_REGWEN_30 | 0x514 | +| MIO_PAD_SLEEP_REGWEN_31 | 0x518 | +| MIO_PAD_SLEEP_REGWEN_32 | 0x51c | +| MIO_PAD_SLEEP_REGWEN_33 | 0x520 | +| MIO_PAD_SLEEP_REGWEN_34 | 0x524 | +| MIO_PAD_SLEEP_REGWEN_35 | 0x528 | +| MIO_PAD_SLEEP_REGWEN_36 | 0x52c | +| MIO_PAD_SLEEP_REGWEN_37 | 0x530 | +| MIO_PAD_SLEEP_REGWEN_38 | 0x534 | +| MIO_PAD_SLEEP_REGWEN_39 | 0x538 | +| MIO_PAD_SLEEP_REGWEN_40 | 0x53c | +| MIO_PAD_SLEEP_REGWEN_41 | 0x540 | +| MIO_PAD_SLEEP_REGWEN_42 | 0x544 | +| MIO_PAD_SLEEP_REGWEN_43 | 0x548 | +| MIO_PAD_SLEEP_REGWEN_44 | 0x54c | +| MIO_PAD_SLEEP_REGWEN_45 | 0x550 | +| MIO_PAD_SLEEP_REGWEN_46 | 0x554 | + + +### 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 | Register write enable bit. If this is cleared to 0, the corresponding [`MIO_PAD_SLEEP_MODE`](#mio_pad_sleep_mode) is not writable anymore. | + +## MIO_PAD_SLEEP_EN +Enables the sleep mode of the corresponding muxed pad. +- Reset default: `0x0` +- Reset mask: `0x1` +- Register enable: [`MIO_PAD_SLEEP_REGWEN`](#mio_pad_sleep_regwen) + +### Instances + +| Name | Offset | +|:--------------------|:---------| +| MIO_PAD_SLEEP_EN_0 | 0x558 | +| MIO_PAD_SLEEP_EN_1 | 0x55c | +| MIO_PAD_SLEEP_EN_2 | 0x560 | +| MIO_PAD_SLEEP_EN_3 | 0x564 | +| MIO_PAD_SLEEP_EN_4 | 0x568 | +| MIO_PAD_SLEEP_EN_5 | 0x56c | +| MIO_PAD_SLEEP_EN_6 | 0x570 | +| MIO_PAD_SLEEP_EN_7 | 0x574 | +| MIO_PAD_SLEEP_EN_8 | 0x578 | +| MIO_PAD_SLEEP_EN_9 | 0x57c | +| MIO_PAD_SLEEP_EN_10 | 0x580 | +| MIO_PAD_SLEEP_EN_11 | 0x584 | +| MIO_PAD_SLEEP_EN_12 | 0x588 | +| MIO_PAD_SLEEP_EN_13 | 0x58c | +| MIO_PAD_SLEEP_EN_14 | 0x590 | +| MIO_PAD_SLEEP_EN_15 | 0x594 | +| MIO_PAD_SLEEP_EN_16 | 0x598 | +| MIO_PAD_SLEEP_EN_17 | 0x59c | +| MIO_PAD_SLEEP_EN_18 | 0x5a0 | +| MIO_PAD_SLEEP_EN_19 | 0x5a4 | +| MIO_PAD_SLEEP_EN_20 | 0x5a8 | +| MIO_PAD_SLEEP_EN_21 | 0x5ac | +| MIO_PAD_SLEEP_EN_22 | 0x5b0 | +| MIO_PAD_SLEEP_EN_23 | 0x5b4 | +| MIO_PAD_SLEEP_EN_24 | 0x5b8 | +| MIO_PAD_SLEEP_EN_25 | 0x5bc | +| MIO_PAD_SLEEP_EN_26 | 0x5c0 | +| MIO_PAD_SLEEP_EN_27 | 0x5c4 | +| MIO_PAD_SLEEP_EN_28 | 0x5c8 | +| MIO_PAD_SLEEP_EN_29 | 0x5cc | +| MIO_PAD_SLEEP_EN_30 | 0x5d0 | +| MIO_PAD_SLEEP_EN_31 | 0x5d4 | +| MIO_PAD_SLEEP_EN_32 | 0x5d8 | +| MIO_PAD_SLEEP_EN_33 | 0x5dc | +| MIO_PAD_SLEEP_EN_34 | 0x5e0 | +| MIO_PAD_SLEEP_EN_35 | 0x5e4 | +| MIO_PAD_SLEEP_EN_36 | 0x5e8 | +| MIO_PAD_SLEEP_EN_37 | 0x5ec | +| MIO_PAD_SLEEP_EN_38 | 0x5f0 | +| MIO_PAD_SLEEP_EN_39 | 0x5f4 | +| MIO_PAD_SLEEP_EN_40 | 0x5f8 | +| MIO_PAD_SLEEP_EN_41 | 0x5fc | +| MIO_PAD_SLEEP_EN_42 | 0x600 | +| MIO_PAD_SLEEP_EN_43 | 0x604 | +| MIO_PAD_SLEEP_EN_44 | 0x608 | +| MIO_PAD_SLEEP_EN_45 | 0x60c | +| MIO_PAD_SLEEP_EN_46 | 0x610 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "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 | [EN](#mio_pad_sleep_en--en) | + +### MIO_PAD_SLEEP_EN . EN +Deep sleep mode enable. +If this bit is set to 1 the corresponding pad will enable the sleep behavior +specified in [`MIO_PAD_SLEEP_MODE`](#mio_pad_sleep_mode) upon deep sleep entry, and the corresponding bit +in [`MIO_PAD_SLEEP_STATUS`](#mio_pad_sleep_status) will be set to 1. +The pad remains in deep sleep mode until the corresponding bit in +[`MIO_PAD_SLEEP_STATUS`](#mio_pad_sleep_status) is cleared by SW. +Note that if an always on peripheral is connected to a specific MIO pad, +the corresponding [`MIO_PAD_SLEEP_EN`](#mio_pad_sleep_en) bit should be set to 0. + +## MIO_PAD_SLEEP_MODE +Defines sleep behavior of the corresponding muxed pad. +- Reset default: `0x2` +- Reset mask: `0x3` +- Register enable: [`MIO_PAD_SLEEP_REGWEN`](#mio_pad_sleep_regwen) + +### Instances + +| Name | Offset | +|:----------------------|:---------| +| MIO_PAD_SLEEP_MODE_0 | 0x614 | +| MIO_PAD_SLEEP_MODE_1 | 0x618 | +| MIO_PAD_SLEEP_MODE_2 | 0x61c | +| MIO_PAD_SLEEP_MODE_3 | 0x620 | +| MIO_PAD_SLEEP_MODE_4 | 0x624 | +| MIO_PAD_SLEEP_MODE_5 | 0x628 | +| MIO_PAD_SLEEP_MODE_6 | 0x62c | +| MIO_PAD_SLEEP_MODE_7 | 0x630 | +| MIO_PAD_SLEEP_MODE_8 | 0x634 | +| MIO_PAD_SLEEP_MODE_9 | 0x638 | +| MIO_PAD_SLEEP_MODE_10 | 0x63c | +| MIO_PAD_SLEEP_MODE_11 | 0x640 | +| MIO_PAD_SLEEP_MODE_12 | 0x644 | +| MIO_PAD_SLEEP_MODE_13 | 0x648 | +| MIO_PAD_SLEEP_MODE_14 | 0x64c | +| MIO_PAD_SLEEP_MODE_15 | 0x650 | +| MIO_PAD_SLEEP_MODE_16 | 0x654 | +| MIO_PAD_SLEEP_MODE_17 | 0x658 | +| MIO_PAD_SLEEP_MODE_18 | 0x65c | +| MIO_PAD_SLEEP_MODE_19 | 0x660 | +| MIO_PAD_SLEEP_MODE_20 | 0x664 | +| MIO_PAD_SLEEP_MODE_21 | 0x668 | +| MIO_PAD_SLEEP_MODE_22 | 0x66c | +| MIO_PAD_SLEEP_MODE_23 | 0x670 | +| MIO_PAD_SLEEP_MODE_24 | 0x674 | +| MIO_PAD_SLEEP_MODE_25 | 0x678 | +| MIO_PAD_SLEEP_MODE_26 | 0x67c | +| MIO_PAD_SLEEP_MODE_27 | 0x680 | +| MIO_PAD_SLEEP_MODE_28 | 0x684 | +| MIO_PAD_SLEEP_MODE_29 | 0x688 | +| MIO_PAD_SLEEP_MODE_30 | 0x68c | +| MIO_PAD_SLEEP_MODE_31 | 0x690 | +| MIO_PAD_SLEEP_MODE_32 | 0x694 | +| MIO_PAD_SLEEP_MODE_33 | 0x698 | +| MIO_PAD_SLEEP_MODE_34 | 0x69c | +| MIO_PAD_SLEEP_MODE_35 | 0x6a0 | +| MIO_PAD_SLEEP_MODE_36 | 0x6a4 | +| MIO_PAD_SLEEP_MODE_37 | 0x6a8 | +| MIO_PAD_SLEEP_MODE_38 | 0x6ac | +| MIO_PAD_SLEEP_MODE_39 | 0x6b0 | +| MIO_PAD_SLEEP_MODE_40 | 0x6b4 | +| MIO_PAD_SLEEP_MODE_41 | 0x6b8 | +| MIO_PAD_SLEEP_MODE_42 | 0x6bc | +| MIO_PAD_SLEEP_MODE_43 | 0x6c0 | +| MIO_PAD_SLEEP_MODE_44 | 0x6c4 | +| MIO_PAD_SLEEP_MODE_45 | 0x6c8 | +| MIO_PAD_SLEEP_MODE_46 | 0x6cc | + + +### Fields + +```wavejson +{"reg": [{"name": "OUT", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------| +| 31:2 | | | Reserved | +| 1:0 | rw | 0x2 | [OUT](#mio_pad_sleep_mode--out) | + +### MIO_PAD_SLEEP_MODE . OUT +Value to drive in deep sleep. + +| Value | Name | Description | +|:--------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 0x0 | Tie-Low | The pad is driven actively to zero in deep sleep mode. | +| 0x1 | Tie-High | The pad is driven actively to one in deep sleep mode. | +| 0x2 | High-Z | The pad is left undriven in deep sleep mode. Note that the actual driving behavior during deep sleep will then depend on the pull-up/-down configuration of in !!MIO_PAD_ATTR. | +| 0x3 | Keep | Keep last driven value (including high-Z). | + + +## DIO_PAD_SLEEP_STATUS +Register indicating whether the corresponding pad is in sleep mode. +- Offset: `0x6d0` +- Reset default: `0x0` +- Reset mask: `0x3fff` + +### Fields + +```wavejson +{"reg": [{"name": "EN_0", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_1", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_2", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_3", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_4", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_5", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_6", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_7", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_8", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_9", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_10", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_11", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_12", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "EN_13", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 18}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:14 | | | | Reserved | +| 13 | rw0c | 0x0 | EN_13 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 12 | rw0c | 0x0 | EN_12 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 11 | rw0c | 0x0 | EN_11 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 10 | rw0c | 0x0 | EN_10 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 9 | rw0c | 0x0 | EN_9 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 8 | rw0c | 0x0 | EN_8 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 7 | rw0c | 0x0 | EN_7 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 6 | rw0c | 0x0 | EN_6 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 5 | rw0c | 0x0 | EN_5 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 4 | rw0c | 0x0 | EN_4 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 3 | rw0c | 0x0 | EN_3 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 2 | rw0c | 0x0 | EN_2 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 1 | rw0c | 0x0 | EN_1 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | +| 0 | rw0c | 0x0 | EN_0 | This register is set to 1 if the deep sleep mode of the corresponding pad has been enabled ([`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode)) upon deep sleep entry. The sleep mode of the corresponding pad will remain active until SW clears this bit. | + +## DIO_PAD_SLEEP_REGWEN +Register write enable for DIO sleep value configuration. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:------------------------|:---------| +| DIO_PAD_SLEEP_REGWEN_0 | 0x6d4 | +| DIO_PAD_SLEEP_REGWEN_1 | 0x6d8 | +| DIO_PAD_SLEEP_REGWEN_2 | 0x6dc | +| DIO_PAD_SLEEP_REGWEN_3 | 0x6e0 | +| DIO_PAD_SLEEP_REGWEN_4 | 0x6e4 | +| DIO_PAD_SLEEP_REGWEN_5 | 0x6e8 | +| DIO_PAD_SLEEP_REGWEN_6 | 0x6ec | +| DIO_PAD_SLEEP_REGWEN_7 | 0x6f0 | +| DIO_PAD_SLEEP_REGWEN_8 | 0x6f4 | +| DIO_PAD_SLEEP_REGWEN_9 | 0x6f8 | +| DIO_PAD_SLEEP_REGWEN_10 | 0x6fc | +| DIO_PAD_SLEEP_REGWEN_11 | 0x700 | +| DIO_PAD_SLEEP_REGWEN_12 | 0x704 | +| DIO_PAD_SLEEP_REGWEN_13 | 0x708 | + + +### 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 | Register write enable bit. If this is cleared to 0, the corresponding [`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode) is not writable anymore. | + +## DIO_PAD_SLEEP_EN +Enables the sleep mode of the corresponding dedicated pad. +- Reset default: `0x0` +- Reset mask: `0x1` +- Register enable: [`DIO_PAD_SLEEP_REGWEN`](#dio_pad_sleep_regwen) + +### Instances + +| Name | Offset | +|:--------------------|:---------| +| DIO_PAD_SLEEP_EN_0 | 0x70c | +| DIO_PAD_SLEEP_EN_1 | 0x710 | +| DIO_PAD_SLEEP_EN_2 | 0x714 | +| DIO_PAD_SLEEP_EN_3 | 0x718 | +| DIO_PAD_SLEEP_EN_4 | 0x71c | +| DIO_PAD_SLEEP_EN_5 | 0x720 | +| DIO_PAD_SLEEP_EN_6 | 0x724 | +| DIO_PAD_SLEEP_EN_7 | 0x728 | +| DIO_PAD_SLEEP_EN_8 | 0x72c | +| DIO_PAD_SLEEP_EN_9 | 0x730 | +| DIO_PAD_SLEEP_EN_10 | 0x734 | +| DIO_PAD_SLEEP_EN_11 | 0x738 | +| DIO_PAD_SLEEP_EN_12 | 0x73c | +| DIO_PAD_SLEEP_EN_13 | 0x740 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "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 | [EN](#dio_pad_sleep_en--en) | + +### DIO_PAD_SLEEP_EN . EN +Deep sleep mode enable. +If this bit is set to 1 the corresponding pad will enable the sleep behavior +specified in [`DIO_PAD_SLEEP_MODE`](#dio_pad_sleep_mode) upon deep sleep entry, and the corresponding bit +in [`DIO_PAD_SLEEP_STATUS`](#dio_pad_sleep_status) will be set to 1. +The pad remains in deep sleep mode until the corresponding bit in +[`DIO_PAD_SLEEP_STATUS`](#dio_pad_sleep_status) is cleared by SW. +Note that if an always on peripheral is connected to a specific DIO pad, +the corresponding [`DIO_PAD_SLEEP_EN`](#dio_pad_sleep_en) bit should be set to 0. + +## DIO_PAD_SLEEP_MODE +Defines sleep behavior of the corresponding dedicated pad. +- Reset default: `0x2` +- Reset mask: `0x3` +- Register enable: [`DIO_PAD_SLEEP_REGWEN`](#dio_pad_sleep_regwen) + +### Instances + +| Name | Offset | +|:----------------------|:---------| +| DIO_PAD_SLEEP_MODE_0 | 0x744 | +| DIO_PAD_SLEEP_MODE_1 | 0x748 | +| DIO_PAD_SLEEP_MODE_2 | 0x74c | +| DIO_PAD_SLEEP_MODE_3 | 0x750 | +| DIO_PAD_SLEEP_MODE_4 | 0x754 | +| DIO_PAD_SLEEP_MODE_5 | 0x758 | +| DIO_PAD_SLEEP_MODE_6 | 0x75c | +| DIO_PAD_SLEEP_MODE_7 | 0x760 | +| DIO_PAD_SLEEP_MODE_8 | 0x764 | +| DIO_PAD_SLEEP_MODE_9 | 0x768 | +| DIO_PAD_SLEEP_MODE_10 | 0x76c | +| DIO_PAD_SLEEP_MODE_11 | 0x770 | +| DIO_PAD_SLEEP_MODE_12 | 0x774 | +| DIO_PAD_SLEEP_MODE_13 | 0x778 | + + +### Fields + +```wavejson +{"reg": [{"name": "OUT", "bits": 2, "attr": ["rw"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:--------------------------------| +| 31:2 | | | Reserved | +| 1:0 | rw | 0x2 | [OUT](#dio_pad_sleep_mode--out) | + +### DIO_PAD_SLEEP_MODE . OUT +Value to drive in deep sleep. + +| Value | Name | Description | +|:--------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 0x0 | Tie-Low | The pad is driven actively to zero in deep sleep mode. | +| 0x1 | Tie-High | The pad is driven actively to one in deep sleep mode. | +| 0x2 | High-Z | The pad is left undriven in deep sleep mode. Note that the actual driving behavior during deep sleep will then depend on the pull-up/-down configuration of in !!DIO_PAD_ATTR. | +| 0x3 | Keep | Keep last driven value (including high-Z). | + + +## WKUP_DETECTOR_REGWEN +Register write enable for wakeup detectors. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| WKUP_DETECTOR_REGWEN_0 | 0x77c | +| WKUP_DETECTOR_REGWEN_1 | 0x780 | +| WKUP_DETECTOR_REGWEN_2 | 0x784 | +| WKUP_DETECTOR_REGWEN_3 | 0x788 | +| WKUP_DETECTOR_REGWEN_4 | 0x78c | +| WKUP_DETECTOR_REGWEN_5 | 0x790 | +| WKUP_DETECTOR_REGWEN_6 | 0x794 | +| WKUP_DETECTOR_REGWEN_7 | 0x798 | + + +### 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 | Register write enable bit. If this is cleared to 0, the corresponding WKUP_DETECTOR configuration is not writable anymore. | + +## WKUP_DETECTOR_EN +Enables for the wakeup detectors. +Note that these registers are synced to the always-on clock. +The first write access always completes immediately. +However, read/write accesses following a write will block until that write has completed. +- Reset default: `0x0` +- Reset mask: `0x1` +- Register enable: [`WKUP_DETECTOR_REGWEN`](#wkup_detector_regwen) + +### Instances + +| Name | Offset | +|:-------------------|:---------| +| WKUP_DETECTOR_EN_0 | 0x79c | +| WKUP_DETECTOR_EN_1 | 0x7a0 | +| WKUP_DETECTOR_EN_2 | 0x7a4 | +| WKUP_DETECTOR_EN_3 | 0x7a8 | +| WKUP_DETECTOR_EN_4 | 0x7ac | +| WKUP_DETECTOR_EN_5 | 0x7b0 | +| WKUP_DETECTOR_EN_6 | 0x7b4 | +| WKUP_DETECTOR_EN_7 | 0x7b8 | + + +### Fields + +```wavejson +{"reg": [{"name": "EN", "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 | EN | Setting this bit activates the corresponding wakeup detector. The behavior is as specified in [`WKUP_DETECTOR`](#wkup_detector), [`WKUP_DETECTOR_CNT_TH`](#wkup_detector_cnt_th) and [`WKUP_DETECTOR_PADSEL.`](#wkup_detector_padsel) | + +## WKUP_DETECTOR +Configuration of wakeup condition detectors. +Note that these registers are synced to the always-on clock. +The first write access always completes immediately. +However, read/write accesses following a write will block until that write has completed. + +Note that the wkup detector should be disabled by setting [`WKUP_DETECTOR_EN_0`](#wkup_detector_en_0) before changing the detection mode. +The reason for that is that the pulse width counter is NOT cleared upon a mode change while the detector is enabled. +- Reset default: `0x0` +- Reset mask: `0x1f` +- Register enable: [`WKUP_DETECTOR_REGWEN`](#wkup_detector_regwen) + +### Instances + +| Name | Offset | +|:----------------|:---------| +| WKUP_DETECTOR_0 | 0x7bc | +| WKUP_DETECTOR_1 | 0x7c0 | +| WKUP_DETECTOR_2 | 0x7c4 | +| WKUP_DETECTOR_3 | 0x7c8 | +| WKUP_DETECTOR_4 | 0x7cc | +| WKUP_DETECTOR_5 | 0x7d0 | +| WKUP_DETECTOR_6 | 0x7d4 | +| WKUP_DETECTOR_7 | 0x7d8 | + + +### Fields + +```wavejson +{"reg": [{"name": "MODE", "bits": 3, "attr": ["rw"], "rotate": 0}, {"name": "FILTER", "bits": 1, "attr": ["rw"], "rotate": -90}, {"name": "MIODIO", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 27}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:---------------------------------| +| 31:5 | | | Reserved | +| 4 | rw | 0x0 | [MIODIO](#wkup_detector--miodio) | +| 3 | rw | 0x0 | [FILTER](#wkup_detector--filter) | +| 2:0 | rw | 0x0 | [MODE](#wkup_detector--mode) | + +### WKUP_DETECTOR . MIODIO +0: select index [`WKUP_DETECTOR_PADSEL`](#wkup_detector_padsel) from MIO pads, +1: select index [`WKUP_DETECTOR_PADSEL`](#wkup_detector_padsel) from DIO pads. + +### WKUP_DETECTOR . FILTER +0: signal filter disabled, 1: signal filter enabled. the signal must +be stable for 4 always-on clock cycles before the value is being forwarded. +can be used for debouncing. + +### WKUP_DETECTOR . MODE +Wakeup detection mode. Out of range values default to Posedge. + +| Value | Name | Description | +|:--------|:----------|:-----------------------------------------------------------------------------------------------------------------------------------------| +| 0x0 | Posedge | Trigger a wakeup request when observing a positive edge. | +| 0x1 | Negedge | Trigger a wakeup request when observing a negative edge. | +| 0x2 | Edge | Trigger a wakeup request when observing an edge in any direction. | +| 0x3 | TimedHigh | Trigger a wakeup request when pin is driven HIGH for a certain amount of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH. | +| 0x4 | TimedLow | Trigger a wakeup request when pin is driven LOW for a certain amount of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH. | + +Other values are reserved. + +## WKUP_DETECTOR_CNT_TH +Counter thresholds for wakeup condition detectors. +Note that these registers are synced to the always-on clock. +The first write access always completes immediately. +However, read/write accesses following a write will block until that write has completed. +- Reset default: `0x0` +- Reset mask: `0xff` +- Register enable: [`WKUP_DETECTOR_REGWEN`](#wkup_detector_regwen) + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| WKUP_DETECTOR_CNT_TH_0 | 0x7dc | +| WKUP_DETECTOR_CNT_TH_1 | 0x7e0 | +| WKUP_DETECTOR_CNT_TH_2 | 0x7e4 | +| WKUP_DETECTOR_CNT_TH_3 | 0x7e8 | +| WKUP_DETECTOR_CNT_TH_4 | 0x7ec | +| WKUP_DETECTOR_CNT_TH_5 | 0x7f0 | +| WKUP_DETECTOR_CNT_TH_6 | 0x7f4 | +| WKUP_DETECTOR_CNT_TH_7 | 0x7f8 | + + +### Fields + +```wavejson +{"reg": [{"name": "TH", "bits": 8, "attr": ["rw"], "rotate": 0}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:8 | | | | Reserved | +| 7:0 | rw | 0x0 | TH | Counter threshold for TimedLow and TimedHigh wakeup detector modes (see [`WKUP_DETECTOR`](#wkup_detector)). The threshold is in terms of always-on clock cycles. | + +## WKUP_DETECTOR_PADSEL +Pad selects for pad wakeup condition detectors. +This register is NOT synced to the AON domain since the muxing mechanism is implemented in the same way as the pinmux muxing matrix. +- Reset default: `0x0` +- Reset mask: `0x3f` +- Register enable: [`WKUP_DETECTOR_REGWEN`](#wkup_detector_regwen) + +### Instances + +| Name | Offset | +|:-----------------------|:---------| +| WKUP_DETECTOR_PADSEL_0 | 0x7fc | +| WKUP_DETECTOR_PADSEL_1 | 0x800 | +| WKUP_DETECTOR_PADSEL_2 | 0x804 | +| WKUP_DETECTOR_PADSEL_3 | 0x808 | +| WKUP_DETECTOR_PADSEL_4 | 0x80c | +| WKUP_DETECTOR_PADSEL_5 | 0x810 | +| WKUP_DETECTOR_PADSEL_6 | 0x814 | +| WKUP_DETECTOR_PADSEL_7 | 0x818 | + + +### Fields + +```wavejson +{"reg": [{"name": "SEL", "bits": 6, "attr": ["rw"], "rotate": 0}, {"bits": 26}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:----------------------------------| +| 31:6 | | | Reserved | +| 5:0 | rw | 0x0 | [SEL](#wkup_detector_padsel--sel) | + +### WKUP_DETECTOR_PADSEL . SEL +Selects a specific MIO or DIO pad (depending on [`WKUP_DETECTOR`](#wkup_detector) configuration). +In case of MIO, the pad select index is the same as used for [`MIO_PERIPH_INSEL`](#mio_periph_insel), meaning that index +0 and 1 just select constants 0 and 1, and the MIO pads live at indices >= 2. In case of DIO pads, +the pad select index corresponds 1:1 to the DIO pad to be selected. + +## WKUP_CAUSE +Cause registers for wakeup detectors. +Note that these registers are synced to the always-on clock. +The first write access always completes immediately. +However, read/write accesses following a write will block until that write has completed. +- Offset: `0x81c` +- Reset default: `0x0` +- Reset mask: `0xff` + +### Fields + +```wavejson +{"reg": [{"name": "CAUSE_0", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CAUSE_1", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CAUSE_2", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CAUSE_3", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CAUSE_4", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CAUSE_5", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CAUSE_6", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"name": "CAUSE_7", "bits": 1, "attr": ["rw0c"], "rotate": -90}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 90}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:--------|:----------------------------------------------------------------------------------------| +| 31:8 | | | | Reserved | +| 7 | rw0c | 0x0 | CAUSE_7 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | +| 6 | rw0c | 0x0 | CAUSE_6 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | +| 5 | rw0c | 0x0 | CAUSE_5 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | +| 4 | rw0c | 0x0 | CAUSE_4 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | +| 3 | rw0c | 0x0 | CAUSE_3 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | +| 2 | rw0c | 0x0 | CAUSE_2 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | +| 1 | rw0c | 0x0 | CAUSE_1 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | +| 0 | rw0c | 0x0 | CAUSE_0 | Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear. | + + + diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/targets.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/targets.md new file mode 100644 index 0000000000000..c3496d2f40b9f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/targets.md @@ -0,0 +1,9 @@ +# "top_englishbreakfast" Pinmux Targets + +| Target Name | #IO Banks | #Muxed Pads | #Direct Pads | #Manual Pads | #Total Pads | Pinout / Pinmux Tables | +|:-------------:|:-----------:|:-------------:|:--------------:|:--------------:|:-------------:|:---------------------------------:| +| CW305 | 4 | 24 | 4 | 10 | 38 | [Pinout Table](./pinout_cw305.md) | diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/doc/theory_of_operation.md b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/theory_of_operation.md new file mode 100644 index 0000000000000..fa1200779d0f3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/doc/theory_of_operation.md @@ -0,0 +1,215 @@ +# Theory of Operation + +## Block Diagram and Overview + +The `pinmux` peripheral is a programmable module designed to wire arbitrary peripheral inputs and outputs to arbitrary multiplexable chip bidirectional pins. +It gives much flexibility at the top level of the device, allowing most data pins to be flexibly wired and controlled by many peripherals. +Even though the `pinmux` is referred to as one IP, it is logically split into two modules that are instantiated on the top-level and the chip-level, respectively, as can be seen in the block diagram below. +The top-level module `pinmux` contains the CSRs accessible via the TL-UL interface, the main muxing matrix, retention registers, a set of programmable wakeup detectors, and the HW strap sampling and TAP / JTAG muxing logic. +The chip-level module `padring` instantiates the bidirectional pads and connects the physical pad attributes. + +![Pinmux Block Diagram](../doc/pinmux_overview_block_diagram.svg) + +### MIO and DIO Signal Categories + +The `pinmux` supports two different IO signal categories: +Muxed IO (MIO) signals that are routed through the `pinmux` matrix, and dedicated IO (DIO) signals that bypass the `pinmux` matrix. +This distinction is useful for accommodating IO signals that are timing critical or that must have a fixed IO mapping for another reason. +Note that although DIO signals are not routed through the `pinmux` matrix, they are still connected to the retention logic and the wakeup detectors (see next section below). + +The number of available peripheral IOs, pads, and their assignment to the MIO / DIO categories is done at design time as part of the top-level configuration. +This configurability is achieved by representing inputs / outputs as packed arrays, in combination with the SystemVerilog parameters `NPeriphIn`, `NPeriphOut`, `NMioPads` and `NDioPads`. +Note however that the register file is also affected by this configuration and needs to be regenerated for each design instance. + +It is assumed that all available pins that the `pinmux` connects to are bidirectional, controlled by logic within this module. +By default, all muxed peripheral inputs are tied to zero. +Further, all output enables are set to zero, which essentially causes all pads to be in high-Z state after reset. +In addition to wiring programmability, each muxed peripheral input can be set constantly to 0 or 1, and each muxed chip output can be set constantly to 0, 1 or high-Z. + +See the [muxing matrix](#muxing-matrix) section for more details about the mux implementation. + +### Retention and Wakeup Features + +The retention logic allows SW to specify a certain behavior during sleep for each muxed and dedicated output. +Legal behaviors are tie low, tie high, high-Z, keeping the previous state, or driving the current value (useful for peripherals that are always on). + +The wakeup detectors can detect patterns such as rising / falling edges and pulses of a certain width up to 255 AON clock cycles. +Each wakeup detector can listen on any one of the MIO / DIO signals that are routed through the `pinmux`, and if a pattern is detected, the power manager is informed of that event via a wakeup request. + +The `pinmux` module itself is in the always-on (AON) power domain, and as such does not loose configuration state when a sleep power cycle is performed. +However, only the wakeup detector logic will be actively clocked during sleep in order to save power. + +See the [retention logic](#retention-logic) and [wakeup detectors](#wakeup-detectors) sections for more details about the mux implementation. + +### USB Wakeup Detection Module + +The USB device in the Earlgrey top-level is not in the AON power domain and hence the associated wakeup detection module is placed inside the pinmux IP in that top-level. +The USB wakeup module is not connected to any pinmux infrastructure or CSRs except for the `usb_wkup_req` signal going to the power manager. +See [USB device documentation](../../../../ip/usbdev/README.md) for more information on the USB wakeup mechanism. + +### Test and Debug Access + +The hardware strap sampling and TAP isolation logic provides test and debug access to the chip during specific life cycle states. +This mechanism is explained in more detail in the [strap sampling and TAP isolation](#strap-sampling-and-tap-isolation) section. + +### Pad Attributes + +Additional pad-specific features such as inversion, pull-up, pull-down, virtual open-drain, drive-strength and input/output inversion etc. can be exercise via the pad attribute CSRs. +The `pinmux` module supports a comprehensive set of such pad attributes, but it is permissible that some of them may not be supported by the underlying pad implementation. +For example, certain ASIC libraries may not provide open-drain outputs, and FPGAs typically do not allow all of these attributes to be programmed dynamically at runtime. +See the [generic pad wrapper](#generic-pad-wrapper) section below for more details. +Note that static pad attributes for FPGAs are currently not covered in this specification. + +## Muxing Matrix + +The diagram below shows connectivity between four arbitrary chip pins, named `MIO0` .. `MIO3`, and several muxed peripheral inputs and outputs. +This shows the connectivity available in all directions, as well as the control registers described later in this document. +Two example peripherals (`uart` and `spidev`) are attached to the `pinmux` in this example, one with one input and one output, the other with three inputs and one output. +The diagram also shows the `padring` module which instantiates the bidirectional chip pads with output enable control. + +![Pinmux Block Diagram](../doc/pinmux_muxing_matrix.svg) + +Note that apart from selecting a specific input pad, the `periph_insel[*]` signals can also be used to tie the peripheral input to 0 or 1. +Likewise, the output select signals `mio_outsel[*]` can also be used to constantly drive an output pin to 0/1 or to put it into high-Z state (default). +The output enable and the associated data signal (i.e. `periph_to_mio` and `periph_to_mio_oe`) are indexed with the same select signal to allow the peripheral hardware to determine the pad direction instead of demoting that control to SW. + +## Retention Logic + +As illustrated in the picture above, all muxing matrix and DIO outputs are routed through the retention logic, which essentially consists of a set of multiplexors and two retention registers per output (one register is for the output data and one for the output enable). +This multiplexor can be configured to be automatically activated upon sleep entry in order to either drive the output low, high, high-Z or to the last seen value (keep). +If no sleep behavior is specified, the retention logic will continue to drive out the value coming from the peripheral side, which can be useful for peripherals that reside in the AON domain. + +The sleep behavior of all outputs is activated in parallel via a trigger signal asserted by the power manager. +Once activated, it is the task of SW to disable the sleep behavior for each individual pin when waking up from sleep. +This ensures that the output values remain stable until the system and its peripherals have been re-initialized. + +## Wakeup Detectors + +The `pinmux` contains eight programmable wakeup detector modules that can listen on any of the MIO or DIO pins. +Each detector contains a debounce filter and an 8bit counter running on the AON clock domain. +The detectors can be programmed via the [`WKUP_DETECTOR_0`](registers.md#wkup_detector) and [`WKUP_DETECTOR_CNT_TH_0`](registers.md#wkup_detector_cnt_th) registers to detect the following patterns: + +- rising edge +- falling edge +- rising or falling edge +- positive pulse up to 255 AON clock cycles in length +- negative pulse up to 255 AON clock cycles in length + +Note that for all patterns listed above, the input signal is sampled with the AON clock. +This means that the input signal needs to remain stable for at least one AON clock cycle after a level change for the detector to recognize the event (depending on the debounce filter configuration, the signal needs to remain stable for multiple clock cycles). + +If a pattern is detected, the wakeup detector will send a wakeup request to the power manager, and the cause bit corresponding to that detector will be set in the [`WKUP_CAUSE`](registers.md#wkup_cause) register. + +Note that the wkup detector should be disabled by setting [`WKUP_DETECTOR_EN_0`](registers.md#wkup_detector_en) before changing the detection mode. +The reason for that is that the pulse width counter is NOT cleared upon a mode change while the detector is enabled. + +## Strap Sampling and TAP Isolation + +The `pinmux` contains a set of dedicated HW "straps", which are essentially signals that are multiplexed onto fixed MIO pad locations. +Depending on the life cycle state, these straps are either continuously sampled, or latched right after POR. + +There are two groups of HW straps: +1. Three DFT straps that determine the DFT mode. + These bits are output via the `dft_strap_test_o` signal such that they can be routed to the tool-inserted DFT controller. +2. Two TAP selection straps for determining which TAP should be multiplexed onto the JTAG IOs. + +The conditions under which these two strap groups are sampled are listed in the tables below. +Note that the HW straps can be used just like regular GPIOs once they have been sampled. + +Strap Group \ Life Cycle State | TEST_UNLOCKED* | RMA | DEV | All Other States +--------------------------------|----------------|--------------|--------------|------------------ +DFT straps | Once at boot | Once at boot | - | - +TAP strap 0 | Continuously | Continuously | Once at boot | Once at boot +TAP strap 1 | Continuously | Continuously | Once at boot | - + +*Once at boot:* Sampled once after life cycle initialization (sampling event is initiated by pwrmgr). + +*Continuously:* Sampled continuously after life cycle initialization. + +The TAP muxing logic is further qualified by the life cycle state in order to isolate the TAPs in certain life cycle states. +The following table lists the TAP strap encoding and the life cycle states in which the associated TAPs can be selected and accessed. + +TAP strap 1 | TAP strap 0 | Life Cycle State | Selected TAP +------------|--------------|--------------------------|--------------- +0 | 0 | All states | - +0 | 1 | All states | Life Cycle +1 | 0 | TEST_UNLOCKED*, RMA, DEV | RISC-V +1 | 1 | TEST_UNLOCKED*, RMA | DFT + +Note that the tool-inserted DFT controller may assert the `dft_hold_tap_sel_i` during a test (e.g. boundary scan) in which case the `pinmux` will temporarily pause sampling of the TAP selection straps. + +It should be noted that the TAP straps are muxed with MIOs and that the pad attributes will take effect even in life cycles states that +continuously sample the straps. As a result, pad attributes can interfere or even disable tap selection entirely in those life cycle states. + +Also, it should be noted that the pad attributes of all JTAG IOs will be gated to all-zero temporarily, while the JTAG is enabled (this does not affect the values in the CSRs). +This is to ensure that any functional attributes like inversion or pull-ups / pull-downs do not interfere with the JTAG while it is in use. + +For more information about the life cycle states, see [Life Cycle Controller Specification](../../../../ip/lc_ctrl/README.md) and the [Life Cycle Definition Table](../../../../../doc/security/specs/device_life_cycle/README.md#manufacturing-states). + +### Non-debug Module Reset + +The only parts of the system that are not reset as part of a non-debug module (NDM) reset are in this strap sampling and TAP selection module, and in the `rv_dm`, power, reset and clock managers. +Hence, in order to keep a `rv_dm` JTAG debug session alive during an NDM reset, the `lc_hw_debug_en` state needs to be memorized. + +To that end, the TAP isolation logic in the pinmux samples the `lc_hw_debug_en` state when the strap sampling pulse is asserted by the power manager. +This pulse is asserted once during boot (and not after an NDM reset). + +Note that DFT TAP selection is not affected by this since the TAP selection logic always consumes the live value for `lc_dft_en`. +The TAP selection logic also invalidates the sampled `lc_hw_debug_en` whenever a life cycle transition is initiated or an escalation is triggered via `lc_escalate_en`. +This ensures that the sampled `lc_hw_debug_en` value does not survive a life cycle transition. + +Finally, note that there is secondary gating on the `rv_dm` and DFT TAPs that is always consuming live `lc_hw_debug_en` and `lc_dft_en` signals for added protection. + +See also [rv_dm documentation](../../../../ip/rv_dm/doc/theory_of_operation.md#non-debug-module-reset-support). + +## Generic Pad Wrapper + +
+ +
+ +The generic pad wrapper is intended to abstract away implementation differences between the target technologies by providing a generic interface that is compatible with the `padring` module. +It is the task of the RTL build flow to select the appropriate pad wrapper implementation. + +A specific implementation of a pad wrapper may choose to instantiate a technology primitive (as it is common in ASIC flows), or it may choose to model the functionality behaviorally such that it can be inferred by the technology mapping tool (e.g., in the case of an FPGA target). +It is permissible to omit the implementation of all IO attributes except input/output inversion. + +The generic pad wrapper must expose the following IOs and parameters, even if they are not connected internally. +In particular, the pad attribute struct `attr_i` must contain all fields listed below, even if not all attributes are supported (it is permissible to just leave them unconnected in the pad wrapper implementation). + +Parameter | Default | Description +---------------|------------|----------------------------------------------------- +`PadType` | `BidirStd` | Pad variant to be instantiated (technology-specific) +`ScanRole` | `NoScan` | Scan role, can be `NoScan`, `ScanIn` or `ScanOut` + +Note that `PadType` is a technology-specific parameter. +The generic pad wrapper only implements variant `BidirStd`, but for other target technologies, this parameter can be used to select among a variety of different pad flavors. + +The `ScanRole` parameter determines the behavior when scanmode is enabled. +Depending on whether a given pad acts as a scan input or output, certain pad attributes and functionalities need to be bypassed. +This parameter is typically only relevant for ASIC targets and therefore not modeled in the generic pad model. + +Also note that the pad wrapper may implement a "virtual" open-drain termination, where standard bidirectional pads are employed, but instead of driving the output high for a logic 1 the pad is put into tristate mode. + +Signal | Direction | Type | Description +---------------------|------------|-------------|----------------------------------------------- +`clk_scan_i` | `input` | `logic` | Scan clock of the pad +`scanmode_i` | `input` | `logic` | Scan mode enable of the pad +`pok_i` | `input` | `pad_pok_t` | Technology-specific power sequencing signals +`inout_io` | `inout` | `wire` | Bidirectional inout of the pad +`in_o` | `output` | `logic` | Input data signal +`in_raw_o` | `output` | `logic` | Un-inverted input data signal +`out_i` | `input` | `logic` | Output data signal +`oe_i` | `input` | `logic` | Output data enable +`attr_i[0]` | `input` | `logic` | Input/output inversion +`attr_i[1]` | `input` | `logic` | Virtual open-drain enable +`attr_i[2]` | `input` | `logic` | Pull enable +`attr_i[3]` | `input` | `logic` | Pull select (0: pull-down, 1: pull-up) +`attr_i[4]` | `input` | `logic` | Keeper enable +`attr_i[5]` | `input` | `logic` | Schmitt trigger enable +`attr_i[6]` | `input` | `logic` | Open drain enable +`attr_i[7]` | `input` | `logic` | Input disable (0: input enabled, 1: input disabled) +`attr_i[9:8]` | `input` | `logic` | Slew rate (0x0: slowest, 0x3: fastest) +`attr_i[13:10]` | `input` | `logic` | Drive strength (0x0: weakest, 0xf: strongest) + +Note that the corresponding pad attribute registers [`MIO_PAD_ATTR_0`](registers.md#mio_pad_attr) and [`DIO_PAD_ATTR_0`](registers.md#dio_pad_attr) have "writes-any-reads-legal" (WARL) behavior (see also [pad attributes](#pad-attributes)). diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_expected_failure.hjson b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_expected_failure.hjson new file mode 100644 index 0000000000000..c6d4640f00fae --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_expected_failure.hjson @@ -0,0 +1,12 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +{ + unreachable: + [ + pinmux_chip_tb.dut_asic.FpvSecCmRegWeOnehotCheck_A:precondition1 + pinmux_chip_tb.dut_asic.u_reg.u_prim_reg_we_check.u_prim_onehot_check.Onehot0Check_A:precondition1 + pinmux_chip_tb.dut_asic.u_reg.u_prim_reg_we_check.u_prim_onehot_check.gen_enable_check.gen_not_strict.EnableCheck_A:precondition1 + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_fpv.core b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_fpv.core new file mode 100644 index 0000000000000..d03515b797955 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_chip_fpv.core @@ -0,0 +1,44 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pinmux_chip_fpv:0.1 +description: "pinmux FPV target with chip_earlgrey parameters" + +filesets: + files_formal: + depend: + - lowrisc:prim:all + - lowrisc:ip:tlul + - lowrisc:ip:jtag_pkg + - lowrisc:prim:mubi_pkg + - lowrisc:ip:lc_ctrl_pkg + - lowrisc:opentitan:top_englishbreakfast_pinmux:0.1 + - lowrisc:fpv:csr_assert_gen + - lowrisc:opentitan:top_englishbreakfast_pinmux_common_fpv:0.1 + - lowrisc:constants:top_englishbreakfast_top_pkg + - lowrisc:systems:top_englishbreakfast_scan_role_pkg + files: + - tb/pinmux_chip_tb.sv + file_type: systemVerilogSource + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../data/pinmux.hjson + +targets: + default: &default_target + default_tool: icarus + filesets: + - files_formal + generate: + - csr_assert_gen + toplevel: pinmux_chip_tb + + formal: + <<: *default_target + + lint: + <<: *default_target diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_common_fpv.core b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_common_fpv.core new file mode 100644 index 0000000000000..5f837ecd336ba --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_common_fpv.core @@ -0,0 +1,28 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pinmux_common_fpv:0.1 +description: "pinmux common FPV target" +filesets: + files_formal: + depend: + - lowrisc:prim:all + - lowrisc:ip:tlul + - lowrisc:opentitan:top_englishbreakfast_pinmux:0.1 + files: + - vip/pinmux_assert_fpv.sv + - tb/pinmux_bind_fpv.sv + file_type: systemVerilogSource + +targets: + default: &default_target + default_tool: icarus + filesets: + - files_formal + + formal: + <<: *default_target + + lint: + <<: *default_target diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_expected_failure.hjson b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_expected_failure.hjson new file mode 100644 index 0000000000000..ccbda769bebb3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_expected_failure.hjson @@ -0,0 +1,12 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +{ + unreachable: + [ + pinmux_tb.dut.FpvSecCmRegWeOnehotCheck_A:precondition1 + pinmux_tb.dut.u_reg.u_prim_reg_we_check.u_prim_onehot_check.Onehot0Check_A:precondition1 + pinmux_tb.dut.u_reg.u_prim_reg_we_check.u_prim_onehot_check.gen_enable_check.gen_not_strict.EnableCheck_A:precondition1 + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_fpv.core b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_fpv.core new file mode 100644 index 0000000000000..3e613448e9bc8 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/pinmux_fpv.core @@ -0,0 +1,38 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pinmux_fpv:0.1 +description: "pinmux FPV target" +filesets: + files_formal: + depend: + - lowrisc:prim:all + - lowrisc:ip:tlul + - lowrisc:opentitan:top_englishbreakfast_pinmux:0.1 + - lowrisc:fpv:csr_assert_gen + - lowrisc:opentitan:top_englishbreakfast_pinmux_common_fpv + files: + - tb/pinmux_tb.sv + file_type: systemVerilogSource + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../data/pinmux.hjson + +targets: + default: &default_target + default_tool: icarus + filesets: + - files_formal + generate: + - csr_assert_gen + toplevel: pinmux_tb + + formal: + <<: *default_target + + lint: + <<: *default_target diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_bind_fpv.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_bind_fpv.sv new file mode 100644 index 0000000000000..85ca035fa236a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_bind_fpv.sv @@ -0,0 +1,86 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +module pinmux_bind_fpv; + + + bind pinmux pinmux_assert_fpv #( + .TargetCfg(TargetCfg), + .AlertAsyncOn(AlertAsyncOn), + .SecVolatileRawUnlockEn(SecVolatileRawUnlockEn) + ) i_pinmux_assert_fpv ( + .clk_i, + .rst_ni, + .rst_sys_ni, + .scanmode_i, + .clk_aon_i, + .rst_aon_ni, + .pin_wkup_req_o, + .usb_wkup_req_o, + .sleep_en_i, + .strap_en_i, + .strap_en_override_i, + .lc_dft_en_i, + .lc_hw_debug_en_i, + .lc_check_byp_en_i, + .lc_escalate_en_i, + .pinmux_hw_debug_en_o, + .dft_strap_test_o, + .dft_hold_tap_sel_i, + .lc_jtag_o, + .lc_jtag_i, + .rv_jtag_o, + .rv_jtag_i, + .dft_jtag_o, + .dft_jtag_i, + .usbdev_dppullup_en_i, + .usbdev_dnpullup_en_i, + .usb_dppullup_en_o, + .usb_dnpullup_en_o, + .usbdev_suspend_req_i, + .usbdev_wake_ack_i, + .usbdev_bus_not_idle_o, + .usbdev_bus_reset_o, + .usbdev_sense_lost_o, + .usbdev_wake_detect_active_o, + .tl_i, + .tl_o, + .alert_rx_i, + .alert_tx_o, + .periph_to_mio_i, + .periph_to_mio_oe_i, + .mio_to_periph_o, + .periph_to_dio_i, + .periph_to_dio_oe_i, + .dio_to_periph_o, + .mio_attr_o, + .mio_out_o, + .mio_oe_o, + .mio_in_i, + .dio_attr_o, + .dio_out_o, + .dio_oe_o, + .dio_in_i + ); + + + bind pinmux tlul_assert #( + .EndpointType("Device") + ) i_tlul_assert_device ( + .clk_i, + .rst_ni, + .h2d (tl_i), + .d2h (tl_o), + .* + ); + + bind pinmux pinmux_csr_assert_fpv i_pinmux_csr_assert_fpv ( + .clk_i, + .rst_ni, + .h2d (tl_i), + .d2h (tl_o) + ); + +endmodule : pinmux_bind_fpv diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_chip_tb.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_chip_tb.sv new file mode 100644 index 0000000000000..036f5e90f7403 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_chip_tb.sv @@ -0,0 +1,242 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Testbench module for pinmux. +// Intended to be used with a formal tool. + +module pinmux_chip_tb + import pinmux_pkg::*; + import pinmux_reg_pkg::*; + import prim_pad_wrapper_pkg::*; + import top_englishbreakfast_pkg::*; +#( + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter bit SecVolatileRawUnlockEn = 1 +) ( + input clk_i, + input rst_ni, + input rst_sys_ni, + input prim_mubi_pkg::mubi4_t scanmode_i, + input clk_aon_i, + input rst_aon_ni, + output logic pin_wkup_req_o, + output logic usb_wkup_req_o, + input sleep_en_i, + input strap_en_i, + input strap_en_override_i, + input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + input lc_ctrl_pkg::lc_tx_t lc_check_byp_en_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + output lc_ctrl_pkg::lc_tx_t pinmux_hw_debug_en_o, + output dft_strap_test_req_t dft_strap_test_o, + input dft_hold_tap_sel_i, + output jtag_pkg::jtag_req_t lc_jtag_o, + input jtag_pkg::jtag_rsp_t lc_jtag_i, + output jtag_pkg::jtag_req_t rv_jtag_o, + input jtag_pkg::jtag_rsp_t rv_jtag_i, + output jtag_pkg::jtag_req_t dft_jtag_o, + input jtag_pkg::jtag_rsp_t dft_jtag_i, + input usbdev_dppullup_en_i, + input usbdev_dnpullup_en_i, + output logic usb_dppullup_en_o, + output logic usb_dnpullup_en_o, + input usbdev_suspend_req_i, + input usbdev_wake_ack_i, + output logic usbdev_bus_not_idle_o, + output logic usbdev_bus_reset_o, + output logic usbdev_sense_lost_o, + output logic usbdev_wake_detect_active_o, + input tlul_pkg::tl_h2d_t tl_i, + output tlul_pkg::tl_d2h_t tl_o, + 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, + input [NMioPeriphOut-1:0] periph_to_mio_i, + input [NMioPeriphOut-1:0] periph_to_mio_oe_i, + output logic[NMioPeriphIn-1:0] mio_to_periph_o, + input [NDioPads-1:0] periph_to_dio_i, + input [NDioPads-1:0] periph_to_dio_oe_i, + output logic[NDioPads-1:0] dio_to_periph_o, + output prim_pad_wrapper_pkg::pad_attr_t[NMioPads-1:0] mio_attr_o, + output logic[NMioPads-1:0] mio_out_o, + output logic[NMioPads-1:0] mio_oe_o, + input [NMioPads-1:0] mio_in_i, + output prim_pad_wrapper_pkg::pad_attr_t[NDioPads-1:0] dio_attr_o, + output logic[NDioPads-1:0] dio_out_o, + output logic[NDioPads-1:0] dio_oe_o, + input [NDioPads-1:0] dio_in_i +); + + import top_englishbreakfast_pkg::*; + + // Copied from chip_englishbreakfast_asic.sv + // TODO: find a better way to automatically generate this FPV testbench via topgen/ipgen. + localparam int Tap0PadIdx = 30; + localparam int Tap1PadIdx = 27; + localparam int Dft0PadIdx = 25; + localparam int Dft1PadIdx = 26; + localparam int TckPadIdx = 38; + localparam int TmsPadIdx = 35; + localparam int TrstNPadIdx = 39; + localparam int TdiPadIdx = 37; + localparam int TdoPadIdx = 36; + // DFT and Debug signal positions in the pinout. + localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{ + tck_idx: TckPadIdx, + tms_idx: TmsPadIdx, + trst_idx: TrstNPadIdx, + tdi_idx: TdiPadIdx, + tdo_idx: TdoPadIdx, + tap_strap0_idx: Tap0PadIdx, + tap_strap1_idx: Tap1PadIdx, + dft_strap0_idx: Dft0PadIdx, + dft_strap1_idx: Dft1PadIdx, + // TODO: check whether there is a better way to pass these USB-specific params + usb_dp_idx: DioUsbdevUsbDp, + usb_dn_idx: DioUsbdevUsbDn, + usb_sense_idx: MioInUsbdevSense, + // Pad types for attribute WARL behavior + dio_pad_type: { + BidirStd, // DIO spi_host0_csb + BidirStd, // DIO spi_host0_sck + InputStd, // DIO spi_device_csb + InputStd, // DIO spi_device_sck + BidirOd, // DIO sysrst_ctrl_aon_flash_wp_l + BidirOd, // DIO sysrst_ctrl_aon_ec_rst_l + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_host0_sd + BidirStd, // DIO spi_host0_sd + BidirStd, // DIO spi_host0_sd + BidirStd, // DIO spi_host0_sd + BidirStd, // DIO usbdev_usb_dn + BidirStd // DIO usbdev_usb_dp + }, + mio_pad_type: { + BidirOd, // MIO Pad 46 + BidirOd, // MIO Pad 45 + BidirOd, // MIO Pad 44 + BidirOd, // MIO Pad 43 + BidirStd, // MIO Pad 42 + BidirStd, // MIO Pad 41 + BidirStd, // MIO Pad 40 + BidirStd, // MIO Pad 39 + BidirStd, // MIO Pad 38 + BidirStd, // MIO Pad 37 + BidirStd, // MIO Pad 36 + BidirStd, // MIO Pad 35 + BidirOd, // MIO Pad 34 + BidirOd, // MIO Pad 33 + BidirOd, // MIO Pad 32 + BidirStd, // MIO Pad 31 + BidirStd, // MIO Pad 30 + BidirStd, // MIO Pad 29 + BidirStd, // MIO Pad 28 + BidirStd, // MIO Pad 27 + BidirStd, // MIO Pad 26 + BidirStd, // MIO Pad 25 + BidirStd, // MIO Pad 24 + BidirStd, // MIO Pad 23 + BidirStd, // MIO Pad 22 + BidirOd, // MIO Pad 21 + BidirOd, // MIO Pad 20 + BidirOd, // MIO Pad 19 + BidirOd, // MIO Pad 18 + BidirStd, // MIO Pad 17 + BidirStd, // MIO Pad 16 + BidirStd, // MIO Pad 15 + BidirStd, // MIO Pad 14 + BidirStd, // MIO Pad 13 + BidirStd, // MIO Pad 12 + BidirStd, // MIO Pad 11 + BidirStd, // MIO Pad 10 + BidirStd, // MIO Pad 9 + BidirOd, // MIO Pad 8 + BidirOd, // MIO Pad 7 + BidirOd, // MIO Pad 6 + BidirStd, // MIO Pad 5 + BidirStd, // MIO Pad 4 + BidirStd, // MIO Pad 3 + BidirStd, // MIO Pad 2 + BidirStd, // MIO Pad 1 + BidirStd // MIO Pad 0 + }, + dio_scan_role: { + scan_role_pkg::DioPadSpiHostCsLScanRole, // DIO spi_host0_csb + scan_role_pkg::DioPadSpiHostClkScanRole, // DIO spi_host0_sck + scan_role_pkg::DioPadSpiDevCsLScanRole, // DIO spi_device_csb + scan_role_pkg::DioPadSpiDevClkScanRole, // DIO spi_device_sck + scan_role_pkg::DioPadIor9ScanRole, // DIO sysrst_ctrl_aon_flash_wp_l + scan_role_pkg::DioPadIor8ScanRole, // DIO sysrst_ctrl_aon_ec_rst_l + scan_role_pkg::DioPadSpiDevD3ScanRole, // DIO spi_device_sd + scan_role_pkg::DioPadSpiDevD2ScanRole, // DIO spi_device_sd + scan_role_pkg::DioPadSpiDevD1ScanRole, // DIO spi_device_sd + scan_role_pkg::DioPadSpiDevD0ScanRole, // DIO spi_device_sd + scan_role_pkg::DioPadSpiHostD3ScanRole, // DIO spi_host0_sd + scan_role_pkg::DioPadSpiHostD2ScanRole, // DIO spi_host0_sd + scan_role_pkg::DioPadSpiHostD1ScanRole, // DIO spi_host0_sd + scan_role_pkg::DioPadSpiHostD0ScanRole, // DIO spi_host0_sd + NoScan, // DIO usbdev_usb_dn + NoScan // DIO usbdev_usb_dp + }, + mio_scan_role: { + scan_role_pkg::MioPadIor13ScanRole, + scan_role_pkg::MioPadIor12ScanRole, + scan_role_pkg::MioPadIor11ScanRole, + scan_role_pkg::MioPadIor10ScanRole, + scan_role_pkg::MioPadIor7ScanRole, + scan_role_pkg::MioPadIor6ScanRole, + scan_role_pkg::MioPadIor5ScanRole, + scan_role_pkg::MioPadIor4ScanRole, + scan_role_pkg::MioPadIor3ScanRole, + scan_role_pkg::MioPadIor2ScanRole, + scan_role_pkg::MioPadIor1ScanRole, + scan_role_pkg::MioPadIor0ScanRole, + scan_role_pkg::MioPadIoc12ScanRole, + scan_role_pkg::MioPadIoc11ScanRole, + scan_role_pkg::MioPadIoc10ScanRole, + scan_role_pkg::MioPadIoc9ScanRole, + scan_role_pkg::MioPadIoc8ScanRole, + scan_role_pkg::MioPadIoc7ScanRole, + scan_role_pkg::MioPadIoc6ScanRole, + scan_role_pkg::MioPadIoc5ScanRole, + scan_role_pkg::MioPadIoc4ScanRole, + scan_role_pkg::MioPadIoc3ScanRole, + scan_role_pkg::MioPadIoc2ScanRole, + scan_role_pkg::MioPadIoc1ScanRole, + scan_role_pkg::MioPadIoc0ScanRole, + scan_role_pkg::MioPadIob12ScanRole, + scan_role_pkg::MioPadIob11ScanRole, + scan_role_pkg::MioPadIob10ScanRole, + scan_role_pkg::MioPadIob9ScanRole, + scan_role_pkg::MioPadIob8ScanRole, + scan_role_pkg::MioPadIob7ScanRole, + scan_role_pkg::MioPadIob6ScanRole, + scan_role_pkg::MioPadIob5ScanRole, + scan_role_pkg::MioPadIob4ScanRole, + scan_role_pkg::MioPadIob3ScanRole, + scan_role_pkg::MioPadIob2ScanRole, + scan_role_pkg::MioPadIob1ScanRole, + scan_role_pkg::MioPadIob0ScanRole, + scan_role_pkg::MioPadIoa8ScanRole, + scan_role_pkg::MioPadIoa7ScanRole, + scan_role_pkg::MioPadIoa6ScanRole, + scan_role_pkg::MioPadIoa5ScanRole, + scan_role_pkg::MioPadIoa4ScanRole, + scan_role_pkg::MioPadIoa3ScanRole, + scan_role_pkg::MioPadIoa2ScanRole, + scan_role_pkg::MioPadIoa1ScanRole, + scan_role_pkg::MioPadIoa0ScanRole + } + }; + + pinmux #( + .TargetCfg(PinmuxTargetCfg), + .AlertAsyncOn(AlertAsyncOn), + .SecVolatileRawUnlockEn(SecVolatileRawUnlockEn) + ) dut_asic (.*); + +endmodule : pinmux_chip_tb diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_tb.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_tb.sv new file mode 100644 index 0000000000000..983a2fa323669 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/tb/pinmux_tb.sv @@ -0,0 +1,108 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Testbench module for pinmux. +// Intended to be used with a formal tool. + +module pinmux_tb + import pinmux_pkg::*; + import pinmux_reg_pkg::*; + import prim_pad_wrapper_pkg::*; +#( + parameter int Tap0PadIdx = 0, + parameter int Tap1PadIdx = 1, + parameter int Dft0PadIdx = 2, + parameter int Dft1PadIdx = 3, + parameter int TckPadIdx = 4, + parameter int TmsPadIdx = 5, + parameter int TrstNPadIdx = 6, + parameter int TdiPadIdx = 7, + parameter int TdoPadIdx = 8, + parameter int DioUsbdevDp = 9, + parameter int DioUsbdevDn = 10, + parameter int MioInUsbdevSense = 11, + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter bit SecVolatileRawUnlockEn = 1 +) ( + input clk_i, + input rst_ni, + input rst_sys_ni, + input prim_mubi_pkg::mubi4_t scanmode_i, + input clk_aon_i, + input rst_aon_ni, + output logic pin_wkup_req_o, + output logic usb_wkup_req_o, + input sleep_en_i, + input strap_en_i, + input strap_en_override_i, + input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + input lc_ctrl_pkg::lc_tx_t lc_check_byp_en_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + output lc_ctrl_pkg::lc_tx_t pinmux_hw_debug_en_o, + output dft_strap_test_req_t dft_strap_test_o, + input dft_hold_tap_sel_i, + output jtag_pkg::jtag_req_t lc_jtag_o, + input jtag_pkg::jtag_rsp_t lc_jtag_i, + output jtag_pkg::jtag_req_t rv_jtag_o, + input jtag_pkg::jtag_rsp_t rv_jtag_i, + output jtag_pkg::jtag_req_t dft_jtag_o, + input jtag_pkg::jtag_rsp_t dft_jtag_i, + input usbdev_dppullup_en_i, + input usbdev_dnpullup_en_i, + output logic usb_dppullup_en_o, + output logic usb_dnpullup_en_o, + input usbdev_suspend_req_i, + input usbdev_wake_ack_i, + output logic usbdev_bus_not_idle_o, + output logic usbdev_bus_reset_o, + output logic usbdev_sense_lost_o, + output logic usbdev_wake_detect_active_o, + input tlul_pkg::tl_h2d_t tl_i, + output tlul_pkg::tl_d2h_t tl_o, + 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, + input [NMioPeriphOut-1:0] periph_to_mio_i, + input [NMioPeriphOut-1:0] periph_to_mio_oe_i, + output logic[NMioPeriphIn-1:0] mio_to_periph_o, + input [NDioPads-1:0] periph_to_dio_i, + input [NDioPads-1:0] periph_to_dio_oe_i, + output logic[NDioPads-1:0] dio_to_periph_o, + output prim_pad_wrapper_pkg::pad_attr_t[NMioPads-1:0] mio_attr_o, + output logic[NMioPads-1:0] mio_out_o, + output logic[NMioPads-1:0] mio_oe_o, + input [NMioPads-1:0] mio_in_i, + output prim_pad_wrapper_pkg::pad_attr_t[NDioPads-1:0] dio_attr_o, + output logic[NDioPads-1:0] dio_out_o, + output logic[NDioPads-1:0] dio_oe_o, + input [NDioPads-1:0] dio_in_i +); + + localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{ + tck_idx: TckPadIdx, + tms_idx: TmsPadIdx, + trst_idx: TrstNPadIdx, + tdi_idx: TdiPadIdx, + tdo_idx: TdoPadIdx, + tap_strap0_idx: Tap0PadIdx, + tap_strap1_idx: Tap1PadIdx, + dft_strap0_idx: Dft0PadIdx, + dft_strap1_idx: Dft1PadIdx, + usb_dp_idx: DioUsbdevDp, + usb_dn_idx: DioUsbdevDn, + usb_sense_idx: MioInUsbdevSense, + // Pad types for attribute WARL behavior + dio_pad_type: {NDioPads{BidirStd}}, + mio_pad_type: {NMioPads{BidirStd}}, + dio_scan_role: {NDioPads{NoScan}}, + mio_scan_role: {NMioPads{NoScan}} + }; + + pinmux #( + .TargetCfg(PinmuxTargetCfg), + .AlertAsyncOn(AlertAsyncOn), + .SecVolatileRawUnlockEn(SecVolatileRawUnlockEn) + ) dut (.*); + +endmodule : pinmux_tb diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/vip/pinmux_assert_fpv.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/vip/pinmux_assert_fpv.sv new file mode 100644 index 0000000000000..94819c2d1c948 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/fpv/vip/pinmux_assert_fpv.sv @@ -0,0 +1,730 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Assertions for pinmux. +// Intended to be used with a formal tool. + +`include "prim_assert.sv" + +module pinmux_assert_fpv + import pinmux_pkg::*; + import pinmux_reg_pkg::*; + import prim_pad_wrapper_pkg::*; +#( + parameter target_cfg_t TargetCfg = DefaultTargetCfg, + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter bit SecVolatileRawUnlockEn = 0 +) ( + input clk_i, + input rst_ni, + input rst_sys_ni, + input prim_mubi_pkg::mubi4_t scanmode_i, + input clk_aon_i, + input rst_aon_ni, + input logic pin_wkup_req_o, + input logic usb_wkup_req_o, + input sleep_en_i, + input strap_en_i, + input strap_en_override_i, + input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + input lc_ctrl_pkg::lc_tx_t lc_check_byp_en_i, + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + input lc_ctrl_pkg::lc_tx_t pinmux_hw_debug_en_o, + input dft_strap_test_req_t dft_strap_test_o, + input dft_hold_tap_sel_i, + input jtag_pkg::jtag_req_t lc_jtag_o, + input jtag_pkg::jtag_rsp_t lc_jtag_i, + input jtag_pkg::jtag_req_t rv_jtag_o, + input jtag_pkg::jtag_rsp_t rv_jtag_i, + input jtag_pkg::jtag_req_t dft_jtag_o, + input jtag_pkg::jtag_rsp_t dft_jtag_i, + input usbdev_dppullup_en_i, + input usbdev_dnpullup_en_i, + input usb_dppullup_en_o, + input usb_dnpullup_en_o, + input usbdev_suspend_req_i, + input usbdev_wake_ack_i, + input usbdev_bus_not_idle_o, + input usbdev_bus_reset_o, + input usbdev_sense_lost_o, + input usbdev_wake_detect_active_o, + input tlul_pkg::tl_h2d_t tl_i, + input tlul_pkg::tl_d2h_t tl_o, + input prim_alert_pkg::alert_rx_t[NumAlerts-1:0] alert_rx_i, + input prim_alert_pkg::alert_tx_t[NumAlerts-1:0] alert_tx_o, + input [NMioPeriphOut-1:0] periph_to_mio_i, + input [NMioPeriphOut-1:0] periph_to_mio_oe_i, + input logic[NMioPeriphIn-1:0] mio_to_periph_o, + input [NDioPads-1:0] periph_to_dio_i, + input [NDioPads-1:0] periph_to_dio_oe_i, + input logic[NDioPads-1:0] dio_to_periph_o, + input prim_pad_wrapper_pkg::pad_attr_t[NMioPads-1:0] mio_attr_o, + input logic[NMioPads-1:0] mio_out_o, + input logic[NMioPads-1:0] mio_oe_o, + input [NMioPads-1:0] mio_in_i, + input prim_pad_wrapper_pkg::pad_attr_t[NDioPads-1:0] dio_attr_o, + input logic[NDioPads-1:0] dio_out_o, + input logic[NDioPads-1:0] dio_oe_o, + input [NDioPads-1:0] dio_in_i +); + + /////////////////////////////// + // Declarations & Parameters // + /////////////////////////////// + + ///////////////// + // Assumptions // + ///////////////// + + // Symbolic inputs for FPV + logic [$clog2(pinmux_reg_pkg::NMioPeriphIn)-1:0] periph_sel_i; + logic [$clog2(pinmux_reg_pkg::NMioPads)-1:0] mio_sel_i; + logic [$clog2(pinmux_reg_pkg::NDioPads)-1:0] dio_sel_i; + logic [$clog2(pinmux_reg_pkg::NWkupDetect)-1:0] wkup_sel_i; + + `ASSUME(PeriphSelRange_M, periph_sel_i < pinmux_reg_pkg::NMioPeriphIn) + `ASSUME(PeriphSelStable_M, ##1 $stable(periph_sel_i)) + + `ASSUME(MioSelRange_M, mio_sel_i < pinmux_reg_pkg::NMioPads && !(mio_sel_i inside + {TargetCfg.tck_idx, TargetCfg.tms_idx, TargetCfg.trst_idx, TargetCfg.tdi_idx, + TargetCfg.tdo_idx})) + `ASSUME(MioSelStable_M, ##1 $stable(mio_sel_i)) + + `ASSUME(DioSelRange_M, dio_sel_i < pinmux_reg_pkg::NDioPads) + `ASSUME(DioSelStable_M, ##1 $stable(dio_sel_i)) + + `ASSUME(WkupSelRange_M, wkup_sel_i < pinmux_reg_pkg::NWkupDetect) + `ASSUME(WkupSelStable_M, ##1 $stable(wkup_sel_i)) + + // ------ Input mux assertions ------ + pinmux_reg_pkg::pinmux_reg2hw_mio_periph_insel_mreg_t periph_insel; + assign periph_insel = pinmux.reg2hw.mio_periph_insel[periph_sel_i]; + + `ASSERT(InSel0_A, periph_insel.q == 0 |-> mio_to_periph_o[periph_sel_i] == 1'b0) + `ASSERT(InSel1_A, periph_insel.q == 1 |-> mio_to_periph_o[periph_sel_i] == 1'b1) + `ASSERT(InSelN_A, periph_insel.q > 1 && periph_insel.q < (pinmux_reg_pkg::NMioPads + 2) && + !((periph_insel.q - 2) inside {TargetCfg.tck_idx, TargetCfg.tms_idx, TargetCfg.trst_idx, + TargetCfg.tdi_idx, TargetCfg.tdo_idx}) |-> + mio_to_periph_o[periph_sel_i] == mio_in_i[periph_insel.q - 2]) + `ASSERT(InSelOOB_A, periph_insel.q >= (pinmux_reg_pkg::NMioPads + 2) |-> + mio_to_periph_o[periph_sel_i] == 0) + + `ASSERT(MioToPeriph0Backward_A, mio_to_periph_o[periph_sel_i] == 0 |-> + (periph_insel.q == 0) || + ((periph_insel.q > 1 && periph_insel.q < (pinmux_reg_pkg::NMioPads + 2) && + (pinmux.u_pinmux_strap_sampling.jtag_en || mio_in_i[periph_insel.q - 2] == 0)) || + periph_insel.q >= (pinmux_reg_pkg::NMioPads + 2))) + + `ASSERT(MioToPeriph1Backward_A, mio_to_periph_o[periph_sel_i] == 1 |-> + (periph_insel.q == 1) || + (periph_insel.q > 1 && periph_insel.q < (pinmux_reg_pkg::NMioPads + 2) && + (mio_in_i[periph_insel.q - 2] == 1 || pinmux.u_pinmux_strap_sampling.jtag_en))) + + `ASSERT(DioInSelN_A, dio_to_periph_o == dio_in_i) + + // ------ Output mux assertions ------ + pinmux_reg_pkg::pinmux_reg2hw_mio_outsel_mreg_t mio_outsel; + assign mio_outsel = pinmux.reg2hw.mio_outsel[mio_sel_i]; + + pinmux_reg_pkg::pinmux_reg2hw_mio_pad_sleep_status_mreg_t mio_pad_sleep_status; + assign mio_pad_sleep_status = pinmux.reg2hw.mio_pad_sleep_status[mio_sel_i]; + + + `ASSERT(OutSel0_A, mio_outsel.q == 0 && !mio_pad_sleep_status.q |-> mio_out_o[mio_sel_i] == 1'b0) + `ASSERT(OutSel1_A, mio_outsel.q == 1 && !mio_pad_sleep_status.q |-> mio_out_o[mio_sel_i] == 1'b1) + `ASSERT(OutSel2_A, mio_outsel.q == 2 && !mio_pad_sleep_status.q |-> mio_out_o[mio_sel_i] == 1'b0) + `ASSERT(OutSelN_A, mio_outsel.q > 2 && mio_outsel.q < (pinmux_reg_pkg::NMioPeriphOut + 3) && + !mio_pad_sleep_status.q |-> mio_out_o[mio_sel_i] == periph_to_mio_i[mio_outsel.q - 3]) + `ASSERT(OutSelOOB_A, mio_outsel.q >= (pinmux_reg_pkg::NMioPeriphOut + 3) && + !mio_pad_sleep_status.q |-> mio_out_o[mio_sel_i] == 0) + + `ASSERT(MioOut0Backward_A, mio_out_o[mio_sel_i] == 0 |-> + mio_pad_sleep_status.q || + mio_outsel.q inside {0, 2} || + mio_outsel.q >= (pinmux_reg_pkg::NMioPeriphOut + 3) || + (mio_outsel.q > 2 && mio_outsel.q < (pinmux_reg_pkg::NMioPeriphOut + 3) && + periph_to_mio_i[mio_outsel.q - 3] == 0)) + + `ASSERT(MioOut1Backward_A, mio_out_o[mio_sel_i] == 1 |-> + mio_pad_sleep_status.q || + mio_outsel.q == 1 || + mio_outsel.q > (pinmux_reg_pkg::NMioPeriphOut + 3) || + (mio_outsel.q > 2 && mio_outsel.q < (pinmux_reg_pkg::NMioPeriphOut + 3) && + periph_to_mio_i[mio_outsel.q - 3] == 1)) + + `ASSERT(OutSelOe0_A, mio_outsel.q == 0 && !mio_pad_sleep_status.q |-> + mio_oe_o[mio_sel_i] == 1'b1) + `ASSERT(OutSelOe1_A, mio_outsel.q == 1 && !mio_pad_sleep_status.q |-> + mio_oe_o[mio_sel_i] == 1'b1) + `ASSERT(OutSelOe2_A, mio_outsel.q == 2 && !mio_pad_sleep_status.q |-> + mio_oe_o[mio_sel_i] == 1'b0) + `ASSERT(OutSelOeN_A, mio_outsel.q > 2 && mio_outsel.q < (pinmux_reg_pkg::NMioPeriphOut + 3) && + !mio_pad_sleep_status.q |-> mio_oe_o[mio_sel_i] == periph_to_mio_oe_i[mio_outsel.q - 3]) + `ASSERT(OutSelOeOOB_A, mio_outsel.q >= (pinmux_reg_pkg::NMioPeriphOut + 3) && + !mio_pad_sleep_status.q |-> mio_oe_o[mio_sel_i] == 0) + + `ASSERT(MioOe0Backward_A, mio_oe_o[mio_sel_i] == 0 |-> + mio_pad_sleep_status.q || + mio_outsel.q == 2 || + mio_outsel.q >= (pinmux_reg_pkg::NMioPeriphOut + 3) || + (mio_outsel.q > 2 && mio_outsel.q < (pinmux_reg_pkg::NMioPeriphOut + 3) && + periph_to_mio_oe_i[mio_outsel.q - 3] == 0)) + + `ASSERT(MioOe1Backward_A, mio_oe_o[mio_sel_i] == 1 |-> + mio_pad_sleep_status.q || + mio_outsel.q inside {0, 1} || + mio_outsel.q > (pinmux_reg_pkg::NMioPeriphOut + 3) || + (mio_outsel.q > 2 && mio_outsel.q < (pinmux_reg_pkg::NMioPeriphOut + 3) && + periph_to_mio_oe_i[mio_outsel.q - 3] == 1)) + + // ------ Mio sleep behavior assertions ------ + pinmux_reg_pkg::pinmux_reg2hw_mio_pad_sleep_en_mreg_t mio_pad_sleep_en; + assign mio_pad_sleep_en = pinmux.reg2hw.mio_pad_sleep_en[mio_sel_i]; + pinmux_reg_pkg::pinmux_reg2hw_mio_pad_sleep_mode_mreg_t mio_pad_sleep_mode; + assign mio_pad_sleep_mode = pinmux.reg2hw.mio_pad_sleep_mode[mio_sel_i]; + + `ASSERT(MioSleepMode0_A, ##1 mio_pad_sleep_mode.q == 0 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + mio_out_o[mio_sel_i] == 1'b0) + `ASSERT(MioSleepMode1_A, ##1 mio_pad_sleep_mode.q == 1 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + mio_out_o[mio_sel_i] == 1'b1) + `ASSERT(MioSleepMode2_A, ##1 mio_pad_sleep_mode.q == 2 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + mio_out_o[mio_sel_i] == 1'b0) + `ASSERT(MioSleepMode3_A, ##1 mio_pad_sleep_mode.q == 3 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + $stable(mio_out_o[mio_sel_i])) + `ASSERT(MioSleepStable_A, ##1 !$rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + $stable(mio_out_o[mio_sel_i])) + + `ASSERT(MioOeSleepMode0_A, ##1 mio_pad_sleep_mode.q == 0 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q && sleep_en_i|-> + mio_oe_o[mio_sel_i] == 1'b1) + `ASSERT(MioOeSleepMode1_A, ##1 mio_pad_sleep_mode.q == 1 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + mio_oe_o[mio_sel_i] == 1'b1) + `ASSERT(MioOeSleepMode2_A, ##1 mio_pad_sleep_mode.q == 2 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + mio_oe_o[mio_sel_i] == 1'b0) + `ASSERT(MioOeSleepMode3_A, ##1 mio_pad_sleep_mode.q == 3 && mio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + $stable(mio_oe_o[mio_sel_i])) + `ASSERT(MioOeSleepStable_A, ##1 !$rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 mio_pad_sleep_status.q |-> + $stable(mio_oe_o[mio_sel_i])) + + // ------Mio sleep enabled backward assertions ------ + `ASSERT(MioSleep0Backward_A, mio_out_o[mio_sel_i] == 0 |-> + mio_pad_sleep_status.q == 0 || + // Sleep mode set to 0 and 2. + $past(mio_pad_sleep_mode.q) inside {0, 2} || + // Previous value is 0 and sleep mode is set to 3. + ($past(mio_out_o[mio_sel_i]) == 0) && + ($past(mio_pad_sleep_mode.q) == 3 || + // Previous value is 0 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !mio_pad_sleep_en.q) && mio_pad_sleep_status.q))) + + `ASSERT(MioSleep1Backward_A, mio_out_o[mio_sel_i] == 1 |-> + mio_pad_sleep_status.q == 0 || + // Sleep mode set to 1. + $past(mio_pad_sleep_mode.q) == 1 || + // Previous value is 1 and sleep mode is set to 3. + ($past(mio_out_o[mio_sel_i]) == 1) && + ($past(mio_pad_sleep_mode.q) == 3 || + // Previous value is 1 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !mio_pad_sleep_en.q) && mio_pad_sleep_status.q))) + + `ASSERT(MioOeSleep0Backward_A, mio_oe_o[mio_sel_i] == 0 |-> + mio_pad_sleep_status.q == 0 || + // Sleep mode set to 2. + $past(mio_pad_sleep_mode.q) == 2 || + // Previous value is 0 and sleep mode is set to 3. + ($past(mio_oe_o[mio_sel_i]) == 0) && + ($past(mio_pad_sleep_mode.q) == 3 || + // Previous value is 0 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !mio_pad_sleep_en.q) && mio_pad_sleep_status.q))) + + `ASSERT(MioOeSleep1Backward_A, mio_oe_o[mio_sel_i] == 1 |-> + mio_pad_sleep_status.q == 0 || + // Sleep mode set to 0 or 1. + $past(mio_pad_sleep_mode.q) inside {0, 1} || + // Previous value is 1 and sleep mode is set to 3. + ($past(mio_oe_o[mio_sel_i]) == 1) && + ($past(mio_pad_sleep_mode.q) == 3 || + // Previous value is 1 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !mio_pad_sleep_en.q) && mio_pad_sleep_status.q))) + + // ------ Mio_attr_o ------ + pad_attr_t mio_pad_attr; + assign mio_pad_attr = pinmux.mio_pad_attr_q[mio_sel_i]; + + pad_attr_t mio_pad_attr_mask; + pad_type_e bid_pad_types[4]; + assign bid_pad_types = {BidirStd, BidirTol, DualBidirTol, BidirOd}; + assign mio_pad_attr_mask.invert = TargetCfg.mio_pad_type[mio_sel_i] != AnalogIn0; + assign mio_pad_attr_mask.virt_od_en = TargetCfg.mio_pad_type[mio_sel_i] inside {bid_pad_types}; + assign mio_pad_attr_mask.pull_en = TargetCfg.mio_pad_type[mio_sel_i] != AnalogIn0; + assign mio_pad_attr_mask.pull_select = TargetCfg.mio_pad_type[mio_sel_i] != AnalogIn0; + assign mio_pad_attr_mask.drive_strength[0] = + TargetCfg.mio_pad_type[mio_sel_i] inside {bid_pad_types}; + assign mio_pad_attr_mask.keep_en = 0; + assign mio_pad_attr_mask.schmitt_en = 0; + assign mio_pad_attr_mask.od_en = 0; + assign mio_pad_attr_mask.input_disable = 1'b1; + assign mio_pad_attr_mask.slew_rate = '0; + assign mio_pad_attr_mask.drive_strength[3:1] = '0; + + `ASSERT(MioAttrO_A, mio_attr_o[mio_sel_i] == (mio_pad_attr & mio_pad_attr_mask)) + + `ASSERT(MioJtagAttrO_A, pinmux.u_pinmux_strap_sampling.jtag_en |-> + mio_attr_o[TargetCfg.tck_idx] == 0 && + mio_attr_o[TargetCfg.tms_idx] == 0 && + mio_attr_o[TargetCfg.trst_idx] == 0 && + mio_attr_o[TargetCfg.tdi_idx] == 0 && + mio_attr_o[TargetCfg.tdo_idx] == 0) + + // ------ Dio_attr_o ------ + pinmux_reg_pkg::pinmux_reg2hw_dio_pad_attr_mreg_t dio_pad_attr; + assign dio_pad_attr = pinmux.dio_pad_attr_q[dio_sel_i]; + + pad_attr_t dio_pad_attr_mask; + assign dio_pad_attr_mask.invert = TargetCfg.dio_pad_type[dio_sel_i] != AnalogIn0; + assign dio_pad_attr_mask.virt_od_en = TargetCfg.dio_pad_type[dio_sel_i] inside {bid_pad_types}; + assign dio_pad_attr_mask.pull_en = TargetCfg.dio_pad_type[dio_sel_i] != AnalogIn0; + assign dio_pad_attr_mask.pull_select = TargetCfg.dio_pad_type[dio_sel_i] != AnalogIn0; + assign dio_pad_attr_mask.drive_strength[0] = + TargetCfg.dio_pad_type[dio_sel_i] inside {bid_pad_types}; + assign dio_pad_attr_mask.keep_en = 0; + assign dio_pad_attr_mask.schmitt_en = 0; + assign dio_pad_attr_mask.od_en = 0; + assign dio_pad_attr_mask.input_disable = 1; + assign dio_pad_attr_mask.slew_rate = '0; + assign dio_pad_attr_mask.drive_strength[3:1] = '0; + + `ASSERT(DioAttrO_A, dio_attr_o[dio_sel_i] == (dio_pad_attr & dio_pad_attr_mask)) + + // ------ Output dedicated output assertions ------ + pinmux_reg_pkg::pinmux_reg2hw_dio_pad_sleep_status_mreg_t dio_pad_sleep_status; + assign dio_pad_sleep_status = pinmux.reg2hw.dio_pad_sleep_status[dio_sel_i]; + + `ASSERT(DOutSelN_A, !dio_pad_sleep_status.q |-> + dio_out_o[dio_sel_i] == periph_to_dio_i[dio_sel_i]) + + `ASSERT(DOutSelOeN_A, !dio_pad_sleep_status.q |-> + dio_oe_o[dio_sel_i] == periph_to_dio_oe_i[dio_sel_i]) + + // ------ Dio sleep behavior assertions ------ + pinmux_reg_pkg::pinmux_reg2hw_dio_pad_sleep_en_mreg_t dio_pad_sleep_en; + assign dio_pad_sleep_en = pinmux.reg2hw.dio_pad_sleep_en[dio_sel_i]; + pinmux_reg_pkg::pinmux_reg2hw_dio_pad_sleep_mode_mreg_t dio_pad_sleep_mode; + assign dio_pad_sleep_mode = pinmux.reg2hw.dio_pad_sleep_mode[dio_sel_i]; + + `ASSERT(DioSleepMode0_A, ##1 dio_pad_sleep_mode.q == 0 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + dio_out_o[dio_sel_i] == 1'b0) + `ASSERT(DioSleepMode1_A, ##1 dio_pad_sleep_mode.q == 1 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + dio_out_o[dio_sel_i] == 1'b1) + `ASSERT(DioSleepMode2_A, ##1 dio_pad_sleep_mode.q == 2 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + dio_out_o[dio_sel_i] == 1'b0) + `ASSERT(DioSleepMode3_A, ##1 dio_pad_sleep_mode.q == 3 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + $stable(dio_out_o[dio_sel_i])) + `ASSERT(DioSleepStable_A, ##1 !$rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + $stable(dio_out_o[dio_sel_i])) + + `ASSERT(DioOeSleepMode0_A, ##1 dio_pad_sleep_mode.q == 0 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + dio_oe_o[dio_sel_i] == 1'b1) + `ASSERT(DioOeSleepMode1_A, ##1 dio_pad_sleep_mode.q == 1 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + dio_oe_o[dio_sel_i] == 1'b1) + `ASSERT(DioOeSleepMode2_A, ##1 dio_pad_sleep_mode.q == 2 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + dio_oe_o[dio_sel_i] == 1'b0) + `ASSERT(DioOeSleepMode3_A, ##1 dio_pad_sleep_mode.q == 3 && dio_pad_sleep_en.q == 1 && + $rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + $stable(dio_oe_o[dio_sel_i])) + `ASSERT(DioOeSleepStable_A, ##1 !$rose(sleep_en_i) + // Ensure SW does not write to sleep status register to clear sleep status. + ##1 dio_pad_sleep_status.q |-> + $stable(dio_oe_o[dio_sel_i])) + + // ------Dio backward assertions ------ + `ASSERT(Dio0Backward_A, dio_out_o[dio_sel_i] == 0 |-> + // Input is 0. + periph_to_dio_i[dio_sel_i] == 0 || + // Sleep mode set to 0 and 2. + $past(dio_pad_sleep_mode.q) inside {0, 2} || + // Previous value is 0 and sleep mode is set to 3. + ($past(dio_out_o[dio_sel_i]) == 0) && + ($past(dio_pad_sleep_mode.q) == 3 || + // Previous value is 0 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !dio_pad_sleep_en.q) && dio_pad_sleep_status.q))) + + `ASSERT(Dio1Backward_A, dio_out_o[dio_sel_i] == 1 |-> + // input is 1. + periph_to_dio_i[dio_sel_i] == 1 || + // Sleep mode set to 1. + $past(dio_pad_sleep_mode.q) == 1 || + // Previous value is 1 and sleep mode is set to 3. + ($past(dio_out_o[dio_sel_i]) == 1) && + ($past(dio_pad_sleep_mode.q) == 3 || + // Previous value is 1 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !dio_pad_sleep_en.q) && dio_pad_sleep_status.q))) + + `ASSERT(DioOe0Backward_A, dio_oe_o[dio_sel_i] == 0 |-> + // Input is 0. + periph_to_dio_oe_i[dio_sel_i] == 0 || + // Sleep mode set to 2. + $past(dio_pad_sleep_mode.q) == 2 || + // Previous value is 0 and sleep mode is set to 3. + ($past(dio_oe_o[dio_sel_i]) == 0) && + ($past(dio_pad_sleep_mode.q) == 3 || + // Previous value is 0 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !dio_pad_sleep_en.q) && dio_pad_sleep_status.q))) + + `ASSERT(DioOe1Backward_A, dio_oe_o[dio_sel_i] == 1 |-> + // input is 1. + periph_to_dio_oe_i[dio_sel_i] == 1 || + // Sleep mode set to 0 or 1. + $past(dio_pad_sleep_mode.q) inside {0, 1} || + // Previous value is 1 and sleep mode is set to 3. + ($past(dio_oe_o[dio_sel_i]) == 1) && + ($past(dio_pad_sleep_mode.q) == 3 || + // Previous value is 1 and sleep mode selection is disabled either by sleep_en_i input + // or sleep_en CSR. + ($past(!$rose(sleep_en_i) || !dio_pad_sleep_en.q) && dio_pad_sleep_status.q))) + + // ------ Wakeup assertions ------ + pinmux_reg2hw_wkup_detector_en_mreg_t wkup_detector_en; + assign wkup_detector_en = pinmux.reg2hw.wkup_detector_en[wkup_sel_i]; + pinmux_reg2hw_wkup_detector_mreg_t wkup_detector; + assign wkup_detector = pinmux.reg2hw.wkup_detector[wkup_sel_i]; + pinmux_reg2hw_wkup_detector_cnt_th_mreg_t wkup_detector_cnt_th; + assign wkup_detector_cnt_th = pinmux.reg2hw.wkup_detector_cnt_th[wkup_sel_i]; + pinmux_reg2hw_wkup_detector_padsel_mreg_t wkup_detector_padsel; + assign wkup_detector_padsel = pinmux.reg2hw.wkup_detector_padsel[wkup_sel_i]; + pinmux_hw2reg_wkup_cause_mreg_t wkup_cause; + assign wkup_cause = pinmux.hw2reg.wkup_cause[wkup_sel_i]; + pinmux_reg2hw_wkup_cause_mreg_t wkup_cause_reg2hw; + + // Variable to gether all wkup causes. + assign wkup_cause_reg2hw = pinmux.reg2hw.wkup_cause[wkup_sel_i]; + logic[pinmux_reg_pkg::NWkupDetect-1:0] wkup_cause_q; + for (genvar i = 0; i < pinmux_reg_pkg::NWkupDetect; i++) begin : gen_wkup_cause_q + assign wkup_cause_q[i] = pinmux.reg2hw.wkup_cause[i].q; + end + + // Retrieve pin value based on Mio and Dio selection. + logic pin_val; + assign pin_val = wkup_detector.miodio.q ? + (wkup_detector_padsel.q >= pinmux_reg_pkg::NDioPads ? 0 : + dio_in_i[wkup_detector_padsel.q]) : + (wkup_detector_padsel.q >= (pinmux_reg_pkg::NMioPads + 2) ? 0 : + wkup_detector_padsel == 0 ? 0 : + wkup_detector_padsel == 1 ? 1 : + mio_in_i[wkup_detector_padsel.q - 2]); + + // Retrieve filterd pin value with a 2 aon_clock synchronizer. + logic [3:0] filter_vals; + logic pin_val_sync_1, pin_val_sync_2; + + always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin + if (!rst_aon_ni) begin + pin_val_sync_1 <= 1'b0; + pin_val_sync_2 <= 1'b0; + end else begin + pin_val_sync_1 <= pin_val; + pin_val_sync_2 <= pin_val_sync_1; + end + end + + always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin + if (!rst_aon_ni) begin + filter_vals <= 4'b0; + end else if (pin_val_sync_2 == filter_vals[0]) begin + filter_vals <= (filter_vals << 1) | pin_val_sync_2; + end else begin + filter_vals <= {filter_vals[3], filter_vals[3], filter_vals[3], pin_val_sync_2}; + end + end + + logic final_pin_val; + assign final_pin_val = wkup_detector.filter.q ? filter_vals[3] : pin_val_sync_2; + + // Threshold counters. + // Adding one more bit for the counters to check overflow case. + // Issue #11194 documented design will use one counter to count for both low and high threshold. + bit [WkupCntWidth:0] cnter; + always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin + if (!rst_aon_ni || !wkup_detector_en.q) begin + cnter <= 0; + end else if (wkup_detector.mode.q == 3) begin + if (final_pin_val && (cnter < wkup_detector_cnt_th.q)) begin + cnter <= cnter + 1; + end else begin + cnter <= 0; + end + end else if (wkup_detector.mode.q == 4) begin + if (!final_pin_val && (cnter < wkup_detector_cnt_th.q)) begin + cnter <= cnter + 1; + end else begin + cnter <= 0; + end + end else begin + cnter <= 0; + end + end + + `ASSERT(WkupPosedge_A, wkup_detector_en.q && wkup_detector.mode.q == 0 && + $rose(final_pin_val) |-> wkup_cause.de, + clk_aon_i, !rst_aon_ni) + `ASSERT(WkupNegedge_A, wkup_detector_en.q && wkup_detector.mode.q == 1 && + $fell(final_pin_val) |-> wkup_cause.de, + clk_aon_i, !rst_aon_ni) + `ASSERT(WkupEdge_A, wkup_detector_en.q && wkup_detector.mode.q == 2 && + ($fell(final_pin_val) || $rose(final_pin_val)) |-> wkup_cause.de, + clk_aon_i, !rst_aon_ni) + `ASSERT(WkupTimedHigh_A, (cnter >= wkup_detector_cnt_th.q) && wkup_detector_en.q && + wkup_detector.mode.q == 3 |-> wkup_cause.de, + clk_aon_i, !rst_aon_ni) + `ASSERT(WkupTimedLow_A, (cnter >= wkup_detector_cnt_th.q) && wkup_detector_en.q && + wkup_detector.mode.q == 4 |-> wkup_cause.de, + clk_aon_i, !rst_aon_ni) + + `ASSERT(WkupCauseQ_A, wkup_cause.de && !u_reg.aon_wkup_cause_we |=> + wkup_cause_reg2hw.q, clk_aon_i, !rst_aon_ni) + + `ASSERT(AonWkupO_A, |wkup_cause_q <-> pin_wkup_req_o, clk_aon_i, !rst_aon_ni) + + `ASSERT(WkupCause0_A, wkup_cause.de == 0 |-> + (wkup_detector_en.q == 0) || + (wkup_detector_en.q == 1 && + ((wkup_detector.mode.q == 0 && !$rose(final_pin_val)) || + (wkup_detector.mode.q > 4 && !$rose(final_pin_val)) || + (wkup_detector.mode.q == 1 && !$fell(final_pin_val)) || + (wkup_detector.mode.q == 2 && !$changed(final_pin_val)) || + (wkup_detector.mode.q == 3 && (cnter < wkup_detector_cnt_th.q)) || + (wkup_detector.mode.q == 4 && (cnter < wkup_detector_cnt_th.q)))), + clk_aon_i, !rst_aon_ni) + + `ASSERT(WkupCause1_A, wkup_cause.de == 1 |-> + wkup_detector_en.q == 1 && + ((wkup_detector.mode.q == 0 && $rose(final_pin_val)) || + (wkup_detector.mode.q > 4 && $rose(final_pin_val)) || + (wkup_detector.mode.q == 1 && $fell(final_pin_val)) || + (wkup_detector.mode.q == 2 && $changed(final_pin_val)) || + (wkup_detector.mode.q == 3 && (cnter >= wkup_detector_cnt_th.q)) || + (wkup_detector.mode.q == 4 && (cnter >= wkup_detector_cnt_th.q))), + clk_aon_i, !rst_aon_ni) + + // ------ JTAG pinmux input assertions ------ + `ASSERT(LcJtagOWoScanmode_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::LcTapSel && + !prim_mubi_pkg::mubi4_test_true_strict(scanmode_i) |-> + lc_jtag_o == {mio_in_i[TargetCfg.tck_idx], + mio_in_i[TargetCfg.tms_idx], + mio_in_i[TargetCfg.trst_idx], + mio_in_i[TargetCfg.tdi_idx]}) + `ASSERT(LcJtagOWScanmode_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::LcTapSel && + prim_mubi_pkg::mubi4_test_true_strict(scanmode_i) |-> + lc_jtag_o == {mio_in_i[TargetCfg.tck_idx], + mio_in_i[TargetCfg.tms_idx], + rst_ni, + mio_in_i[TargetCfg.tdi_idx]}) + `ASSERT(LcJtagODefault_A, u_pinmux_strap_sampling.tap_strap != pinmux_pkg::LcTapSel |-> + lc_jtag_o == '0) + + `ASSERT(LcJtagBackward_A, + lc_jtag_o[0] == mio_in_i[TargetCfg.tdi_idx] && + lc_jtag_o[1] inside {mio_in_i[TargetCfg.trst_idx], rst_ni } && + lc_jtag_o[2] == mio_in_i[TargetCfg.tms_idx] && + lc_jtag_o[3] == mio_in_i[TargetCfg.tck_idx] |-> + u_pinmux_strap_sampling.tap_strap == pinmux_pkg::LcTapSel || lc_jtag_o == 0) + + // Lc_hw_debug_en_i signal goes through a two clock cycle synchronizer. + `ASSERT(RvJtagOWoScanmode_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::RvTapSel && + !prim_mubi_pkg::mubi4_test_true_strict(scanmode_i) && + u_pinmux_strap_sampling.pinmux_hw_debug_en_q == lc_ctrl_pkg::On |-> + rv_jtag_o == {mio_in_i[TargetCfg.tck_idx], + mio_in_i[TargetCfg.tms_idx], + mio_in_i[TargetCfg.trst_idx], + mio_in_i[TargetCfg.tdi_idx]}) + `ASSERT(RvJtagOWScanmode_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::RvTapSel && + prim_mubi_pkg::mubi4_test_true_strict(scanmode_i) && + u_pinmux_strap_sampling.pinmux_hw_debug_en_q == lc_ctrl_pkg::On |-> + rv_jtag_o == {mio_in_i[TargetCfg.tck_idx], + mio_in_i[TargetCfg.tms_idx], + rst_ni, + mio_in_i[TargetCfg.tdi_idx]}) + `ASSERT(RvJtagODefault_A, u_pinmux_strap_sampling.tap_strap != pinmux_pkg::RvTapSel || + u_pinmux_strap_sampling.pinmux_hw_debug_en_q != lc_ctrl_pkg::On |-> + rv_jtag_o == '0) + + `ASSERT(RvJtagBackward_A, + rv_jtag_o[0] == mio_in_i[TargetCfg.tdi_idx] && + rv_jtag_o[1] inside {mio_in_i[TargetCfg.trst_idx], rst_ni } && + rv_jtag_o[2] == mio_in_i[TargetCfg.tms_idx] && + rv_jtag_o[3] == mio_in_i[TargetCfg.tck_idx] |-> + (u_pinmux_strap_sampling.tap_strap == pinmux_pkg::RvTapSel && + u_pinmux_strap_sampling.pinmux_hw_debug_en_q == lc_ctrl_pkg::On) || rv_jtag_o == 0) + + // Lc_dft_en_i signal goes through a two clock cycle synchronizer. + `ASSERT(DftJtagOWoScanmode_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::DftTapSel && + !prim_mubi_pkg::mubi4_test_true_strict(scanmode_i) && + $past(lc_dft_en_i, 2) == lc_ctrl_pkg::On |-> + dft_jtag_o == {mio_in_i[TargetCfg.tck_idx], + mio_in_i[TargetCfg.tms_idx], + mio_in_i[TargetCfg.trst_idx], + mio_in_i[TargetCfg.tdi_idx]}) + `ASSERT(DftJtagOWScanmode_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::DftTapSel && + prim_mubi_pkg::mubi4_test_true_strict(scanmode_i) && + $past(lc_dft_en_i, 2) == lc_ctrl_pkg::On |-> + dft_jtag_o == {mio_in_i[TargetCfg.tck_idx], + mio_in_i[TargetCfg.tms_idx], + rst_ni, + mio_in_i[TargetCfg.tdi_idx]}) + `ASSERT(DftJtagODefault_A, u_pinmux_strap_sampling.tap_strap != pinmux_pkg::DftTapSel || + $past(lc_dft_en_i, 2) != lc_ctrl_pkg::On |-> + dft_jtag_o == '0) + + `ASSERT(DftJtagBackward_A, + dft_jtag_o[0] == mio_in_i[TargetCfg.tdi_idx] && + dft_jtag_o[1] inside {mio_in_i[TargetCfg.trst_idx], rst_ni } && + dft_jtag_o[2] == mio_in_i[TargetCfg.tms_idx] && + dft_jtag_o[3] == mio_in_i[TargetCfg.tck_idx] |-> + (u_pinmux_strap_sampling.tap_strap == pinmux_pkg::DftTapSel && + $past(lc_dft_en_i, 2) == lc_ctrl_pkg::On) || dft_jtag_o == 0) + + `ASSERT(TapStrap_A, ##3 ((!dft_hold_tap_sel_i && $past(lc_dft_en_i, 2) == lc_ctrl_pkg::On) || + $past(strap_en_i || SecVolatileRawUnlockEn && $past($rose(strap_en_override_i), 2)) && + !dft_hold_tap_sel_i) && + u_pinmux_strap_sampling.pinmux_hw_debug_en_q == lc_ctrl_pkg::On |=> + u_pinmux_strap_sampling.tap_strap == + $past({mio_in_i[TargetCfg.tap_strap1_idx], mio_in_i[TargetCfg.tap_strap0_idx]})) + + `ASSERT(TapStrap0_A, ##3 ((!dft_hold_tap_sel_i && $past(lc_dft_en_i, 2) == lc_ctrl_pkg::On) || + $past(strap_en_i || SecVolatileRawUnlockEn && $past($rose(strap_en_override_i), 2)) && + !dft_hold_tap_sel_i) |=> + u_pinmux_strap_sampling.tap_strap[0] == $past(mio_in_i[TargetCfg.tap_strap0_idx])) + + `ASSERT(TapStrapStable_A, ##4 dft_hold_tap_sel_i && !$past(strap_en_i || + SecVolatileRawUnlockEn && $past($rose(strap_en_override_i), 2)) |=> + $stable(u_pinmux_strap_sampling.tap_strap)) + + // ------ JTAG pinmux output assertions ------ + `ASSERT(LcJtagI_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::LcTapSel |-> + lc_jtag_i == {mio_out_o[TargetCfg.tdo_idx], + mio_oe_o[TargetCfg.tdo_idx]}) + `ASSERT(RvJtagI_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::RvTapSel && + u_pinmux_strap_sampling.pinmux_hw_debug_en_q == lc_ctrl_pkg::On |-> + rv_jtag_i == {mio_out_o[TargetCfg.tdo_idx], + mio_oe_o[TargetCfg.tdo_idx]}) + `ASSERT(DftJtagI_A, u_pinmux_strap_sampling.tap_strap == pinmux_pkg::DftTapSel && + $past(lc_dft_en_i, 2) == lc_ctrl_pkg::On |-> + dft_jtag_i == {mio_out_o[TargetCfg.tdo_idx], + mio_oe_o[TargetCfg.tdo_idx]}) + + // ------ DFT strap_test_o assertions ------ + `ASSERT(DftStrapTestO_A, ##2 strap_en_i || SecVolatileRawUnlockEn && + $past($rose(strap_en_override_i), 2) ##1 $past(lc_dft_en_i, 2) == lc_ctrl_pkg::On && + !dft_hold_tap_sel_i |=> + dft_strap_test_o.valid && + dft_strap_test_o.straps == $past({mio_in_i[TargetCfg.dft_strap1_idx], + mio_in_i[TargetCfg.dft_strap0_idx]})) + `ASSERT(DftStrapTestOValidStable_A, dft_strap_test_o.valid |=> dft_strap_test_o.valid) + `ASSERT(DftStrapTestOStrapStable_A, dft_strap_test_o.valid |-> + $stable(dft_strap_test_o.straps) || + (dft_strap_test_o.straps == $past({mio_in_i[TargetCfg.dft_strap1_idx], + mio_in_i[TargetCfg.dft_strap0_idx]}))) + + // ------ Check USB connectivity ------ + // Note the following assertions only work if the testbench blackboxed u_usbdev_aon_wake module. + `ASSERT(UsbdevDppullupEnI_A, usbdev_dppullup_en_i <-> + u_usbdev_aon_wake.usbdev_dppullup_en_i, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsdevbDnpullupEnI_A, usbdev_dnpullup_en_i <-> + u_usbdev_aon_wake.usbdev_dnpullup_en_i, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsbDppullupEnO_A, ##1 usb_dppullup_en_o <-> + u_usbdev_aon_wake.usb_dppullup_en_o, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsbDnpullupEnO_A, ##1 usb_dnpullup_en_o <-> + u_usbdev_aon_wake.usb_dnpullup_en_o, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsbdevSuspendReqI_A, ##1 usbdev_suspend_req_i <-> + u_usbdev_aon_wake.suspend_req_aon_i, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsbdevWkupAckI_A, usbdev_wake_ack_i <-> + u_usbdev_aon_wake.wake_ack_aon_i, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsbdevBusResetO_A, ##1 usbdev_bus_reset_o <-> + u_usbdev_aon_wake.bus_reset_aon_o, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsbdevSenseLostO_A, ##1 usbdev_sense_lost_o <-> + u_usbdev_aon_wake.sense_lost_aon_o, clk_aon_i, !rst_aon_ni) + + `ASSERT(UsbdevWakeDetectActiveO_A, ##1 usbdev_wake_detect_active_o <-> + u_usbdev_aon_wake.wake_detect_active_aon_o, clk_aon_i, !rst_aon_ni) + + // Fatal alert related assertions + `ASSUME(TriggerAfterAlertInit_S, $stable(rst_ni) == 0 |-> + pinmux.u_reg.intg_err_o == 0 [*10]) + `ASSERT(TlIntgFatalAlert_A, pinmux.u_reg.intg_err_o |-> (##[0:7] (alert_tx_o[0].alert_p)) [*2]) + + // Since the USB wake module is blackboxed, we have to add an assumption here since the + // ASSERT_KNOWN assertions embedded in pinmux.sv would fail otherwise. + `ASSUME_FPV(UsbWkupReqKnownO_M, + !$isunknown(u_usbdev_aon_wake.wake_req_aon_o), clk_aon_i, !rst_aon_ni) + `ASSUME_FPV(UsbWakeDetectActiveKnownO_M, + !$isunknown(u_usbdev_aon_wake.wake_detect_active_aon_o), clk_aon_i, !rst_aon_ni) + +endmodule : pinmux_assert_fpv diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.vlt b/hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.vlt new file mode 100644 index 0000000000000..26ea262b5bc4a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.vlt @@ -0,0 +1,5 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// waiver file for pinmux diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.waiver b/hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.waiver new file mode 100644 index 0000000000000..4c147d6407013 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/lint/pinmux.waiver @@ -0,0 +1,41 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# waiver file for pinmux + +waive -rules NOT_READ -location {pinmux_reg_top.sv} -regexp {.*reg_wdata.*} \ + -comment "Upper bits of reg_wdata are not read" + +waive -rules HIER_NET_NOT_READ -location {pinmux_reg_top.sv} -regexp {.*reg_wdata.*} \ + -comment "Upper bits of reg_wdata are not read" + +waive -rules VAR_INDEX_RANGE -location {pinmux.sv} -regexp {.*maximum value.*} \ + -comment "Indexed arrays may not be fully populated." + +waive -rules RESET_USE -location {pinmux_strap_sampling.sv} -regexp {'rst_ni' is connected to 'prim_clock_mux2' port 'clk1_i', and used as an asynchronous reset or set at pinmux_strap_sampling} \ + -comment "This is a clock mux for DFT." + +waive -rules RESET_MUX -location {pinmux_strap_sampling.sv} -regexp {Asynchronous reset 'rst_ni' reaches a multiplexer here, used as a reset at pinmux_strap_sampling} \ + -comment "This is a clock mux for DFT." + +waive -rules {CLOCK_DRIVER CLOCK_MUX} -location {pinmux_strap_sampling.sv} -regexp {'(lc|rv)_jtag_req.tck' is driven( by a multiplexer)? here,( and)? used as a clock 'tck_i' at dmi_jtag_tap.sv} \ + -comment "These signals are muxed using the JTAG Selection Mux." + +waive -rules CLOCK_MUX -location {pinmux_strap_sampling.sv pinmux.sv} -regexp {Clock '(in_padring_i\[38\]|mio_in_i\[38\]|jtag_req.tck)' reaches a multiplexer here, used as a clock 'tck_i' at dmi_jtag_tap.sv} \ + -comment "The 'mio_in_i[TckPadIdx]' input signal is connected to 'jtag_req.tck' which eventually feeds into the JTAG Selection Mux." + +waive -rules CLOCK_DRIVER -location {pinmux.sv} -regexp {'mio_attr\[28\].pull_select' is driven here, and used as a clock} \ + -comment "'MioPadIoc6' at index 28 may also serve as an external clock input. The 'pull_select' signal impacts the actual value obtained from the pad simulation model." + +waive -rules CLOCK_USE -location {pinmux.sv} -regexp {'hw2reg.mio_pad_attr\[28\].pull_select.d' is connected to 'pinmux_reg_top' port 'hw2reg.mio_pad_attr\[28\].pull_select.d', and used as a clock} \ + -comment "'MioPadIoc6' at index 28 may also serve as an external clock input. The 'pull_select' signal impacts the actual value obtained from the pad simulation model." + +waive -rules CLOCK_USE -location {pinmux.sv} -regexp {'(dio_wkup_mux\[12\]|dio_wkup_mux\[13\]|mio_wkup_mux\[40\])' is used for some other purpose, and as clock} \ + -comment "The wakeup detectors can be configured to observe any MIO / DIO pins. 'DioSpiDeviceSck' (index 12) is the spi_device clock, 'DioSpiDeviceCsb' (index 13) is the spi_device chip select (used as a clock for detecting toggles inside spi_device), and 'Dft0PadIdx' (index 40) controls the first TAP strap and thus the TAP selection mux driving the JTAG clocks." + +waive -rules CLOCK_MUX -location {pinmux.sv} -regexp {Clock 'dio_in_i\[12\]' reaches a multiplexer here, used as a clock 'clk_i'} \ + -comment "This mux is required to filter designated scan clock inputs (e.g. 'DioSpiDeviceSck' at index 12) from wakeup detector inputs" + +waive -rules RESET_ONLY -location {pinmux.sv} -regexp {'mio_pad_attr_q\[0\]' is asynchronously reset but has no other assignments in this block} \ + -comment "This error can safely be ignored: The signal is obviously driven further down in the very same block, changing the TargetCfg.tap_strap0_idx value to a non-zero value (which it actually is in the Earlgrey top level) makes the error go away." diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux.core b/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux.core new file mode 100644 index 0000000000000..350d795e680c1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux.core @@ -0,0 +1,94 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pinmux:0.1 +description: "Pin Multiplexer" + +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:prim:all + - lowrisc:prim:clock_buf + - lowrisc:prim:buf + - lowrisc:prim:lc_dec + - lowrisc:prim:lc_sync + - lowrisc:prim:lc_sender + - lowrisc:prim:lc_or_hardened + - lowrisc:prim:pad_wrapper_pkg + - lowrisc:prim:pad_attr + - lowrisc:ip:jtag_pkg + - lowrisc:ip:usbdev + - lowrisc:opentitan:top_englishbreakfast_pinmux_reg:0.1 + - lowrisc:opentitan:top_englishbreakfast_pinmux_pkg:0.1 + files: + - rtl/pinmux_wkup.sv + - rtl/pinmux_jtag_buf.sv + - rtl/pinmux_jtag_breakout.sv + - rtl/pinmux_strap_sampling.sv + - rtl/pinmux.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/pinmux.vlt + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/pinmux.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: pinmux + + lint: + <<: *default_target + default_tool: verilator + parameters: + - SYNTHESIS=true + tools: + verilator: + mode: lint-only + verilator_options: + - "-Wall" + + syn: + <<: *default_target + # TODO: set default to DC once + # this option is available + # olofk/edalize#89 + default_tool: icarus + parameters: + - SYNTHESIS=true + + formal: + filesets: + - files_rtl + toplevel: pinmux_tb diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_pkg.core b/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_pkg.core new file mode 100644 index 0000000000000..39e76cb8da10f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_pkg.core @@ -0,0 +1,23 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pinmux_pkg:0.1 +description: "Pinmux package" +virtual: + - lowrisc:ip_interfaces:pinmux_pkg + +filesets: + files_rtl: + depend: + - lowrisc:prim:pad_wrapper_pkg + - lowrisc:tlul:headers + files: + - rtl/pinmux_reg_pkg.sv + - rtl/pinmux_pkg.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_reg.core b/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_reg.core new file mode 100644 index 0000000000000..161f7df7ff203 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/pinmux_reg.core @@ -0,0 +1,21 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pinmux_reg:0.1 +description: "Auto-generated pinmux register sources" + +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:prim:subreg + - lowrisc:opentitan:top_englishbreakfast_pinmux_pkg + files: + - rtl/pinmux_reg_top.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux.sv new file mode 100644 index 0000000000000..bd3d9212f3247 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux.sv @@ -0,0 +1,692 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Pinmux toplevel. +// + +`include "prim_assert.sv" + +module pinmux + import pinmux_pkg::*; + import pinmux_reg_pkg::*; + import prim_pad_wrapper_pkg::*; +#( + // Taget-specific pinmux configuration passed down from the + // target-specific top-level. + parameter target_cfg_t TargetCfg = DefaultTargetCfg, + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter bit SecVolatileRawUnlockEn = 0 +) ( + input clk_i, + input rst_ni, + input rst_sys_ni, + // Scan enable + input prim_mubi_pkg::mubi4_t scanmode_i, + // Slow always-on clock + input clk_aon_i, + input rst_aon_ni, + // Wakeup request, running on clk_aon_i + output logic pin_wkup_req_o, + output logic usb_wkup_req_o, + // Sleep enable and strap sample enable + // from pwrmgr, running on clk_i + input sleep_en_i, + input strap_en_i, + // ---------- VOLATILE_TEST_UNLOCKED CODE SECTION START ---------- + // NOTE THAT THIS IS A FEATURE FOR TEST CHIPS ONLY TO MITIGATE + // THE RISK OF A BROKEN OTP MACRO. THIS WILL BE DISABLED VIA + // SecVolatileRawUnlockEn AT COMPILETIME FOR PRODUCTION DEVICES. + // --------------------------------------------------------------- + // Strap sampling override that is only used when SecVolatileRawUnlockEn = 1, Otherwise this input + // is unused. This needs to be synchronized since it is coming from a different clock domain. + // This signal goes from 0 -> 1 and then stays high, since we only ever re-sample once. The + // synchronization logic can therefore just detect the edge to create the sampling pulse + // internally. + input strap_en_override_i, + // ----------- VOLATILE_TEST_UNLOCKED CODE SECTION END ----------- + // LC signals for TAP qualification + // SEC_CM: LC_DFT_EN.INTERSIG.MUBI + input lc_ctrl_pkg::lc_tx_t lc_dft_en_i, + // SEC_CM: LC_HW_DEBUG_EN.INTERSIG.MUBI + input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i, + // SEC_CM: LC_CHECK_BYP_EN.INTERSIG.MUBI + input lc_ctrl_pkg::lc_tx_t lc_check_byp_en_i, + // SEC_CM: LC_ESCALATE_EN.INTERSIG.MUBI + input lc_ctrl_pkg::lc_tx_t lc_escalate_en_i, + // SEC_CM: PINMUX_HW_DEBUG_EN.INTERSIG.MUBI + output lc_ctrl_pkg::lc_tx_t pinmux_hw_debug_en_o, + // Sampled values for DFT straps + output dft_strap_test_req_t dft_strap_test_o, + // DFT indication to stop tap strap sampling + input dft_hold_tap_sel_i, + // Qualified JTAG signals for TAPs + output jtag_pkg::jtag_req_t lc_jtag_o, + input jtag_pkg::jtag_rsp_t lc_jtag_i, + output jtag_pkg::jtag_req_t rv_jtag_o, + input jtag_pkg::jtag_rsp_t rv_jtag_i, + output jtag_pkg::jtag_req_t dft_jtag_o, + input jtag_pkg::jtag_rsp_t dft_jtag_i, + // Direct USB connection + input usbdev_dppullup_en_i, + input usbdev_dnpullup_en_i, + output usb_dppullup_en_o, + output usb_dnpullup_en_o, + input usbdev_suspend_req_i, + input usbdev_wake_ack_i, + output usbdev_bus_not_idle_o, + output usbdev_bus_reset_o, + output usbdev_sense_lost_o, + output usbdev_wake_detect_active_o, + // Bus Interface (device) + 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, + // Muxed Peripheral side + input [NMioPeriphOut-1:0] periph_to_mio_i, + input [NMioPeriphOut-1:0] periph_to_mio_oe_i, + output logic [NMioPeriphIn-1:0] mio_to_periph_o, + // Dedicated Peripheral side + input [NDioPads-1:0] periph_to_dio_i, + input [NDioPads-1:0] periph_to_dio_oe_i, + output logic [NDioPads-1:0] dio_to_periph_o, + // Pad side + // MIOs + output prim_pad_wrapper_pkg::pad_attr_t [NMioPads-1:0] mio_attr_o, + output logic [NMioPads-1:0] mio_out_o, + output logic [NMioPads-1:0] mio_oe_o, + input [NMioPads-1:0] mio_in_i, + // DIOs + output prim_pad_wrapper_pkg::pad_attr_t [NDioPads-1:0] dio_attr_o, + output logic [NDioPads-1:0] dio_out_o, + output logic [NDioPads-1:0] dio_oe_o, + input [NDioPads-1:0] dio_in_i +); + + ////////////////////////////////// + // Regfile Breakout and Mapping // + ////////////////////////////////// + + logic [NumAlerts-1:0] alert_test, alerts; + pinmux_reg2hw_t reg2hw; + pinmux_hw2reg_t hw2reg; + + pinmux_reg_top u_reg ( + .clk_i, + .rst_ni, + .clk_aon_i, + .rst_aon_ni, + .tl_i, + .tl_o, + .reg2hw, + .hw2reg, + // SEC_CM: BUS.INTEGRITY + .intg_err_o(alerts[0]) + ); + + //////////// + // Alerts // + //////////// + + assign alert_test = { + reg2hw.alert_test.q & + reg2hw.alert_test.qe + }; + + 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, + .rst_ni, + .alert_test_i ( alert_test[i] ), + .alert_req_i ( alerts[0] ), + .alert_ack_o ( ), + .alert_state_o ( ), + .alert_rx_i ( alert_rx_i[i] ), + .alert_tx_o ( alert_tx_o[i] ) + ); + end + + ///////////////////////////// + // Pad attribute registers // + ///////////////////////////// + + prim_pad_wrapper_pkg::pad_attr_t [NDioPads-1:0] dio_pad_attr_q; + prim_pad_wrapper_pkg::pad_attr_t [NMioPads-1:0] mio_pad_attr_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_regs + if (!rst_ni) begin + dio_pad_attr_q <= '0; + for (int kk = 0; kk < NMioPads; kk++) begin + if (kk == TargetCfg.tap_strap0_idx) begin + // TAP strap 0 is sampled after reset (and only once for life cycle states that are not + // TEST_UNLOCKED* or RMA). To ensure it gets sampled as 0 unless driven to 1 from an + // external source (and specifically that it gets sampled as 0 when left floating / not + // connected), this enables the pull-down of the pad at reset. + mio_pad_attr_q[kk] <= '{pull_en: 1'b1, default: '0}; + end else begin + mio_pad_attr_q[kk] <= '0; + end + end + end else begin + // dedicated pads + for (int kk = 0; kk < NDioPads; kk++) begin + if (reg2hw.dio_pad_attr[kk].drive_strength.qe) begin + dio_pad_attr_q[kk].drive_strength <= reg2hw.dio_pad_attr[kk].drive_strength.q; + end + if (reg2hw.dio_pad_attr[kk].slew_rate.qe) begin + dio_pad_attr_q[kk].slew_rate <= reg2hw.dio_pad_attr[kk].slew_rate.q; + end + if (reg2hw.dio_pad_attr[kk].input_disable.qe) begin + dio_pad_attr_q[kk].input_disable <= reg2hw.dio_pad_attr[kk].input_disable.q; + end + if (reg2hw.dio_pad_attr[kk].od_en.qe) begin + dio_pad_attr_q[kk].od_en <= reg2hw.dio_pad_attr[kk].od_en.q; + end + if (reg2hw.dio_pad_attr[kk].schmitt_en.qe) begin + dio_pad_attr_q[kk].schmitt_en <= reg2hw.dio_pad_attr[kk].schmitt_en.q; + end + if (reg2hw.dio_pad_attr[kk].keeper_en.qe) begin + dio_pad_attr_q[kk].keep_en <= reg2hw.dio_pad_attr[kk].keeper_en.q; + end + if (reg2hw.dio_pad_attr[kk].pull_select.qe) begin + dio_pad_attr_q[kk].pull_select <= reg2hw.dio_pad_attr[kk].pull_select.q; + end + if (reg2hw.dio_pad_attr[kk].pull_en.qe) begin + dio_pad_attr_q[kk].pull_en <= reg2hw.dio_pad_attr[kk].pull_en.q; + end + if (reg2hw.dio_pad_attr[kk].virtual_od_en.qe) begin + dio_pad_attr_q[kk].virt_od_en <= reg2hw.dio_pad_attr[kk].virtual_od_en.q; + end + if (reg2hw.dio_pad_attr[kk].invert.qe) begin + dio_pad_attr_q[kk].invert <= reg2hw.dio_pad_attr[kk].invert.q; + end + end + // muxed pads + for (int kk = 0; kk < NMioPads; kk++) begin + if (reg2hw.mio_pad_attr[kk].drive_strength.qe) begin + mio_pad_attr_q[kk].drive_strength <= reg2hw.mio_pad_attr[kk].drive_strength.q; + end + if (reg2hw.mio_pad_attr[kk].slew_rate.qe) begin + mio_pad_attr_q[kk].slew_rate <= reg2hw.mio_pad_attr[kk].slew_rate.q; + end + if (reg2hw.mio_pad_attr[kk].input_disable.qe) begin + mio_pad_attr_q[kk].input_disable <= reg2hw.mio_pad_attr[kk].input_disable.q; + end + if (reg2hw.mio_pad_attr[kk].od_en.qe) begin + mio_pad_attr_q[kk].od_en <= reg2hw.mio_pad_attr[kk].od_en.q; + end + if (reg2hw.mio_pad_attr[kk].schmitt_en.qe) begin + mio_pad_attr_q[kk].schmitt_en <= reg2hw.mio_pad_attr[kk].schmitt_en.q; + end + if (reg2hw.mio_pad_attr[kk].keeper_en.qe) begin + mio_pad_attr_q[kk].keep_en <= reg2hw.mio_pad_attr[kk].keeper_en.q; + end + if (reg2hw.mio_pad_attr[kk].pull_select.qe) begin + mio_pad_attr_q[kk].pull_select <= reg2hw.mio_pad_attr[kk].pull_select.q; + end + if (reg2hw.mio_pad_attr[kk].pull_en.qe) begin + mio_pad_attr_q[kk].pull_en <= reg2hw.mio_pad_attr[kk].pull_en.q; + end + if (reg2hw.mio_pad_attr[kk].virtual_od_en.qe) begin + mio_pad_attr_q[kk].virt_od_en <= reg2hw.mio_pad_attr[kk].virtual_od_en.q; + end + if (reg2hw.mio_pad_attr[kk].invert.qe) begin + mio_pad_attr_q[kk].invert <= reg2hw.mio_pad_attr[kk].invert.q; + end + end + end + end + + //////////////////////// + // Connect attributes // + //////////////////////// + + pad_attr_t [NDioPads-1:0] dio_attr; + for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_attr + pad_attr_t warl_mask; + + prim_pad_attr #( + .PadType(TargetCfg.dio_pad_type[k]) + ) u_prim_pad_attr ( + .attr_warl_o(warl_mask) + ); + + assign dio_attr[k] = dio_pad_attr_q[k] & warl_mask; + assign hw2reg.dio_pad_attr[k].drive_strength.d = dio_attr[k].drive_strength; + assign hw2reg.dio_pad_attr[k].slew_rate.d = dio_attr[k].slew_rate; + assign hw2reg.dio_pad_attr[k].input_disable.d = dio_attr[k].input_disable; + assign hw2reg.dio_pad_attr[k].od_en.d = dio_attr[k].od_en; + assign hw2reg.dio_pad_attr[k].schmitt_en.d = dio_attr[k].schmitt_en; + assign hw2reg.dio_pad_attr[k].keeper_en.d = dio_attr[k].keep_en; + assign hw2reg.dio_pad_attr[k].pull_select.d = dio_attr[k].pull_select; + assign hw2reg.dio_pad_attr[k].pull_en.d = dio_attr[k].pull_en; + assign hw2reg.dio_pad_attr[k].virtual_od_en.d = dio_attr[k].virt_od_en; + assign hw2reg.dio_pad_attr[k].invert.d = dio_attr[k].invert; + end + + pad_attr_t [NMioPads-1:0] mio_attr; + for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_attr + pad_attr_t warl_mask; + + prim_pad_attr #( + .PadType(TargetCfg.mio_pad_type[k]) + ) u_prim_pad_attr ( + .attr_warl_o(warl_mask) + ); + + assign mio_attr[k] = mio_pad_attr_q[k] & warl_mask; + assign hw2reg.mio_pad_attr[k].drive_strength.d = mio_attr[k].drive_strength; + assign hw2reg.mio_pad_attr[k].slew_rate.d = mio_attr[k].slew_rate; + assign hw2reg.mio_pad_attr[k].input_disable.d = mio_attr[k].input_disable; + assign hw2reg.mio_pad_attr[k].od_en.d = mio_attr[k].od_en; + assign hw2reg.mio_pad_attr[k].schmitt_en.d = mio_attr[k].schmitt_en; + assign hw2reg.mio_pad_attr[k].keeper_en.d = mio_attr[k].keep_en; + assign hw2reg.mio_pad_attr[k].pull_select.d = mio_attr[k].pull_select; + assign hw2reg.mio_pad_attr[k].pull_en.d = mio_attr[k].pull_en; + assign hw2reg.mio_pad_attr[k].virtual_od_en.d = mio_attr[k].virt_od_en; + assign hw2reg.mio_pad_attr[k].invert.d = mio_attr[k].invert; + end + + // Local versions of the input signals + logic [NMioPads-1:0] mio_out, mio_oe, mio_in; + logic [NDioPads-1:0] dio_out, dio_oe, dio_in; + + + ////////////////////////// + // Strap Sampling Logic // + ////////////////////////// + + logic strap_en; + if (SecVolatileRawUnlockEn) begin : gen_strap_override + logic strap_en_override_d, strap_en_override_q; + prim_flop_2sync #( + .Width(1), + .ResetValue(0) + ) u_prim_flop_2sync ( + .clk_i, + .rst_ni, + .d_i(strap_en_override_i), + .q_o(strap_en_override_d) + ); + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_strap_override_reg + if(!rst_ni) begin + strap_en_override_q <= 1'b0; + end else begin + strap_en_override_q <= strap_en_override_d; + end + end + + // Detect a change from 0 -> 1 on the override signal (it will stay at 1 afterwards). + assign strap_en = strap_en_i || (strap_en_override_d && !strap_en_override_q); + + // The strap sampling override shall be set to high exactly once. + `ASSUME(LcCtrlStrapSampleOverrideOnce_A, + $rose(strap_en_override_i) |-> always strap_en_override_i) + + end else begin : gen_no_strap_override + logic unused_strap_en_override; + assign unused_strap_en_override = strap_en_override_i; + assign strap_en = strap_en_i; + end + + // This module contains the strap sampling and JTAG mux. + // Affected inputs are intercepted/tapped before they go to the pinmux + // matrix. Likewise, affected outputs are intercepted/tapped after the + // retention registers. + pinmux_strap_sampling #( + .TargetCfg (TargetCfg) + ) u_pinmux_strap_sampling ( + .clk_i, + // Inside the pinmux, the strap sampling module is the only module using SYS_RST. The reason for + // that is that SYS_RST reset will not be asserted during a NDM reset from the RV_DM and hence + // it retains some of the TAP selection state during an active debug session where NDM reset + // is triggered. To that end, the strap sampling module latches the lc_hw_debug_en_i signal + // whenever strap_en_i is asserted. Note that this does not affect the DFT TAP selection, since + // we always consume the live lc_dft_en_i signal. + .rst_ni (rst_sys_ni), + .scanmode_i, + // To padring side + .out_padring_o ( {dio_out_o, mio_out_o} ), + .oe_padring_o ( {dio_oe_o , mio_oe_o } ), + .in_padring_i ( {dio_in_i , mio_in_i } ), + .attr_padring_o ( {dio_attr_o, mio_attr_o} ), + // To core side + .out_core_i ( {dio_out, mio_out} ), + .oe_core_i ( {dio_oe, mio_oe} ), + .in_core_o ( {dio_in, mio_in} ), + .attr_core_i ( {dio_attr, mio_attr} ), + // Strap and JTAG signals + .strap_en_i ( strap_en ), + .lc_dft_en_i, + .lc_hw_debug_en_i, + .lc_escalate_en_i, + .lc_check_byp_en_i, + // This is the latched version of lc_hw_debug_en_i. We use it exclusively to gate the JTAG + // signals and TAP side of the RV_DM so that RV_DM can remain live during an NDM reset cycle. + .pinmux_hw_debug_en_o, + .dft_strap_test_o, + .dft_hold_tap_sel_i, + .lc_jtag_o, + .lc_jtag_i, + .rv_jtag_o, + .rv_jtag_i, + .dft_jtag_o, + .dft_jtag_i + ); + + /////////////////////////////////////// + // USB wake detect module connection // + /////////////////////////////////////// + + // Dedicated Peripheral side + usbdev_aon_wake u_usbdev_aon_wake ( + .clk_aon_i, + .rst_aon_ni, + + // input signals for resume detection + .usb_dp_i(dio_to_periph_o[TargetCfg.usb_dp_idx]), + .usb_dn_i(dio_to_periph_o[TargetCfg.usb_dn_idx]), + .usb_sense_i(mio_to_periph_o[TargetCfg.usb_sense_idx]), + .usbdev_dppullup_en_i(usbdev_dppullup_en_i), + .usbdev_dnpullup_en_i(usbdev_dnpullup_en_i), + + // output signals for pullup connectivity + .usb_dppullup_en_o(usb_dppullup_en_o), + .usb_dnpullup_en_o(usb_dnpullup_en_o), + + // tie this to something from usbdev to indicate its out of reset + .suspend_req_aon_i(usbdev_suspend_req_i), + .wake_ack_aon_i(usbdev_wake_ack_i), + + // wake/powerup request + .wake_req_aon_o(usb_wkup_req_o), + .bus_not_idle_aon_o(usbdev_bus_not_idle_o), + .bus_reset_aon_o(usbdev_bus_reset_o), + .sense_lost_aon_o(usbdev_sense_lost_o), + .wake_detect_active_aon_o(usbdev_wake_detect_active_o) + ); + + ///////////////////////// + // Retention Registers // + ///////////////////////// + + logic sleep_en_q, sleep_trig; + + logic [NMioPads-1:0] mio_sleep_trig; + logic [NMioPads-1:0] mio_out_retreg_d, mio_oe_retreg_d; + logic [NMioPads-1:0] mio_out_retreg_q, mio_oe_retreg_q; + + logic [NDioPads-1:0] dio_sleep_trig; + logic [NDioPads-1:0] dio_out_retreg_d, dio_oe_retreg_d; + logic [NDioPads-1:0] dio_out_retreg_q, dio_oe_retreg_q; + + // Sleep entry trigger + assign sleep_trig = sleep_en_i & ~sleep_en_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_sleep + if (!rst_ni) begin + sleep_en_q <= 1'b0; + mio_out_retreg_q <= '0; + mio_oe_retreg_q <= '0; + dio_out_retreg_q <= '0; + dio_oe_retreg_q <= '0; + end else begin + sleep_en_q <= sleep_en_i; + + // MIOs + for (int k = 0; k < NMioPads; k++) begin + if (mio_sleep_trig[k]) begin + mio_out_retreg_q[k] <= mio_out_retreg_d[k]; + mio_oe_retreg_q[k] <= mio_oe_retreg_d[k]; + end + end + + // DIOs + for (int k = 0; k < NDioPads; k++) begin + if (dio_sleep_trig[k]) begin + dio_out_retreg_q[k] <= dio_out_retreg_d[k]; + dio_oe_retreg_q[k] <= dio_oe_retreg_d[k]; + end + end + end + end + + ///////////////////// + // MIO Input Muxes // + ///////////////////// + + localparam int AlignedMuxSize = (NMioPads + 2 > NDioPads) ? 2**$clog2(NMioPads + 2) : + 2**$clog2(NDioPads); + + // stack input and default signals for convenient indexing below possible defaults: + // constant 0 or 1. make sure mux is aligned to a power of 2 to avoid Xes. + logic [AlignedMuxSize-1:0] mio_mux; + assign mio_mux = AlignedMuxSize'({mio_in, 1'b1, 1'b0}); + + for (genvar k = 0; k < NMioPeriphIn; k++) begin : gen_mio_periph_in + // index using configured insel + assign mio_to_periph_o[k] = mio_mux[reg2hw.mio_periph_insel[k].q]; + end + + ////////////////////// + // MIO Output Muxes // + ////////////////////// + + // stack output data/enable and default signals for convenient indexing below + // possible defaults: 0, 1 or 2 (high-Z). make sure mux is aligned to a power of 2 to avoid Xes. + logic [2**$clog2(NMioPeriphOut+3)-1:0] periph_data_mux, periph_oe_mux; + assign periph_data_mux = $bits(periph_data_mux)'({periph_to_mio_i, 1'b0, 1'b1, 1'b0}); + assign periph_oe_mux = $bits(periph_oe_mux)'({periph_to_mio_oe_i, 1'b0, 1'b1, 1'b1}); + + for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_out + // Check individual sleep enable status bits + assign mio_out[k] = reg2hw.mio_pad_sleep_status[k].q ? + mio_out_retreg_q[k] : + periph_data_mux[reg2hw.mio_outsel[k].q]; + + assign mio_oe[k] = reg2hw.mio_pad_sleep_status[k].q ? + mio_oe_retreg_q[k] : + periph_oe_mux[reg2hw.mio_outsel[k].q]; + + // latch state when going to sleep + // 0: drive low + // 1: drive high + // 2: high-z + // 3: previous value + assign mio_out_retreg_d[k] = (reg2hw.mio_pad_sleep_mode[k].q == 0) ? 1'b0 : + (reg2hw.mio_pad_sleep_mode[k].q == 1) ? 1'b1 : + (reg2hw.mio_pad_sleep_mode[k].q == 2) ? 1'b0 : mio_out[k]; + + assign mio_oe_retreg_d[k] = (reg2hw.mio_pad_sleep_mode[k].q == 0) ? 1'b1 : + (reg2hw.mio_pad_sleep_mode[k].q == 1) ? 1'b1 : + (reg2hw.mio_pad_sleep_mode[k].q == 2) ? 1'b0 : mio_oe[k]; + + // Activate sleep behavior only if it has been enabled + assign mio_sleep_trig[k] = reg2hw.mio_pad_sleep_en[k].q & sleep_trig; + assign hw2reg.mio_pad_sleep_status[k].d = 1'b1; + assign hw2reg.mio_pad_sleep_status[k].de = mio_sleep_trig[k]; + end + + ///////////////////// + // DIO connections // + ///////////////////// + + // Inputs are just fed through + assign dio_to_periph_o = dio_in; + + for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_out + // Check individual sleep enable status bits + assign dio_out[k] = reg2hw.dio_pad_sleep_status[k].q ? + dio_out_retreg_q[k] : + periph_to_dio_i[k]; + + assign dio_oe[k] = reg2hw.dio_pad_sleep_status[k].q ? + dio_oe_retreg_q[k] : + periph_to_dio_oe_i[k]; + + // latch state when going to sleep + // 0: drive low + // 1: drive high + // 2: high-z + // 3: previous value + assign dio_out_retreg_d[k] = (reg2hw.dio_pad_sleep_mode[k].q == 0) ? 1'b0 : + (reg2hw.dio_pad_sleep_mode[k].q == 1) ? 1'b1 : + (reg2hw.dio_pad_sleep_mode[k].q == 2) ? 1'b0 : dio_out[k]; + + assign dio_oe_retreg_d[k] = (reg2hw.dio_pad_sleep_mode[k].q == 0) ? 1'b1 : + (reg2hw.dio_pad_sleep_mode[k].q == 1) ? 1'b1 : + (reg2hw.dio_pad_sleep_mode[k].q == 2) ? 1'b0 : dio_oe[k]; + + // Activate sleep behavior only if it has been enabled + assign dio_sleep_trig[k] = reg2hw.dio_pad_sleep_en[k].q & sleep_trig; + assign hw2reg.dio_pad_sleep_status[k].d = 1'b1; + assign hw2reg.dio_pad_sleep_status[k].de = dio_sleep_trig[k]; + end + + ////////////////////// + // Wakeup detectors // + ////////////////////// + + // Wakeup detectors should not be connected to the scan clock, so filter + // those inputs. + logic [NDioPads-1:0] dio_wkup_no_scan; + for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_wkup_filter + if (TargetCfg.dio_scan_role[k] == ScanClock) begin : gen_dio_scan + always_comb begin + dio_wkup_no_scan[k] = dio_in_i[k]; + if (prim_mubi_pkg::mubi4_test_true_strict(scanmode_i)) begin + dio_wkup_no_scan[k] = 1'b0; + end + end + end else begin : gen_no_dio_scan + assign dio_wkup_no_scan[k] = dio_in_i[k]; + end + end + + logic [NMioPads-1:0] mio_wkup_no_scan; + for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_wkup_filter + if (TargetCfg.mio_scan_role[k] == ScanClock) begin : gen_mio_scan + always_comb begin + mio_wkup_no_scan[k] = mio_in_i[k]; + if (prim_mubi_pkg::mubi4_test_true_strict(scanmode_i)) begin + mio_wkup_no_scan[k] = 1'b0; + end + end + end else begin : gen_no_mio_scan + assign mio_wkup_no_scan[k] = mio_in_i[k]; + end + end + + // Wakeup detector taps are not affected by JTAG/strap + // selection mux. I.e., we always sample the unmuxed inputs + // that come directly from the pads. + logic [AlignedMuxSize-1:0] dio_wkup_mux; + logic [AlignedMuxSize-1:0] mio_wkup_mux; + assign dio_wkup_mux = AlignedMuxSize'(dio_wkup_no_scan); + // The two constants that are concatenated here make sure tha the selection + // indices used to index this array are the same as the ones used to index + // the mio_mux array above, where positions 0 and 1 select constant 0 and + // 1, respectively. + assign mio_wkup_mux = AlignedMuxSize'({mio_wkup_no_scan, 1'b1, 1'b0}); + + logic [NWkupDetect-1:0] aon_wkup_req; + for (genvar k = 0; k < NWkupDetect; k++) begin : gen_wkup_detect + logic pin_value; + assign pin_value = (reg2hw.wkup_detector[k].miodio.q) ? + dio_wkup_mux[reg2hw.wkup_detector_padsel[k]] : + mio_wkup_mux[reg2hw.wkup_detector_padsel[k]]; + + // This module runs on the AON clock entirely + pinmux_wkup u_pinmux_wkup ( + .clk_i (clk_aon_i ), + .rst_ni (rst_aon_ni ), + // config signals have already been synced to the AON domain inside the CSR node. + .wkup_en_i ( reg2hw.wkup_detector_en[k].q ), + .filter_en_i ( reg2hw.wkup_detector[k].filter.q ), + .wkup_mode_i ( wkup_mode_e'(reg2hw.wkup_detector[k].mode.q) ), + .wkup_cnt_th_i ( reg2hw.wkup_detector_cnt_th[k].q ), + .pin_value_i ( pin_value ), + // wakeup request pulse on clk_aon, will be synced back to the bus domain insie the CSR node. + .aon_wkup_pulse_o ( hw2reg.wkup_cause[k].de ) + ); + + assign hw2reg.wkup_cause[k].d = 1'b1; + + // This is the latched wakeup request, hence this request signal is level encoded. + assign aon_wkup_req[k] = reg2hw.wkup_cause[k].q; + end + + // OR' together all wakeup requests + assign pin_wkup_req_o = |aon_wkup_req; + + //////////////// + // Assertions // + //////////////// + + `ASSERT_KNOWN(TlDValidKnownO_A, tl_o.d_valid) + `ASSERT_KNOWN(TlAReadyKnownO_A, tl_o.a_ready) + `ASSERT_KNOWN(AlertsKnown_A, alert_tx_o) + `ASSERT_KNOWN(MioOeKnownO_A, mio_oe_o) + `ASSERT_KNOWN(DioOeKnownO_A, dio_oe_o) + + `ASSERT_KNOWN(MioKnownO_A, mio_attr_o) + `ASSERT_KNOWN(DioKnownO_A, dio_attr_o) + + `ASSERT_KNOWN(LcJtagTckKnown_A, lc_jtag_o.tck) + `ASSERT_KNOWN(LcJtagTrstKnown_A, lc_jtag_o.trst_n) + `ASSERT_KNOWN(LcJtagTmsKnown_A, lc_jtag_o.tms) + + `ASSERT_KNOWN(RvJtagTckKnown_A, rv_jtag_o.tck) + `ASSERT_KNOWN(RvJtagTrstKnown_A, rv_jtag_o.trst_n) + `ASSERT_KNOWN(RvJtagTmsKnown_A, rv_jtag_o.tms) + + `ASSERT_KNOWN(DftJtagTckKnown_A, dft_jtag_o.tck) + `ASSERT_KNOWN(DftJtagTrstKnown_A, dft_jtag_o.trst_n) + `ASSERT_KNOWN(DftJtagTmsKnown_A, dft_jtag_o.tms) + + `ASSERT_KNOWN(DftStrapsKnown_A, dft_strap_test_o) + + // running on slow AON clock + `ASSERT_KNOWN(AonWkupReqKnownO_A, pin_wkup_req_o, clk_aon_i, !rst_aon_ni) + `ASSERT_KNOWN(UsbWkupReqKnownO_A, usb_wkup_req_o, clk_aon_i, !rst_aon_ni) + `ASSERT_KNOWN(UsbWakeDetectActiveKnownO_A, usbdev_wake_detect_active_o, clk_aon_i, !rst_aon_ni) + + // The wakeup signal is not latched in the pwrmgr so must be held until acked by software + `ASSUME(PinmuxWkupStable_A, pin_wkup_req_o |=> pin_wkup_req_o || + $fell(|reg2hw.wkup_cause) && !sleep_en_i, clk_aon_i, !rst_aon_ni) + + // Some inputs at the chip-level may be forced to X in chip-level simulations. + // Therefore, we do not instantiate these assertions. + // `ASSERT_KNOWN(MioToPeriphKnownO_A, mio_to_periph_o) + // `ASSERT_KNOWN(DioToPeriphKnownO_A, dio_to_periph_o) + + // The assertions below are not instantiated for a similar reason as the assertions above. + // I.e., some IPs have pass-through paths, which may lead to X'es propagating + // from input to output. + // for (genvar k = 0; k < NMioPads; k++) begin : gen_mio_known_if + // `ASSERT_KNOWN_IF(MioOutKnownO_A, mio_out_o[k], mio_oe_o[k]) + // end + // for (genvar k = 0; k < NDioPads; k++) begin : gen_dio_known_if + // `ASSERT_KNOWN_IF(DioOutKnownO_A, dio_out_o[k], dio_oe_o[k]) + // end + + // Pinmux does not have a block-level DV environment, hence we add an FPV assertion to test this. + `ASSERT(FpvSecCmBusIntegrity_A, + $rose(u_reg.intg_err) + |-> + ##[0:`_SEC_CM_ALERT_MAX_CYC] (alert_tx_o[0].alert_p)) + + // Alert assertions for reg_we onehot check + `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[0]) + + // The strap sampling enable input shall be pulsed high for exactly one cycle after cold boot. + `ASSUME(PwrMgrStrapSampleOnce0_A, strap_en_i |=> !strap_en_i) + `ASSUME(PwrMgrStrapSampleOnce1_A, $fell(strap_en_i) |-> always !strap_en_i) + +endmodule : pinmux diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_breakout.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_breakout.sv new file mode 100644 index 0000000000000..2acba6ff7406b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_breakout.sv @@ -0,0 +1,24 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module pinmux_jtag_breakout ( + input jtag_pkg::jtag_req_t req_i, + output jtag_pkg::jtag_rsp_t rsp_o, + + output logic tck_o, + output logic trst_no, + output logic tms_o, + output logic tdi_o, + input tdo_i, + input tdo_oe_i +); + + assign tck_o = req_i.tck; + assign trst_no = req_i.trst_n; + assign tms_o = req_i.tms; + assign tdi_o = req_i.tdi; + assign rsp_o.tdo = tdo_i; + assign rsp_o.tdo_oe = tdo_oe_i; + +endmodule : pinmux_jtag_breakout diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_buf.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_buf.sv new file mode 100644 index 0000000000000..161a0cb4cbe29 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_jtag_buf.sv @@ -0,0 +1,37 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module pinmux_jtag_buf ( + input jtag_pkg::jtag_req_t req_i, + output jtag_pkg::jtag_req_t req_o, + input jtag_pkg::jtag_rsp_t rsp_i, + output jtag_pkg::jtag_rsp_t rsp_o +); + + prim_clock_buf prim_clock_buf_tck ( + .clk_i(req_i.tck), + .clk_o(req_o.tck) + ); + prim_buf prim_buf_trst_n ( + .in_i (req_i.trst_n), + .out_o(req_o.trst_n) + ); + prim_buf prim_buf_tms ( + .in_i (req_i.tms), + .out_o(req_o.tms) + ); + prim_buf prim_buf_tdi ( + .in_i (req_i.tdi), + .out_o(req_o.tdi) + ); + prim_buf prim_buf_tdo ( + .in_i (rsp_i.tdo), + .out_o(rsp_o.tdo) + ); + prim_buf prim_buf_tdo_oe ( + .in_i (rsp_i.tdo_oe), + .out_o(rsp_o.tdo_oe) + ); + +endmodule : pinmux_jtag_buf diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_pkg.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_pkg.sv new file mode 100644 index 0000000000000..d2df26f6c0c8a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_pkg.sv @@ -0,0 +1,78 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package pinmux_pkg; + + import pinmux_reg_pkg::*; + import prim_pad_wrapper_pkg::*; + + parameter int NumIOs = NMioPads + NDioPads; + parameter int NDFTStraps = 2; + parameter int NTapStraps = 2; + + // Since the target-specific top-levels often have slightly different debug signal positions, we + // need a way to pass this info from the target specific top-level into the pinmux logic. The + // datastructure below serves this purpose. Note that all the indices below are with respect to + // the concatenated {DIO, MIO} packed array. + typedef struct packed { + integer tck_idx; + integer tms_idx; + integer trst_idx; + integer tdi_idx; + integer tdo_idx; + integer tap_strap0_idx; + integer tap_strap1_idx; + integer dft_strap0_idx; + integer dft_strap1_idx; + integer usb_dp_idx; + integer usb_dn_idx; + integer usb_sense_idx; + pad_type_e [NDioPads-1:0] dio_pad_type; + pad_type_e [NMioPads-1:0] mio_pad_type; + scan_role_e [NDioPads-1:0] dio_scan_role; + scan_role_e [NMioPads-1:0] mio_scan_role; + } target_cfg_t; + + parameter target_cfg_t DefaultTargetCfg = '{ + tck_idx: 0, + tms_idx: 0, + trst_idx: 0, + tdi_idx: 0, + tdo_idx: 0, + tap_strap0_idx: 0, + tap_strap1_idx: 0, + dft_strap0_idx: 0, + dft_strap1_idx: 0, + usb_dp_idx: 0, + usb_dn_idx: 0, + usb_sense_idx: 0, + dio_pad_type: {NDioPads{BidirStd}}, + mio_pad_type: {NMioPads{BidirStd}}, + dio_scan_role: {NDioPads{NoScan}}, + mio_scan_role: {NMioPads{NoScan}} + }; + + // Wakeup Detector Modes + typedef enum logic [2:0] { + Posedge = 3'b000, + Negedge = 3'b001, + Edge = 3'b010, + HighTimed = 3'b011, + LowTimed = 3'b100 + } wkup_mode_e; + + // Interface with LC controller + typedef struct packed { + logic valid; + logic [NDFTStraps-1:0] straps; + } dft_strap_test_req_t; + + typedef enum logic [NTapStraps-1:0] { + FuncSel = 2'b00, + LcTapSel = 2'b01, + RvTapSel = 2'b10, + DftTapSel = 2'b11 + } tap_strap_t; + +endpackage : pinmux_pkg diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_pkg.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_pkg.sv new file mode 100644 index 0000000000000..f85f457ee1d4e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_pkg.sv @@ -0,0 +1,2531 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 pinmux_reg_pkg; + + // Param list + parameter int NMioPeriphIn = 38; + parameter int NMioPeriphOut = 35; + parameter int NMioPads = 47; + parameter int NDioPads = 14; + parameter int NWkupDetect = 8; + parameter int WkupCntWidth = 8; + parameter int NumAlerts = 1; + + // Address widths within the block + parameter int BlockAw = 12; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + logic q; + logic qe; + } pinmux_reg2hw_alert_test_reg_t; + + typedef struct packed { + logic [5:0] q; + } pinmux_reg2hw_mio_periph_insel_mreg_t; + + typedef struct packed { + logic [5:0] q; + } pinmux_reg2hw_mio_outsel_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + logic qe; + } drive_strength; + struct packed { + logic [1:0] q; + logic qe; + } slew_rate; + struct packed { + logic q; + logic qe; + } input_disable; + struct packed { + logic q; + logic qe; + } od_en; + struct packed { + logic q; + logic qe; + } schmitt_en; + struct packed { + logic q; + logic qe; + } keeper_en; + struct packed { + logic q; + logic qe; + } pull_select; + struct packed { + logic q; + logic qe; + } pull_en; + struct packed { + logic q; + logic qe; + } virtual_od_en; + struct packed { + logic q; + logic qe; + } invert; + } pinmux_reg2hw_mio_pad_attr_mreg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + logic qe; + } drive_strength; + struct packed { + logic [1:0] q; + logic qe; + } slew_rate; + struct packed { + logic q; + logic qe; + } input_disable; + struct packed { + logic q; + logic qe; + } od_en; + struct packed { + logic q; + logic qe; + } schmitt_en; + struct packed { + logic q; + logic qe; + } keeper_en; + struct packed { + logic q; + logic qe; + } pull_select; + struct packed { + logic q; + logic qe; + } pull_en; + struct packed { + logic q; + logic qe; + } virtual_od_en; + struct packed { + logic q; + logic qe; + } invert; + } pinmux_reg2hw_dio_pad_attr_mreg_t; + + typedef struct packed { + logic q; + } pinmux_reg2hw_mio_pad_sleep_status_mreg_t; + + typedef struct packed { + logic q; + } pinmux_reg2hw_mio_pad_sleep_en_mreg_t; + + typedef struct packed { + logic [1:0] q; + } pinmux_reg2hw_mio_pad_sleep_mode_mreg_t; + + typedef struct packed { + logic q; + } pinmux_reg2hw_dio_pad_sleep_status_mreg_t; + + typedef struct packed { + logic q; + } pinmux_reg2hw_dio_pad_sleep_en_mreg_t; + + typedef struct packed { + logic [1:0] q; + } pinmux_reg2hw_dio_pad_sleep_mode_mreg_t; + + typedef struct packed { + logic q; + } pinmux_reg2hw_wkup_detector_en_mreg_t; + + typedef struct packed { + struct packed { + logic q; + } miodio; + struct packed { + logic q; + } filter; + struct packed { + logic [2:0] q; + } mode; + } pinmux_reg2hw_wkup_detector_mreg_t; + + typedef struct packed { + logic [7:0] q; + } pinmux_reg2hw_wkup_detector_cnt_th_mreg_t; + + typedef struct packed { + logic [5:0] q; + } pinmux_reg2hw_wkup_detector_padsel_mreg_t; + + typedef struct packed { + logic q; + } pinmux_reg2hw_wkup_cause_mreg_t; + + typedef struct packed { + struct packed { + logic d; + } invert; + struct packed { + logic d; + } virtual_od_en; + struct packed { + logic d; + } pull_en; + struct packed { + logic d; + } pull_select; + struct packed { + logic d; + } keeper_en; + struct packed { + logic d; + } schmitt_en; + struct packed { + logic d; + } od_en; + struct packed { + logic d; + } input_disable; + struct packed { + logic [1:0] d; + } slew_rate; + struct packed { + logic [3:0] d; + } drive_strength; + } pinmux_hw2reg_mio_pad_attr_mreg_t; + + typedef struct packed { + struct packed { + logic d; + } invert; + struct packed { + logic d; + } virtual_od_en; + struct packed { + logic d; + } pull_en; + struct packed { + logic d; + } pull_select; + struct packed { + logic d; + } keeper_en; + struct packed { + logic d; + } schmitt_en; + struct packed { + logic d; + } od_en; + struct packed { + logic d; + } input_disable; + struct packed { + logic [1:0] d; + } slew_rate; + struct packed { + logic [3:0] d; + } drive_strength; + } pinmux_hw2reg_dio_pad_attr_mreg_t; + + typedef struct packed { + logic d; + logic de; + } pinmux_hw2reg_mio_pad_sleep_status_mreg_t; + + typedef struct packed { + logic d; + logic de; + } pinmux_hw2reg_dio_pad_sleep_status_mreg_t; + + typedef struct packed { + logic d; + logic de; + } pinmux_hw2reg_wkup_cause_mreg_t; + + // Register -> HW type + typedef struct packed { + pinmux_reg2hw_alert_test_reg_t alert_test; // [2387:2386] + pinmux_reg2hw_mio_periph_insel_mreg_t [37:0] mio_periph_insel; // [2385:2158] + pinmux_reg2hw_mio_outsel_mreg_t [46:0] mio_outsel; // [2157:1876] + pinmux_reg2hw_mio_pad_attr_mreg_t [46:0] mio_pad_attr; // [1875:748] + pinmux_reg2hw_dio_pad_attr_mreg_t [13:0] dio_pad_attr; // [747:412] + pinmux_reg2hw_mio_pad_sleep_status_mreg_t [46:0] mio_pad_sleep_status; // [411:365] + pinmux_reg2hw_mio_pad_sleep_en_mreg_t [46:0] mio_pad_sleep_en; // [364:318] + pinmux_reg2hw_mio_pad_sleep_mode_mreg_t [46:0] mio_pad_sleep_mode; // [317:224] + pinmux_reg2hw_dio_pad_sleep_status_mreg_t [13:0] dio_pad_sleep_status; // [223:210] + pinmux_reg2hw_dio_pad_sleep_en_mreg_t [13:0] dio_pad_sleep_en; // [209:196] + pinmux_reg2hw_dio_pad_sleep_mode_mreg_t [13:0] dio_pad_sleep_mode; // [195:168] + pinmux_reg2hw_wkup_detector_en_mreg_t [7:0] wkup_detector_en; // [167:160] + pinmux_reg2hw_wkup_detector_mreg_t [7:0] wkup_detector; // [159:120] + pinmux_reg2hw_wkup_detector_cnt_th_mreg_t [7:0] wkup_detector_cnt_th; // [119:56] + pinmux_reg2hw_wkup_detector_padsel_mreg_t [7:0] wkup_detector_padsel; // [55:8] + pinmux_reg2hw_wkup_cause_mreg_t [7:0] wkup_cause; // [7:0] + } pinmux_reg2hw_t; + + // HW -> register type + typedef struct packed { + pinmux_hw2reg_mio_pad_attr_mreg_t [46:0] mio_pad_attr; // [991:334] + pinmux_hw2reg_dio_pad_attr_mreg_t [13:0] dio_pad_attr; // [333:138] + pinmux_hw2reg_mio_pad_sleep_status_mreg_t [46:0] mio_pad_sleep_status; // [137:44] + pinmux_hw2reg_dio_pad_sleep_status_mreg_t [13:0] dio_pad_sleep_status; // [43:16] + pinmux_hw2reg_wkup_cause_mreg_t [7:0] wkup_cause; // [15:0] + } pinmux_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] PINMUX_ALERT_TEST_OFFSET = 12'h 0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_0_OFFSET = 12'h 4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_1_OFFSET = 12'h 8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_2_OFFSET = 12'h c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_3_OFFSET = 12'h 10; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_4_OFFSET = 12'h 14; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_5_OFFSET = 12'h 18; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_6_OFFSET = 12'h 1c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_7_OFFSET = 12'h 20; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_8_OFFSET = 12'h 24; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_9_OFFSET = 12'h 28; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_10_OFFSET = 12'h 2c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_11_OFFSET = 12'h 30; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_12_OFFSET = 12'h 34; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_13_OFFSET = 12'h 38; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_14_OFFSET = 12'h 3c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_15_OFFSET = 12'h 40; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_16_OFFSET = 12'h 44; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_17_OFFSET = 12'h 48; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_18_OFFSET = 12'h 4c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_19_OFFSET = 12'h 50; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_20_OFFSET = 12'h 54; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_21_OFFSET = 12'h 58; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_22_OFFSET = 12'h 5c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_23_OFFSET = 12'h 60; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_24_OFFSET = 12'h 64; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_25_OFFSET = 12'h 68; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_26_OFFSET = 12'h 6c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_27_OFFSET = 12'h 70; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_28_OFFSET = 12'h 74; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_29_OFFSET = 12'h 78; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_30_OFFSET = 12'h 7c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_31_OFFSET = 12'h 80; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_32_OFFSET = 12'h 84; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_33_OFFSET = 12'h 88; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_34_OFFSET = 12'h 8c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_35_OFFSET = 12'h 90; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_36_OFFSET = 12'h 94; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_REGWEN_37_OFFSET = 12'h 98; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_0_OFFSET = 12'h 9c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_1_OFFSET = 12'h a0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_2_OFFSET = 12'h a4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_3_OFFSET = 12'h a8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_4_OFFSET = 12'h ac; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_5_OFFSET = 12'h b0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_6_OFFSET = 12'h b4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_7_OFFSET = 12'h b8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_8_OFFSET = 12'h bc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_9_OFFSET = 12'h c0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_10_OFFSET = 12'h c4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_11_OFFSET = 12'h c8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_12_OFFSET = 12'h cc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_13_OFFSET = 12'h d0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_14_OFFSET = 12'h d4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_15_OFFSET = 12'h d8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_16_OFFSET = 12'h dc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_17_OFFSET = 12'h e0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_18_OFFSET = 12'h e4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_19_OFFSET = 12'h e8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_20_OFFSET = 12'h ec; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_21_OFFSET = 12'h f0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_22_OFFSET = 12'h f4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_23_OFFSET = 12'h f8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_24_OFFSET = 12'h fc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_25_OFFSET = 12'h 100; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_26_OFFSET = 12'h 104; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_27_OFFSET = 12'h 108; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_28_OFFSET = 12'h 10c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_29_OFFSET = 12'h 110; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_30_OFFSET = 12'h 114; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_31_OFFSET = 12'h 118; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_32_OFFSET = 12'h 11c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_33_OFFSET = 12'h 120; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_34_OFFSET = 12'h 124; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_35_OFFSET = 12'h 128; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_36_OFFSET = 12'h 12c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PERIPH_INSEL_37_OFFSET = 12'h 130; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_0_OFFSET = 12'h 134; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_1_OFFSET = 12'h 138; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_2_OFFSET = 12'h 13c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_3_OFFSET = 12'h 140; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_4_OFFSET = 12'h 144; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_5_OFFSET = 12'h 148; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_6_OFFSET = 12'h 14c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_7_OFFSET = 12'h 150; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_8_OFFSET = 12'h 154; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_9_OFFSET = 12'h 158; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_10_OFFSET = 12'h 15c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_11_OFFSET = 12'h 160; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_12_OFFSET = 12'h 164; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_13_OFFSET = 12'h 168; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_14_OFFSET = 12'h 16c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_15_OFFSET = 12'h 170; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_16_OFFSET = 12'h 174; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_17_OFFSET = 12'h 178; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_18_OFFSET = 12'h 17c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_19_OFFSET = 12'h 180; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_20_OFFSET = 12'h 184; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_21_OFFSET = 12'h 188; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_22_OFFSET = 12'h 18c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_23_OFFSET = 12'h 190; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_24_OFFSET = 12'h 194; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_25_OFFSET = 12'h 198; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_26_OFFSET = 12'h 19c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_27_OFFSET = 12'h 1a0; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_28_OFFSET = 12'h 1a4; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_29_OFFSET = 12'h 1a8; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_30_OFFSET = 12'h 1ac; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_31_OFFSET = 12'h 1b0; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_32_OFFSET = 12'h 1b4; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_33_OFFSET = 12'h 1b8; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_34_OFFSET = 12'h 1bc; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_35_OFFSET = 12'h 1c0; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_36_OFFSET = 12'h 1c4; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_37_OFFSET = 12'h 1c8; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_38_OFFSET = 12'h 1cc; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_39_OFFSET = 12'h 1d0; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_40_OFFSET = 12'h 1d4; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_41_OFFSET = 12'h 1d8; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_42_OFFSET = 12'h 1dc; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_43_OFFSET = 12'h 1e0; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_44_OFFSET = 12'h 1e4; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_45_OFFSET = 12'h 1e8; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_REGWEN_46_OFFSET = 12'h 1ec; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_0_OFFSET = 12'h 1f0; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_1_OFFSET = 12'h 1f4; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_2_OFFSET = 12'h 1f8; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_3_OFFSET = 12'h 1fc; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_4_OFFSET = 12'h 200; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_5_OFFSET = 12'h 204; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_6_OFFSET = 12'h 208; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_7_OFFSET = 12'h 20c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_8_OFFSET = 12'h 210; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_9_OFFSET = 12'h 214; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_10_OFFSET = 12'h 218; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_11_OFFSET = 12'h 21c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_12_OFFSET = 12'h 220; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_13_OFFSET = 12'h 224; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_14_OFFSET = 12'h 228; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_15_OFFSET = 12'h 22c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_16_OFFSET = 12'h 230; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_17_OFFSET = 12'h 234; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_18_OFFSET = 12'h 238; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_19_OFFSET = 12'h 23c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_20_OFFSET = 12'h 240; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_21_OFFSET = 12'h 244; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_22_OFFSET = 12'h 248; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_23_OFFSET = 12'h 24c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_24_OFFSET = 12'h 250; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_25_OFFSET = 12'h 254; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_26_OFFSET = 12'h 258; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_27_OFFSET = 12'h 25c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_28_OFFSET = 12'h 260; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_29_OFFSET = 12'h 264; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_30_OFFSET = 12'h 268; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_31_OFFSET = 12'h 26c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_32_OFFSET = 12'h 270; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_33_OFFSET = 12'h 274; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_34_OFFSET = 12'h 278; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_35_OFFSET = 12'h 27c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_36_OFFSET = 12'h 280; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_37_OFFSET = 12'h 284; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_38_OFFSET = 12'h 288; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_39_OFFSET = 12'h 28c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_40_OFFSET = 12'h 290; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_41_OFFSET = 12'h 294; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_42_OFFSET = 12'h 298; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_43_OFFSET = 12'h 29c; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_44_OFFSET = 12'h 2a0; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_45_OFFSET = 12'h 2a4; + parameter logic [BlockAw-1:0] PINMUX_MIO_OUTSEL_46_OFFSET = 12'h 2a8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_0_OFFSET = 12'h 2ac; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_1_OFFSET = 12'h 2b0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_2_OFFSET = 12'h 2b4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_3_OFFSET = 12'h 2b8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_4_OFFSET = 12'h 2bc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_5_OFFSET = 12'h 2c0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_6_OFFSET = 12'h 2c4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_7_OFFSET = 12'h 2c8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_8_OFFSET = 12'h 2cc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_9_OFFSET = 12'h 2d0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_10_OFFSET = 12'h 2d4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_11_OFFSET = 12'h 2d8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_12_OFFSET = 12'h 2dc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_13_OFFSET = 12'h 2e0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_14_OFFSET = 12'h 2e4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_15_OFFSET = 12'h 2e8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_16_OFFSET = 12'h 2ec; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_17_OFFSET = 12'h 2f0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_18_OFFSET = 12'h 2f4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_19_OFFSET = 12'h 2f8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_20_OFFSET = 12'h 2fc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_21_OFFSET = 12'h 300; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_22_OFFSET = 12'h 304; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_23_OFFSET = 12'h 308; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_24_OFFSET = 12'h 30c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_25_OFFSET = 12'h 310; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_26_OFFSET = 12'h 314; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_27_OFFSET = 12'h 318; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_28_OFFSET = 12'h 31c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_29_OFFSET = 12'h 320; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_30_OFFSET = 12'h 324; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_31_OFFSET = 12'h 328; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_32_OFFSET = 12'h 32c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_33_OFFSET = 12'h 330; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_34_OFFSET = 12'h 334; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_35_OFFSET = 12'h 338; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_36_OFFSET = 12'h 33c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_37_OFFSET = 12'h 340; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_38_OFFSET = 12'h 344; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_39_OFFSET = 12'h 348; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_40_OFFSET = 12'h 34c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_41_OFFSET = 12'h 350; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_42_OFFSET = 12'h 354; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_43_OFFSET = 12'h 358; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_44_OFFSET = 12'h 35c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_45_OFFSET = 12'h 360; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_REGWEN_46_OFFSET = 12'h 364; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_0_OFFSET = 12'h 368; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_1_OFFSET = 12'h 36c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_2_OFFSET = 12'h 370; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_3_OFFSET = 12'h 374; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_4_OFFSET = 12'h 378; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_5_OFFSET = 12'h 37c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_6_OFFSET = 12'h 380; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_7_OFFSET = 12'h 384; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_8_OFFSET = 12'h 388; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_9_OFFSET = 12'h 38c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_10_OFFSET = 12'h 390; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_11_OFFSET = 12'h 394; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_12_OFFSET = 12'h 398; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_13_OFFSET = 12'h 39c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_14_OFFSET = 12'h 3a0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_15_OFFSET = 12'h 3a4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_16_OFFSET = 12'h 3a8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_17_OFFSET = 12'h 3ac; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_18_OFFSET = 12'h 3b0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_19_OFFSET = 12'h 3b4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_20_OFFSET = 12'h 3b8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_21_OFFSET = 12'h 3bc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_22_OFFSET = 12'h 3c0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_23_OFFSET = 12'h 3c4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_24_OFFSET = 12'h 3c8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_25_OFFSET = 12'h 3cc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_26_OFFSET = 12'h 3d0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_27_OFFSET = 12'h 3d4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_28_OFFSET = 12'h 3d8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_29_OFFSET = 12'h 3dc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_30_OFFSET = 12'h 3e0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_31_OFFSET = 12'h 3e4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_32_OFFSET = 12'h 3e8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_33_OFFSET = 12'h 3ec; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_34_OFFSET = 12'h 3f0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_35_OFFSET = 12'h 3f4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_36_OFFSET = 12'h 3f8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_37_OFFSET = 12'h 3fc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_38_OFFSET = 12'h 400; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_39_OFFSET = 12'h 404; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_40_OFFSET = 12'h 408; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_41_OFFSET = 12'h 40c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_42_OFFSET = 12'h 410; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_43_OFFSET = 12'h 414; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_44_OFFSET = 12'h 418; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_45_OFFSET = 12'h 41c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_ATTR_46_OFFSET = 12'h 420; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_0_OFFSET = 12'h 424; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_1_OFFSET = 12'h 428; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_2_OFFSET = 12'h 42c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_3_OFFSET = 12'h 430; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_4_OFFSET = 12'h 434; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_5_OFFSET = 12'h 438; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_6_OFFSET = 12'h 43c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_7_OFFSET = 12'h 440; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_8_OFFSET = 12'h 444; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_9_OFFSET = 12'h 448; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_10_OFFSET = 12'h 44c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_11_OFFSET = 12'h 450; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_12_OFFSET = 12'h 454; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_REGWEN_13_OFFSET = 12'h 458; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_0_OFFSET = 12'h 45c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_1_OFFSET = 12'h 460; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_2_OFFSET = 12'h 464; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_3_OFFSET = 12'h 468; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_4_OFFSET = 12'h 46c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_5_OFFSET = 12'h 470; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_6_OFFSET = 12'h 474; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_7_OFFSET = 12'h 478; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_8_OFFSET = 12'h 47c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_9_OFFSET = 12'h 480; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_10_OFFSET = 12'h 484; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_11_OFFSET = 12'h 488; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_12_OFFSET = 12'h 48c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_ATTR_13_OFFSET = 12'h 490; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_STATUS_0_OFFSET = 12'h 494; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_STATUS_1_OFFSET = 12'h 498; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_0_OFFSET = 12'h 49c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_1_OFFSET = 12'h 4a0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_2_OFFSET = 12'h 4a4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_3_OFFSET = 12'h 4a8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_4_OFFSET = 12'h 4ac; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_5_OFFSET = 12'h 4b0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_6_OFFSET = 12'h 4b4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_7_OFFSET = 12'h 4b8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_8_OFFSET = 12'h 4bc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_9_OFFSET = 12'h 4c0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_10_OFFSET = 12'h 4c4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_11_OFFSET = 12'h 4c8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_12_OFFSET = 12'h 4cc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_13_OFFSET = 12'h 4d0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_14_OFFSET = 12'h 4d4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_15_OFFSET = 12'h 4d8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_16_OFFSET = 12'h 4dc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_17_OFFSET = 12'h 4e0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_18_OFFSET = 12'h 4e4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_19_OFFSET = 12'h 4e8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_20_OFFSET = 12'h 4ec; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_21_OFFSET = 12'h 4f0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_22_OFFSET = 12'h 4f4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_23_OFFSET = 12'h 4f8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_24_OFFSET = 12'h 4fc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_25_OFFSET = 12'h 500; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_26_OFFSET = 12'h 504; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_27_OFFSET = 12'h 508; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_28_OFFSET = 12'h 50c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_29_OFFSET = 12'h 510; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_30_OFFSET = 12'h 514; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_31_OFFSET = 12'h 518; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_32_OFFSET = 12'h 51c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_33_OFFSET = 12'h 520; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_34_OFFSET = 12'h 524; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_35_OFFSET = 12'h 528; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_36_OFFSET = 12'h 52c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_37_OFFSET = 12'h 530; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_38_OFFSET = 12'h 534; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_39_OFFSET = 12'h 538; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_40_OFFSET = 12'h 53c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_41_OFFSET = 12'h 540; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_42_OFFSET = 12'h 544; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_43_OFFSET = 12'h 548; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_44_OFFSET = 12'h 54c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_45_OFFSET = 12'h 550; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_REGWEN_46_OFFSET = 12'h 554; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_0_OFFSET = 12'h 558; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_1_OFFSET = 12'h 55c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_2_OFFSET = 12'h 560; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_3_OFFSET = 12'h 564; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_4_OFFSET = 12'h 568; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_5_OFFSET = 12'h 56c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_6_OFFSET = 12'h 570; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_7_OFFSET = 12'h 574; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_8_OFFSET = 12'h 578; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_9_OFFSET = 12'h 57c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_10_OFFSET = 12'h 580; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_11_OFFSET = 12'h 584; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_12_OFFSET = 12'h 588; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_13_OFFSET = 12'h 58c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_14_OFFSET = 12'h 590; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_15_OFFSET = 12'h 594; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_16_OFFSET = 12'h 598; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_17_OFFSET = 12'h 59c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_18_OFFSET = 12'h 5a0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_19_OFFSET = 12'h 5a4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_20_OFFSET = 12'h 5a8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_21_OFFSET = 12'h 5ac; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_22_OFFSET = 12'h 5b0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_23_OFFSET = 12'h 5b4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_24_OFFSET = 12'h 5b8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_25_OFFSET = 12'h 5bc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_26_OFFSET = 12'h 5c0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_27_OFFSET = 12'h 5c4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_28_OFFSET = 12'h 5c8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_29_OFFSET = 12'h 5cc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_30_OFFSET = 12'h 5d0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_31_OFFSET = 12'h 5d4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_32_OFFSET = 12'h 5d8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_33_OFFSET = 12'h 5dc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_34_OFFSET = 12'h 5e0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_35_OFFSET = 12'h 5e4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_36_OFFSET = 12'h 5e8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_37_OFFSET = 12'h 5ec; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_38_OFFSET = 12'h 5f0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_39_OFFSET = 12'h 5f4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_40_OFFSET = 12'h 5f8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_41_OFFSET = 12'h 5fc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_42_OFFSET = 12'h 600; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_43_OFFSET = 12'h 604; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_44_OFFSET = 12'h 608; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_45_OFFSET = 12'h 60c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_EN_46_OFFSET = 12'h 610; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_0_OFFSET = 12'h 614; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_1_OFFSET = 12'h 618; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_2_OFFSET = 12'h 61c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_3_OFFSET = 12'h 620; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_4_OFFSET = 12'h 624; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_5_OFFSET = 12'h 628; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_6_OFFSET = 12'h 62c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_7_OFFSET = 12'h 630; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_8_OFFSET = 12'h 634; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_9_OFFSET = 12'h 638; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_10_OFFSET = 12'h 63c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_11_OFFSET = 12'h 640; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_12_OFFSET = 12'h 644; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_13_OFFSET = 12'h 648; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_14_OFFSET = 12'h 64c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_15_OFFSET = 12'h 650; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_16_OFFSET = 12'h 654; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_17_OFFSET = 12'h 658; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_18_OFFSET = 12'h 65c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_19_OFFSET = 12'h 660; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_20_OFFSET = 12'h 664; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_21_OFFSET = 12'h 668; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_22_OFFSET = 12'h 66c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_23_OFFSET = 12'h 670; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_24_OFFSET = 12'h 674; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_25_OFFSET = 12'h 678; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_26_OFFSET = 12'h 67c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_27_OFFSET = 12'h 680; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_28_OFFSET = 12'h 684; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_29_OFFSET = 12'h 688; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_30_OFFSET = 12'h 68c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_31_OFFSET = 12'h 690; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_32_OFFSET = 12'h 694; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_33_OFFSET = 12'h 698; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_34_OFFSET = 12'h 69c; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_35_OFFSET = 12'h 6a0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_36_OFFSET = 12'h 6a4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_37_OFFSET = 12'h 6a8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_38_OFFSET = 12'h 6ac; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_39_OFFSET = 12'h 6b0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_40_OFFSET = 12'h 6b4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_41_OFFSET = 12'h 6b8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_42_OFFSET = 12'h 6bc; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_43_OFFSET = 12'h 6c0; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_44_OFFSET = 12'h 6c4; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_45_OFFSET = 12'h 6c8; + parameter logic [BlockAw-1:0] PINMUX_MIO_PAD_SLEEP_MODE_46_OFFSET = 12'h 6cc; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_STATUS_OFFSET = 12'h 6d0; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_0_OFFSET = 12'h 6d4; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_1_OFFSET = 12'h 6d8; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_2_OFFSET = 12'h 6dc; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_3_OFFSET = 12'h 6e0; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_4_OFFSET = 12'h 6e4; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_5_OFFSET = 12'h 6e8; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_6_OFFSET = 12'h 6ec; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_7_OFFSET = 12'h 6f0; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_8_OFFSET = 12'h 6f4; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_9_OFFSET = 12'h 6f8; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_10_OFFSET = 12'h 6fc; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_11_OFFSET = 12'h 700; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_12_OFFSET = 12'h 704; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_REGWEN_13_OFFSET = 12'h 708; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_0_OFFSET = 12'h 70c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_1_OFFSET = 12'h 710; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_2_OFFSET = 12'h 714; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_3_OFFSET = 12'h 718; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_4_OFFSET = 12'h 71c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_5_OFFSET = 12'h 720; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_6_OFFSET = 12'h 724; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_7_OFFSET = 12'h 728; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_8_OFFSET = 12'h 72c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_9_OFFSET = 12'h 730; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_10_OFFSET = 12'h 734; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_11_OFFSET = 12'h 738; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_12_OFFSET = 12'h 73c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_EN_13_OFFSET = 12'h 740; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_0_OFFSET = 12'h 744; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_1_OFFSET = 12'h 748; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_2_OFFSET = 12'h 74c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_3_OFFSET = 12'h 750; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_4_OFFSET = 12'h 754; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_5_OFFSET = 12'h 758; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_6_OFFSET = 12'h 75c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_7_OFFSET = 12'h 760; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_8_OFFSET = 12'h 764; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_9_OFFSET = 12'h 768; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_10_OFFSET = 12'h 76c; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_11_OFFSET = 12'h 770; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_12_OFFSET = 12'h 774; + parameter logic [BlockAw-1:0] PINMUX_DIO_PAD_SLEEP_MODE_13_OFFSET = 12'h 778; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_0_OFFSET = 12'h 77c; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_1_OFFSET = 12'h 780; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_2_OFFSET = 12'h 784; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_3_OFFSET = 12'h 788; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_4_OFFSET = 12'h 78c; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_5_OFFSET = 12'h 790; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_6_OFFSET = 12'h 794; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_REGWEN_7_OFFSET = 12'h 798; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_0_OFFSET = 12'h 79c; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_1_OFFSET = 12'h 7a0; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_2_OFFSET = 12'h 7a4; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_3_OFFSET = 12'h 7a8; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_4_OFFSET = 12'h 7ac; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_5_OFFSET = 12'h 7b0; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_6_OFFSET = 12'h 7b4; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_EN_7_OFFSET = 12'h 7b8; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_0_OFFSET = 12'h 7bc; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_1_OFFSET = 12'h 7c0; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_2_OFFSET = 12'h 7c4; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_3_OFFSET = 12'h 7c8; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_4_OFFSET = 12'h 7cc; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_5_OFFSET = 12'h 7d0; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_6_OFFSET = 12'h 7d4; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_7_OFFSET = 12'h 7d8; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_0_OFFSET = 12'h 7dc; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_1_OFFSET = 12'h 7e0; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_2_OFFSET = 12'h 7e4; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_3_OFFSET = 12'h 7e8; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_4_OFFSET = 12'h 7ec; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_5_OFFSET = 12'h 7f0; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_6_OFFSET = 12'h 7f4; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_CNT_TH_7_OFFSET = 12'h 7f8; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_0_OFFSET = 12'h 7fc; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_1_OFFSET = 12'h 800; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_2_OFFSET = 12'h 804; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_3_OFFSET = 12'h 808; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_4_OFFSET = 12'h 80c; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_5_OFFSET = 12'h 810; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_6_OFFSET = 12'h 814; + parameter logic [BlockAw-1:0] PINMUX_WKUP_DETECTOR_PADSEL_7_OFFSET = 12'h 818; + parameter logic [BlockAw-1:0] PINMUX_WKUP_CAUSE_OFFSET = 12'h 81c; + + // Reset values for hwext registers and their fields + parameter logic [0:0] PINMUX_ALERT_TEST_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_0_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_INVERT_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_VIRTUAL_OD_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_PULL_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_PULL_SELECT_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_KEEPER_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_SCHMITT_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_OD_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_0_INPUT_DISABLE_0_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_0_SLEW_RATE_0_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_0_DRIVE_STRENGTH_0_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_1_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_INVERT_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_VIRTUAL_OD_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_PULL_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_PULL_SELECT_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_KEEPER_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_SCHMITT_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_OD_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_1_INPUT_DISABLE_1_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_1_SLEW_RATE_1_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_1_DRIVE_STRENGTH_1_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_2_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_INVERT_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_VIRTUAL_OD_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_PULL_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_PULL_SELECT_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_KEEPER_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_SCHMITT_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_OD_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_2_INPUT_DISABLE_2_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_2_SLEW_RATE_2_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_2_DRIVE_STRENGTH_2_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_3_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_INVERT_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_VIRTUAL_OD_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_PULL_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_PULL_SELECT_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_KEEPER_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_SCHMITT_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_OD_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_3_INPUT_DISABLE_3_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_3_SLEW_RATE_3_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_3_DRIVE_STRENGTH_3_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_4_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_INVERT_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_VIRTUAL_OD_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_PULL_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_PULL_SELECT_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_KEEPER_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_SCHMITT_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_OD_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_4_INPUT_DISABLE_4_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_4_SLEW_RATE_4_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_4_DRIVE_STRENGTH_4_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_5_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_INVERT_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_VIRTUAL_OD_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_PULL_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_PULL_SELECT_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_KEEPER_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_SCHMITT_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_OD_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_5_INPUT_DISABLE_5_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_5_SLEW_RATE_5_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_5_DRIVE_STRENGTH_5_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_6_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_INVERT_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_VIRTUAL_OD_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_PULL_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_PULL_SELECT_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_KEEPER_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_SCHMITT_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_OD_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_6_INPUT_DISABLE_6_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_6_SLEW_RATE_6_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_6_DRIVE_STRENGTH_6_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_7_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_INVERT_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_VIRTUAL_OD_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_PULL_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_PULL_SELECT_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_KEEPER_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_SCHMITT_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_OD_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_7_INPUT_DISABLE_7_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_7_SLEW_RATE_7_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_7_DRIVE_STRENGTH_7_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_8_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_INVERT_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_VIRTUAL_OD_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_PULL_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_PULL_SELECT_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_KEEPER_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_SCHMITT_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_OD_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_8_INPUT_DISABLE_8_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_8_SLEW_RATE_8_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_8_DRIVE_STRENGTH_8_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_9_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_INVERT_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_VIRTUAL_OD_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_PULL_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_PULL_SELECT_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_KEEPER_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_SCHMITT_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_OD_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_9_INPUT_DISABLE_9_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_9_SLEW_RATE_9_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_9_DRIVE_STRENGTH_9_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_10_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_INVERT_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_VIRTUAL_OD_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_PULL_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_PULL_SELECT_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_KEEPER_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_SCHMITT_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_OD_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_10_INPUT_DISABLE_10_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_10_SLEW_RATE_10_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_10_DRIVE_STRENGTH_10_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_11_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_INVERT_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_VIRTUAL_OD_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_PULL_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_PULL_SELECT_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_KEEPER_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_SCHMITT_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_OD_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_11_INPUT_DISABLE_11_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_11_SLEW_RATE_11_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_11_DRIVE_STRENGTH_11_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_12_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_INVERT_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_VIRTUAL_OD_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_PULL_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_PULL_SELECT_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_KEEPER_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_SCHMITT_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_OD_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_12_INPUT_DISABLE_12_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_12_SLEW_RATE_12_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_12_DRIVE_STRENGTH_12_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_13_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_INVERT_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_VIRTUAL_OD_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_PULL_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_PULL_SELECT_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_KEEPER_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_SCHMITT_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_OD_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_13_INPUT_DISABLE_13_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_13_SLEW_RATE_13_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_13_DRIVE_STRENGTH_13_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_14_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_INVERT_14_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_VIRTUAL_OD_EN_14_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_PULL_EN_14_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_PULL_SELECT_14_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_KEEPER_EN_14_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_SCHMITT_EN_14_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_OD_EN_14_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_14_INPUT_DISABLE_14_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_14_SLEW_RATE_14_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_14_DRIVE_STRENGTH_14_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_15_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_INVERT_15_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_VIRTUAL_OD_EN_15_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_PULL_EN_15_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_PULL_SELECT_15_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_KEEPER_EN_15_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_SCHMITT_EN_15_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_OD_EN_15_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_15_INPUT_DISABLE_15_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_15_SLEW_RATE_15_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_15_DRIVE_STRENGTH_15_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_16_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_INVERT_16_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_VIRTUAL_OD_EN_16_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_PULL_EN_16_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_PULL_SELECT_16_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_KEEPER_EN_16_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_SCHMITT_EN_16_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_OD_EN_16_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_16_INPUT_DISABLE_16_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_16_SLEW_RATE_16_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_16_DRIVE_STRENGTH_16_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_17_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_INVERT_17_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_VIRTUAL_OD_EN_17_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_PULL_EN_17_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_PULL_SELECT_17_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_KEEPER_EN_17_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_SCHMITT_EN_17_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_OD_EN_17_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_17_INPUT_DISABLE_17_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_17_SLEW_RATE_17_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_17_DRIVE_STRENGTH_17_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_18_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_INVERT_18_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_VIRTUAL_OD_EN_18_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_PULL_EN_18_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_PULL_SELECT_18_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_KEEPER_EN_18_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_SCHMITT_EN_18_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_OD_EN_18_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_18_INPUT_DISABLE_18_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_18_SLEW_RATE_18_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_18_DRIVE_STRENGTH_18_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_19_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_INVERT_19_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_VIRTUAL_OD_EN_19_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_PULL_EN_19_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_PULL_SELECT_19_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_KEEPER_EN_19_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_SCHMITT_EN_19_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_OD_EN_19_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_19_INPUT_DISABLE_19_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_19_SLEW_RATE_19_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_19_DRIVE_STRENGTH_19_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_20_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_INVERT_20_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_VIRTUAL_OD_EN_20_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_PULL_EN_20_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_PULL_SELECT_20_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_KEEPER_EN_20_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_SCHMITT_EN_20_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_OD_EN_20_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_20_INPUT_DISABLE_20_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_20_SLEW_RATE_20_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_20_DRIVE_STRENGTH_20_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_21_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_INVERT_21_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_VIRTUAL_OD_EN_21_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_PULL_EN_21_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_PULL_SELECT_21_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_KEEPER_EN_21_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_SCHMITT_EN_21_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_OD_EN_21_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_21_INPUT_DISABLE_21_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_21_SLEW_RATE_21_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_21_DRIVE_STRENGTH_21_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_22_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_INVERT_22_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_VIRTUAL_OD_EN_22_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_PULL_EN_22_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_PULL_SELECT_22_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_KEEPER_EN_22_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_SCHMITT_EN_22_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_OD_EN_22_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_22_INPUT_DISABLE_22_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_22_SLEW_RATE_22_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_22_DRIVE_STRENGTH_22_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_23_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_INVERT_23_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_VIRTUAL_OD_EN_23_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_PULL_EN_23_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_PULL_SELECT_23_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_KEEPER_EN_23_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_SCHMITT_EN_23_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_OD_EN_23_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_23_INPUT_DISABLE_23_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_23_SLEW_RATE_23_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_23_DRIVE_STRENGTH_23_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_24_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_INVERT_24_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_VIRTUAL_OD_EN_24_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_PULL_EN_24_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_PULL_SELECT_24_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_KEEPER_EN_24_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_SCHMITT_EN_24_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_OD_EN_24_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_24_INPUT_DISABLE_24_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_24_SLEW_RATE_24_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_24_DRIVE_STRENGTH_24_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_25_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_INVERT_25_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_VIRTUAL_OD_EN_25_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_PULL_EN_25_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_PULL_SELECT_25_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_KEEPER_EN_25_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_SCHMITT_EN_25_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_OD_EN_25_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_25_INPUT_DISABLE_25_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_25_SLEW_RATE_25_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_25_DRIVE_STRENGTH_25_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_26_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_INVERT_26_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_VIRTUAL_OD_EN_26_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_PULL_EN_26_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_PULL_SELECT_26_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_KEEPER_EN_26_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_SCHMITT_EN_26_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_OD_EN_26_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_26_INPUT_DISABLE_26_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_26_SLEW_RATE_26_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_26_DRIVE_STRENGTH_26_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_27_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_INVERT_27_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_VIRTUAL_OD_EN_27_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_PULL_EN_27_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_PULL_SELECT_27_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_KEEPER_EN_27_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_SCHMITT_EN_27_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_OD_EN_27_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_27_INPUT_DISABLE_27_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_27_SLEW_RATE_27_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_27_DRIVE_STRENGTH_27_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_28_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_INVERT_28_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_VIRTUAL_OD_EN_28_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_PULL_EN_28_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_PULL_SELECT_28_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_KEEPER_EN_28_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_SCHMITT_EN_28_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_OD_EN_28_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_28_INPUT_DISABLE_28_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_28_SLEW_RATE_28_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_28_DRIVE_STRENGTH_28_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_29_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_INVERT_29_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_VIRTUAL_OD_EN_29_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_PULL_EN_29_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_PULL_SELECT_29_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_KEEPER_EN_29_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_SCHMITT_EN_29_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_OD_EN_29_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_29_INPUT_DISABLE_29_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_29_SLEW_RATE_29_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_29_DRIVE_STRENGTH_29_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_30_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_INVERT_30_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_VIRTUAL_OD_EN_30_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_PULL_EN_30_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_PULL_SELECT_30_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_KEEPER_EN_30_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_SCHMITT_EN_30_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_OD_EN_30_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_30_INPUT_DISABLE_30_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_30_SLEW_RATE_30_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_30_DRIVE_STRENGTH_30_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_31_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_INVERT_31_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_VIRTUAL_OD_EN_31_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_PULL_EN_31_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_PULL_SELECT_31_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_KEEPER_EN_31_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_SCHMITT_EN_31_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_OD_EN_31_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_31_INPUT_DISABLE_31_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_31_SLEW_RATE_31_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_31_DRIVE_STRENGTH_31_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_32_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_INVERT_32_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_VIRTUAL_OD_EN_32_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_PULL_EN_32_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_PULL_SELECT_32_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_KEEPER_EN_32_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_SCHMITT_EN_32_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_OD_EN_32_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_32_INPUT_DISABLE_32_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_32_SLEW_RATE_32_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_32_DRIVE_STRENGTH_32_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_33_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_INVERT_33_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_VIRTUAL_OD_EN_33_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_PULL_EN_33_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_PULL_SELECT_33_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_KEEPER_EN_33_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_SCHMITT_EN_33_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_OD_EN_33_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_33_INPUT_DISABLE_33_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_33_SLEW_RATE_33_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_33_DRIVE_STRENGTH_33_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_34_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_INVERT_34_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_VIRTUAL_OD_EN_34_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_PULL_EN_34_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_PULL_SELECT_34_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_KEEPER_EN_34_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_SCHMITT_EN_34_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_OD_EN_34_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_34_INPUT_DISABLE_34_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_34_SLEW_RATE_34_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_34_DRIVE_STRENGTH_34_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_35_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_INVERT_35_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_VIRTUAL_OD_EN_35_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_PULL_EN_35_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_PULL_SELECT_35_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_KEEPER_EN_35_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_SCHMITT_EN_35_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_OD_EN_35_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_35_INPUT_DISABLE_35_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_35_SLEW_RATE_35_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_35_DRIVE_STRENGTH_35_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_36_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_INVERT_36_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_VIRTUAL_OD_EN_36_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_PULL_EN_36_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_PULL_SELECT_36_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_KEEPER_EN_36_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_SCHMITT_EN_36_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_OD_EN_36_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_36_INPUT_DISABLE_36_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_36_SLEW_RATE_36_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_36_DRIVE_STRENGTH_36_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_37_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_INVERT_37_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_VIRTUAL_OD_EN_37_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_PULL_EN_37_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_PULL_SELECT_37_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_KEEPER_EN_37_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_SCHMITT_EN_37_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_OD_EN_37_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_37_INPUT_DISABLE_37_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_37_SLEW_RATE_37_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_37_DRIVE_STRENGTH_37_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_38_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_INVERT_38_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_VIRTUAL_OD_EN_38_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_PULL_EN_38_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_PULL_SELECT_38_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_KEEPER_EN_38_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_SCHMITT_EN_38_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_OD_EN_38_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_38_INPUT_DISABLE_38_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_38_SLEW_RATE_38_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_38_DRIVE_STRENGTH_38_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_39_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_INVERT_39_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_VIRTUAL_OD_EN_39_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_PULL_EN_39_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_PULL_SELECT_39_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_KEEPER_EN_39_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_SCHMITT_EN_39_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_OD_EN_39_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_39_INPUT_DISABLE_39_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_39_SLEW_RATE_39_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_39_DRIVE_STRENGTH_39_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_40_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_INVERT_40_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_VIRTUAL_OD_EN_40_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_PULL_EN_40_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_PULL_SELECT_40_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_KEEPER_EN_40_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_SCHMITT_EN_40_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_OD_EN_40_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_40_INPUT_DISABLE_40_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_40_SLEW_RATE_40_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_40_DRIVE_STRENGTH_40_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_41_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_INVERT_41_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_VIRTUAL_OD_EN_41_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_PULL_EN_41_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_PULL_SELECT_41_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_KEEPER_EN_41_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_SCHMITT_EN_41_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_OD_EN_41_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_41_INPUT_DISABLE_41_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_41_SLEW_RATE_41_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_41_DRIVE_STRENGTH_41_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_42_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_INVERT_42_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_VIRTUAL_OD_EN_42_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_PULL_EN_42_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_PULL_SELECT_42_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_KEEPER_EN_42_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_SCHMITT_EN_42_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_OD_EN_42_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_42_INPUT_DISABLE_42_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_42_SLEW_RATE_42_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_42_DRIVE_STRENGTH_42_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_43_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_INVERT_43_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_VIRTUAL_OD_EN_43_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_PULL_EN_43_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_PULL_SELECT_43_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_KEEPER_EN_43_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_SCHMITT_EN_43_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_OD_EN_43_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_43_INPUT_DISABLE_43_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_43_SLEW_RATE_43_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_43_DRIVE_STRENGTH_43_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_44_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_INVERT_44_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_VIRTUAL_OD_EN_44_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_PULL_EN_44_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_PULL_SELECT_44_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_KEEPER_EN_44_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_SCHMITT_EN_44_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_OD_EN_44_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_44_INPUT_DISABLE_44_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_44_SLEW_RATE_44_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_44_DRIVE_STRENGTH_44_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_45_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_INVERT_45_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_VIRTUAL_OD_EN_45_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_PULL_EN_45_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_PULL_SELECT_45_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_KEEPER_EN_45_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_SCHMITT_EN_45_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_OD_EN_45_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_45_INPUT_DISABLE_45_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_45_SLEW_RATE_45_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_45_DRIVE_STRENGTH_45_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_MIO_PAD_ATTR_46_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_INVERT_46_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_VIRTUAL_OD_EN_46_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_PULL_EN_46_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_PULL_SELECT_46_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_KEEPER_EN_46_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_SCHMITT_EN_46_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_OD_EN_46_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_MIO_PAD_ATTR_46_INPUT_DISABLE_46_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_MIO_PAD_ATTR_46_SLEW_RATE_46_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_MIO_PAD_ATTR_46_DRIVE_STRENGTH_46_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_0_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_INVERT_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_VIRTUAL_OD_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_PULL_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_PULL_SELECT_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_KEEPER_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_SCHMITT_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_OD_EN_0_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_0_INPUT_DISABLE_0_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_0_SLEW_RATE_0_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_0_DRIVE_STRENGTH_0_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_1_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_INVERT_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_VIRTUAL_OD_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_PULL_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_PULL_SELECT_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_KEEPER_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_SCHMITT_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_OD_EN_1_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_1_INPUT_DISABLE_1_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_1_SLEW_RATE_1_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_1_DRIVE_STRENGTH_1_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_2_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_INVERT_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_VIRTUAL_OD_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_PULL_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_PULL_SELECT_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_KEEPER_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_SCHMITT_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_OD_EN_2_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_2_INPUT_DISABLE_2_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_2_SLEW_RATE_2_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_2_DRIVE_STRENGTH_2_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_3_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_INVERT_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_VIRTUAL_OD_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_PULL_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_PULL_SELECT_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_KEEPER_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_SCHMITT_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_OD_EN_3_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_3_INPUT_DISABLE_3_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_3_SLEW_RATE_3_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_3_DRIVE_STRENGTH_3_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_4_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_INVERT_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_VIRTUAL_OD_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_PULL_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_PULL_SELECT_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_KEEPER_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_SCHMITT_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_OD_EN_4_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_4_INPUT_DISABLE_4_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_4_SLEW_RATE_4_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_4_DRIVE_STRENGTH_4_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_5_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_INVERT_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_VIRTUAL_OD_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_PULL_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_PULL_SELECT_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_KEEPER_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_SCHMITT_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_OD_EN_5_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_5_INPUT_DISABLE_5_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_5_SLEW_RATE_5_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_5_DRIVE_STRENGTH_5_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_6_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_INVERT_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_VIRTUAL_OD_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_PULL_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_PULL_SELECT_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_KEEPER_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_SCHMITT_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_OD_EN_6_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_6_INPUT_DISABLE_6_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_6_SLEW_RATE_6_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_6_DRIVE_STRENGTH_6_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_7_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_INVERT_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_VIRTUAL_OD_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_PULL_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_PULL_SELECT_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_KEEPER_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_SCHMITT_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_OD_EN_7_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_7_INPUT_DISABLE_7_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_7_SLEW_RATE_7_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_7_DRIVE_STRENGTH_7_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_8_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_INVERT_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_VIRTUAL_OD_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_PULL_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_PULL_SELECT_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_KEEPER_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_SCHMITT_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_OD_EN_8_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_8_INPUT_DISABLE_8_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_8_SLEW_RATE_8_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_8_DRIVE_STRENGTH_8_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_9_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_INVERT_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_VIRTUAL_OD_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_PULL_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_PULL_SELECT_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_KEEPER_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_SCHMITT_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_OD_EN_9_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_9_INPUT_DISABLE_9_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_9_SLEW_RATE_9_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_9_DRIVE_STRENGTH_9_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_10_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_INVERT_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_VIRTUAL_OD_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_PULL_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_PULL_SELECT_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_KEEPER_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_SCHMITT_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_OD_EN_10_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_10_INPUT_DISABLE_10_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_10_SLEW_RATE_10_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_10_DRIVE_STRENGTH_10_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_11_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_INVERT_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_VIRTUAL_OD_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_PULL_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_PULL_SELECT_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_KEEPER_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_SCHMITT_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_OD_EN_11_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_11_INPUT_DISABLE_11_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_11_SLEW_RATE_11_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_11_DRIVE_STRENGTH_11_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_12_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_INVERT_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_VIRTUAL_OD_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_PULL_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_PULL_SELECT_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_KEEPER_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_SCHMITT_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_OD_EN_12_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_12_INPUT_DISABLE_12_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_12_SLEW_RATE_12_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_12_DRIVE_STRENGTH_12_RESVAL = 4'h 0; + parameter logic [23:0] PINMUX_DIO_PAD_ATTR_13_RESVAL = 24'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_INVERT_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_VIRTUAL_OD_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_PULL_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_PULL_SELECT_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_KEEPER_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_SCHMITT_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_OD_EN_13_RESVAL = 1'h 0; + parameter logic [0:0] PINMUX_DIO_PAD_ATTR_13_INPUT_DISABLE_13_RESVAL = 1'h 0; + parameter logic [1:0] PINMUX_DIO_PAD_ATTR_13_SLEW_RATE_13_RESVAL = 2'h 0; + parameter logic [3:0] PINMUX_DIO_PAD_ATTR_13_DRIVE_STRENGTH_13_RESVAL = 4'h 0; + + // Register index + typedef enum int { + PINMUX_ALERT_TEST, + PINMUX_MIO_PERIPH_INSEL_REGWEN_0, + PINMUX_MIO_PERIPH_INSEL_REGWEN_1, + PINMUX_MIO_PERIPH_INSEL_REGWEN_2, + PINMUX_MIO_PERIPH_INSEL_REGWEN_3, + PINMUX_MIO_PERIPH_INSEL_REGWEN_4, + PINMUX_MIO_PERIPH_INSEL_REGWEN_5, + PINMUX_MIO_PERIPH_INSEL_REGWEN_6, + PINMUX_MIO_PERIPH_INSEL_REGWEN_7, + PINMUX_MIO_PERIPH_INSEL_REGWEN_8, + PINMUX_MIO_PERIPH_INSEL_REGWEN_9, + PINMUX_MIO_PERIPH_INSEL_REGWEN_10, + PINMUX_MIO_PERIPH_INSEL_REGWEN_11, + PINMUX_MIO_PERIPH_INSEL_REGWEN_12, + PINMUX_MIO_PERIPH_INSEL_REGWEN_13, + PINMUX_MIO_PERIPH_INSEL_REGWEN_14, + PINMUX_MIO_PERIPH_INSEL_REGWEN_15, + PINMUX_MIO_PERIPH_INSEL_REGWEN_16, + PINMUX_MIO_PERIPH_INSEL_REGWEN_17, + PINMUX_MIO_PERIPH_INSEL_REGWEN_18, + PINMUX_MIO_PERIPH_INSEL_REGWEN_19, + PINMUX_MIO_PERIPH_INSEL_REGWEN_20, + PINMUX_MIO_PERIPH_INSEL_REGWEN_21, + PINMUX_MIO_PERIPH_INSEL_REGWEN_22, + PINMUX_MIO_PERIPH_INSEL_REGWEN_23, + PINMUX_MIO_PERIPH_INSEL_REGWEN_24, + PINMUX_MIO_PERIPH_INSEL_REGWEN_25, + PINMUX_MIO_PERIPH_INSEL_REGWEN_26, + PINMUX_MIO_PERIPH_INSEL_REGWEN_27, + PINMUX_MIO_PERIPH_INSEL_REGWEN_28, + PINMUX_MIO_PERIPH_INSEL_REGWEN_29, + PINMUX_MIO_PERIPH_INSEL_REGWEN_30, + PINMUX_MIO_PERIPH_INSEL_REGWEN_31, + PINMUX_MIO_PERIPH_INSEL_REGWEN_32, + PINMUX_MIO_PERIPH_INSEL_REGWEN_33, + PINMUX_MIO_PERIPH_INSEL_REGWEN_34, + PINMUX_MIO_PERIPH_INSEL_REGWEN_35, + PINMUX_MIO_PERIPH_INSEL_REGWEN_36, + PINMUX_MIO_PERIPH_INSEL_REGWEN_37, + PINMUX_MIO_PERIPH_INSEL_0, + PINMUX_MIO_PERIPH_INSEL_1, + PINMUX_MIO_PERIPH_INSEL_2, + PINMUX_MIO_PERIPH_INSEL_3, + PINMUX_MIO_PERIPH_INSEL_4, + PINMUX_MIO_PERIPH_INSEL_5, + PINMUX_MIO_PERIPH_INSEL_6, + PINMUX_MIO_PERIPH_INSEL_7, + PINMUX_MIO_PERIPH_INSEL_8, + PINMUX_MIO_PERIPH_INSEL_9, + PINMUX_MIO_PERIPH_INSEL_10, + PINMUX_MIO_PERIPH_INSEL_11, + PINMUX_MIO_PERIPH_INSEL_12, + PINMUX_MIO_PERIPH_INSEL_13, + PINMUX_MIO_PERIPH_INSEL_14, + PINMUX_MIO_PERIPH_INSEL_15, + PINMUX_MIO_PERIPH_INSEL_16, + PINMUX_MIO_PERIPH_INSEL_17, + PINMUX_MIO_PERIPH_INSEL_18, + PINMUX_MIO_PERIPH_INSEL_19, + PINMUX_MIO_PERIPH_INSEL_20, + PINMUX_MIO_PERIPH_INSEL_21, + PINMUX_MIO_PERIPH_INSEL_22, + PINMUX_MIO_PERIPH_INSEL_23, + PINMUX_MIO_PERIPH_INSEL_24, + PINMUX_MIO_PERIPH_INSEL_25, + PINMUX_MIO_PERIPH_INSEL_26, + PINMUX_MIO_PERIPH_INSEL_27, + PINMUX_MIO_PERIPH_INSEL_28, + PINMUX_MIO_PERIPH_INSEL_29, + PINMUX_MIO_PERIPH_INSEL_30, + PINMUX_MIO_PERIPH_INSEL_31, + PINMUX_MIO_PERIPH_INSEL_32, + PINMUX_MIO_PERIPH_INSEL_33, + PINMUX_MIO_PERIPH_INSEL_34, + PINMUX_MIO_PERIPH_INSEL_35, + PINMUX_MIO_PERIPH_INSEL_36, + PINMUX_MIO_PERIPH_INSEL_37, + PINMUX_MIO_OUTSEL_REGWEN_0, + PINMUX_MIO_OUTSEL_REGWEN_1, + PINMUX_MIO_OUTSEL_REGWEN_2, + PINMUX_MIO_OUTSEL_REGWEN_3, + PINMUX_MIO_OUTSEL_REGWEN_4, + PINMUX_MIO_OUTSEL_REGWEN_5, + PINMUX_MIO_OUTSEL_REGWEN_6, + PINMUX_MIO_OUTSEL_REGWEN_7, + PINMUX_MIO_OUTSEL_REGWEN_8, + PINMUX_MIO_OUTSEL_REGWEN_9, + PINMUX_MIO_OUTSEL_REGWEN_10, + PINMUX_MIO_OUTSEL_REGWEN_11, + PINMUX_MIO_OUTSEL_REGWEN_12, + PINMUX_MIO_OUTSEL_REGWEN_13, + PINMUX_MIO_OUTSEL_REGWEN_14, + PINMUX_MIO_OUTSEL_REGWEN_15, + PINMUX_MIO_OUTSEL_REGWEN_16, + PINMUX_MIO_OUTSEL_REGWEN_17, + PINMUX_MIO_OUTSEL_REGWEN_18, + PINMUX_MIO_OUTSEL_REGWEN_19, + PINMUX_MIO_OUTSEL_REGWEN_20, + PINMUX_MIO_OUTSEL_REGWEN_21, + PINMUX_MIO_OUTSEL_REGWEN_22, + PINMUX_MIO_OUTSEL_REGWEN_23, + PINMUX_MIO_OUTSEL_REGWEN_24, + PINMUX_MIO_OUTSEL_REGWEN_25, + PINMUX_MIO_OUTSEL_REGWEN_26, + PINMUX_MIO_OUTSEL_REGWEN_27, + PINMUX_MIO_OUTSEL_REGWEN_28, + PINMUX_MIO_OUTSEL_REGWEN_29, + PINMUX_MIO_OUTSEL_REGWEN_30, + PINMUX_MIO_OUTSEL_REGWEN_31, + PINMUX_MIO_OUTSEL_REGWEN_32, + PINMUX_MIO_OUTSEL_REGWEN_33, + PINMUX_MIO_OUTSEL_REGWEN_34, + PINMUX_MIO_OUTSEL_REGWEN_35, + PINMUX_MIO_OUTSEL_REGWEN_36, + PINMUX_MIO_OUTSEL_REGWEN_37, + PINMUX_MIO_OUTSEL_REGWEN_38, + PINMUX_MIO_OUTSEL_REGWEN_39, + PINMUX_MIO_OUTSEL_REGWEN_40, + PINMUX_MIO_OUTSEL_REGWEN_41, + PINMUX_MIO_OUTSEL_REGWEN_42, + PINMUX_MIO_OUTSEL_REGWEN_43, + PINMUX_MIO_OUTSEL_REGWEN_44, + PINMUX_MIO_OUTSEL_REGWEN_45, + PINMUX_MIO_OUTSEL_REGWEN_46, + PINMUX_MIO_OUTSEL_0, + PINMUX_MIO_OUTSEL_1, + PINMUX_MIO_OUTSEL_2, + PINMUX_MIO_OUTSEL_3, + PINMUX_MIO_OUTSEL_4, + PINMUX_MIO_OUTSEL_5, + PINMUX_MIO_OUTSEL_6, + PINMUX_MIO_OUTSEL_7, + PINMUX_MIO_OUTSEL_8, + PINMUX_MIO_OUTSEL_9, + PINMUX_MIO_OUTSEL_10, + PINMUX_MIO_OUTSEL_11, + PINMUX_MIO_OUTSEL_12, + PINMUX_MIO_OUTSEL_13, + PINMUX_MIO_OUTSEL_14, + PINMUX_MIO_OUTSEL_15, + PINMUX_MIO_OUTSEL_16, + PINMUX_MIO_OUTSEL_17, + PINMUX_MIO_OUTSEL_18, + PINMUX_MIO_OUTSEL_19, + PINMUX_MIO_OUTSEL_20, + PINMUX_MIO_OUTSEL_21, + PINMUX_MIO_OUTSEL_22, + PINMUX_MIO_OUTSEL_23, + PINMUX_MIO_OUTSEL_24, + PINMUX_MIO_OUTSEL_25, + PINMUX_MIO_OUTSEL_26, + PINMUX_MIO_OUTSEL_27, + PINMUX_MIO_OUTSEL_28, + PINMUX_MIO_OUTSEL_29, + PINMUX_MIO_OUTSEL_30, + PINMUX_MIO_OUTSEL_31, + PINMUX_MIO_OUTSEL_32, + PINMUX_MIO_OUTSEL_33, + PINMUX_MIO_OUTSEL_34, + PINMUX_MIO_OUTSEL_35, + PINMUX_MIO_OUTSEL_36, + PINMUX_MIO_OUTSEL_37, + PINMUX_MIO_OUTSEL_38, + PINMUX_MIO_OUTSEL_39, + PINMUX_MIO_OUTSEL_40, + PINMUX_MIO_OUTSEL_41, + PINMUX_MIO_OUTSEL_42, + PINMUX_MIO_OUTSEL_43, + PINMUX_MIO_OUTSEL_44, + PINMUX_MIO_OUTSEL_45, + PINMUX_MIO_OUTSEL_46, + PINMUX_MIO_PAD_ATTR_REGWEN_0, + PINMUX_MIO_PAD_ATTR_REGWEN_1, + PINMUX_MIO_PAD_ATTR_REGWEN_2, + PINMUX_MIO_PAD_ATTR_REGWEN_3, + PINMUX_MIO_PAD_ATTR_REGWEN_4, + PINMUX_MIO_PAD_ATTR_REGWEN_5, + PINMUX_MIO_PAD_ATTR_REGWEN_6, + PINMUX_MIO_PAD_ATTR_REGWEN_7, + PINMUX_MIO_PAD_ATTR_REGWEN_8, + PINMUX_MIO_PAD_ATTR_REGWEN_9, + PINMUX_MIO_PAD_ATTR_REGWEN_10, + PINMUX_MIO_PAD_ATTR_REGWEN_11, + PINMUX_MIO_PAD_ATTR_REGWEN_12, + PINMUX_MIO_PAD_ATTR_REGWEN_13, + PINMUX_MIO_PAD_ATTR_REGWEN_14, + PINMUX_MIO_PAD_ATTR_REGWEN_15, + PINMUX_MIO_PAD_ATTR_REGWEN_16, + PINMUX_MIO_PAD_ATTR_REGWEN_17, + PINMUX_MIO_PAD_ATTR_REGWEN_18, + PINMUX_MIO_PAD_ATTR_REGWEN_19, + PINMUX_MIO_PAD_ATTR_REGWEN_20, + PINMUX_MIO_PAD_ATTR_REGWEN_21, + PINMUX_MIO_PAD_ATTR_REGWEN_22, + PINMUX_MIO_PAD_ATTR_REGWEN_23, + PINMUX_MIO_PAD_ATTR_REGWEN_24, + PINMUX_MIO_PAD_ATTR_REGWEN_25, + PINMUX_MIO_PAD_ATTR_REGWEN_26, + PINMUX_MIO_PAD_ATTR_REGWEN_27, + PINMUX_MIO_PAD_ATTR_REGWEN_28, + PINMUX_MIO_PAD_ATTR_REGWEN_29, + PINMUX_MIO_PAD_ATTR_REGWEN_30, + PINMUX_MIO_PAD_ATTR_REGWEN_31, + PINMUX_MIO_PAD_ATTR_REGWEN_32, + PINMUX_MIO_PAD_ATTR_REGWEN_33, + PINMUX_MIO_PAD_ATTR_REGWEN_34, + PINMUX_MIO_PAD_ATTR_REGWEN_35, + PINMUX_MIO_PAD_ATTR_REGWEN_36, + PINMUX_MIO_PAD_ATTR_REGWEN_37, + PINMUX_MIO_PAD_ATTR_REGWEN_38, + PINMUX_MIO_PAD_ATTR_REGWEN_39, + PINMUX_MIO_PAD_ATTR_REGWEN_40, + PINMUX_MIO_PAD_ATTR_REGWEN_41, + PINMUX_MIO_PAD_ATTR_REGWEN_42, + PINMUX_MIO_PAD_ATTR_REGWEN_43, + PINMUX_MIO_PAD_ATTR_REGWEN_44, + PINMUX_MIO_PAD_ATTR_REGWEN_45, + PINMUX_MIO_PAD_ATTR_REGWEN_46, + PINMUX_MIO_PAD_ATTR_0, + PINMUX_MIO_PAD_ATTR_1, + PINMUX_MIO_PAD_ATTR_2, + PINMUX_MIO_PAD_ATTR_3, + PINMUX_MIO_PAD_ATTR_4, + PINMUX_MIO_PAD_ATTR_5, + PINMUX_MIO_PAD_ATTR_6, + PINMUX_MIO_PAD_ATTR_7, + PINMUX_MIO_PAD_ATTR_8, + PINMUX_MIO_PAD_ATTR_9, + PINMUX_MIO_PAD_ATTR_10, + PINMUX_MIO_PAD_ATTR_11, + PINMUX_MIO_PAD_ATTR_12, + PINMUX_MIO_PAD_ATTR_13, + PINMUX_MIO_PAD_ATTR_14, + PINMUX_MIO_PAD_ATTR_15, + PINMUX_MIO_PAD_ATTR_16, + PINMUX_MIO_PAD_ATTR_17, + PINMUX_MIO_PAD_ATTR_18, + PINMUX_MIO_PAD_ATTR_19, + PINMUX_MIO_PAD_ATTR_20, + PINMUX_MIO_PAD_ATTR_21, + PINMUX_MIO_PAD_ATTR_22, + PINMUX_MIO_PAD_ATTR_23, + PINMUX_MIO_PAD_ATTR_24, + PINMUX_MIO_PAD_ATTR_25, + PINMUX_MIO_PAD_ATTR_26, + PINMUX_MIO_PAD_ATTR_27, + PINMUX_MIO_PAD_ATTR_28, + PINMUX_MIO_PAD_ATTR_29, + PINMUX_MIO_PAD_ATTR_30, + PINMUX_MIO_PAD_ATTR_31, + PINMUX_MIO_PAD_ATTR_32, + PINMUX_MIO_PAD_ATTR_33, + PINMUX_MIO_PAD_ATTR_34, + PINMUX_MIO_PAD_ATTR_35, + PINMUX_MIO_PAD_ATTR_36, + PINMUX_MIO_PAD_ATTR_37, + PINMUX_MIO_PAD_ATTR_38, + PINMUX_MIO_PAD_ATTR_39, + PINMUX_MIO_PAD_ATTR_40, + PINMUX_MIO_PAD_ATTR_41, + PINMUX_MIO_PAD_ATTR_42, + PINMUX_MIO_PAD_ATTR_43, + PINMUX_MIO_PAD_ATTR_44, + PINMUX_MIO_PAD_ATTR_45, + PINMUX_MIO_PAD_ATTR_46, + PINMUX_DIO_PAD_ATTR_REGWEN_0, + PINMUX_DIO_PAD_ATTR_REGWEN_1, + PINMUX_DIO_PAD_ATTR_REGWEN_2, + PINMUX_DIO_PAD_ATTR_REGWEN_3, + PINMUX_DIO_PAD_ATTR_REGWEN_4, + PINMUX_DIO_PAD_ATTR_REGWEN_5, + PINMUX_DIO_PAD_ATTR_REGWEN_6, + PINMUX_DIO_PAD_ATTR_REGWEN_7, + PINMUX_DIO_PAD_ATTR_REGWEN_8, + PINMUX_DIO_PAD_ATTR_REGWEN_9, + PINMUX_DIO_PAD_ATTR_REGWEN_10, + PINMUX_DIO_PAD_ATTR_REGWEN_11, + PINMUX_DIO_PAD_ATTR_REGWEN_12, + PINMUX_DIO_PAD_ATTR_REGWEN_13, + PINMUX_DIO_PAD_ATTR_0, + PINMUX_DIO_PAD_ATTR_1, + PINMUX_DIO_PAD_ATTR_2, + PINMUX_DIO_PAD_ATTR_3, + PINMUX_DIO_PAD_ATTR_4, + PINMUX_DIO_PAD_ATTR_5, + PINMUX_DIO_PAD_ATTR_6, + PINMUX_DIO_PAD_ATTR_7, + PINMUX_DIO_PAD_ATTR_8, + PINMUX_DIO_PAD_ATTR_9, + PINMUX_DIO_PAD_ATTR_10, + PINMUX_DIO_PAD_ATTR_11, + PINMUX_DIO_PAD_ATTR_12, + PINMUX_DIO_PAD_ATTR_13, + PINMUX_MIO_PAD_SLEEP_STATUS_0, + PINMUX_MIO_PAD_SLEEP_STATUS_1, + PINMUX_MIO_PAD_SLEEP_REGWEN_0, + PINMUX_MIO_PAD_SLEEP_REGWEN_1, + PINMUX_MIO_PAD_SLEEP_REGWEN_2, + PINMUX_MIO_PAD_SLEEP_REGWEN_3, + PINMUX_MIO_PAD_SLEEP_REGWEN_4, + PINMUX_MIO_PAD_SLEEP_REGWEN_5, + PINMUX_MIO_PAD_SLEEP_REGWEN_6, + PINMUX_MIO_PAD_SLEEP_REGWEN_7, + PINMUX_MIO_PAD_SLEEP_REGWEN_8, + PINMUX_MIO_PAD_SLEEP_REGWEN_9, + PINMUX_MIO_PAD_SLEEP_REGWEN_10, + PINMUX_MIO_PAD_SLEEP_REGWEN_11, + PINMUX_MIO_PAD_SLEEP_REGWEN_12, + PINMUX_MIO_PAD_SLEEP_REGWEN_13, + PINMUX_MIO_PAD_SLEEP_REGWEN_14, + PINMUX_MIO_PAD_SLEEP_REGWEN_15, + PINMUX_MIO_PAD_SLEEP_REGWEN_16, + PINMUX_MIO_PAD_SLEEP_REGWEN_17, + PINMUX_MIO_PAD_SLEEP_REGWEN_18, + PINMUX_MIO_PAD_SLEEP_REGWEN_19, + PINMUX_MIO_PAD_SLEEP_REGWEN_20, + PINMUX_MIO_PAD_SLEEP_REGWEN_21, + PINMUX_MIO_PAD_SLEEP_REGWEN_22, + PINMUX_MIO_PAD_SLEEP_REGWEN_23, + PINMUX_MIO_PAD_SLEEP_REGWEN_24, + PINMUX_MIO_PAD_SLEEP_REGWEN_25, + PINMUX_MIO_PAD_SLEEP_REGWEN_26, + PINMUX_MIO_PAD_SLEEP_REGWEN_27, + PINMUX_MIO_PAD_SLEEP_REGWEN_28, + PINMUX_MIO_PAD_SLEEP_REGWEN_29, + PINMUX_MIO_PAD_SLEEP_REGWEN_30, + PINMUX_MIO_PAD_SLEEP_REGWEN_31, + PINMUX_MIO_PAD_SLEEP_REGWEN_32, + PINMUX_MIO_PAD_SLEEP_REGWEN_33, + PINMUX_MIO_PAD_SLEEP_REGWEN_34, + PINMUX_MIO_PAD_SLEEP_REGWEN_35, + PINMUX_MIO_PAD_SLEEP_REGWEN_36, + PINMUX_MIO_PAD_SLEEP_REGWEN_37, + PINMUX_MIO_PAD_SLEEP_REGWEN_38, + PINMUX_MIO_PAD_SLEEP_REGWEN_39, + PINMUX_MIO_PAD_SLEEP_REGWEN_40, + PINMUX_MIO_PAD_SLEEP_REGWEN_41, + PINMUX_MIO_PAD_SLEEP_REGWEN_42, + PINMUX_MIO_PAD_SLEEP_REGWEN_43, + PINMUX_MIO_PAD_SLEEP_REGWEN_44, + PINMUX_MIO_PAD_SLEEP_REGWEN_45, + PINMUX_MIO_PAD_SLEEP_REGWEN_46, + PINMUX_MIO_PAD_SLEEP_EN_0, + PINMUX_MIO_PAD_SLEEP_EN_1, + PINMUX_MIO_PAD_SLEEP_EN_2, + PINMUX_MIO_PAD_SLEEP_EN_3, + PINMUX_MIO_PAD_SLEEP_EN_4, + PINMUX_MIO_PAD_SLEEP_EN_5, + PINMUX_MIO_PAD_SLEEP_EN_6, + PINMUX_MIO_PAD_SLEEP_EN_7, + PINMUX_MIO_PAD_SLEEP_EN_8, + PINMUX_MIO_PAD_SLEEP_EN_9, + PINMUX_MIO_PAD_SLEEP_EN_10, + PINMUX_MIO_PAD_SLEEP_EN_11, + PINMUX_MIO_PAD_SLEEP_EN_12, + PINMUX_MIO_PAD_SLEEP_EN_13, + PINMUX_MIO_PAD_SLEEP_EN_14, + PINMUX_MIO_PAD_SLEEP_EN_15, + PINMUX_MIO_PAD_SLEEP_EN_16, + PINMUX_MIO_PAD_SLEEP_EN_17, + PINMUX_MIO_PAD_SLEEP_EN_18, + PINMUX_MIO_PAD_SLEEP_EN_19, + PINMUX_MIO_PAD_SLEEP_EN_20, + PINMUX_MIO_PAD_SLEEP_EN_21, + PINMUX_MIO_PAD_SLEEP_EN_22, + PINMUX_MIO_PAD_SLEEP_EN_23, + PINMUX_MIO_PAD_SLEEP_EN_24, + PINMUX_MIO_PAD_SLEEP_EN_25, + PINMUX_MIO_PAD_SLEEP_EN_26, + PINMUX_MIO_PAD_SLEEP_EN_27, + PINMUX_MIO_PAD_SLEEP_EN_28, + PINMUX_MIO_PAD_SLEEP_EN_29, + PINMUX_MIO_PAD_SLEEP_EN_30, + PINMUX_MIO_PAD_SLEEP_EN_31, + PINMUX_MIO_PAD_SLEEP_EN_32, + PINMUX_MIO_PAD_SLEEP_EN_33, + PINMUX_MIO_PAD_SLEEP_EN_34, + PINMUX_MIO_PAD_SLEEP_EN_35, + PINMUX_MIO_PAD_SLEEP_EN_36, + PINMUX_MIO_PAD_SLEEP_EN_37, + PINMUX_MIO_PAD_SLEEP_EN_38, + PINMUX_MIO_PAD_SLEEP_EN_39, + PINMUX_MIO_PAD_SLEEP_EN_40, + PINMUX_MIO_PAD_SLEEP_EN_41, + PINMUX_MIO_PAD_SLEEP_EN_42, + PINMUX_MIO_PAD_SLEEP_EN_43, + PINMUX_MIO_PAD_SLEEP_EN_44, + PINMUX_MIO_PAD_SLEEP_EN_45, + PINMUX_MIO_PAD_SLEEP_EN_46, + PINMUX_MIO_PAD_SLEEP_MODE_0, + PINMUX_MIO_PAD_SLEEP_MODE_1, + PINMUX_MIO_PAD_SLEEP_MODE_2, + PINMUX_MIO_PAD_SLEEP_MODE_3, + PINMUX_MIO_PAD_SLEEP_MODE_4, + PINMUX_MIO_PAD_SLEEP_MODE_5, + PINMUX_MIO_PAD_SLEEP_MODE_6, + PINMUX_MIO_PAD_SLEEP_MODE_7, + PINMUX_MIO_PAD_SLEEP_MODE_8, + PINMUX_MIO_PAD_SLEEP_MODE_9, + PINMUX_MIO_PAD_SLEEP_MODE_10, + PINMUX_MIO_PAD_SLEEP_MODE_11, + PINMUX_MIO_PAD_SLEEP_MODE_12, + PINMUX_MIO_PAD_SLEEP_MODE_13, + PINMUX_MIO_PAD_SLEEP_MODE_14, + PINMUX_MIO_PAD_SLEEP_MODE_15, + PINMUX_MIO_PAD_SLEEP_MODE_16, + PINMUX_MIO_PAD_SLEEP_MODE_17, + PINMUX_MIO_PAD_SLEEP_MODE_18, + PINMUX_MIO_PAD_SLEEP_MODE_19, + PINMUX_MIO_PAD_SLEEP_MODE_20, + PINMUX_MIO_PAD_SLEEP_MODE_21, + PINMUX_MIO_PAD_SLEEP_MODE_22, + PINMUX_MIO_PAD_SLEEP_MODE_23, + PINMUX_MIO_PAD_SLEEP_MODE_24, + PINMUX_MIO_PAD_SLEEP_MODE_25, + PINMUX_MIO_PAD_SLEEP_MODE_26, + PINMUX_MIO_PAD_SLEEP_MODE_27, + PINMUX_MIO_PAD_SLEEP_MODE_28, + PINMUX_MIO_PAD_SLEEP_MODE_29, + PINMUX_MIO_PAD_SLEEP_MODE_30, + PINMUX_MIO_PAD_SLEEP_MODE_31, + PINMUX_MIO_PAD_SLEEP_MODE_32, + PINMUX_MIO_PAD_SLEEP_MODE_33, + PINMUX_MIO_PAD_SLEEP_MODE_34, + PINMUX_MIO_PAD_SLEEP_MODE_35, + PINMUX_MIO_PAD_SLEEP_MODE_36, + PINMUX_MIO_PAD_SLEEP_MODE_37, + PINMUX_MIO_PAD_SLEEP_MODE_38, + PINMUX_MIO_PAD_SLEEP_MODE_39, + PINMUX_MIO_PAD_SLEEP_MODE_40, + PINMUX_MIO_PAD_SLEEP_MODE_41, + PINMUX_MIO_PAD_SLEEP_MODE_42, + PINMUX_MIO_PAD_SLEEP_MODE_43, + PINMUX_MIO_PAD_SLEEP_MODE_44, + PINMUX_MIO_PAD_SLEEP_MODE_45, + PINMUX_MIO_PAD_SLEEP_MODE_46, + PINMUX_DIO_PAD_SLEEP_STATUS, + PINMUX_DIO_PAD_SLEEP_REGWEN_0, + PINMUX_DIO_PAD_SLEEP_REGWEN_1, + PINMUX_DIO_PAD_SLEEP_REGWEN_2, + PINMUX_DIO_PAD_SLEEP_REGWEN_3, + PINMUX_DIO_PAD_SLEEP_REGWEN_4, + PINMUX_DIO_PAD_SLEEP_REGWEN_5, + PINMUX_DIO_PAD_SLEEP_REGWEN_6, + PINMUX_DIO_PAD_SLEEP_REGWEN_7, + PINMUX_DIO_PAD_SLEEP_REGWEN_8, + PINMUX_DIO_PAD_SLEEP_REGWEN_9, + PINMUX_DIO_PAD_SLEEP_REGWEN_10, + PINMUX_DIO_PAD_SLEEP_REGWEN_11, + PINMUX_DIO_PAD_SLEEP_REGWEN_12, + PINMUX_DIO_PAD_SLEEP_REGWEN_13, + PINMUX_DIO_PAD_SLEEP_EN_0, + PINMUX_DIO_PAD_SLEEP_EN_1, + PINMUX_DIO_PAD_SLEEP_EN_2, + PINMUX_DIO_PAD_SLEEP_EN_3, + PINMUX_DIO_PAD_SLEEP_EN_4, + PINMUX_DIO_PAD_SLEEP_EN_5, + PINMUX_DIO_PAD_SLEEP_EN_6, + PINMUX_DIO_PAD_SLEEP_EN_7, + PINMUX_DIO_PAD_SLEEP_EN_8, + PINMUX_DIO_PAD_SLEEP_EN_9, + PINMUX_DIO_PAD_SLEEP_EN_10, + PINMUX_DIO_PAD_SLEEP_EN_11, + PINMUX_DIO_PAD_SLEEP_EN_12, + PINMUX_DIO_PAD_SLEEP_EN_13, + PINMUX_DIO_PAD_SLEEP_MODE_0, + PINMUX_DIO_PAD_SLEEP_MODE_1, + PINMUX_DIO_PAD_SLEEP_MODE_2, + PINMUX_DIO_PAD_SLEEP_MODE_3, + PINMUX_DIO_PAD_SLEEP_MODE_4, + PINMUX_DIO_PAD_SLEEP_MODE_5, + PINMUX_DIO_PAD_SLEEP_MODE_6, + PINMUX_DIO_PAD_SLEEP_MODE_7, + PINMUX_DIO_PAD_SLEEP_MODE_8, + PINMUX_DIO_PAD_SLEEP_MODE_9, + PINMUX_DIO_PAD_SLEEP_MODE_10, + PINMUX_DIO_PAD_SLEEP_MODE_11, + PINMUX_DIO_PAD_SLEEP_MODE_12, + PINMUX_DIO_PAD_SLEEP_MODE_13, + PINMUX_WKUP_DETECTOR_REGWEN_0, + PINMUX_WKUP_DETECTOR_REGWEN_1, + PINMUX_WKUP_DETECTOR_REGWEN_2, + PINMUX_WKUP_DETECTOR_REGWEN_3, + PINMUX_WKUP_DETECTOR_REGWEN_4, + PINMUX_WKUP_DETECTOR_REGWEN_5, + PINMUX_WKUP_DETECTOR_REGWEN_6, + PINMUX_WKUP_DETECTOR_REGWEN_7, + PINMUX_WKUP_DETECTOR_EN_0, + PINMUX_WKUP_DETECTOR_EN_1, + PINMUX_WKUP_DETECTOR_EN_2, + PINMUX_WKUP_DETECTOR_EN_3, + PINMUX_WKUP_DETECTOR_EN_4, + PINMUX_WKUP_DETECTOR_EN_5, + PINMUX_WKUP_DETECTOR_EN_6, + PINMUX_WKUP_DETECTOR_EN_7, + PINMUX_WKUP_DETECTOR_0, + PINMUX_WKUP_DETECTOR_1, + PINMUX_WKUP_DETECTOR_2, + PINMUX_WKUP_DETECTOR_3, + PINMUX_WKUP_DETECTOR_4, + PINMUX_WKUP_DETECTOR_5, + PINMUX_WKUP_DETECTOR_6, + PINMUX_WKUP_DETECTOR_7, + PINMUX_WKUP_DETECTOR_CNT_TH_0, + PINMUX_WKUP_DETECTOR_CNT_TH_1, + PINMUX_WKUP_DETECTOR_CNT_TH_2, + PINMUX_WKUP_DETECTOR_CNT_TH_3, + PINMUX_WKUP_DETECTOR_CNT_TH_4, + PINMUX_WKUP_DETECTOR_CNT_TH_5, + PINMUX_WKUP_DETECTOR_CNT_TH_6, + PINMUX_WKUP_DETECTOR_CNT_TH_7, + PINMUX_WKUP_DETECTOR_PADSEL_0, + PINMUX_WKUP_DETECTOR_PADSEL_1, + PINMUX_WKUP_DETECTOR_PADSEL_2, + PINMUX_WKUP_DETECTOR_PADSEL_3, + PINMUX_WKUP_DETECTOR_PADSEL_4, + PINMUX_WKUP_DETECTOR_PADSEL_5, + PINMUX_WKUP_DETECTOR_PADSEL_6, + PINMUX_WKUP_DETECTOR_PADSEL_7, + PINMUX_WKUP_CAUSE + } pinmux_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] PINMUX_PERMIT [520] = '{ + 4'b 0001, // index[ 0] PINMUX_ALERT_TEST + 4'b 0001, // index[ 1] PINMUX_MIO_PERIPH_INSEL_REGWEN_0 + 4'b 0001, // index[ 2] PINMUX_MIO_PERIPH_INSEL_REGWEN_1 + 4'b 0001, // index[ 3] PINMUX_MIO_PERIPH_INSEL_REGWEN_2 + 4'b 0001, // index[ 4] PINMUX_MIO_PERIPH_INSEL_REGWEN_3 + 4'b 0001, // index[ 5] PINMUX_MIO_PERIPH_INSEL_REGWEN_4 + 4'b 0001, // index[ 6] PINMUX_MIO_PERIPH_INSEL_REGWEN_5 + 4'b 0001, // index[ 7] PINMUX_MIO_PERIPH_INSEL_REGWEN_6 + 4'b 0001, // index[ 8] PINMUX_MIO_PERIPH_INSEL_REGWEN_7 + 4'b 0001, // index[ 9] PINMUX_MIO_PERIPH_INSEL_REGWEN_8 + 4'b 0001, // index[ 10] PINMUX_MIO_PERIPH_INSEL_REGWEN_9 + 4'b 0001, // index[ 11] PINMUX_MIO_PERIPH_INSEL_REGWEN_10 + 4'b 0001, // index[ 12] PINMUX_MIO_PERIPH_INSEL_REGWEN_11 + 4'b 0001, // index[ 13] PINMUX_MIO_PERIPH_INSEL_REGWEN_12 + 4'b 0001, // index[ 14] PINMUX_MIO_PERIPH_INSEL_REGWEN_13 + 4'b 0001, // index[ 15] PINMUX_MIO_PERIPH_INSEL_REGWEN_14 + 4'b 0001, // index[ 16] PINMUX_MIO_PERIPH_INSEL_REGWEN_15 + 4'b 0001, // index[ 17] PINMUX_MIO_PERIPH_INSEL_REGWEN_16 + 4'b 0001, // index[ 18] PINMUX_MIO_PERIPH_INSEL_REGWEN_17 + 4'b 0001, // index[ 19] PINMUX_MIO_PERIPH_INSEL_REGWEN_18 + 4'b 0001, // index[ 20] PINMUX_MIO_PERIPH_INSEL_REGWEN_19 + 4'b 0001, // index[ 21] PINMUX_MIO_PERIPH_INSEL_REGWEN_20 + 4'b 0001, // index[ 22] PINMUX_MIO_PERIPH_INSEL_REGWEN_21 + 4'b 0001, // index[ 23] PINMUX_MIO_PERIPH_INSEL_REGWEN_22 + 4'b 0001, // index[ 24] PINMUX_MIO_PERIPH_INSEL_REGWEN_23 + 4'b 0001, // index[ 25] PINMUX_MIO_PERIPH_INSEL_REGWEN_24 + 4'b 0001, // index[ 26] PINMUX_MIO_PERIPH_INSEL_REGWEN_25 + 4'b 0001, // index[ 27] PINMUX_MIO_PERIPH_INSEL_REGWEN_26 + 4'b 0001, // index[ 28] PINMUX_MIO_PERIPH_INSEL_REGWEN_27 + 4'b 0001, // index[ 29] PINMUX_MIO_PERIPH_INSEL_REGWEN_28 + 4'b 0001, // index[ 30] PINMUX_MIO_PERIPH_INSEL_REGWEN_29 + 4'b 0001, // index[ 31] PINMUX_MIO_PERIPH_INSEL_REGWEN_30 + 4'b 0001, // index[ 32] PINMUX_MIO_PERIPH_INSEL_REGWEN_31 + 4'b 0001, // index[ 33] PINMUX_MIO_PERIPH_INSEL_REGWEN_32 + 4'b 0001, // index[ 34] PINMUX_MIO_PERIPH_INSEL_REGWEN_33 + 4'b 0001, // index[ 35] PINMUX_MIO_PERIPH_INSEL_REGWEN_34 + 4'b 0001, // index[ 36] PINMUX_MIO_PERIPH_INSEL_REGWEN_35 + 4'b 0001, // index[ 37] PINMUX_MIO_PERIPH_INSEL_REGWEN_36 + 4'b 0001, // index[ 38] PINMUX_MIO_PERIPH_INSEL_REGWEN_37 + 4'b 0001, // index[ 39] PINMUX_MIO_PERIPH_INSEL_0 + 4'b 0001, // index[ 40] PINMUX_MIO_PERIPH_INSEL_1 + 4'b 0001, // index[ 41] PINMUX_MIO_PERIPH_INSEL_2 + 4'b 0001, // index[ 42] PINMUX_MIO_PERIPH_INSEL_3 + 4'b 0001, // index[ 43] PINMUX_MIO_PERIPH_INSEL_4 + 4'b 0001, // index[ 44] PINMUX_MIO_PERIPH_INSEL_5 + 4'b 0001, // index[ 45] PINMUX_MIO_PERIPH_INSEL_6 + 4'b 0001, // index[ 46] PINMUX_MIO_PERIPH_INSEL_7 + 4'b 0001, // index[ 47] PINMUX_MIO_PERIPH_INSEL_8 + 4'b 0001, // index[ 48] PINMUX_MIO_PERIPH_INSEL_9 + 4'b 0001, // index[ 49] PINMUX_MIO_PERIPH_INSEL_10 + 4'b 0001, // index[ 50] PINMUX_MIO_PERIPH_INSEL_11 + 4'b 0001, // index[ 51] PINMUX_MIO_PERIPH_INSEL_12 + 4'b 0001, // index[ 52] PINMUX_MIO_PERIPH_INSEL_13 + 4'b 0001, // index[ 53] PINMUX_MIO_PERIPH_INSEL_14 + 4'b 0001, // index[ 54] PINMUX_MIO_PERIPH_INSEL_15 + 4'b 0001, // index[ 55] PINMUX_MIO_PERIPH_INSEL_16 + 4'b 0001, // index[ 56] PINMUX_MIO_PERIPH_INSEL_17 + 4'b 0001, // index[ 57] PINMUX_MIO_PERIPH_INSEL_18 + 4'b 0001, // index[ 58] PINMUX_MIO_PERIPH_INSEL_19 + 4'b 0001, // index[ 59] PINMUX_MIO_PERIPH_INSEL_20 + 4'b 0001, // index[ 60] PINMUX_MIO_PERIPH_INSEL_21 + 4'b 0001, // index[ 61] PINMUX_MIO_PERIPH_INSEL_22 + 4'b 0001, // index[ 62] PINMUX_MIO_PERIPH_INSEL_23 + 4'b 0001, // index[ 63] PINMUX_MIO_PERIPH_INSEL_24 + 4'b 0001, // index[ 64] PINMUX_MIO_PERIPH_INSEL_25 + 4'b 0001, // index[ 65] PINMUX_MIO_PERIPH_INSEL_26 + 4'b 0001, // index[ 66] PINMUX_MIO_PERIPH_INSEL_27 + 4'b 0001, // index[ 67] PINMUX_MIO_PERIPH_INSEL_28 + 4'b 0001, // index[ 68] PINMUX_MIO_PERIPH_INSEL_29 + 4'b 0001, // index[ 69] PINMUX_MIO_PERIPH_INSEL_30 + 4'b 0001, // index[ 70] PINMUX_MIO_PERIPH_INSEL_31 + 4'b 0001, // index[ 71] PINMUX_MIO_PERIPH_INSEL_32 + 4'b 0001, // index[ 72] PINMUX_MIO_PERIPH_INSEL_33 + 4'b 0001, // index[ 73] PINMUX_MIO_PERIPH_INSEL_34 + 4'b 0001, // index[ 74] PINMUX_MIO_PERIPH_INSEL_35 + 4'b 0001, // index[ 75] PINMUX_MIO_PERIPH_INSEL_36 + 4'b 0001, // index[ 76] PINMUX_MIO_PERIPH_INSEL_37 + 4'b 0001, // index[ 77] PINMUX_MIO_OUTSEL_REGWEN_0 + 4'b 0001, // index[ 78] PINMUX_MIO_OUTSEL_REGWEN_1 + 4'b 0001, // index[ 79] PINMUX_MIO_OUTSEL_REGWEN_2 + 4'b 0001, // index[ 80] PINMUX_MIO_OUTSEL_REGWEN_3 + 4'b 0001, // index[ 81] PINMUX_MIO_OUTSEL_REGWEN_4 + 4'b 0001, // index[ 82] PINMUX_MIO_OUTSEL_REGWEN_5 + 4'b 0001, // index[ 83] PINMUX_MIO_OUTSEL_REGWEN_6 + 4'b 0001, // index[ 84] PINMUX_MIO_OUTSEL_REGWEN_7 + 4'b 0001, // index[ 85] PINMUX_MIO_OUTSEL_REGWEN_8 + 4'b 0001, // index[ 86] PINMUX_MIO_OUTSEL_REGWEN_9 + 4'b 0001, // index[ 87] PINMUX_MIO_OUTSEL_REGWEN_10 + 4'b 0001, // index[ 88] PINMUX_MIO_OUTSEL_REGWEN_11 + 4'b 0001, // index[ 89] PINMUX_MIO_OUTSEL_REGWEN_12 + 4'b 0001, // index[ 90] PINMUX_MIO_OUTSEL_REGWEN_13 + 4'b 0001, // index[ 91] PINMUX_MIO_OUTSEL_REGWEN_14 + 4'b 0001, // index[ 92] PINMUX_MIO_OUTSEL_REGWEN_15 + 4'b 0001, // index[ 93] PINMUX_MIO_OUTSEL_REGWEN_16 + 4'b 0001, // index[ 94] PINMUX_MIO_OUTSEL_REGWEN_17 + 4'b 0001, // index[ 95] PINMUX_MIO_OUTSEL_REGWEN_18 + 4'b 0001, // index[ 96] PINMUX_MIO_OUTSEL_REGWEN_19 + 4'b 0001, // index[ 97] PINMUX_MIO_OUTSEL_REGWEN_20 + 4'b 0001, // index[ 98] PINMUX_MIO_OUTSEL_REGWEN_21 + 4'b 0001, // index[ 99] PINMUX_MIO_OUTSEL_REGWEN_22 + 4'b 0001, // index[100] PINMUX_MIO_OUTSEL_REGWEN_23 + 4'b 0001, // index[101] PINMUX_MIO_OUTSEL_REGWEN_24 + 4'b 0001, // index[102] PINMUX_MIO_OUTSEL_REGWEN_25 + 4'b 0001, // index[103] PINMUX_MIO_OUTSEL_REGWEN_26 + 4'b 0001, // index[104] PINMUX_MIO_OUTSEL_REGWEN_27 + 4'b 0001, // index[105] PINMUX_MIO_OUTSEL_REGWEN_28 + 4'b 0001, // index[106] PINMUX_MIO_OUTSEL_REGWEN_29 + 4'b 0001, // index[107] PINMUX_MIO_OUTSEL_REGWEN_30 + 4'b 0001, // index[108] PINMUX_MIO_OUTSEL_REGWEN_31 + 4'b 0001, // index[109] PINMUX_MIO_OUTSEL_REGWEN_32 + 4'b 0001, // index[110] PINMUX_MIO_OUTSEL_REGWEN_33 + 4'b 0001, // index[111] PINMUX_MIO_OUTSEL_REGWEN_34 + 4'b 0001, // index[112] PINMUX_MIO_OUTSEL_REGWEN_35 + 4'b 0001, // index[113] PINMUX_MIO_OUTSEL_REGWEN_36 + 4'b 0001, // index[114] PINMUX_MIO_OUTSEL_REGWEN_37 + 4'b 0001, // index[115] PINMUX_MIO_OUTSEL_REGWEN_38 + 4'b 0001, // index[116] PINMUX_MIO_OUTSEL_REGWEN_39 + 4'b 0001, // index[117] PINMUX_MIO_OUTSEL_REGWEN_40 + 4'b 0001, // index[118] PINMUX_MIO_OUTSEL_REGWEN_41 + 4'b 0001, // index[119] PINMUX_MIO_OUTSEL_REGWEN_42 + 4'b 0001, // index[120] PINMUX_MIO_OUTSEL_REGWEN_43 + 4'b 0001, // index[121] PINMUX_MIO_OUTSEL_REGWEN_44 + 4'b 0001, // index[122] PINMUX_MIO_OUTSEL_REGWEN_45 + 4'b 0001, // index[123] PINMUX_MIO_OUTSEL_REGWEN_46 + 4'b 0001, // index[124] PINMUX_MIO_OUTSEL_0 + 4'b 0001, // index[125] PINMUX_MIO_OUTSEL_1 + 4'b 0001, // index[126] PINMUX_MIO_OUTSEL_2 + 4'b 0001, // index[127] PINMUX_MIO_OUTSEL_3 + 4'b 0001, // index[128] PINMUX_MIO_OUTSEL_4 + 4'b 0001, // index[129] PINMUX_MIO_OUTSEL_5 + 4'b 0001, // index[130] PINMUX_MIO_OUTSEL_6 + 4'b 0001, // index[131] PINMUX_MIO_OUTSEL_7 + 4'b 0001, // index[132] PINMUX_MIO_OUTSEL_8 + 4'b 0001, // index[133] PINMUX_MIO_OUTSEL_9 + 4'b 0001, // index[134] PINMUX_MIO_OUTSEL_10 + 4'b 0001, // index[135] PINMUX_MIO_OUTSEL_11 + 4'b 0001, // index[136] PINMUX_MIO_OUTSEL_12 + 4'b 0001, // index[137] PINMUX_MIO_OUTSEL_13 + 4'b 0001, // index[138] PINMUX_MIO_OUTSEL_14 + 4'b 0001, // index[139] PINMUX_MIO_OUTSEL_15 + 4'b 0001, // index[140] PINMUX_MIO_OUTSEL_16 + 4'b 0001, // index[141] PINMUX_MIO_OUTSEL_17 + 4'b 0001, // index[142] PINMUX_MIO_OUTSEL_18 + 4'b 0001, // index[143] PINMUX_MIO_OUTSEL_19 + 4'b 0001, // index[144] PINMUX_MIO_OUTSEL_20 + 4'b 0001, // index[145] PINMUX_MIO_OUTSEL_21 + 4'b 0001, // index[146] PINMUX_MIO_OUTSEL_22 + 4'b 0001, // index[147] PINMUX_MIO_OUTSEL_23 + 4'b 0001, // index[148] PINMUX_MIO_OUTSEL_24 + 4'b 0001, // index[149] PINMUX_MIO_OUTSEL_25 + 4'b 0001, // index[150] PINMUX_MIO_OUTSEL_26 + 4'b 0001, // index[151] PINMUX_MIO_OUTSEL_27 + 4'b 0001, // index[152] PINMUX_MIO_OUTSEL_28 + 4'b 0001, // index[153] PINMUX_MIO_OUTSEL_29 + 4'b 0001, // index[154] PINMUX_MIO_OUTSEL_30 + 4'b 0001, // index[155] PINMUX_MIO_OUTSEL_31 + 4'b 0001, // index[156] PINMUX_MIO_OUTSEL_32 + 4'b 0001, // index[157] PINMUX_MIO_OUTSEL_33 + 4'b 0001, // index[158] PINMUX_MIO_OUTSEL_34 + 4'b 0001, // index[159] PINMUX_MIO_OUTSEL_35 + 4'b 0001, // index[160] PINMUX_MIO_OUTSEL_36 + 4'b 0001, // index[161] PINMUX_MIO_OUTSEL_37 + 4'b 0001, // index[162] PINMUX_MIO_OUTSEL_38 + 4'b 0001, // index[163] PINMUX_MIO_OUTSEL_39 + 4'b 0001, // index[164] PINMUX_MIO_OUTSEL_40 + 4'b 0001, // index[165] PINMUX_MIO_OUTSEL_41 + 4'b 0001, // index[166] PINMUX_MIO_OUTSEL_42 + 4'b 0001, // index[167] PINMUX_MIO_OUTSEL_43 + 4'b 0001, // index[168] PINMUX_MIO_OUTSEL_44 + 4'b 0001, // index[169] PINMUX_MIO_OUTSEL_45 + 4'b 0001, // index[170] PINMUX_MIO_OUTSEL_46 + 4'b 0001, // index[171] PINMUX_MIO_PAD_ATTR_REGWEN_0 + 4'b 0001, // index[172] PINMUX_MIO_PAD_ATTR_REGWEN_1 + 4'b 0001, // index[173] PINMUX_MIO_PAD_ATTR_REGWEN_2 + 4'b 0001, // index[174] PINMUX_MIO_PAD_ATTR_REGWEN_3 + 4'b 0001, // index[175] PINMUX_MIO_PAD_ATTR_REGWEN_4 + 4'b 0001, // index[176] PINMUX_MIO_PAD_ATTR_REGWEN_5 + 4'b 0001, // index[177] PINMUX_MIO_PAD_ATTR_REGWEN_6 + 4'b 0001, // index[178] PINMUX_MIO_PAD_ATTR_REGWEN_7 + 4'b 0001, // index[179] PINMUX_MIO_PAD_ATTR_REGWEN_8 + 4'b 0001, // index[180] PINMUX_MIO_PAD_ATTR_REGWEN_9 + 4'b 0001, // index[181] PINMUX_MIO_PAD_ATTR_REGWEN_10 + 4'b 0001, // index[182] PINMUX_MIO_PAD_ATTR_REGWEN_11 + 4'b 0001, // index[183] PINMUX_MIO_PAD_ATTR_REGWEN_12 + 4'b 0001, // index[184] PINMUX_MIO_PAD_ATTR_REGWEN_13 + 4'b 0001, // index[185] PINMUX_MIO_PAD_ATTR_REGWEN_14 + 4'b 0001, // index[186] PINMUX_MIO_PAD_ATTR_REGWEN_15 + 4'b 0001, // index[187] PINMUX_MIO_PAD_ATTR_REGWEN_16 + 4'b 0001, // index[188] PINMUX_MIO_PAD_ATTR_REGWEN_17 + 4'b 0001, // index[189] PINMUX_MIO_PAD_ATTR_REGWEN_18 + 4'b 0001, // index[190] PINMUX_MIO_PAD_ATTR_REGWEN_19 + 4'b 0001, // index[191] PINMUX_MIO_PAD_ATTR_REGWEN_20 + 4'b 0001, // index[192] PINMUX_MIO_PAD_ATTR_REGWEN_21 + 4'b 0001, // index[193] PINMUX_MIO_PAD_ATTR_REGWEN_22 + 4'b 0001, // index[194] PINMUX_MIO_PAD_ATTR_REGWEN_23 + 4'b 0001, // index[195] PINMUX_MIO_PAD_ATTR_REGWEN_24 + 4'b 0001, // index[196] PINMUX_MIO_PAD_ATTR_REGWEN_25 + 4'b 0001, // index[197] PINMUX_MIO_PAD_ATTR_REGWEN_26 + 4'b 0001, // index[198] PINMUX_MIO_PAD_ATTR_REGWEN_27 + 4'b 0001, // index[199] PINMUX_MIO_PAD_ATTR_REGWEN_28 + 4'b 0001, // index[200] PINMUX_MIO_PAD_ATTR_REGWEN_29 + 4'b 0001, // index[201] PINMUX_MIO_PAD_ATTR_REGWEN_30 + 4'b 0001, // index[202] PINMUX_MIO_PAD_ATTR_REGWEN_31 + 4'b 0001, // index[203] PINMUX_MIO_PAD_ATTR_REGWEN_32 + 4'b 0001, // index[204] PINMUX_MIO_PAD_ATTR_REGWEN_33 + 4'b 0001, // index[205] PINMUX_MIO_PAD_ATTR_REGWEN_34 + 4'b 0001, // index[206] PINMUX_MIO_PAD_ATTR_REGWEN_35 + 4'b 0001, // index[207] PINMUX_MIO_PAD_ATTR_REGWEN_36 + 4'b 0001, // index[208] PINMUX_MIO_PAD_ATTR_REGWEN_37 + 4'b 0001, // index[209] PINMUX_MIO_PAD_ATTR_REGWEN_38 + 4'b 0001, // index[210] PINMUX_MIO_PAD_ATTR_REGWEN_39 + 4'b 0001, // index[211] PINMUX_MIO_PAD_ATTR_REGWEN_40 + 4'b 0001, // index[212] PINMUX_MIO_PAD_ATTR_REGWEN_41 + 4'b 0001, // index[213] PINMUX_MIO_PAD_ATTR_REGWEN_42 + 4'b 0001, // index[214] PINMUX_MIO_PAD_ATTR_REGWEN_43 + 4'b 0001, // index[215] PINMUX_MIO_PAD_ATTR_REGWEN_44 + 4'b 0001, // index[216] PINMUX_MIO_PAD_ATTR_REGWEN_45 + 4'b 0001, // index[217] PINMUX_MIO_PAD_ATTR_REGWEN_46 + 4'b 0111, // index[218] PINMUX_MIO_PAD_ATTR_0 + 4'b 0111, // index[219] PINMUX_MIO_PAD_ATTR_1 + 4'b 0111, // index[220] PINMUX_MIO_PAD_ATTR_2 + 4'b 0111, // index[221] PINMUX_MIO_PAD_ATTR_3 + 4'b 0111, // index[222] PINMUX_MIO_PAD_ATTR_4 + 4'b 0111, // index[223] PINMUX_MIO_PAD_ATTR_5 + 4'b 0111, // index[224] PINMUX_MIO_PAD_ATTR_6 + 4'b 0111, // index[225] PINMUX_MIO_PAD_ATTR_7 + 4'b 0111, // index[226] PINMUX_MIO_PAD_ATTR_8 + 4'b 0111, // index[227] PINMUX_MIO_PAD_ATTR_9 + 4'b 0111, // index[228] PINMUX_MIO_PAD_ATTR_10 + 4'b 0111, // index[229] PINMUX_MIO_PAD_ATTR_11 + 4'b 0111, // index[230] PINMUX_MIO_PAD_ATTR_12 + 4'b 0111, // index[231] PINMUX_MIO_PAD_ATTR_13 + 4'b 0111, // index[232] PINMUX_MIO_PAD_ATTR_14 + 4'b 0111, // index[233] PINMUX_MIO_PAD_ATTR_15 + 4'b 0111, // index[234] PINMUX_MIO_PAD_ATTR_16 + 4'b 0111, // index[235] PINMUX_MIO_PAD_ATTR_17 + 4'b 0111, // index[236] PINMUX_MIO_PAD_ATTR_18 + 4'b 0111, // index[237] PINMUX_MIO_PAD_ATTR_19 + 4'b 0111, // index[238] PINMUX_MIO_PAD_ATTR_20 + 4'b 0111, // index[239] PINMUX_MIO_PAD_ATTR_21 + 4'b 0111, // index[240] PINMUX_MIO_PAD_ATTR_22 + 4'b 0111, // index[241] PINMUX_MIO_PAD_ATTR_23 + 4'b 0111, // index[242] PINMUX_MIO_PAD_ATTR_24 + 4'b 0111, // index[243] PINMUX_MIO_PAD_ATTR_25 + 4'b 0111, // index[244] PINMUX_MIO_PAD_ATTR_26 + 4'b 0111, // index[245] PINMUX_MIO_PAD_ATTR_27 + 4'b 0111, // index[246] PINMUX_MIO_PAD_ATTR_28 + 4'b 0111, // index[247] PINMUX_MIO_PAD_ATTR_29 + 4'b 0111, // index[248] PINMUX_MIO_PAD_ATTR_30 + 4'b 0111, // index[249] PINMUX_MIO_PAD_ATTR_31 + 4'b 0111, // index[250] PINMUX_MIO_PAD_ATTR_32 + 4'b 0111, // index[251] PINMUX_MIO_PAD_ATTR_33 + 4'b 0111, // index[252] PINMUX_MIO_PAD_ATTR_34 + 4'b 0111, // index[253] PINMUX_MIO_PAD_ATTR_35 + 4'b 0111, // index[254] PINMUX_MIO_PAD_ATTR_36 + 4'b 0111, // index[255] PINMUX_MIO_PAD_ATTR_37 + 4'b 0111, // index[256] PINMUX_MIO_PAD_ATTR_38 + 4'b 0111, // index[257] PINMUX_MIO_PAD_ATTR_39 + 4'b 0111, // index[258] PINMUX_MIO_PAD_ATTR_40 + 4'b 0111, // index[259] PINMUX_MIO_PAD_ATTR_41 + 4'b 0111, // index[260] PINMUX_MIO_PAD_ATTR_42 + 4'b 0111, // index[261] PINMUX_MIO_PAD_ATTR_43 + 4'b 0111, // index[262] PINMUX_MIO_PAD_ATTR_44 + 4'b 0111, // index[263] PINMUX_MIO_PAD_ATTR_45 + 4'b 0111, // index[264] PINMUX_MIO_PAD_ATTR_46 + 4'b 0001, // index[265] PINMUX_DIO_PAD_ATTR_REGWEN_0 + 4'b 0001, // index[266] PINMUX_DIO_PAD_ATTR_REGWEN_1 + 4'b 0001, // index[267] PINMUX_DIO_PAD_ATTR_REGWEN_2 + 4'b 0001, // index[268] PINMUX_DIO_PAD_ATTR_REGWEN_3 + 4'b 0001, // index[269] PINMUX_DIO_PAD_ATTR_REGWEN_4 + 4'b 0001, // index[270] PINMUX_DIO_PAD_ATTR_REGWEN_5 + 4'b 0001, // index[271] PINMUX_DIO_PAD_ATTR_REGWEN_6 + 4'b 0001, // index[272] PINMUX_DIO_PAD_ATTR_REGWEN_7 + 4'b 0001, // index[273] PINMUX_DIO_PAD_ATTR_REGWEN_8 + 4'b 0001, // index[274] PINMUX_DIO_PAD_ATTR_REGWEN_9 + 4'b 0001, // index[275] PINMUX_DIO_PAD_ATTR_REGWEN_10 + 4'b 0001, // index[276] PINMUX_DIO_PAD_ATTR_REGWEN_11 + 4'b 0001, // index[277] PINMUX_DIO_PAD_ATTR_REGWEN_12 + 4'b 0001, // index[278] PINMUX_DIO_PAD_ATTR_REGWEN_13 + 4'b 0111, // index[279] PINMUX_DIO_PAD_ATTR_0 + 4'b 0111, // index[280] PINMUX_DIO_PAD_ATTR_1 + 4'b 0111, // index[281] PINMUX_DIO_PAD_ATTR_2 + 4'b 0111, // index[282] PINMUX_DIO_PAD_ATTR_3 + 4'b 0111, // index[283] PINMUX_DIO_PAD_ATTR_4 + 4'b 0111, // index[284] PINMUX_DIO_PAD_ATTR_5 + 4'b 0111, // index[285] PINMUX_DIO_PAD_ATTR_6 + 4'b 0111, // index[286] PINMUX_DIO_PAD_ATTR_7 + 4'b 0111, // index[287] PINMUX_DIO_PAD_ATTR_8 + 4'b 0111, // index[288] PINMUX_DIO_PAD_ATTR_9 + 4'b 0111, // index[289] PINMUX_DIO_PAD_ATTR_10 + 4'b 0111, // index[290] PINMUX_DIO_PAD_ATTR_11 + 4'b 0111, // index[291] PINMUX_DIO_PAD_ATTR_12 + 4'b 0111, // index[292] PINMUX_DIO_PAD_ATTR_13 + 4'b 1111, // index[293] PINMUX_MIO_PAD_SLEEP_STATUS_0 + 4'b 0011, // index[294] PINMUX_MIO_PAD_SLEEP_STATUS_1 + 4'b 0001, // index[295] PINMUX_MIO_PAD_SLEEP_REGWEN_0 + 4'b 0001, // index[296] PINMUX_MIO_PAD_SLEEP_REGWEN_1 + 4'b 0001, // index[297] PINMUX_MIO_PAD_SLEEP_REGWEN_2 + 4'b 0001, // index[298] PINMUX_MIO_PAD_SLEEP_REGWEN_3 + 4'b 0001, // index[299] PINMUX_MIO_PAD_SLEEP_REGWEN_4 + 4'b 0001, // index[300] PINMUX_MIO_PAD_SLEEP_REGWEN_5 + 4'b 0001, // index[301] PINMUX_MIO_PAD_SLEEP_REGWEN_6 + 4'b 0001, // index[302] PINMUX_MIO_PAD_SLEEP_REGWEN_7 + 4'b 0001, // index[303] PINMUX_MIO_PAD_SLEEP_REGWEN_8 + 4'b 0001, // index[304] PINMUX_MIO_PAD_SLEEP_REGWEN_9 + 4'b 0001, // index[305] PINMUX_MIO_PAD_SLEEP_REGWEN_10 + 4'b 0001, // index[306] PINMUX_MIO_PAD_SLEEP_REGWEN_11 + 4'b 0001, // index[307] PINMUX_MIO_PAD_SLEEP_REGWEN_12 + 4'b 0001, // index[308] PINMUX_MIO_PAD_SLEEP_REGWEN_13 + 4'b 0001, // index[309] PINMUX_MIO_PAD_SLEEP_REGWEN_14 + 4'b 0001, // index[310] PINMUX_MIO_PAD_SLEEP_REGWEN_15 + 4'b 0001, // index[311] PINMUX_MIO_PAD_SLEEP_REGWEN_16 + 4'b 0001, // index[312] PINMUX_MIO_PAD_SLEEP_REGWEN_17 + 4'b 0001, // index[313] PINMUX_MIO_PAD_SLEEP_REGWEN_18 + 4'b 0001, // index[314] PINMUX_MIO_PAD_SLEEP_REGWEN_19 + 4'b 0001, // index[315] PINMUX_MIO_PAD_SLEEP_REGWEN_20 + 4'b 0001, // index[316] PINMUX_MIO_PAD_SLEEP_REGWEN_21 + 4'b 0001, // index[317] PINMUX_MIO_PAD_SLEEP_REGWEN_22 + 4'b 0001, // index[318] PINMUX_MIO_PAD_SLEEP_REGWEN_23 + 4'b 0001, // index[319] PINMUX_MIO_PAD_SLEEP_REGWEN_24 + 4'b 0001, // index[320] PINMUX_MIO_PAD_SLEEP_REGWEN_25 + 4'b 0001, // index[321] PINMUX_MIO_PAD_SLEEP_REGWEN_26 + 4'b 0001, // index[322] PINMUX_MIO_PAD_SLEEP_REGWEN_27 + 4'b 0001, // index[323] PINMUX_MIO_PAD_SLEEP_REGWEN_28 + 4'b 0001, // index[324] PINMUX_MIO_PAD_SLEEP_REGWEN_29 + 4'b 0001, // index[325] PINMUX_MIO_PAD_SLEEP_REGWEN_30 + 4'b 0001, // index[326] PINMUX_MIO_PAD_SLEEP_REGWEN_31 + 4'b 0001, // index[327] PINMUX_MIO_PAD_SLEEP_REGWEN_32 + 4'b 0001, // index[328] PINMUX_MIO_PAD_SLEEP_REGWEN_33 + 4'b 0001, // index[329] PINMUX_MIO_PAD_SLEEP_REGWEN_34 + 4'b 0001, // index[330] PINMUX_MIO_PAD_SLEEP_REGWEN_35 + 4'b 0001, // index[331] PINMUX_MIO_PAD_SLEEP_REGWEN_36 + 4'b 0001, // index[332] PINMUX_MIO_PAD_SLEEP_REGWEN_37 + 4'b 0001, // index[333] PINMUX_MIO_PAD_SLEEP_REGWEN_38 + 4'b 0001, // index[334] PINMUX_MIO_PAD_SLEEP_REGWEN_39 + 4'b 0001, // index[335] PINMUX_MIO_PAD_SLEEP_REGWEN_40 + 4'b 0001, // index[336] PINMUX_MIO_PAD_SLEEP_REGWEN_41 + 4'b 0001, // index[337] PINMUX_MIO_PAD_SLEEP_REGWEN_42 + 4'b 0001, // index[338] PINMUX_MIO_PAD_SLEEP_REGWEN_43 + 4'b 0001, // index[339] PINMUX_MIO_PAD_SLEEP_REGWEN_44 + 4'b 0001, // index[340] PINMUX_MIO_PAD_SLEEP_REGWEN_45 + 4'b 0001, // index[341] PINMUX_MIO_PAD_SLEEP_REGWEN_46 + 4'b 0001, // index[342] PINMUX_MIO_PAD_SLEEP_EN_0 + 4'b 0001, // index[343] PINMUX_MIO_PAD_SLEEP_EN_1 + 4'b 0001, // index[344] PINMUX_MIO_PAD_SLEEP_EN_2 + 4'b 0001, // index[345] PINMUX_MIO_PAD_SLEEP_EN_3 + 4'b 0001, // index[346] PINMUX_MIO_PAD_SLEEP_EN_4 + 4'b 0001, // index[347] PINMUX_MIO_PAD_SLEEP_EN_5 + 4'b 0001, // index[348] PINMUX_MIO_PAD_SLEEP_EN_6 + 4'b 0001, // index[349] PINMUX_MIO_PAD_SLEEP_EN_7 + 4'b 0001, // index[350] PINMUX_MIO_PAD_SLEEP_EN_8 + 4'b 0001, // index[351] PINMUX_MIO_PAD_SLEEP_EN_9 + 4'b 0001, // index[352] PINMUX_MIO_PAD_SLEEP_EN_10 + 4'b 0001, // index[353] PINMUX_MIO_PAD_SLEEP_EN_11 + 4'b 0001, // index[354] PINMUX_MIO_PAD_SLEEP_EN_12 + 4'b 0001, // index[355] PINMUX_MIO_PAD_SLEEP_EN_13 + 4'b 0001, // index[356] PINMUX_MIO_PAD_SLEEP_EN_14 + 4'b 0001, // index[357] PINMUX_MIO_PAD_SLEEP_EN_15 + 4'b 0001, // index[358] PINMUX_MIO_PAD_SLEEP_EN_16 + 4'b 0001, // index[359] PINMUX_MIO_PAD_SLEEP_EN_17 + 4'b 0001, // index[360] PINMUX_MIO_PAD_SLEEP_EN_18 + 4'b 0001, // index[361] PINMUX_MIO_PAD_SLEEP_EN_19 + 4'b 0001, // index[362] PINMUX_MIO_PAD_SLEEP_EN_20 + 4'b 0001, // index[363] PINMUX_MIO_PAD_SLEEP_EN_21 + 4'b 0001, // index[364] PINMUX_MIO_PAD_SLEEP_EN_22 + 4'b 0001, // index[365] PINMUX_MIO_PAD_SLEEP_EN_23 + 4'b 0001, // index[366] PINMUX_MIO_PAD_SLEEP_EN_24 + 4'b 0001, // index[367] PINMUX_MIO_PAD_SLEEP_EN_25 + 4'b 0001, // index[368] PINMUX_MIO_PAD_SLEEP_EN_26 + 4'b 0001, // index[369] PINMUX_MIO_PAD_SLEEP_EN_27 + 4'b 0001, // index[370] PINMUX_MIO_PAD_SLEEP_EN_28 + 4'b 0001, // index[371] PINMUX_MIO_PAD_SLEEP_EN_29 + 4'b 0001, // index[372] PINMUX_MIO_PAD_SLEEP_EN_30 + 4'b 0001, // index[373] PINMUX_MIO_PAD_SLEEP_EN_31 + 4'b 0001, // index[374] PINMUX_MIO_PAD_SLEEP_EN_32 + 4'b 0001, // index[375] PINMUX_MIO_PAD_SLEEP_EN_33 + 4'b 0001, // index[376] PINMUX_MIO_PAD_SLEEP_EN_34 + 4'b 0001, // index[377] PINMUX_MIO_PAD_SLEEP_EN_35 + 4'b 0001, // index[378] PINMUX_MIO_PAD_SLEEP_EN_36 + 4'b 0001, // index[379] PINMUX_MIO_PAD_SLEEP_EN_37 + 4'b 0001, // index[380] PINMUX_MIO_PAD_SLEEP_EN_38 + 4'b 0001, // index[381] PINMUX_MIO_PAD_SLEEP_EN_39 + 4'b 0001, // index[382] PINMUX_MIO_PAD_SLEEP_EN_40 + 4'b 0001, // index[383] PINMUX_MIO_PAD_SLEEP_EN_41 + 4'b 0001, // index[384] PINMUX_MIO_PAD_SLEEP_EN_42 + 4'b 0001, // index[385] PINMUX_MIO_PAD_SLEEP_EN_43 + 4'b 0001, // index[386] PINMUX_MIO_PAD_SLEEP_EN_44 + 4'b 0001, // index[387] PINMUX_MIO_PAD_SLEEP_EN_45 + 4'b 0001, // index[388] PINMUX_MIO_PAD_SLEEP_EN_46 + 4'b 0001, // index[389] PINMUX_MIO_PAD_SLEEP_MODE_0 + 4'b 0001, // index[390] PINMUX_MIO_PAD_SLEEP_MODE_1 + 4'b 0001, // index[391] PINMUX_MIO_PAD_SLEEP_MODE_2 + 4'b 0001, // index[392] PINMUX_MIO_PAD_SLEEP_MODE_3 + 4'b 0001, // index[393] PINMUX_MIO_PAD_SLEEP_MODE_4 + 4'b 0001, // index[394] PINMUX_MIO_PAD_SLEEP_MODE_5 + 4'b 0001, // index[395] PINMUX_MIO_PAD_SLEEP_MODE_6 + 4'b 0001, // index[396] PINMUX_MIO_PAD_SLEEP_MODE_7 + 4'b 0001, // index[397] PINMUX_MIO_PAD_SLEEP_MODE_8 + 4'b 0001, // index[398] PINMUX_MIO_PAD_SLEEP_MODE_9 + 4'b 0001, // index[399] PINMUX_MIO_PAD_SLEEP_MODE_10 + 4'b 0001, // index[400] PINMUX_MIO_PAD_SLEEP_MODE_11 + 4'b 0001, // index[401] PINMUX_MIO_PAD_SLEEP_MODE_12 + 4'b 0001, // index[402] PINMUX_MIO_PAD_SLEEP_MODE_13 + 4'b 0001, // index[403] PINMUX_MIO_PAD_SLEEP_MODE_14 + 4'b 0001, // index[404] PINMUX_MIO_PAD_SLEEP_MODE_15 + 4'b 0001, // index[405] PINMUX_MIO_PAD_SLEEP_MODE_16 + 4'b 0001, // index[406] PINMUX_MIO_PAD_SLEEP_MODE_17 + 4'b 0001, // index[407] PINMUX_MIO_PAD_SLEEP_MODE_18 + 4'b 0001, // index[408] PINMUX_MIO_PAD_SLEEP_MODE_19 + 4'b 0001, // index[409] PINMUX_MIO_PAD_SLEEP_MODE_20 + 4'b 0001, // index[410] PINMUX_MIO_PAD_SLEEP_MODE_21 + 4'b 0001, // index[411] PINMUX_MIO_PAD_SLEEP_MODE_22 + 4'b 0001, // index[412] PINMUX_MIO_PAD_SLEEP_MODE_23 + 4'b 0001, // index[413] PINMUX_MIO_PAD_SLEEP_MODE_24 + 4'b 0001, // index[414] PINMUX_MIO_PAD_SLEEP_MODE_25 + 4'b 0001, // index[415] PINMUX_MIO_PAD_SLEEP_MODE_26 + 4'b 0001, // index[416] PINMUX_MIO_PAD_SLEEP_MODE_27 + 4'b 0001, // index[417] PINMUX_MIO_PAD_SLEEP_MODE_28 + 4'b 0001, // index[418] PINMUX_MIO_PAD_SLEEP_MODE_29 + 4'b 0001, // index[419] PINMUX_MIO_PAD_SLEEP_MODE_30 + 4'b 0001, // index[420] PINMUX_MIO_PAD_SLEEP_MODE_31 + 4'b 0001, // index[421] PINMUX_MIO_PAD_SLEEP_MODE_32 + 4'b 0001, // index[422] PINMUX_MIO_PAD_SLEEP_MODE_33 + 4'b 0001, // index[423] PINMUX_MIO_PAD_SLEEP_MODE_34 + 4'b 0001, // index[424] PINMUX_MIO_PAD_SLEEP_MODE_35 + 4'b 0001, // index[425] PINMUX_MIO_PAD_SLEEP_MODE_36 + 4'b 0001, // index[426] PINMUX_MIO_PAD_SLEEP_MODE_37 + 4'b 0001, // index[427] PINMUX_MIO_PAD_SLEEP_MODE_38 + 4'b 0001, // index[428] PINMUX_MIO_PAD_SLEEP_MODE_39 + 4'b 0001, // index[429] PINMUX_MIO_PAD_SLEEP_MODE_40 + 4'b 0001, // index[430] PINMUX_MIO_PAD_SLEEP_MODE_41 + 4'b 0001, // index[431] PINMUX_MIO_PAD_SLEEP_MODE_42 + 4'b 0001, // index[432] PINMUX_MIO_PAD_SLEEP_MODE_43 + 4'b 0001, // index[433] PINMUX_MIO_PAD_SLEEP_MODE_44 + 4'b 0001, // index[434] PINMUX_MIO_PAD_SLEEP_MODE_45 + 4'b 0001, // index[435] PINMUX_MIO_PAD_SLEEP_MODE_46 + 4'b 0011, // index[436] PINMUX_DIO_PAD_SLEEP_STATUS + 4'b 0001, // index[437] PINMUX_DIO_PAD_SLEEP_REGWEN_0 + 4'b 0001, // index[438] PINMUX_DIO_PAD_SLEEP_REGWEN_1 + 4'b 0001, // index[439] PINMUX_DIO_PAD_SLEEP_REGWEN_2 + 4'b 0001, // index[440] PINMUX_DIO_PAD_SLEEP_REGWEN_3 + 4'b 0001, // index[441] PINMUX_DIO_PAD_SLEEP_REGWEN_4 + 4'b 0001, // index[442] PINMUX_DIO_PAD_SLEEP_REGWEN_5 + 4'b 0001, // index[443] PINMUX_DIO_PAD_SLEEP_REGWEN_6 + 4'b 0001, // index[444] PINMUX_DIO_PAD_SLEEP_REGWEN_7 + 4'b 0001, // index[445] PINMUX_DIO_PAD_SLEEP_REGWEN_8 + 4'b 0001, // index[446] PINMUX_DIO_PAD_SLEEP_REGWEN_9 + 4'b 0001, // index[447] PINMUX_DIO_PAD_SLEEP_REGWEN_10 + 4'b 0001, // index[448] PINMUX_DIO_PAD_SLEEP_REGWEN_11 + 4'b 0001, // index[449] PINMUX_DIO_PAD_SLEEP_REGWEN_12 + 4'b 0001, // index[450] PINMUX_DIO_PAD_SLEEP_REGWEN_13 + 4'b 0001, // index[451] PINMUX_DIO_PAD_SLEEP_EN_0 + 4'b 0001, // index[452] PINMUX_DIO_PAD_SLEEP_EN_1 + 4'b 0001, // index[453] PINMUX_DIO_PAD_SLEEP_EN_2 + 4'b 0001, // index[454] PINMUX_DIO_PAD_SLEEP_EN_3 + 4'b 0001, // index[455] PINMUX_DIO_PAD_SLEEP_EN_4 + 4'b 0001, // index[456] PINMUX_DIO_PAD_SLEEP_EN_5 + 4'b 0001, // index[457] PINMUX_DIO_PAD_SLEEP_EN_6 + 4'b 0001, // index[458] PINMUX_DIO_PAD_SLEEP_EN_7 + 4'b 0001, // index[459] PINMUX_DIO_PAD_SLEEP_EN_8 + 4'b 0001, // index[460] PINMUX_DIO_PAD_SLEEP_EN_9 + 4'b 0001, // index[461] PINMUX_DIO_PAD_SLEEP_EN_10 + 4'b 0001, // index[462] PINMUX_DIO_PAD_SLEEP_EN_11 + 4'b 0001, // index[463] PINMUX_DIO_PAD_SLEEP_EN_12 + 4'b 0001, // index[464] PINMUX_DIO_PAD_SLEEP_EN_13 + 4'b 0001, // index[465] PINMUX_DIO_PAD_SLEEP_MODE_0 + 4'b 0001, // index[466] PINMUX_DIO_PAD_SLEEP_MODE_1 + 4'b 0001, // index[467] PINMUX_DIO_PAD_SLEEP_MODE_2 + 4'b 0001, // index[468] PINMUX_DIO_PAD_SLEEP_MODE_3 + 4'b 0001, // index[469] PINMUX_DIO_PAD_SLEEP_MODE_4 + 4'b 0001, // index[470] PINMUX_DIO_PAD_SLEEP_MODE_5 + 4'b 0001, // index[471] PINMUX_DIO_PAD_SLEEP_MODE_6 + 4'b 0001, // index[472] PINMUX_DIO_PAD_SLEEP_MODE_7 + 4'b 0001, // index[473] PINMUX_DIO_PAD_SLEEP_MODE_8 + 4'b 0001, // index[474] PINMUX_DIO_PAD_SLEEP_MODE_9 + 4'b 0001, // index[475] PINMUX_DIO_PAD_SLEEP_MODE_10 + 4'b 0001, // index[476] PINMUX_DIO_PAD_SLEEP_MODE_11 + 4'b 0001, // index[477] PINMUX_DIO_PAD_SLEEP_MODE_12 + 4'b 0001, // index[478] PINMUX_DIO_PAD_SLEEP_MODE_13 + 4'b 0001, // index[479] PINMUX_WKUP_DETECTOR_REGWEN_0 + 4'b 0001, // index[480] PINMUX_WKUP_DETECTOR_REGWEN_1 + 4'b 0001, // index[481] PINMUX_WKUP_DETECTOR_REGWEN_2 + 4'b 0001, // index[482] PINMUX_WKUP_DETECTOR_REGWEN_3 + 4'b 0001, // index[483] PINMUX_WKUP_DETECTOR_REGWEN_4 + 4'b 0001, // index[484] PINMUX_WKUP_DETECTOR_REGWEN_5 + 4'b 0001, // index[485] PINMUX_WKUP_DETECTOR_REGWEN_6 + 4'b 0001, // index[486] PINMUX_WKUP_DETECTOR_REGWEN_7 + 4'b 0001, // index[487] PINMUX_WKUP_DETECTOR_EN_0 + 4'b 0001, // index[488] PINMUX_WKUP_DETECTOR_EN_1 + 4'b 0001, // index[489] PINMUX_WKUP_DETECTOR_EN_2 + 4'b 0001, // index[490] PINMUX_WKUP_DETECTOR_EN_3 + 4'b 0001, // index[491] PINMUX_WKUP_DETECTOR_EN_4 + 4'b 0001, // index[492] PINMUX_WKUP_DETECTOR_EN_5 + 4'b 0001, // index[493] PINMUX_WKUP_DETECTOR_EN_6 + 4'b 0001, // index[494] PINMUX_WKUP_DETECTOR_EN_7 + 4'b 0001, // index[495] PINMUX_WKUP_DETECTOR_0 + 4'b 0001, // index[496] PINMUX_WKUP_DETECTOR_1 + 4'b 0001, // index[497] PINMUX_WKUP_DETECTOR_2 + 4'b 0001, // index[498] PINMUX_WKUP_DETECTOR_3 + 4'b 0001, // index[499] PINMUX_WKUP_DETECTOR_4 + 4'b 0001, // index[500] PINMUX_WKUP_DETECTOR_5 + 4'b 0001, // index[501] PINMUX_WKUP_DETECTOR_6 + 4'b 0001, // index[502] PINMUX_WKUP_DETECTOR_7 + 4'b 0001, // index[503] PINMUX_WKUP_DETECTOR_CNT_TH_0 + 4'b 0001, // index[504] PINMUX_WKUP_DETECTOR_CNT_TH_1 + 4'b 0001, // index[505] PINMUX_WKUP_DETECTOR_CNT_TH_2 + 4'b 0001, // index[506] PINMUX_WKUP_DETECTOR_CNT_TH_3 + 4'b 0001, // index[507] PINMUX_WKUP_DETECTOR_CNT_TH_4 + 4'b 0001, // index[508] PINMUX_WKUP_DETECTOR_CNT_TH_5 + 4'b 0001, // index[509] PINMUX_WKUP_DETECTOR_CNT_TH_6 + 4'b 0001, // index[510] PINMUX_WKUP_DETECTOR_CNT_TH_7 + 4'b 0001, // index[511] PINMUX_WKUP_DETECTOR_PADSEL_0 + 4'b 0001, // index[512] PINMUX_WKUP_DETECTOR_PADSEL_1 + 4'b 0001, // index[513] PINMUX_WKUP_DETECTOR_PADSEL_2 + 4'b 0001, // index[514] PINMUX_WKUP_DETECTOR_PADSEL_3 + 4'b 0001, // index[515] PINMUX_WKUP_DETECTOR_PADSEL_4 + 4'b 0001, // index[516] PINMUX_WKUP_DETECTOR_PADSEL_5 + 4'b 0001, // index[517] PINMUX_WKUP_DETECTOR_PADSEL_6 + 4'b 0001, // index[518] PINMUX_WKUP_DETECTOR_PADSEL_7 + 4'b 0001 // index[519] PINMUX_WKUP_CAUSE + }; + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_top.sv new file mode 100644 index 0000000000000..c320d10d3d5d5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_reg_top.sv @@ -0,0 +1,37746 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 pinmux_reg_top ( + input clk_i, + input rst_ni, + input clk_aon_i, + input rst_aon_ni, + input tlul_pkg::tl_h2d_t tl_i, + output tlul_pkg::tl_d2h_t tl_o, + // To HW + output pinmux_reg_pkg::pinmux_reg2hw_t reg2hw, // Write + input pinmux_reg_pkg::pinmux_hw2reg_t hw2reg, // Read + + // Integrity check errors + output logic intg_err_o +); + + import pinmux_reg_pkg::* ; + + localparam int AW = 12; + 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 [519:0] reg_we_check; + prim_reg_we_check #( + .OneHotWidth(520) + ) 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 = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic alert_test_we; + logic alert_test_wd; + logic mio_periph_insel_regwen_0_we; + logic mio_periph_insel_regwen_0_qs; + logic mio_periph_insel_regwen_0_wd; + logic mio_periph_insel_regwen_1_we; + logic mio_periph_insel_regwen_1_qs; + logic mio_periph_insel_regwen_1_wd; + logic mio_periph_insel_regwen_2_we; + logic mio_periph_insel_regwen_2_qs; + logic mio_periph_insel_regwen_2_wd; + logic mio_periph_insel_regwen_3_we; + logic mio_periph_insel_regwen_3_qs; + logic mio_periph_insel_regwen_3_wd; + logic mio_periph_insel_regwen_4_we; + logic mio_periph_insel_regwen_4_qs; + logic mio_periph_insel_regwen_4_wd; + logic mio_periph_insel_regwen_5_we; + logic mio_periph_insel_regwen_5_qs; + logic mio_periph_insel_regwen_5_wd; + logic mio_periph_insel_regwen_6_we; + logic mio_periph_insel_regwen_6_qs; + logic mio_periph_insel_regwen_6_wd; + logic mio_periph_insel_regwen_7_we; + logic mio_periph_insel_regwen_7_qs; + logic mio_periph_insel_regwen_7_wd; + logic mio_periph_insel_regwen_8_we; + logic mio_periph_insel_regwen_8_qs; + logic mio_periph_insel_regwen_8_wd; + logic mio_periph_insel_regwen_9_we; + logic mio_periph_insel_regwen_9_qs; + logic mio_periph_insel_regwen_9_wd; + logic mio_periph_insel_regwen_10_we; + logic mio_periph_insel_regwen_10_qs; + logic mio_periph_insel_regwen_10_wd; + logic mio_periph_insel_regwen_11_we; + logic mio_periph_insel_regwen_11_qs; + logic mio_periph_insel_regwen_11_wd; + logic mio_periph_insel_regwen_12_we; + logic mio_periph_insel_regwen_12_qs; + logic mio_periph_insel_regwen_12_wd; + logic mio_periph_insel_regwen_13_we; + logic mio_periph_insel_regwen_13_qs; + logic mio_periph_insel_regwen_13_wd; + logic mio_periph_insel_regwen_14_we; + logic mio_periph_insel_regwen_14_qs; + logic mio_periph_insel_regwen_14_wd; + logic mio_periph_insel_regwen_15_we; + logic mio_periph_insel_regwen_15_qs; + logic mio_periph_insel_regwen_15_wd; + logic mio_periph_insel_regwen_16_we; + logic mio_periph_insel_regwen_16_qs; + logic mio_periph_insel_regwen_16_wd; + logic mio_periph_insel_regwen_17_we; + logic mio_periph_insel_regwen_17_qs; + logic mio_periph_insel_regwen_17_wd; + logic mio_periph_insel_regwen_18_we; + logic mio_periph_insel_regwen_18_qs; + logic mio_periph_insel_regwen_18_wd; + logic mio_periph_insel_regwen_19_we; + logic mio_periph_insel_regwen_19_qs; + logic mio_periph_insel_regwen_19_wd; + logic mio_periph_insel_regwen_20_we; + logic mio_periph_insel_regwen_20_qs; + logic mio_periph_insel_regwen_20_wd; + logic mio_periph_insel_regwen_21_we; + logic mio_periph_insel_regwen_21_qs; + logic mio_periph_insel_regwen_21_wd; + logic mio_periph_insel_regwen_22_we; + logic mio_periph_insel_regwen_22_qs; + logic mio_periph_insel_regwen_22_wd; + logic mio_periph_insel_regwen_23_we; + logic mio_periph_insel_regwen_23_qs; + logic mio_periph_insel_regwen_23_wd; + logic mio_periph_insel_regwen_24_we; + logic mio_periph_insel_regwen_24_qs; + logic mio_periph_insel_regwen_24_wd; + logic mio_periph_insel_regwen_25_we; + logic mio_periph_insel_regwen_25_qs; + logic mio_periph_insel_regwen_25_wd; + logic mio_periph_insel_regwen_26_we; + logic mio_periph_insel_regwen_26_qs; + logic mio_periph_insel_regwen_26_wd; + logic mio_periph_insel_regwen_27_we; + logic mio_periph_insel_regwen_27_qs; + logic mio_periph_insel_regwen_27_wd; + logic mio_periph_insel_regwen_28_we; + logic mio_periph_insel_regwen_28_qs; + logic mio_periph_insel_regwen_28_wd; + logic mio_periph_insel_regwen_29_we; + logic mio_periph_insel_regwen_29_qs; + logic mio_periph_insel_regwen_29_wd; + logic mio_periph_insel_regwen_30_we; + logic mio_periph_insel_regwen_30_qs; + logic mio_periph_insel_regwen_30_wd; + logic mio_periph_insel_regwen_31_we; + logic mio_periph_insel_regwen_31_qs; + logic mio_periph_insel_regwen_31_wd; + logic mio_periph_insel_regwen_32_we; + logic mio_periph_insel_regwen_32_qs; + logic mio_periph_insel_regwen_32_wd; + logic mio_periph_insel_regwen_33_we; + logic mio_periph_insel_regwen_33_qs; + logic mio_periph_insel_regwen_33_wd; + logic mio_periph_insel_regwen_34_we; + logic mio_periph_insel_regwen_34_qs; + logic mio_periph_insel_regwen_34_wd; + logic mio_periph_insel_regwen_35_we; + logic mio_periph_insel_regwen_35_qs; + logic mio_periph_insel_regwen_35_wd; + logic mio_periph_insel_regwen_36_we; + logic mio_periph_insel_regwen_36_qs; + logic mio_periph_insel_regwen_36_wd; + logic mio_periph_insel_regwen_37_we; + logic mio_periph_insel_regwen_37_qs; + logic mio_periph_insel_regwen_37_wd; + logic mio_periph_insel_0_we; + logic [5:0] mio_periph_insel_0_qs; + logic [5:0] mio_periph_insel_0_wd; + logic mio_periph_insel_1_we; + logic [5:0] mio_periph_insel_1_qs; + logic [5:0] mio_periph_insel_1_wd; + logic mio_periph_insel_2_we; + logic [5:0] mio_periph_insel_2_qs; + logic [5:0] mio_periph_insel_2_wd; + logic mio_periph_insel_3_we; + logic [5:0] mio_periph_insel_3_qs; + logic [5:0] mio_periph_insel_3_wd; + logic mio_periph_insel_4_we; + logic [5:0] mio_periph_insel_4_qs; + logic [5:0] mio_periph_insel_4_wd; + logic mio_periph_insel_5_we; + logic [5:0] mio_periph_insel_5_qs; + logic [5:0] mio_periph_insel_5_wd; + logic mio_periph_insel_6_we; + logic [5:0] mio_periph_insel_6_qs; + logic [5:0] mio_periph_insel_6_wd; + logic mio_periph_insel_7_we; + logic [5:0] mio_periph_insel_7_qs; + logic [5:0] mio_periph_insel_7_wd; + logic mio_periph_insel_8_we; + logic [5:0] mio_periph_insel_8_qs; + logic [5:0] mio_periph_insel_8_wd; + logic mio_periph_insel_9_we; + logic [5:0] mio_periph_insel_9_qs; + logic [5:0] mio_periph_insel_9_wd; + logic mio_periph_insel_10_we; + logic [5:0] mio_periph_insel_10_qs; + logic [5:0] mio_periph_insel_10_wd; + logic mio_periph_insel_11_we; + logic [5:0] mio_periph_insel_11_qs; + logic [5:0] mio_periph_insel_11_wd; + logic mio_periph_insel_12_we; + logic [5:0] mio_periph_insel_12_qs; + logic [5:0] mio_periph_insel_12_wd; + logic mio_periph_insel_13_we; + logic [5:0] mio_periph_insel_13_qs; + logic [5:0] mio_periph_insel_13_wd; + logic mio_periph_insel_14_we; + logic [5:0] mio_periph_insel_14_qs; + logic [5:0] mio_periph_insel_14_wd; + logic mio_periph_insel_15_we; + logic [5:0] mio_periph_insel_15_qs; + logic [5:0] mio_periph_insel_15_wd; + logic mio_periph_insel_16_we; + logic [5:0] mio_periph_insel_16_qs; + logic [5:0] mio_periph_insel_16_wd; + logic mio_periph_insel_17_we; + logic [5:0] mio_periph_insel_17_qs; + logic [5:0] mio_periph_insel_17_wd; + logic mio_periph_insel_18_we; + logic [5:0] mio_periph_insel_18_qs; + logic [5:0] mio_periph_insel_18_wd; + logic mio_periph_insel_19_we; + logic [5:0] mio_periph_insel_19_qs; + logic [5:0] mio_periph_insel_19_wd; + logic mio_periph_insel_20_we; + logic [5:0] mio_periph_insel_20_qs; + logic [5:0] mio_periph_insel_20_wd; + logic mio_periph_insel_21_we; + logic [5:0] mio_periph_insel_21_qs; + logic [5:0] mio_periph_insel_21_wd; + logic mio_periph_insel_22_we; + logic [5:0] mio_periph_insel_22_qs; + logic [5:0] mio_periph_insel_22_wd; + logic mio_periph_insel_23_we; + logic [5:0] mio_periph_insel_23_qs; + logic [5:0] mio_periph_insel_23_wd; + logic mio_periph_insel_24_we; + logic [5:0] mio_periph_insel_24_qs; + logic [5:0] mio_periph_insel_24_wd; + logic mio_periph_insel_25_we; + logic [5:0] mio_periph_insel_25_qs; + logic [5:0] mio_periph_insel_25_wd; + logic mio_periph_insel_26_we; + logic [5:0] mio_periph_insel_26_qs; + logic [5:0] mio_periph_insel_26_wd; + logic mio_periph_insel_27_we; + logic [5:0] mio_periph_insel_27_qs; + logic [5:0] mio_periph_insel_27_wd; + logic mio_periph_insel_28_we; + logic [5:0] mio_periph_insel_28_qs; + logic [5:0] mio_periph_insel_28_wd; + logic mio_periph_insel_29_we; + logic [5:0] mio_periph_insel_29_qs; + logic [5:0] mio_periph_insel_29_wd; + logic mio_periph_insel_30_we; + logic [5:0] mio_periph_insel_30_qs; + logic [5:0] mio_periph_insel_30_wd; + logic mio_periph_insel_31_we; + logic [5:0] mio_periph_insel_31_qs; + logic [5:0] mio_periph_insel_31_wd; + logic mio_periph_insel_32_we; + logic [5:0] mio_periph_insel_32_qs; + logic [5:0] mio_periph_insel_32_wd; + logic mio_periph_insel_33_we; + logic [5:0] mio_periph_insel_33_qs; + logic [5:0] mio_periph_insel_33_wd; + logic mio_periph_insel_34_we; + logic [5:0] mio_periph_insel_34_qs; + logic [5:0] mio_periph_insel_34_wd; + logic mio_periph_insel_35_we; + logic [5:0] mio_periph_insel_35_qs; + logic [5:0] mio_periph_insel_35_wd; + logic mio_periph_insel_36_we; + logic [5:0] mio_periph_insel_36_qs; + logic [5:0] mio_periph_insel_36_wd; + logic mio_periph_insel_37_we; + logic [5:0] mio_periph_insel_37_qs; + logic [5:0] mio_periph_insel_37_wd; + logic mio_outsel_regwen_0_we; + logic mio_outsel_regwen_0_qs; + logic mio_outsel_regwen_0_wd; + logic mio_outsel_regwen_1_we; + logic mio_outsel_regwen_1_qs; + logic mio_outsel_regwen_1_wd; + logic mio_outsel_regwen_2_we; + logic mio_outsel_regwen_2_qs; + logic mio_outsel_regwen_2_wd; + logic mio_outsel_regwen_3_we; + logic mio_outsel_regwen_3_qs; + logic mio_outsel_regwen_3_wd; + logic mio_outsel_regwen_4_we; + logic mio_outsel_regwen_4_qs; + logic mio_outsel_regwen_4_wd; + logic mio_outsel_regwen_5_we; + logic mio_outsel_regwen_5_qs; + logic mio_outsel_regwen_5_wd; + logic mio_outsel_regwen_6_we; + logic mio_outsel_regwen_6_qs; + logic mio_outsel_regwen_6_wd; + logic mio_outsel_regwen_7_we; + logic mio_outsel_regwen_7_qs; + logic mio_outsel_regwen_7_wd; + logic mio_outsel_regwen_8_we; + logic mio_outsel_regwen_8_qs; + logic mio_outsel_regwen_8_wd; + logic mio_outsel_regwen_9_we; + logic mio_outsel_regwen_9_qs; + logic mio_outsel_regwen_9_wd; + logic mio_outsel_regwen_10_we; + logic mio_outsel_regwen_10_qs; + logic mio_outsel_regwen_10_wd; + logic mio_outsel_regwen_11_we; + logic mio_outsel_regwen_11_qs; + logic mio_outsel_regwen_11_wd; + logic mio_outsel_regwen_12_we; + logic mio_outsel_regwen_12_qs; + logic mio_outsel_regwen_12_wd; + logic mio_outsel_regwen_13_we; + logic mio_outsel_regwen_13_qs; + logic mio_outsel_regwen_13_wd; + logic mio_outsel_regwen_14_we; + logic mio_outsel_regwen_14_qs; + logic mio_outsel_regwen_14_wd; + logic mio_outsel_regwen_15_we; + logic mio_outsel_regwen_15_qs; + logic mio_outsel_regwen_15_wd; + logic mio_outsel_regwen_16_we; + logic mio_outsel_regwen_16_qs; + logic mio_outsel_regwen_16_wd; + logic mio_outsel_regwen_17_we; + logic mio_outsel_regwen_17_qs; + logic mio_outsel_regwen_17_wd; + logic mio_outsel_regwen_18_we; + logic mio_outsel_regwen_18_qs; + logic mio_outsel_regwen_18_wd; + logic mio_outsel_regwen_19_we; + logic mio_outsel_regwen_19_qs; + logic mio_outsel_regwen_19_wd; + logic mio_outsel_regwen_20_we; + logic mio_outsel_regwen_20_qs; + logic mio_outsel_regwen_20_wd; + logic mio_outsel_regwen_21_we; + logic mio_outsel_regwen_21_qs; + logic mio_outsel_regwen_21_wd; + logic mio_outsel_regwen_22_we; + logic mio_outsel_regwen_22_qs; + logic mio_outsel_regwen_22_wd; + logic mio_outsel_regwen_23_we; + logic mio_outsel_regwen_23_qs; + logic mio_outsel_regwen_23_wd; + logic mio_outsel_regwen_24_we; + logic mio_outsel_regwen_24_qs; + logic mio_outsel_regwen_24_wd; + logic mio_outsel_regwen_25_we; + logic mio_outsel_regwen_25_qs; + logic mio_outsel_regwen_25_wd; + logic mio_outsel_regwen_26_we; + logic mio_outsel_regwen_26_qs; + logic mio_outsel_regwen_26_wd; + logic mio_outsel_regwen_27_we; + logic mio_outsel_regwen_27_qs; + logic mio_outsel_regwen_27_wd; + logic mio_outsel_regwen_28_we; + logic mio_outsel_regwen_28_qs; + logic mio_outsel_regwen_28_wd; + logic mio_outsel_regwen_29_we; + logic mio_outsel_regwen_29_qs; + logic mio_outsel_regwen_29_wd; + logic mio_outsel_regwen_30_we; + logic mio_outsel_regwen_30_qs; + logic mio_outsel_regwen_30_wd; + logic mio_outsel_regwen_31_we; + logic mio_outsel_regwen_31_qs; + logic mio_outsel_regwen_31_wd; + logic mio_outsel_regwen_32_we; + logic mio_outsel_regwen_32_qs; + logic mio_outsel_regwen_32_wd; + logic mio_outsel_regwen_33_we; + logic mio_outsel_regwen_33_qs; + logic mio_outsel_regwen_33_wd; + logic mio_outsel_regwen_34_we; + logic mio_outsel_regwen_34_qs; + logic mio_outsel_regwen_34_wd; + logic mio_outsel_regwen_35_we; + logic mio_outsel_regwen_35_qs; + logic mio_outsel_regwen_35_wd; + logic mio_outsel_regwen_36_we; + logic mio_outsel_regwen_36_qs; + logic mio_outsel_regwen_36_wd; + logic mio_outsel_regwen_37_we; + logic mio_outsel_regwen_37_qs; + logic mio_outsel_regwen_37_wd; + logic mio_outsel_regwen_38_we; + logic mio_outsel_regwen_38_qs; + logic mio_outsel_regwen_38_wd; + logic mio_outsel_regwen_39_we; + logic mio_outsel_regwen_39_qs; + logic mio_outsel_regwen_39_wd; + logic mio_outsel_regwen_40_we; + logic mio_outsel_regwen_40_qs; + logic mio_outsel_regwen_40_wd; + logic mio_outsel_regwen_41_we; + logic mio_outsel_regwen_41_qs; + logic mio_outsel_regwen_41_wd; + logic mio_outsel_regwen_42_we; + logic mio_outsel_regwen_42_qs; + logic mio_outsel_regwen_42_wd; + logic mio_outsel_regwen_43_we; + logic mio_outsel_regwen_43_qs; + logic mio_outsel_regwen_43_wd; + logic mio_outsel_regwen_44_we; + logic mio_outsel_regwen_44_qs; + logic mio_outsel_regwen_44_wd; + logic mio_outsel_regwen_45_we; + logic mio_outsel_regwen_45_qs; + logic mio_outsel_regwen_45_wd; + logic mio_outsel_regwen_46_we; + logic mio_outsel_regwen_46_qs; + logic mio_outsel_regwen_46_wd; + logic mio_outsel_0_we; + logic [5:0] mio_outsel_0_qs; + logic [5:0] mio_outsel_0_wd; + logic mio_outsel_1_we; + logic [5:0] mio_outsel_1_qs; + logic [5:0] mio_outsel_1_wd; + logic mio_outsel_2_we; + logic [5:0] mio_outsel_2_qs; + logic [5:0] mio_outsel_2_wd; + logic mio_outsel_3_we; + logic [5:0] mio_outsel_3_qs; + logic [5:0] mio_outsel_3_wd; + logic mio_outsel_4_we; + logic [5:0] mio_outsel_4_qs; + logic [5:0] mio_outsel_4_wd; + logic mio_outsel_5_we; + logic [5:0] mio_outsel_5_qs; + logic [5:0] mio_outsel_5_wd; + logic mio_outsel_6_we; + logic [5:0] mio_outsel_6_qs; + logic [5:0] mio_outsel_6_wd; + logic mio_outsel_7_we; + logic [5:0] mio_outsel_7_qs; + logic [5:0] mio_outsel_7_wd; + logic mio_outsel_8_we; + logic [5:0] mio_outsel_8_qs; + logic [5:0] mio_outsel_8_wd; + logic mio_outsel_9_we; + logic [5:0] mio_outsel_9_qs; + logic [5:0] mio_outsel_9_wd; + logic mio_outsel_10_we; + logic [5:0] mio_outsel_10_qs; + logic [5:0] mio_outsel_10_wd; + logic mio_outsel_11_we; + logic [5:0] mio_outsel_11_qs; + logic [5:0] mio_outsel_11_wd; + logic mio_outsel_12_we; + logic [5:0] mio_outsel_12_qs; + logic [5:0] mio_outsel_12_wd; + logic mio_outsel_13_we; + logic [5:0] mio_outsel_13_qs; + logic [5:0] mio_outsel_13_wd; + logic mio_outsel_14_we; + logic [5:0] mio_outsel_14_qs; + logic [5:0] mio_outsel_14_wd; + logic mio_outsel_15_we; + logic [5:0] mio_outsel_15_qs; + logic [5:0] mio_outsel_15_wd; + logic mio_outsel_16_we; + logic [5:0] mio_outsel_16_qs; + logic [5:0] mio_outsel_16_wd; + logic mio_outsel_17_we; + logic [5:0] mio_outsel_17_qs; + logic [5:0] mio_outsel_17_wd; + logic mio_outsel_18_we; + logic [5:0] mio_outsel_18_qs; + logic [5:0] mio_outsel_18_wd; + logic mio_outsel_19_we; + logic [5:0] mio_outsel_19_qs; + logic [5:0] mio_outsel_19_wd; + logic mio_outsel_20_we; + logic [5:0] mio_outsel_20_qs; + logic [5:0] mio_outsel_20_wd; + logic mio_outsel_21_we; + logic [5:0] mio_outsel_21_qs; + logic [5:0] mio_outsel_21_wd; + logic mio_outsel_22_we; + logic [5:0] mio_outsel_22_qs; + logic [5:0] mio_outsel_22_wd; + logic mio_outsel_23_we; + logic [5:0] mio_outsel_23_qs; + logic [5:0] mio_outsel_23_wd; + logic mio_outsel_24_we; + logic [5:0] mio_outsel_24_qs; + logic [5:0] mio_outsel_24_wd; + logic mio_outsel_25_we; + logic [5:0] mio_outsel_25_qs; + logic [5:0] mio_outsel_25_wd; + logic mio_outsel_26_we; + logic [5:0] mio_outsel_26_qs; + logic [5:0] mio_outsel_26_wd; + logic mio_outsel_27_we; + logic [5:0] mio_outsel_27_qs; + logic [5:0] mio_outsel_27_wd; + logic mio_outsel_28_we; + logic [5:0] mio_outsel_28_qs; + logic [5:0] mio_outsel_28_wd; + logic mio_outsel_29_we; + logic [5:0] mio_outsel_29_qs; + logic [5:0] mio_outsel_29_wd; + logic mio_outsel_30_we; + logic [5:0] mio_outsel_30_qs; + logic [5:0] mio_outsel_30_wd; + logic mio_outsel_31_we; + logic [5:0] mio_outsel_31_qs; + logic [5:0] mio_outsel_31_wd; + logic mio_outsel_32_we; + logic [5:0] mio_outsel_32_qs; + logic [5:0] mio_outsel_32_wd; + logic mio_outsel_33_we; + logic [5:0] mio_outsel_33_qs; + logic [5:0] mio_outsel_33_wd; + logic mio_outsel_34_we; + logic [5:0] mio_outsel_34_qs; + logic [5:0] mio_outsel_34_wd; + logic mio_outsel_35_we; + logic [5:0] mio_outsel_35_qs; + logic [5:0] mio_outsel_35_wd; + logic mio_outsel_36_we; + logic [5:0] mio_outsel_36_qs; + logic [5:0] mio_outsel_36_wd; + logic mio_outsel_37_we; + logic [5:0] mio_outsel_37_qs; + logic [5:0] mio_outsel_37_wd; + logic mio_outsel_38_we; + logic [5:0] mio_outsel_38_qs; + logic [5:0] mio_outsel_38_wd; + logic mio_outsel_39_we; + logic [5:0] mio_outsel_39_qs; + logic [5:0] mio_outsel_39_wd; + logic mio_outsel_40_we; + logic [5:0] mio_outsel_40_qs; + logic [5:0] mio_outsel_40_wd; + logic mio_outsel_41_we; + logic [5:0] mio_outsel_41_qs; + logic [5:0] mio_outsel_41_wd; + logic mio_outsel_42_we; + logic [5:0] mio_outsel_42_qs; + logic [5:0] mio_outsel_42_wd; + logic mio_outsel_43_we; + logic [5:0] mio_outsel_43_qs; + logic [5:0] mio_outsel_43_wd; + logic mio_outsel_44_we; + logic [5:0] mio_outsel_44_qs; + logic [5:0] mio_outsel_44_wd; + logic mio_outsel_45_we; + logic [5:0] mio_outsel_45_qs; + logic [5:0] mio_outsel_45_wd; + logic mio_outsel_46_we; + logic [5:0] mio_outsel_46_qs; + logic [5:0] mio_outsel_46_wd; + logic mio_pad_attr_regwen_0_we; + logic mio_pad_attr_regwen_0_qs; + logic mio_pad_attr_regwen_0_wd; + logic mio_pad_attr_regwen_1_we; + logic mio_pad_attr_regwen_1_qs; + logic mio_pad_attr_regwen_1_wd; + logic mio_pad_attr_regwen_2_we; + logic mio_pad_attr_regwen_2_qs; + logic mio_pad_attr_regwen_2_wd; + logic mio_pad_attr_regwen_3_we; + logic mio_pad_attr_regwen_3_qs; + logic mio_pad_attr_regwen_3_wd; + logic mio_pad_attr_regwen_4_we; + logic mio_pad_attr_regwen_4_qs; + logic mio_pad_attr_regwen_4_wd; + logic mio_pad_attr_regwen_5_we; + logic mio_pad_attr_regwen_5_qs; + logic mio_pad_attr_regwen_5_wd; + logic mio_pad_attr_regwen_6_we; + logic mio_pad_attr_regwen_6_qs; + logic mio_pad_attr_regwen_6_wd; + logic mio_pad_attr_regwen_7_we; + logic mio_pad_attr_regwen_7_qs; + logic mio_pad_attr_regwen_7_wd; + logic mio_pad_attr_regwen_8_we; + logic mio_pad_attr_regwen_8_qs; + logic mio_pad_attr_regwen_8_wd; + logic mio_pad_attr_regwen_9_we; + logic mio_pad_attr_regwen_9_qs; + logic mio_pad_attr_regwen_9_wd; + logic mio_pad_attr_regwen_10_we; + logic mio_pad_attr_regwen_10_qs; + logic mio_pad_attr_regwen_10_wd; + logic mio_pad_attr_regwen_11_we; + logic mio_pad_attr_regwen_11_qs; + logic mio_pad_attr_regwen_11_wd; + logic mio_pad_attr_regwen_12_we; + logic mio_pad_attr_regwen_12_qs; + logic mio_pad_attr_regwen_12_wd; + logic mio_pad_attr_regwen_13_we; + logic mio_pad_attr_regwen_13_qs; + logic mio_pad_attr_regwen_13_wd; + logic mio_pad_attr_regwen_14_we; + logic mio_pad_attr_regwen_14_qs; + logic mio_pad_attr_regwen_14_wd; + logic mio_pad_attr_regwen_15_we; + logic mio_pad_attr_regwen_15_qs; + logic mio_pad_attr_regwen_15_wd; + logic mio_pad_attr_regwen_16_we; + logic mio_pad_attr_regwen_16_qs; + logic mio_pad_attr_regwen_16_wd; + logic mio_pad_attr_regwen_17_we; + logic mio_pad_attr_regwen_17_qs; + logic mio_pad_attr_regwen_17_wd; + logic mio_pad_attr_regwen_18_we; + logic mio_pad_attr_regwen_18_qs; + logic mio_pad_attr_regwen_18_wd; + logic mio_pad_attr_regwen_19_we; + logic mio_pad_attr_regwen_19_qs; + logic mio_pad_attr_regwen_19_wd; + logic mio_pad_attr_regwen_20_we; + logic mio_pad_attr_regwen_20_qs; + logic mio_pad_attr_regwen_20_wd; + logic mio_pad_attr_regwen_21_we; + logic mio_pad_attr_regwen_21_qs; + logic mio_pad_attr_regwen_21_wd; + logic mio_pad_attr_regwen_22_we; + logic mio_pad_attr_regwen_22_qs; + logic mio_pad_attr_regwen_22_wd; + logic mio_pad_attr_regwen_23_we; + logic mio_pad_attr_regwen_23_qs; + logic mio_pad_attr_regwen_23_wd; + logic mio_pad_attr_regwen_24_we; + logic mio_pad_attr_regwen_24_qs; + logic mio_pad_attr_regwen_24_wd; + logic mio_pad_attr_regwen_25_we; + logic mio_pad_attr_regwen_25_qs; + logic mio_pad_attr_regwen_25_wd; + logic mio_pad_attr_regwen_26_we; + logic mio_pad_attr_regwen_26_qs; + logic mio_pad_attr_regwen_26_wd; + logic mio_pad_attr_regwen_27_we; + logic mio_pad_attr_regwen_27_qs; + logic mio_pad_attr_regwen_27_wd; + logic mio_pad_attr_regwen_28_we; + logic mio_pad_attr_regwen_28_qs; + logic mio_pad_attr_regwen_28_wd; + logic mio_pad_attr_regwen_29_we; + logic mio_pad_attr_regwen_29_qs; + logic mio_pad_attr_regwen_29_wd; + logic mio_pad_attr_regwen_30_we; + logic mio_pad_attr_regwen_30_qs; + logic mio_pad_attr_regwen_30_wd; + logic mio_pad_attr_regwen_31_we; + logic mio_pad_attr_regwen_31_qs; + logic mio_pad_attr_regwen_31_wd; + logic mio_pad_attr_regwen_32_we; + logic mio_pad_attr_regwen_32_qs; + logic mio_pad_attr_regwen_32_wd; + logic mio_pad_attr_regwen_33_we; + logic mio_pad_attr_regwen_33_qs; + logic mio_pad_attr_regwen_33_wd; + logic mio_pad_attr_regwen_34_we; + logic mio_pad_attr_regwen_34_qs; + logic mio_pad_attr_regwen_34_wd; + logic mio_pad_attr_regwen_35_we; + logic mio_pad_attr_regwen_35_qs; + logic mio_pad_attr_regwen_35_wd; + logic mio_pad_attr_regwen_36_we; + logic mio_pad_attr_regwen_36_qs; + logic mio_pad_attr_regwen_36_wd; + logic mio_pad_attr_regwen_37_we; + logic mio_pad_attr_regwen_37_qs; + logic mio_pad_attr_regwen_37_wd; + logic mio_pad_attr_regwen_38_we; + logic mio_pad_attr_regwen_38_qs; + logic mio_pad_attr_regwen_38_wd; + logic mio_pad_attr_regwen_39_we; + logic mio_pad_attr_regwen_39_qs; + logic mio_pad_attr_regwen_39_wd; + logic mio_pad_attr_regwen_40_we; + logic mio_pad_attr_regwen_40_qs; + logic mio_pad_attr_regwen_40_wd; + logic mio_pad_attr_regwen_41_we; + logic mio_pad_attr_regwen_41_qs; + logic mio_pad_attr_regwen_41_wd; + logic mio_pad_attr_regwen_42_we; + logic mio_pad_attr_regwen_42_qs; + logic mio_pad_attr_regwen_42_wd; + logic mio_pad_attr_regwen_43_we; + logic mio_pad_attr_regwen_43_qs; + logic mio_pad_attr_regwen_43_wd; + logic mio_pad_attr_regwen_44_we; + logic mio_pad_attr_regwen_44_qs; + logic mio_pad_attr_regwen_44_wd; + logic mio_pad_attr_regwen_45_we; + logic mio_pad_attr_regwen_45_qs; + logic mio_pad_attr_regwen_45_wd; + logic mio_pad_attr_regwen_46_we; + logic mio_pad_attr_regwen_46_qs; + logic mio_pad_attr_regwen_46_wd; + logic mio_pad_attr_0_re; + logic mio_pad_attr_0_we; + logic mio_pad_attr_0_invert_0_qs; + logic mio_pad_attr_0_invert_0_wd; + logic mio_pad_attr_0_virtual_od_en_0_qs; + logic mio_pad_attr_0_virtual_od_en_0_wd; + logic mio_pad_attr_0_pull_en_0_qs; + logic mio_pad_attr_0_pull_en_0_wd; + logic mio_pad_attr_0_pull_select_0_qs; + logic mio_pad_attr_0_pull_select_0_wd; + logic mio_pad_attr_0_keeper_en_0_qs; + logic mio_pad_attr_0_keeper_en_0_wd; + logic mio_pad_attr_0_schmitt_en_0_qs; + logic mio_pad_attr_0_schmitt_en_0_wd; + logic mio_pad_attr_0_od_en_0_qs; + logic mio_pad_attr_0_od_en_0_wd; + logic mio_pad_attr_0_input_disable_0_qs; + logic mio_pad_attr_0_input_disable_0_wd; + logic [1:0] mio_pad_attr_0_slew_rate_0_qs; + logic [1:0] mio_pad_attr_0_slew_rate_0_wd; + logic [3:0] mio_pad_attr_0_drive_strength_0_qs; + logic [3:0] mio_pad_attr_0_drive_strength_0_wd; + logic mio_pad_attr_1_re; + logic mio_pad_attr_1_we; + logic mio_pad_attr_1_invert_1_qs; + logic mio_pad_attr_1_invert_1_wd; + logic mio_pad_attr_1_virtual_od_en_1_qs; + logic mio_pad_attr_1_virtual_od_en_1_wd; + logic mio_pad_attr_1_pull_en_1_qs; + logic mio_pad_attr_1_pull_en_1_wd; + logic mio_pad_attr_1_pull_select_1_qs; + logic mio_pad_attr_1_pull_select_1_wd; + logic mio_pad_attr_1_keeper_en_1_qs; + logic mio_pad_attr_1_keeper_en_1_wd; + logic mio_pad_attr_1_schmitt_en_1_qs; + logic mio_pad_attr_1_schmitt_en_1_wd; + logic mio_pad_attr_1_od_en_1_qs; + logic mio_pad_attr_1_od_en_1_wd; + logic mio_pad_attr_1_input_disable_1_qs; + logic mio_pad_attr_1_input_disable_1_wd; + logic [1:0] mio_pad_attr_1_slew_rate_1_qs; + logic [1:0] mio_pad_attr_1_slew_rate_1_wd; + logic [3:0] mio_pad_attr_1_drive_strength_1_qs; + logic [3:0] mio_pad_attr_1_drive_strength_1_wd; + logic mio_pad_attr_2_re; + logic mio_pad_attr_2_we; + logic mio_pad_attr_2_invert_2_qs; + logic mio_pad_attr_2_invert_2_wd; + logic mio_pad_attr_2_virtual_od_en_2_qs; + logic mio_pad_attr_2_virtual_od_en_2_wd; + logic mio_pad_attr_2_pull_en_2_qs; + logic mio_pad_attr_2_pull_en_2_wd; + logic mio_pad_attr_2_pull_select_2_qs; + logic mio_pad_attr_2_pull_select_2_wd; + logic mio_pad_attr_2_keeper_en_2_qs; + logic mio_pad_attr_2_keeper_en_2_wd; + logic mio_pad_attr_2_schmitt_en_2_qs; + logic mio_pad_attr_2_schmitt_en_2_wd; + logic mio_pad_attr_2_od_en_2_qs; + logic mio_pad_attr_2_od_en_2_wd; + logic mio_pad_attr_2_input_disable_2_qs; + logic mio_pad_attr_2_input_disable_2_wd; + logic [1:0] mio_pad_attr_2_slew_rate_2_qs; + logic [1:0] mio_pad_attr_2_slew_rate_2_wd; + logic [3:0] mio_pad_attr_2_drive_strength_2_qs; + logic [3:0] mio_pad_attr_2_drive_strength_2_wd; + logic mio_pad_attr_3_re; + logic mio_pad_attr_3_we; + logic mio_pad_attr_3_invert_3_qs; + logic mio_pad_attr_3_invert_3_wd; + logic mio_pad_attr_3_virtual_od_en_3_qs; + logic mio_pad_attr_3_virtual_od_en_3_wd; + logic mio_pad_attr_3_pull_en_3_qs; + logic mio_pad_attr_3_pull_en_3_wd; + logic mio_pad_attr_3_pull_select_3_qs; + logic mio_pad_attr_3_pull_select_3_wd; + logic mio_pad_attr_3_keeper_en_3_qs; + logic mio_pad_attr_3_keeper_en_3_wd; + logic mio_pad_attr_3_schmitt_en_3_qs; + logic mio_pad_attr_3_schmitt_en_3_wd; + logic mio_pad_attr_3_od_en_3_qs; + logic mio_pad_attr_3_od_en_3_wd; + logic mio_pad_attr_3_input_disable_3_qs; + logic mio_pad_attr_3_input_disable_3_wd; + logic [1:0] mio_pad_attr_3_slew_rate_3_qs; + logic [1:0] mio_pad_attr_3_slew_rate_3_wd; + logic [3:0] mio_pad_attr_3_drive_strength_3_qs; + logic [3:0] mio_pad_attr_3_drive_strength_3_wd; + logic mio_pad_attr_4_re; + logic mio_pad_attr_4_we; + logic mio_pad_attr_4_invert_4_qs; + logic mio_pad_attr_4_invert_4_wd; + logic mio_pad_attr_4_virtual_od_en_4_qs; + logic mio_pad_attr_4_virtual_od_en_4_wd; + logic mio_pad_attr_4_pull_en_4_qs; + logic mio_pad_attr_4_pull_en_4_wd; + logic mio_pad_attr_4_pull_select_4_qs; + logic mio_pad_attr_4_pull_select_4_wd; + logic mio_pad_attr_4_keeper_en_4_qs; + logic mio_pad_attr_4_keeper_en_4_wd; + logic mio_pad_attr_4_schmitt_en_4_qs; + logic mio_pad_attr_4_schmitt_en_4_wd; + logic mio_pad_attr_4_od_en_4_qs; + logic mio_pad_attr_4_od_en_4_wd; + logic mio_pad_attr_4_input_disable_4_qs; + logic mio_pad_attr_4_input_disable_4_wd; + logic [1:0] mio_pad_attr_4_slew_rate_4_qs; + logic [1:0] mio_pad_attr_4_slew_rate_4_wd; + logic [3:0] mio_pad_attr_4_drive_strength_4_qs; + logic [3:0] mio_pad_attr_4_drive_strength_4_wd; + logic mio_pad_attr_5_re; + logic mio_pad_attr_5_we; + logic mio_pad_attr_5_invert_5_qs; + logic mio_pad_attr_5_invert_5_wd; + logic mio_pad_attr_5_virtual_od_en_5_qs; + logic mio_pad_attr_5_virtual_od_en_5_wd; + logic mio_pad_attr_5_pull_en_5_qs; + logic mio_pad_attr_5_pull_en_5_wd; + logic mio_pad_attr_5_pull_select_5_qs; + logic mio_pad_attr_5_pull_select_5_wd; + logic mio_pad_attr_5_keeper_en_5_qs; + logic mio_pad_attr_5_keeper_en_5_wd; + logic mio_pad_attr_5_schmitt_en_5_qs; + logic mio_pad_attr_5_schmitt_en_5_wd; + logic mio_pad_attr_5_od_en_5_qs; + logic mio_pad_attr_5_od_en_5_wd; + logic mio_pad_attr_5_input_disable_5_qs; + logic mio_pad_attr_5_input_disable_5_wd; + logic [1:0] mio_pad_attr_5_slew_rate_5_qs; + logic [1:0] mio_pad_attr_5_slew_rate_5_wd; + logic [3:0] mio_pad_attr_5_drive_strength_5_qs; + logic [3:0] mio_pad_attr_5_drive_strength_5_wd; + logic mio_pad_attr_6_re; + logic mio_pad_attr_6_we; + logic mio_pad_attr_6_invert_6_qs; + logic mio_pad_attr_6_invert_6_wd; + logic mio_pad_attr_6_virtual_od_en_6_qs; + logic mio_pad_attr_6_virtual_od_en_6_wd; + logic mio_pad_attr_6_pull_en_6_qs; + logic mio_pad_attr_6_pull_en_6_wd; + logic mio_pad_attr_6_pull_select_6_qs; + logic mio_pad_attr_6_pull_select_6_wd; + logic mio_pad_attr_6_keeper_en_6_qs; + logic mio_pad_attr_6_keeper_en_6_wd; + logic mio_pad_attr_6_schmitt_en_6_qs; + logic mio_pad_attr_6_schmitt_en_6_wd; + logic mio_pad_attr_6_od_en_6_qs; + logic mio_pad_attr_6_od_en_6_wd; + logic mio_pad_attr_6_input_disable_6_qs; + logic mio_pad_attr_6_input_disable_6_wd; + logic [1:0] mio_pad_attr_6_slew_rate_6_qs; + logic [1:0] mio_pad_attr_6_slew_rate_6_wd; + logic [3:0] mio_pad_attr_6_drive_strength_6_qs; + logic [3:0] mio_pad_attr_6_drive_strength_6_wd; + logic mio_pad_attr_7_re; + logic mio_pad_attr_7_we; + logic mio_pad_attr_7_invert_7_qs; + logic mio_pad_attr_7_invert_7_wd; + logic mio_pad_attr_7_virtual_od_en_7_qs; + logic mio_pad_attr_7_virtual_od_en_7_wd; + logic mio_pad_attr_7_pull_en_7_qs; + logic mio_pad_attr_7_pull_en_7_wd; + logic mio_pad_attr_7_pull_select_7_qs; + logic mio_pad_attr_7_pull_select_7_wd; + logic mio_pad_attr_7_keeper_en_7_qs; + logic mio_pad_attr_7_keeper_en_7_wd; + logic mio_pad_attr_7_schmitt_en_7_qs; + logic mio_pad_attr_7_schmitt_en_7_wd; + logic mio_pad_attr_7_od_en_7_qs; + logic mio_pad_attr_7_od_en_7_wd; + logic mio_pad_attr_7_input_disable_7_qs; + logic mio_pad_attr_7_input_disable_7_wd; + logic [1:0] mio_pad_attr_7_slew_rate_7_qs; + logic [1:0] mio_pad_attr_7_slew_rate_7_wd; + logic [3:0] mio_pad_attr_7_drive_strength_7_qs; + logic [3:0] mio_pad_attr_7_drive_strength_7_wd; + logic mio_pad_attr_8_re; + logic mio_pad_attr_8_we; + logic mio_pad_attr_8_invert_8_qs; + logic mio_pad_attr_8_invert_8_wd; + logic mio_pad_attr_8_virtual_od_en_8_qs; + logic mio_pad_attr_8_virtual_od_en_8_wd; + logic mio_pad_attr_8_pull_en_8_qs; + logic mio_pad_attr_8_pull_en_8_wd; + logic mio_pad_attr_8_pull_select_8_qs; + logic mio_pad_attr_8_pull_select_8_wd; + logic mio_pad_attr_8_keeper_en_8_qs; + logic mio_pad_attr_8_keeper_en_8_wd; + logic mio_pad_attr_8_schmitt_en_8_qs; + logic mio_pad_attr_8_schmitt_en_8_wd; + logic mio_pad_attr_8_od_en_8_qs; + logic mio_pad_attr_8_od_en_8_wd; + logic mio_pad_attr_8_input_disable_8_qs; + logic mio_pad_attr_8_input_disable_8_wd; + logic [1:0] mio_pad_attr_8_slew_rate_8_qs; + logic [1:0] mio_pad_attr_8_slew_rate_8_wd; + logic [3:0] mio_pad_attr_8_drive_strength_8_qs; + logic [3:0] mio_pad_attr_8_drive_strength_8_wd; + logic mio_pad_attr_9_re; + logic mio_pad_attr_9_we; + logic mio_pad_attr_9_invert_9_qs; + logic mio_pad_attr_9_invert_9_wd; + logic mio_pad_attr_9_virtual_od_en_9_qs; + logic mio_pad_attr_9_virtual_od_en_9_wd; + logic mio_pad_attr_9_pull_en_9_qs; + logic mio_pad_attr_9_pull_en_9_wd; + logic mio_pad_attr_9_pull_select_9_qs; + logic mio_pad_attr_9_pull_select_9_wd; + logic mio_pad_attr_9_keeper_en_9_qs; + logic mio_pad_attr_9_keeper_en_9_wd; + logic mio_pad_attr_9_schmitt_en_9_qs; + logic mio_pad_attr_9_schmitt_en_9_wd; + logic mio_pad_attr_9_od_en_9_qs; + logic mio_pad_attr_9_od_en_9_wd; + logic mio_pad_attr_9_input_disable_9_qs; + logic mio_pad_attr_9_input_disable_9_wd; + logic [1:0] mio_pad_attr_9_slew_rate_9_qs; + logic [1:0] mio_pad_attr_9_slew_rate_9_wd; + logic [3:0] mio_pad_attr_9_drive_strength_9_qs; + logic [3:0] mio_pad_attr_9_drive_strength_9_wd; + logic mio_pad_attr_10_re; + logic mio_pad_attr_10_we; + logic mio_pad_attr_10_invert_10_qs; + logic mio_pad_attr_10_invert_10_wd; + logic mio_pad_attr_10_virtual_od_en_10_qs; + logic mio_pad_attr_10_virtual_od_en_10_wd; + logic mio_pad_attr_10_pull_en_10_qs; + logic mio_pad_attr_10_pull_en_10_wd; + logic mio_pad_attr_10_pull_select_10_qs; + logic mio_pad_attr_10_pull_select_10_wd; + logic mio_pad_attr_10_keeper_en_10_qs; + logic mio_pad_attr_10_keeper_en_10_wd; + logic mio_pad_attr_10_schmitt_en_10_qs; + logic mio_pad_attr_10_schmitt_en_10_wd; + logic mio_pad_attr_10_od_en_10_qs; + logic mio_pad_attr_10_od_en_10_wd; + logic mio_pad_attr_10_input_disable_10_qs; + logic mio_pad_attr_10_input_disable_10_wd; + logic [1:0] mio_pad_attr_10_slew_rate_10_qs; + logic [1:0] mio_pad_attr_10_slew_rate_10_wd; + logic [3:0] mio_pad_attr_10_drive_strength_10_qs; + logic [3:0] mio_pad_attr_10_drive_strength_10_wd; + logic mio_pad_attr_11_re; + logic mio_pad_attr_11_we; + logic mio_pad_attr_11_invert_11_qs; + logic mio_pad_attr_11_invert_11_wd; + logic mio_pad_attr_11_virtual_od_en_11_qs; + logic mio_pad_attr_11_virtual_od_en_11_wd; + logic mio_pad_attr_11_pull_en_11_qs; + logic mio_pad_attr_11_pull_en_11_wd; + logic mio_pad_attr_11_pull_select_11_qs; + logic mio_pad_attr_11_pull_select_11_wd; + logic mio_pad_attr_11_keeper_en_11_qs; + logic mio_pad_attr_11_keeper_en_11_wd; + logic mio_pad_attr_11_schmitt_en_11_qs; + logic mio_pad_attr_11_schmitt_en_11_wd; + logic mio_pad_attr_11_od_en_11_qs; + logic mio_pad_attr_11_od_en_11_wd; + logic mio_pad_attr_11_input_disable_11_qs; + logic mio_pad_attr_11_input_disable_11_wd; + logic [1:0] mio_pad_attr_11_slew_rate_11_qs; + logic [1:0] mio_pad_attr_11_slew_rate_11_wd; + logic [3:0] mio_pad_attr_11_drive_strength_11_qs; + logic [3:0] mio_pad_attr_11_drive_strength_11_wd; + logic mio_pad_attr_12_re; + logic mio_pad_attr_12_we; + logic mio_pad_attr_12_invert_12_qs; + logic mio_pad_attr_12_invert_12_wd; + logic mio_pad_attr_12_virtual_od_en_12_qs; + logic mio_pad_attr_12_virtual_od_en_12_wd; + logic mio_pad_attr_12_pull_en_12_qs; + logic mio_pad_attr_12_pull_en_12_wd; + logic mio_pad_attr_12_pull_select_12_qs; + logic mio_pad_attr_12_pull_select_12_wd; + logic mio_pad_attr_12_keeper_en_12_qs; + logic mio_pad_attr_12_keeper_en_12_wd; + logic mio_pad_attr_12_schmitt_en_12_qs; + logic mio_pad_attr_12_schmitt_en_12_wd; + logic mio_pad_attr_12_od_en_12_qs; + logic mio_pad_attr_12_od_en_12_wd; + logic mio_pad_attr_12_input_disable_12_qs; + logic mio_pad_attr_12_input_disable_12_wd; + logic [1:0] mio_pad_attr_12_slew_rate_12_qs; + logic [1:0] mio_pad_attr_12_slew_rate_12_wd; + logic [3:0] mio_pad_attr_12_drive_strength_12_qs; + logic [3:0] mio_pad_attr_12_drive_strength_12_wd; + logic mio_pad_attr_13_re; + logic mio_pad_attr_13_we; + logic mio_pad_attr_13_invert_13_qs; + logic mio_pad_attr_13_invert_13_wd; + logic mio_pad_attr_13_virtual_od_en_13_qs; + logic mio_pad_attr_13_virtual_od_en_13_wd; + logic mio_pad_attr_13_pull_en_13_qs; + logic mio_pad_attr_13_pull_en_13_wd; + logic mio_pad_attr_13_pull_select_13_qs; + logic mio_pad_attr_13_pull_select_13_wd; + logic mio_pad_attr_13_keeper_en_13_qs; + logic mio_pad_attr_13_keeper_en_13_wd; + logic mio_pad_attr_13_schmitt_en_13_qs; + logic mio_pad_attr_13_schmitt_en_13_wd; + logic mio_pad_attr_13_od_en_13_qs; + logic mio_pad_attr_13_od_en_13_wd; + logic mio_pad_attr_13_input_disable_13_qs; + logic mio_pad_attr_13_input_disable_13_wd; + logic [1:0] mio_pad_attr_13_slew_rate_13_qs; + logic [1:0] mio_pad_attr_13_slew_rate_13_wd; + logic [3:0] mio_pad_attr_13_drive_strength_13_qs; + logic [3:0] mio_pad_attr_13_drive_strength_13_wd; + logic mio_pad_attr_14_re; + logic mio_pad_attr_14_we; + logic mio_pad_attr_14_invert_14_qs; + logic mio_pad_attr_14_invert_14_wd; + logic mio_pad_attr_14_virtual_od_en_14_qs; + logic mio_pad_attr_14_virtual_od_en_14_wd; + logic mio_pad_attr_14_pull_en_14_qs; + logic mio_pad_attr_14_pull_en_14_wd; + logic mio_pad_attr_14_pull_select_14_qs; + logic mio_pad_attr_14_pull_select_14_wd; + logic mio_pad_attr_14_keeper_en_14_qs; + logic mio_pad_attr_14_keeper_en_14_wd; + logic mio_pad_attr_14_schmitt_en_14_qs; + logic mio_pad_attr_14_schmitt_en_14_wd; + logic mio_pad_attr_14_od_en_14_qs; + logic mio_pad_attr_14_od_en_14_wd; + logic mio_pad_attr_14_input_disable_14_qs; + logic mio_pad_attr_14_input_disable_14_wd; + logic [1:0] mio_pad_attr_14_slew_rate_14_qs; + logic [1:0] mio_pad_attr_14_slew_rate_14_wd; + logic [3:0] mio_pad_attr_14_drive_strength_14_qs; + logic [3:0] mio_pad_attr_14_drive_strength_14_wd; + logic mio_pad_attr_15_re; + logic mio_pad_attr_15_we; + logic mio_pad_attr_15_invert_15_qs; + logic mio_pad_attr_15_invert_15_wd; + logic mio_pad_attr_15_virtual_od_en_15_qs; + logic mio_pad_attr_15_virtual_od_en_15_wd; + logic mio_pad_attr_15_pull_en_15_qs; + logic mio_pad_attr_15_pull_en_15_wd; + logic mio_pad_attr_15_pull_select_15_qs; + logic mio_pad_attr_15_pull_select_15_wd; + logic mio_pad_attr_15_keeper_en_15_qs; + logic mio_pad_attr_15_keeper_en_15_wd; + logic mio_pad_attr_15_schmitt_en_15_qs; + logic mio_pad_attr_15_schmitt_en_15_wd; + logic mio_pad_attr_15_od_en_15_qs; + logic mio_pad_attr_15_od_en_15_wd; + logic mio_pad_attr_15_input_disable_15_qs; + logic mio_pad_attr_15_input_disable_15_wd; + logic [1:0] mio_pad_attr_15_slew_rate_15_qs; + logic [1:0] mio_pad_attr_15_slew_rate_15_wd; + logic [3:0] mio_pad_attr_15_drive_strength_15_qs; + logic [3:0] mio_pad_attr_15_drive_strength_15_wd; + logic mio_pad_attr_16_re; + logic mio_pad_attr_16_we; + logic mio_pad_attr_16_invert_16_qs; + logic mio_pad_attr_16_invert_16_wd; + logic mio_pad_attr_16_virtual_od_en_16_qs; + logic mio_pad_attr_16_virtual_od_en_16_wd; + logic mio_pad_attr_16_pull_en_16_qs; + logic mio_pad_attr_16_pull_en_16_wd; + logic mio_pad_attr_16_pull_select_16_qs; + logic mio_pad_attr_16_pull_select_16_wd; + logic mio_pad_attr_16_keeper_en_16_qs; + logic mio_pad_attr_16_keeper_en_16_wd; + logic mio_pad_attr_16_schmitt_en_16_qs; + logic mio_pad_attr_16_schmitt_en_16_wd; + logic mio_pad_attr_16_od_en_16_qs; + logic mio_pad_attr_16_od_en_16_wd; + logic mio_pad_attr_16_input_disable_16_qs; + logic mio_pad_attr_16_input_disable_16_wd; + logic [1:0] mio_pad_attr_16_slew_rate_16_qs; + logic [1:0] mio_pad_attr_16_slew_rate_16_wd; + logic [3:0] mio_pad_attr_16_drive_strength_16_qs; + logic [3:0] mio_pad_attr_16_drive_strength_16_wd; + logic mio_pad_attr_17_re; + logic mio_pad_attr_17_we; + logic mio_pad_attr_17_invert_17_qs; + logic mio_pad_attr_17_invert_17_wd; + logic mio_pad_attr_17_virtual_od_en_17_qs; + logic mio_pad_attr_17_virtual_od_en_17_wd; + logic mio_pad_attr_17_pull_en_17_qs; + logic mio_pad_attr_17_pull_en_17_wd; + logic mio_pad_attr_17_pull_select_17_qs; + logic mio_pad_attr_17_pull_select_17_wd; + logic mio_pad_attr_17_keeper_en_17_qs; + logic mio_pad_attr_17_keeper_en_17_wd; + logic mio_pad_attr_17_schmitt_en_17_qs; + logic mio_pad_attr_17_schmitt_en_17_wd; + logic mio_pad_attr_17_od_en_17_qs; + logic mio_pad_attr_17_od_en_17_wd; + logic mio_pad_attr_17_input_disable_17_qs; + logic mio_pad_attr_17_input_disable_17_wd; + logic [1:0] mio_pad_attr_17_slew_rate_17_qs; + logic [1:0] mio_pad_attr_17_slew_rate_17_wd; + logic [3:0] mio_pad_attr_17_drive_strength_17_qs; + logic [3:0] mio_pad_attr_17_drive_strength_17_wd; + logic mio_pad_attr_18_re; + logic mio_pad_attr_18_we; + logic mio_pad_attr_18_invert_18_qs; + logic mio_pad_attr_18_invert_18_wd; + logic mio_pad_attr_18_virtual_od_en_18_qs; + logic mio_pad_attr_18_virtual_od_en_18_wd; + logic mio_pad_attr_18_pull_en_18_qs; + logic mio_pad_attr_18_pull_en_18_wd; + logic mio_pad_attr_18_pull_select_18_qs; + logic mio_pad_attr_18_pull_select_18_wd; + logic mio_pad_attr_18_keeper_en_18_qs; + logic mio_pad_attr_18_keeper_en_18_wd; + logic mio_pad_attr_18_schmitt_en_18_qs; + logic mio_pad_attr_18_schmitt_en_18_wd; + logic mio_pad_attr_18_od_en_18_qs; + logic mio_pad_attr_18_od_en_18_wd; + logic mio_pad_attr_18_input_disable_18_qs; + logic mio_pad_attr_18_input_disable_18_wd; + logic [1:0] mio_pad_attr_18_slew_rate_18_qs; + logic [1:0] mio_pad_attr_18_slew_rate_18_wd; + logic [3:0] mio_pad_attr_18_drive_strength_18_qs; + logic [3:0] mio_pad_attr_18_drive_strength_18_wd; + logic mio_pad_attr_19_re; + logic mio_pad_attr_19_we; + logic mio_pad_attr_19_invert_19_qs; + logic mio_pad_attr_19_invert_19_wd; + logic mio_pad_attr_19_virtual_od_en_19_qs; + logic mio_pad_attr_19_virtual_od_en_19_wd; + logic mio_pad_attr_19_pull_en_19_qs; + logic mio_pad_attr_19_pull_en_19_wd; + logic mio_pad_attr_19_pull_select_19_qs; + logic mio_pad_attr_19_pull_select_19_wd; + logic mio_pad_attr_19_keeper_en_19_qs; + logic mio_pad_attr_19_keeper_en_19_wd; + logic mio_pad_attr_19_schmitt_en_19_qs; + logic mio_pad_attr_19_schmitt_en_19_wd; + logic mio_pad_attr_19_od_en_19_qs; + logic mio_pad_attr_19_od_en_19_wd; + logic mio_pad_attr_19_input_disable_19_qs; + logic mio_pad_attr_19_input_disable_19_wd; + logic [1:0] mio_pad_attr_19_slew_rate_19_qs; + logic [1:0] mio_pad_attr_19_slew_rate_19_wd; + logic [3:0] mio_pad_attr_19_drive_strength_19_qs; + logic [3:0] mio_pad_attr_19_drive_strength_19_wd; + logic mio_pad_attr_20_re; + logic mio_pad_attr_20_we; + logic mio_pad_attr_20_invert_20_qs; + logic mio_pad_attr_20_invert_20_wd; + logic mio_pad_attr_20_virtual_od_en_20_qs; + logic mio_pad_attr_20_virtual_od_en_20_wd; + logic mio_pad_attr_20_pull_en_20_qs; + logic mio_pad_attr_20_pull_en_20_wd; + logic mio_pad_attr_20_pull_select_20_qs; + logic mio_pad_attr_20_pull_select_20_wd; + logic mio_pad_attr_20_keeper_en_20_qs; + logic mio_pad_attr_20_keeper_en_20_wd; + logic mio_pad_attr_20_schmitt_en_20_qs; + logic mio_pad_attr_20_schmitt_en_20_wd; + logic mio_pad_attr_20_od_en_20_qs; + logic mio_pad_attr_20_od_en_20_wd; + logic mio_pad_attr_20_input_disable_20_qs; + logic mio_pad_attr_20_input_disable_20_wd; + logic [1:0] mio_pad_attr_20_slew_rate_20_qs; + logic [1:0] mio_pad_attr_20_slew_rate_20_wd; + logic [3:0] mio_pad_attr_20_drive_strength_20_qs; + logic [3:0] mio_pad_attr_20_drive_strength_20_wd; + logic mio_pad_attr_21_re; + logic mio_pad_attr_21_we; + logic mio_pad_attr_21_invert_21_qs; + logic mio_pad_attr_21_invert_21_wd; + logic mio_pad_attr_21_virtual_od_en_21_qs; + logic mio_pad_attr_21_virtual_od_en_21_wd; + logic mio_pad_attr_21_pull_en_21_qs; + logic mio_pad_attr_21_pull_en_21_wd; + logic mio_pad_attr_21_pull_select_21_qs; + logic mio_pad_attr_21_pull_select_21_wd; + logic mio_pad_attr_21_keeper_en_21_qs; + logic mio_pad_attr_21_keeper_en_21_wd; + logic mio_pad_attr_21_schmitt_en_21_qs; + logic mio_pad_attr_21_schmitt_en_21_wd; + logic mio_pad_attr_21_od_en_21_qs; + logic mio_pad_attr_21_od_en_21_wd; + logic mio_pad_attr_21_input_disable_21_qs; + logic mio_pad_attr_21_input_disable_21_wd; + logic [1:0] mio_pad_attr_21_slew_rate_21_qs; + logic [1:0] mio_pad_attr_21_slew_rate_21_wd; + logic [3:0] mio_pad_attr_21_drive_strength_21_qs; + logic [3:0] mio_pad_attr_21_drive_strength_21_wd; + logic mio_pad_attr_22_re; + logic mio_pad_attr_22_we; + logic mio_pad_attr_22_invert_22_qs; + logic mio_pad_attr_22_invert_22_wd; + logic mio_pad_attr_22_virtual_od_en_22_qs; + logic mio_pad_attr_22_virtual_od_en_22_wd; + logic mio_pad_attr_22_pull_en_22_qs; + logic mio_pad_attr_22_pull_en_22_wd; + logic mio_pad_attr_22_pull_select_22_qs; + logic mio_pad_attr_22_pull_select_22_wd; + logic mio_pad_attr_22_keeper_en_22_qs; + logic mio_pad_attr_22_keeper_en_22_wd; + logic mio_pad_attr_22_schmitt_en_22_qs; + logic mio_pad_attr_22_schmitt_en_22_wd; + logic mio_pad_attr_22_od_en_22_qs; + logic mio_pad_attr_22_od_en_22_wd; + logic mio_pad_attr_22_input_disable_22_qs; + logic mio_pad_attr_22_input_disable_22_wd; + logic [1:0] mio_pad_attr_22_slew_rate_22_qs; + logic [1:0] mio_pad_attr_22_slew_rate_22_wd; + logic [3:0] mio_pad_attr_22_drive_strength_22_qs; + logic [3:0] mio_pad_attr_22_drive_strength_22_wd; + logic mio_pad_attr_23_re; + logic mio_pad_attr_23_we; + logic mio_pad_attr_23_invert_23_qs; + logic mio_pad_attr_23_invert_23_wd; + logic mio_pad_attr_23_virtual_od_en_23_qs; + logic mio_pad_attr_23_virtual_od_en_23_wd; + logic mio_pad_attr_23_pull_en_23_qs; + logic mio_pad_attr_23_pull_en_23_wd; + logic mio_pad_attr_23_pull_select_23_qs; + logic mio_pad_attr_23_pull_select_23_wd; + logic mio_pad_attr_23_keeper_en_23_qs; + logic mio_pad_attr_23_keeper_en_23_wd; + logic mio_pad_attr_23_schmitt_en_23_qs; + logic mio_pad_attr_23_schmitt_en_23_wd; + logic mio_pad_attr_23_od_en_23_qs; + logic mio_pad_attr_23_od_en_23_wd; + logic mio_pad_attr_23_input_disable_23_qs; + logic mio_pad_attr_23_input_disable_23_wd; + logic [1:0] mio_pad_attr_23_slew_rate_23_qs; + logic [1:0] mio_pad_attr_23_slew_rate_23_wd; + logic [3:0] mio_pad_attr_23_drive_strength_23_qs; + logic [3:0] mio_pad_attr_23_drive_strength_23_wd; + logic mio_pad_attr_24_re; + logic mio_pad_attr_24_we; + logic mio_pad_attr_24_invert_24_qs; + logic mio_pad_attr_24_invert_24_wd; + logic mio_pad_attr_24_virtual_od_en_24_qs; + logic mio_pad_attr_24_virtual_od_en_24_wd; + logic mio_pad_attr_24_pull_en_24_qs; + logic mio_pad_attr_24_pull_en_24_wd; + logic mio_pad_attr_24_pull_select_24_qs; + logic mio_pad_attr_24_pull_select_24_wd; + logic mio_pad_attr_24_keeper_en_24_qs; + logic mio_pad_attr_24_keeper_en_24_wd; + logic mio_pad_attr_24_schmitt_en_24_qs; + logic mio_pad_attr_24_schmitt_en_24_wd; + logic mio_pad_attr_24_od_en_24_qs; + logic mio_pad_attr_24_od_en_24_wd; + logic mio_pad_attr_24_input_disable_24_qs; + logic mio_pad_attr_24_input_disable_24_wd; + logic [1:0] mio_pad_attr_24_slew_rate_24_qs; + logic [1:0] mio_pad_attr_24_slew_rate_24_wd; + logic [3:0] mio_pad_attr_24_drive_strength_24_qs; + logic [3:0] mio_pad_attr_24_drive_strength_24_wd; + logic mio_pad_attr_25_re; + logic mio_pad_attr_25_we; + logic mio_pad_attr_25_invert_25_qs; + logic mio_pad_attr_25_invert_25_wd; + logic mio_pad_attr_25_virtual_od_en_25_qs; + logic mio_pad_attr_25_virtual_od_en_25_wd; + logic mio_pad_attr_25_pull_en_25_qs; + logic mio_pad_attr_25_pull_en_25_wd; + logic mio_pad_attr_25_pull_select_25_qs; + logic mio_pad_attr_25_pull_select_25_wd; + logic mio_pad_attr_25_keeper_en_25_qs; + logic mio_pad_attr_25_keeper_en_25_wd; + logic mio_pad_attr_25_schmitt_en_25_qs; + logic mio_pad_attr_25_schmitt_en_25_wd; + logic mio_pad_attr_25_od_en_25_qs; + logic mio_pad_attr_25_od_en_25_wd; + logic mio_pad_attr_25_input_disable_25_qs; + logic mio_pad_attr_25_input_disable_25_wd; + logic [1:0] mio_pad_attr_25_slew_rate_25_qs; + logic [1:0] mio_pad_attr_25_slew_rate_25_wd; + logic [3:0] mio_pad_attr_25_drive_strength_25_qs; + logic [3:0] mio_pad_attr_25_drive_strength_25_wd; + logic mio_pad_attr_26_re; + logic mio_pad_attr_26_we; + logic mio_pad_attr_26_invert_26_qs; + logic mio_pad_attr_26_invert_26_wd; + logic mio_pad_attr_26_virtual_od_en_26_qs; + logic mio_pad_attr_26_virtual_od_en_26_wd; + logic mio_pad_attr_26_pull_en_26_qs; + logic mio_pad_attr_26_pull_en_26_wd; + logic mio_pad_attr_26_pull_select_26_qs; + logic mio_pad_attr_26_pull_select_26_wd; + logic mio_pad_attr_26_keeper_en_26_qs; + logic mio_pad_attr_26_keeper_en_26_wd; + logic mio_pad_attr_26_schmitt_en_26_qs; + logic mio_pad_attr_26_schmitt_en_26_wd; + logic mio_pad_attr_26_od_en_26_qs; + logic mio_pad_attr_26_od_en_26_wd; + logic mio_pad_attr_26_input_disable_26_qs; + logic mio_pad_attr_26_input_disable_26_wd; + logic [1:0] mio_pad_attr_26_slew_rate_26_qs; + logic [1:0] mio_pad_attr_26_slew_rate_26_wd; + logic [3:0] mio_pad_attr_26_drive_strength_26_qs; + logic [3:0] mio_pad_attr_26_drive_strength_26_wd; + logic mio_pad_attr_27_re; + logic mio_pad_attr_27_we; + logic mio_pad_attr_27_invert_27_qs; + logic mio_pad_attr_27_invert_27_wd; + logic mio_pad_attr_27_virtual_od_en_27_qs; + logic mio_pad_attr_27_virtual_od_en_27_wd; + logic mio_pad_attr_27_pull_en_27_qs; + logic mio_pad_attr_27_pull_en_27_wd; + logic mio_pad_attr_27_pull_select_27_qs; + logic mio_pad_attr_27_pull_select_27_wd; + logic mio_pad_attr_27_keeper_en_27_qs; + logic mio_pad_attr_27_keeper_en_27_wd; + logic mio_pad_attr_27_schmitt_en_27_qs; + logic mio_pad_attr_27_schmitt_en_27_wd; + logic mio_pad_attr_27_od_en_27_qs; + logic mio_pad_attr_27_od_en_27_wd; + logic mio_pad_attr_27_input_disable_27_qs; + logic mio_pad_attr_27_input_disable_27_wd; + logic [1:0] mio_pad_attr_27_slew_rate_27_qs; + logic [1:0] mio_pad_attr_27_slew_rate_27_wd; + logic [3:0] mio_pad_attr_27_drive_strength_27_qs; + logic [3:0] mio_pad_attr_27_drive_strength_27_wd; + logic mio_pad_attr_28_re; + logic mio_pad_attr_28_we; + logic mio_pad_attr_28_invert_28_qs; + logic mio_pad_attr_28_invert_28_wd; + logic mio_pad_attr_28_virtual_od_en_28_qs; + logic mio_pad_attr_28_virtual_od_en_28_wd; + logic mio_pad_attr_28_pull_en_28_qs; + logic mio_pad_attr_28_pull_en_28_wd; + logic mio_pad_attr_28_pull_select_28_qs; + logic mio_pad_attr_28_pull_select_28_wd; + logic mio_pad_attr_28_keeper_en_28_qs; + logic mio_pad_attr_28_keeper_en_28_wd; + logic mio_pad_attr_28_schmitt_en_28_qs; + logic mio_pad_attr_28_schmitt_en_28_wd; + logic mio_pad_attr_28_od_en_28_qs; + logic mio_pad_attr_28_od_en_28_wd; + logic mio_pad_attr_28_input_disable_28_qs; + logic mio_pad_attr_28_input_disable_28_wd; + logic [1:0] mio_pad_attr_28_slew_rate_28_qs; + logic [1:0] mio_pad_attr_28_slew_rate_28_wd; + logic [3:0] mio_pad_attr_28_drive_strength_28_qs; + logic [3:0] mio_pad_attr_28_drive_strength_28_wd; + logic mio_pad_attr_29_re; + logic mio_pad_attr_29_we; + logic mio_pad_attr_29_invert_29_qs; + logic mio_pad_attr_29_invert_29_wd; + logic mio_pad_attr_29_virtual_od_en_29_qs; + logic mio_pad_attr_29_virtual_od_en_29_wd; + logic mio_pad_attr_29_pull_en_29_qs; + logic mio_pad_attr_29_pull_en_29_wd; + logic mio_pad_attr_29_pull_select_29_qs; + logic mio_pad_attr_29_pull_select_29_wd; + logic mio_pad_attr_29_keeper_en_29_qs; + logic mio_pad_attr_29_keeper_en_29_wd; + logic mio_pad_attr_29_schmitt_en_29_qs; + logic mio_pad_attr_29_schmitt_en_29_wd; + logic mio_pad_attr_29_od_en_29_qs; + logic mio_pad_attr_29_od_en_29_wd; + logic mio_pad_attr_29_input_disable_29_qs; + logic mio_pad_attr_29_input_disable_29_wd; + logic [1:0] mio_pad_attr_29_slew_rate_29_qs; + logic [1:0] mio_pad_attr_29_slew_rate_29_wd; + logic [3:0] mio_pad_attr_29_drive_strength_29_qs; + logic [3:0] mio_pad_attr_29_drive_strength_29_wd; + logic mio_pad_attr_30_re; + logic mio_pad_attr_30_we; + logic mio_pad_attr_30_invert_30_qs; + logic mio_pad_attr_30_invert_30_wd; + logic mio_pad_attr_30_virtual_od_en_30_qs; + logic mio_pad_attr_30_virtual_od_en_30_wd; + logic mio_pad_attr_30_pull_en_30_qs; + logic mio_pad_attr_30_pull_en_30_wd; + logic mio_pad_attr_30_pull_select_30_qs; + logic mio_pad_attr_30_pull_select_30_wd; + logic mio_pad_attr_30_keeper_en_30_qs; + logic mio_pad_attr_30_keeper_en_30_wd; + logic mio_pad_attr_30_schmitt_en_30_qs; + logic mio_pad_attr_30_schmitt_en_30_wd; + logic mio_pad_attr_30_od_en_30_qs; + logic mio_pad_attr_30_od_en_30_wd; + logic mio_pad_attr_30_input_disable_30_qs; + logic mio_pad_attr_30_input_disable_30_wd; + logic [1:0] mio_pad_attr_30_slew_rate_30_qs; + logic [1:0] mio_pad_attr_30_slew_rate_30_wd; + logic [3:0] mio_pad_attr_30_drive_strength_30_qs; + logic [3:0] mio_pad_attr_30_drive_strength_30_wd; + logic mio_pad_attr_31_re; + logic mio_pad_attr_31_we; + logic mio_pad_attr_31_invert_31_qs; + logic mio_pad_attr_31_invert_31_wd; + logic mio_pad_attr_31_virtual_od_en_31_qs; + logic mio_pad_attr_31_virtual_od_en_31_wd; + logic mio_pad_attr_31_pull_en_31_qs; + logic mio_pad_attr_31_pull_en_31_wd; + logic mio_pad_attr_31_pull_select_31_qs; + logic mio_pad_attr_31_pull_select_31_wd; + logic mio_pad_attr_31_keeper_en_31_qs; + logic mio_pad_attr_31_keeper_en_31_wd; + logic mio_pad_attr_31_schmitt_en_31_qs; + logic mio_pad_attr_31_schmitt_en_31_wd; + logic mio_pad_attr_31_od_en_31_qs; + logic mio_pad_attr_31_od_en_31_wd; + logic mio_pad_attr_31_input_disable_31_qs; + logic mio_pad_attr_31_input_disable_31_wd; + logic [1:0] mio_pad_attr_31_slew_rate_31_qs; + logic [1:0] mio_pad_attr_31_slew_rate_31_wd; + logic [3:0] mio_pad_attr_31_drive_strength_31_qs; + logic [3:0] mio_pad_attr_31_drive_strength_31_wd; + logic mio_pad_attr_32_re; + logic mio_pad_attr_32_we; + logic mio_pad_attr_32_invert_32_qs; + logic mio_pad_attr_32_invert_32_wd; + logic mio_pad_attr_32_virtual_od_en_32_qs; + logic mio_pad_attr_32_virtual_od_en_32_wd; + logic mio_pad_attr_32_pull_en_32_qs; + logic mio_pad_attr_32_pull_en_32_wd; + logic mio_pad_attr_32_pull_select_32_qs; + logic mio_pad_attr_32_pull_select_32_wd; + logic mio_pad_attr_32_keeper_en_32_qs; + logic mio_pad_attr_32_keeper_en_32_wd; + logic mio_pad_attr_32_schmitt_en_32_qs; + logic mio_pad_attr_32_schmitt_en_32_wd; + logic mio_pad_attr_32_od_en_32_qs; + logic mio_pad_attr_32_od_en_32_wd; + logic mio_pad_attr_32_input_disable_32_qs; + logic mio_pad_attr_32_input_disable_32_wd; + logic [1:0] mio_pad_attr_32_slew_rate_32_qs; + logic [1:0] mio_pad_attr_32_slew_rate_32_wd; + logic [3:0] mio_pad_attr_32_drive_strength_32_qs; + logic [3:0] mio_pad_attr_32_drive_strength_32_wd; + logic mio_pad_attr_33_re; + logic mio_pad_attr_33_we; + logic mio_pad_attr_33_invert_33_qs; + logic mio_pad_attr_33_invert_33_wd; + logic mio_pad_attr_33_virtual_od_en_33_qs; + logic mio_pad_attr_33_virtual_od_en_33_wd; + logic mio_pad_attr_33_pull_en_33_qs; + logic mio_pad_attr_33_pull_en_33_wd; + logic mio_pad_attr_33_pull_select_33_qs; + logic mio_pad_attr_33_pull_select_33_wd; + logic mio_pad_attr_33_keeper_en_33_qs; + logic mio_pad_attr_33_keeper_en_33_wd; + logic mio_pad_attr_33_schmitt_en_33_qs; + logic mio_pad_attr_33_schmitt_en_33_wd; + logic mio_pad_attr_33_od_en_33_qs; + logic mio_pad_attr_33_od_en_33_wd; + logic mio_pad_attr_33_input_disable_33_qs; + logic mio_pad_attr_33_input_disable_33_wd; + logic [1:0] mio_pad_attr_33_slew_rate_33_qs; + logic [1:0] mio_pad_attr_33_slew_rate_33_wd; + logic [3:0] mio_pad_attr_33_drive_strength_33_qs; + logic [3:0] mio_pad_attr_33_drive_strength_33_wd; + logic mio_pad_attr_34_re; + logic mio_pad_attr_34_we; + logic mio_pad_attr_34_invert_34_qs; + logic mio_pad_attr_34_invert_34_wd; + logic mio_pad_attr_34_virtual_od_en_34_qs; + logic mio_pad_attr_34_virtual_od_en_34_wd; + logic mio_pad_attr_34_pull_en_34_qs; + logic mio_pad_attr_34_pull_en_34_wd; + logic mio_pad_attr_34_pull_select_34_qs; + logic mio_pad_attr_34_pull_select_34_wd; + logic mio_pad_attr_34_keeper_en_34_qs; + logic mio_pad_attr_34_keeper_en_34_wd; + logic mio_pad_attr_34_schmitt_en_34_qs; + logic mio_pad_attr_34_schmitt_en_34_wd; + logic mio_pad_attr_34_od_en_34_qs; + logic mio_pad_attr_34_od_en_34_wd; + logic mio_pad_attr_34_input_disable_34_qs; + logic mio_pad_attr_34_input_disable_34_wd; + logic [1:0] mio_pad_attr_34_slew_rate_34_qs; + logic [1:0] mio_pad_attr_34_slew_rate_34_wd; + logic [3:0] mio_pad_attr_34_drive_strength_34_qs; + logic [3:0] mio_pad_attr_34_drive_strength_34_wd; + logic mio_pad_attr_35_re; + logic mio_pad_attr_35_we; + logic mio_pad_attr_35_invert_35_qs; + logic mio_pad_attr_35_invert_35_wd; + logic mio_pad_attr_35_virtual_od_en_35_qs; + logic mio_pad_attr_35_virtual_od_en_35_wd; + logic mio_pad_attr_35_pull_en_35_qs; + logic mio_pad_attr_35_pull_en_35_wd; + logic mio_pad_attr_35_pull_select_35_qs; + logic mio_pad_attr_35_pull_select_35_wd; + logic mio_pad_attr_35_keeper_en_35_qs; + logic mio_pad_attr_35_keeper_en_35_wd; + logic mio_pad_attr_35_schmitt_en_35_qs; + logic mio_pad_attr_35_schmitt_en_35_wd; + logic mio_pad_attr_35_od_en_35_qs; + logic mio_pad_attr_35_od_en_35_wd; + logic mio_pad_attr_35_input_disable_35_qs; + logic mio_pad_attr_35_input_disable_35_wd; + logic [1:0] mio_pad_attr_35_slew_rate_35_qs; + logic [1:0] mio_pad_attr_35_slew_rate_35_wd; + logic [3:0] mio_pad_attr_35_drive_strength_35_qs; + logic [3:0] mio_pad_attr_35_drive_strength_35_wd; + logic mio_pad_attr_36_re; + logic mio_pad_attr_36_we; + logic mio_pad_attr_36_invert_36_qs; + logic mio_pad_attr_36_invert_36_wd; + logic mio_pad_attr_36_virtual_od_en_36_qs; + logic mio_pad_attr_36_virtual_od_en_36_wd; + logic mio_pad_attr_36_pull_en_36_qs; + logic mio_pad_attr_36_pull_en_36_wd; + logic mio_pad_attr_36_pull_select_36_qs; + logic mio_pad_attr_36_pull_select_36_wd; + logic mio_pad_attr_36_keeper_en_36_qs; + logic mio_pad_attr_36_keeper_en_36_wd; + logic mio_pad_attr_36_schmitt_en_36_qs; + logic mio_pad_attr_36_schmitt_en_36_wd; + logic mio_pad_attr_36_od_en_36_qs; + logic mio_pad_attr_36_od_en_36_wd; + logic mio_pad_attr_36_input_disable_36_qs; + logic mio_pad_attr_36_input_disable_36_wd; + logic [1:0] mio_pad_attr_36_slew_rate_36_qs; + logic [1:0] mio_pad_attr_36_slew_rate_36_wd; + logic [3:0] mio_pad_attr_36_drive_strength_36_qs; + logic [3:0] mio_pad_attr_36_drive_strength_36_wd; + logic mio_pad_attr_37_re; + logic mio_pad_attr_37_we; + logic mio_pad_attr_37_invert_37_qs; + logic mio_pad_attr_37_invert_37_wd; + logic mio_pad_attr_37_virtual_od_en_37_qs; + logic mio_pad_attr_37_virtual_od_en_37_wd; + logic mio_pad_attr_37_pull_en_37_qs; + logic mio_pad_attr_37_pull_en_37_wd; + logic mio_pad_attr_37_pull_select_37_qs; + logic mio_pad_attr_37_pull_select_37_wd; + logic mio_pad_attr_37_keeper_en_37_qs; + logic mio_pad_attr_37_keeper_en_37_wd; + logic mio_pad_attr_37_schmitt_en_37_qs; + logic mio_pad_attr_37_schmitt_en_37_wd; + logic mio_pad_attr_37_od_en_37_qs; + logic mio_pad_attr_37_od_en_37_wd; + logic mio_pad_attr_37_input_disable_37_qs; + logic mio_pad_attr_37_input_disable_37_wd; + logic [1:0] mio_pad_attr_37_slew_rate_37_qs; + logic [1:0] mio_pad_attr_37_slew_rate_37_wd; + logic [3:0] mio_pad_attr_37_drive_strength_37_qs; + logic [3:0] mio_pad_attr_37_drive_strength_37_wd; + logic mio_pad_attr_38_re; + logic mio_pad_attr_38_we; + logic mio_pad_attr_38_invert_38_qs; + logic mio_pad_attr_38_invert_38_wd; + logic mio_pad_attr_38_virtual_od_en_38_qs; + logic mio_pad_attr_38_virtual_od_en_38_wd; + logic mio_pad_attr_38_pull_en_38_qs; + logic mio_pad_attr_38_pull_en_38_wd; + logic mio_pad_attr_38_pull_select_38_qs; + logic mio_pad_attr_38_pull_select_38_wd; + logic mio_pad_attr_38_keeper_en_38_qs; + logic mio_pad_attr_38_keeper_en_38_wd; + logic mio_pad_attr_38_schmitt_en_38_qs; + logic mio_pad_attr_38_schmitt_en_38_wd; + logic mio_pad_attr_38_od_en_38_qs; + logic mio_pad_attr_38_od_en_38_wd; + logic mio_pad_attr_38_input_disable_38_qs; + logic mio_pad_attr_38_input_disable_38_wd; + logic [1:0] mio_pad_attr_38_slew_rate_38_qs; + logic [1:0] mio_pad_attr_38_slew_rate_38_wd; + logic [3:0] mio_pad_attr_38_drive_strength_38_qs; + logic [3:0] mio_pad_attr_38_drive_strength_38_wd; + logic mio_pad_attr_39_re; + logic mio_pad_attr_39_we; + logic mio_pad_attr_39_invert_39_qs; + logic mio_pad_attr_39_invert_39_wd; + logic mio_pad_attr_39_virtual_od_en_39_qs; + logic mio_pad_attr_39_virtual_od_en_39_wd; + logic mio_pad_attr_39_pull_en_39_qs; + logic mio_pad_attr_39_pull_en_39_wd; + logic mio_pad_attr_39_pull_select_39_qs; + logic mio_pad_attr_39_pull_select_39_wd; + logic mio_pad_attr_39_keeper_en_39_qs; + logic mio_pad_attr_39_keeper_en_39_wd; + logic mio_pad_attr_39_schmitt_en_39_qs; + logic mio_pad_attr_39_schmitt_en_39_wd; + logic mio_pad_attr_39_od_en_39_qs; + logic mio_pad_attr_39_od_en_39_wd; + logic mio_pad_attr_39_input_disable_39_qs; + logic mio_pad_attr_39_input_disable_39_wd; + logic [1:0] mio_pad_attr_39_slew_rate_39_qs; + logic [1:0] mio_pad_attr_39_slew_rate_39_wd; + logic [3:0] mio_pad_attr_39_drive_strength_39_qs; + logic [3:0] mio_pad_attr_39_drive_strength_39_wd; + logic mio_pad_attr_40_re; + logic mio_pad_attr_40_we; + logic mio_pad_attr_40_invert_40_qs; + logic mio_pad_attr_40_invert_40_wd; + logic mio_pad_attr_40_virtual_od_en_40_qs; + logic mio_pad_attr_40_virtual_od_en_40_wd; + logic mio_pad_attr_40_pull_en_40_qs; + logic mio_pad_attr_40_pull_en_40_wd; + logic mio_pad_attr_40_pull_select_40_qs; + logic mio_pad_attr_40_pull_select_40_wd; + logic mio_pad_attr_40_keeper_en_40_qs; + logic mio_pad_attr_40_keeper_en_40_wd; + logic mio_pad_attr_40_schmitt_en_40_qs; + logic mio_pad_attr_40_schmitt_en_40_wd; + logic mio_pad_attr_40_od_en_40_qs; + logic mio_pad_attr_40_od_en_40_wd; + logic mio_pad_attr_40_input_disable_40_qs; + logic mio_pad_attr_40_input_disable_40_wd; + logic [1:0] mio_pad_attr_40_slew_rate_40_qs; + logic [1:0] mio_pad_attr_40_slew_rate_40_wd; + logic [3:0] mio_pad_attr_40_drive_strength_40_qs; + logic [3:0] mio_pad_attr_40_drive_strength_40_wd; + logic mio_pad_attr_41_re; + logic mio_pad_attr_41_we; + logic mio_pad_attr_41_invert_41_qs; + logic mio_pad_attr_41_invert_41_wd; + logic mio_pad_attr_41_virtual_od_en_41_qs; + logic mio_pad_attr_41_virtual_od_en_41_wd; + logic mio_pad_attr_41_pull_en_41_qs; + logic mio_pad_attr_41_pull_en_41_wd; + logic mio_pad_attr_41_pull_select_41_qs; + logic mio_pad_attr_41_pull_select_41_wd; + logic mio_pad_attr_41_keeper_en_41_qs; + logic mio_pad_attr_41_keeper_en_41_wd; + logic mio_pad_attr_41_schmitt_en_41_qs; + logic mio_pad_attr_41_schmitt_en_41_wd; + logic mio_pad_attr_41_od_en_41_qs; + logic mio_pad_attr_41_od_en_41_wd; + logic mio_pad_attr_41_input_disable_41_qs; + logic mio_pad_attr_41_input_disable_41_wd; + logic [1:0] mio_pad_attr_41_slew_rate_41_qs; + logic [1:0] mio_pad_attr_41_slew_rate_41_wd; + logic [3:0] mio_pad_attr_41_drive_strength_41_qs; + logic [3:0] mio_pad_attr_41_drive_strength_41_wd; + logic mio_pad_attr_42_re; + logic mio_pad_attr_42_we; + logic mio_pad_attr_42_invert_42_qs; + logic mio_pad_attr_42_invert_42_wd; + logic mio_pad_attr_42_virtual_od_en_42_qs; + logic mio_pad_attr_42_virtual_od_en_42_wd; + logic mio_pad_attr_42_pull_en_42_qs; + logic mio_pad_attr_42_pull_en_42_wd; + logic mio_pad_attr_42_pull_select_42_qs; + logic mio_pad_attr_42_pull_select_42_wd; + logic mio_pad_attr_42_keeper_en_42_qs; + logic mio_pad_attr_42_keeper_en_42_wd; + logic mio_pad_attr_42_schmitt_en_42_qs; + logic mio_pad_attr_42_schmitt_en_42_wd; + logic mio_pad_attr_42_od_en_42_qs; + logic mio_pad_attr_42_od_en_42_wd; + logic mio_pad_attr_42_input_disable_42_qs; + logic mio_pad_attr_42_input_disable_42_wd; + logic [1:0] mio_pad_attr_42_slew_rate_42_qs; + logic [1:0] mio_pad_attr_42_slew_rate_42_wd; + logic [3:0] mio_pad_attr_42_drive_strength_42_qs; + logic [3:0] mio_pad_attr_42_drive_strength_42_wd; + logic mio_pad_attr_43_re; + logic mio_pad_attr_43_we; + logic mio_pad_attr_43_invert_43_qs; + logic mio_pad_attr_43_invert_43_wd; + logic mio_pad_attr_43_virtual_od_en_43_qs; + logic mio_pad_attr_43_virtual_od_en_43_wd; + logic mio_pad_attr_43_pull_en_43_qs; + logic mio_pad_attr_43_pull_en_43_wd; + logic mio_pad_attr_43_pull_select_43_qs; + logic mio_pad_attr_43_pull_select_43_wd; + logic mio_pad_attr_43_keeper_en_43_qs; + logic mio_pad_attr_43_keeper_en_43_wd; + logic mio_pad_attr_43_schmitt_en_43_qs; + logic mio_pad_attr_43_schmitt_en_43_wd; + logic mio_pad_attr_43_od_en_43_qs; + logic mio_pad_attr_43_od_en_43_wd; + logic mio_pad_attr_43_input_disable_43_qs; + logic mio_pad_attr_43_input_disable_43_wd; + logic [1:0] mio_pad_attr_43_slew_rate_43_qs; + logic [1:0] mio_pad_attr_43_slew_rate_43_wd; + logic [3:0] mio_pad_attr_43_drive_strength_43_qs; + logic [3:0] mio_pad_attr_43_drive_strength_43_wd; + logic mio_pad_attr_44_re; + logic mio_pad_attr_44_we; + logic mio_pad_attr_44_invert_44_qs; + logic mio_pad_attr_44_invert_44_wd; + logic mio_pad_attr_44_virtual_od_en_44_qs; + logic mio_pad_attr_44_virtual_od_en_44_wd; + logic mio_pad_attr_44_pull_en_44_qs; + logic mio_pad_attr_44_pull_en_44_wd; + logic mio_pad_attr_44_pull_select_44_qs; + logic mio_pad_attr_44_pull_select_44_wd; + logic mio_pad_attr_44_keeper_en_44_qs; + logic mio_pad_attr_44_keeper_en_44_wd; + logic mio_pad_attr_44_schmitt_en_44_qs; + logic mio_pad_attr_44_schmitt_en_44_wd; + logic mio_pad_attr_44_od_en_44_qs; + logic mio_pad_attr_44_od_en_44_wd; + logic mio_pad_attr_44_input_disable_44_qs; + logic mio_pad_attr_44_input_disable_44_wd; + logic [1:0] mio_pad_attr_44_slew_rate_44_qs; + logic [1:0] mio_pad_attr_44_slew_rate_44_wd; + logic [3:0] mio_pad_attr_44_drive_strength_44_qs; + logic [3:0] mio_pad_attr_44_drive_strength_44_wd; + logic mio_pad_attr_45_re; + logic mio_pad_attr_45_we; + logic mio_pad_attr_45_invert_45_qs; + logic mio_pad_attr_45_invert_45_wd; + logic mio_pad_attr_45_virtual_od_en_45_qs; + logic mio_pad_attr_45_virtual_od_en_45_wd; + logic mio_pad_attr_45_pull_en_45_qs; + logic mio_pad_attr_45_pull_en_45_wd; + logic mio_pad_attr_45_pull_select_45_qs; + logic mio_pad_attr_45_pull_select_45_wd; + logic mio_pad_attr_45_keeper_en_45_qs; + logic mio_pad_attr_45_keeper_en_45_wd; + logic mio_pad_attr_45_schmitt_en_45_qs; + logic mio_pad_attr_45_schmitt_en_45_wd; + logic mio_pad_attr_45_od_en_45_qs; + logic mio_pad_attr_45_od_en_45_wd; + logic mio_pad_attr_45_input_disable_45_qs; + logic mio_pad_attr_45_input_disable_45_wd; + logic [1:0] mio_pad_attr_45_slew_rate_45_qs; + logic [1:0] mio_pad_attr_45_slew_rate_45_wd; + logic [3:0] mio_pad_attr_45_drive_strength_45_qs; + logic [3:0] mio_pad_attr_45_drive_strength_45_wd; + logic mio_pad_attr_46_re; + logic mio_pad_attr_46_we; + logic mio_pad_attr_46_invert_46_qs; + logic mio_pad_attr_46_invert_46_wd; + logic mio_pad_attr_46_virtual_od_en_46_qs; + logic mio_pad_attr_46_virtual_od_en_46_wd; + logic mio_pad_attr_46_pull_en_46_qs; + logic mio_pad_attr_46_pull_en_46_wd; + logic mio_pad_attr_46_pull_select_46_qs; + logic mio_pad_attr_46_pull_select_46_wd; + logic mio_pad_attr_46_keeper_en_46_qs; + logic mio_pad_attr_46_keeper_en_46_wd; + logic mio_pad_attr_46_schmitt_en_46_qs; + logic mio_pad_attr_46_schmitt_en_46_wd; + logic mio_pad_attr_46_od_en_46_qs; + logic mio_pad_attr_46_od_en_46_wd; + logic mio_pad_attr_46_input_disable_46_qs; + logic mio_pad_attr_46_input_disable_46_wd; + logic [1:0] mio_pad_attr_46_slew_rate_46_qs; + logic [1:0] mio_pad_attr_46_slew_rate_46_wd; + logic [3:0] mio_pad_attr_46_drive_strength_46_qs; + logic [3:0] mio_pad_attr_46_drive_strength_46_wd; + logic dio_pad_attr_regwen_0_we; + logic dio_pad_attr_regwen_0_qs; + logic dio_pad_attr_regwen_0_wd; + logic dio_pad_attr_regwen_1_we; + logic dio_pad_attr_regwen_1_qs; + logic dio_pad_attr_regwen_1_wd; + logic dio_pad_attr_regwen_2_we; + logic dio_pad_attr_regwen_2_qs; + logic dio_pad_attr_regwen_2_wd; + logic dio_pad_attr_regwen_3_we; + logic dio_pad_attr_regwen_3_qs; + logic dio_pad_attr_regwen_3_wd; + logic dio_pad_attr_regwen_4_we; + logic dio_pad_attr_regwen_4_qs; + logic dio_pad_attr_regwen_4_wd; + logic dio_pad_attr_regwen_5_we; + logic dio_pad_attr_regwen_5_qs; + logic dio_pad_attr_regwen_5_wd; + logic dio_pad_attr_regwen_6_we; + logic dio_pad_attr_regwen_6_qs; + logic dio_pad_attr_regwen_6_wd; + logic dio_pad_attr_regwen_7_we; + logic dio_pad_attr_regwen_7_qs; + logic dio_pad_attr_regwen_7_wd; + logic dio_pad_attr_regwen_8_we; + logic dio_pad_attr_regwen_8_qs; + logic dio_pad_attr_regwen_8_wd; + logic dio_pad_attr_regwen_9_we; + logic dio_pad_attr_regwen_9_qs; + logic dio_pad_attr_regwen_9_wd; + logic dio_pad_attr_regwen_10_we; + logic dio_pad_attr_regwen_10_qs; + logic dio_pad_attr_regwen_10_wd; + logic dio_pad_attr_regwen_11_we; + logic dio_pad_attr_regwen_11_qs; + logic dio_pad_attr_regwen_11_wd; + logic dio_pad_attr_regwen_12_we; + logic dio_pad_attr_regwen_12_qs; + logic dio_pad_attr_regwen_12_wd; + logic dio_pad_attr_regwen_13_we; + logic dio_pad_attr_regwen_13_qs; + logic dio_pad_attr_regwen_13_wd; + logic dio_pad_attr_0_re; + logic dio_pad_attr_0_we; + logic dio_pad_attr_0_invert_0_qs; + logic dio_pad_attr_0_invert_0_wd; + logic dio_pad_attr_0_virtual_od_en_0_qs; + logic dio_pad_attr_0_virtual_od_en_0_wd; + logic dio_pad_attr_0_pull_en_0_qs; + logic dio_pad_attr_0_pull_en_0_wd; + logic dio_pad_attr_0_pull_select_0_qs; + logic dio_pad_attr_0_pull_select_0_wd; + logic dio_pad_attr_0_keeper_en_0_qs; + logic dio_pad_attr_0_keeper_en_0_wd; + logic dio_pad_attr_0_schmitt_en_0_qs; + logic dio_pad_attr_0_schmitt_en_0_wd; + logic dio_pad_attr_0_od_en_0_qs; + logic dio_pad_attr_0_od_en_0_wd; + logic dio_pad_attr_0_input_disable_0_qs; + logic dio_pad_attr_0_input_disable_0_wd; + logic [1:0] dio_pad_attr_0_slew_rate_0_qs; + logic [1:0] dio_pad_attr_0_slew_rate_0_wd; + logic [3:0] dio_pad_attr_0_drive_strength_0_qs; + logic [3:0] dio_pad_attr_0_drive_strength_0_wd; + logic dio_pad_attr_1_re; + logic dio_pad_attr_1_we; + logic dio_pad_attr_1_invert_1_qs; + logic dio_pad_attr_1_invert_1_wd; + logic dio_pad_attr_1_virtual_od_en_1_qs; + logic dio_pad_attr_1_virtual_od_en_1_wd; + logic dio_pad_attr_1_pull_en_1_qs; + logic dio_pad_attr_1_pull_en_1_wd; + logic dio_pad_attr_1_pull_select_1_qs; + logic dio_pad_attr_1_pull_select_1_wd; + logic dio_pad_attr_1_keeper_en_1_qs; + logic dio_pad_attr_1_keeper_en_1_wd; + logic dio_pad_attr_1_schmitt_en_1_qs; + logic dio_pad_attr_1_schmitt_en_1_wd; + logic dio_pad_attr_1_od_en_1_qs; + logic dio_pad_attr_1_od_en_1_wd; + logic dio_pad_attr_1_input_disable_1_qs; + logic dio_pad_attr_1_input_disable_1_wd; + logic [1:0] dio_pad_attr_1_slew_rate_1_qs; + logic [1:0] dio_pad_attr_1_slew_rate_1_wd; + logic [3:0] dio_pad_attr_1_drive_strength_1_qs; + logic [3:0] dio_pad_attr_1_drive_strength_1_wd; + logic dio_pad_attr_2_re; + logic dio_pad_attr_2_we; + logic dio_pad_attr_2_invert_2_qs; + logic dio_pad_attr_2_invert_2_wd; + logic dio_pad_attr_2_virtual_od_en_2_qs; + logic dio_pad_attr_2_virtual_od_en_2_wd; + logic dio_pad_attr_2_pull_en_2_qs; + logic dio_pad_attr_2_pull_en_2_wd; + logic dio_pad_attr_2_pull_select_2_qs; + logic dio_pad_attr_2_pull_select_2_wd; + logic dio_pad_attr_2_keeper_en_2_qs; + logic dio_pad_attr_2_keeper_en_2_wd; + logic dio_pad_attr_2_schmitt_en_2_qs; + logic dio_pad_attr_2_schmitt_en_2_wd; + logic dio_pad_attr_2_od_en_2_qs; + logic dio_pad_attr_2_od_en_2_wd; + logic dio_pad_attr_2_input_disable_2_qs; + logic dio_pad_attr_2_input_disable_2_wd; + logic [1:0] dio_pad_attr_2_slew_rate_2_qs; + logic [1:0] dio_pad_attr_2_slew_rate_2_wd; + logic [3:0] dio_pad_attr_2_drive_strength_2_qs; + logic [3:0] dio_pad_attr_2_drive_strength_2_wd; + logic dio_pad_attr_3_re; + logic dio_pad_attr_3_we; + logic dio_pad_attr_3_invert_3_qs; + logic dio_pad_attr_3_invert_3_wd; + logic dio_pad_attr_3_virtual_od_en_3_qs; + logic dio_pad_attr_3_virtual_od_en_3_wd; + logic dio_pad_attr_3_pull_en_3_qs; + logic dio_pad_attr_3_pull_en_3_wd; + logic dio_pad_attr_3_pull_select_3_qs; + logic dio_pad_attr_3_pull_select_3_wd; + logic dio_pad_attr_3_keeper_en_3_qs; + logic dio_pad_attr_3_keeper_en_3_wd; + logic dio_pad_attr_3_schmitt_en_3_qs; + logic dio_pad_attr_3_schmitt_en_3_wd; + logic dio_pad_attr_3_od_en_3_qs; + logic dio_pad_attr_3_od_en_3_wd; + logic dio_pad_attr_3_input_disable_3_qs; + logic dio_pad_attr_3_input_disable_3_wd; + logic [1:0] dio_pad_attr_3_slew_rate_3_qs; + logic [1:0] dio_pad_attr_3_slew_rate_3_wd; + logic [3:0] dio_pad_attr_3_drive_strength_3_qs; + logic [3:0] dio_pad_attr_3_drive_strength_3_wd; + logic dio_pad_attr_4_re; + logic dio_pad_attr_4_we; + logic dio_pad_attr_4_invert_4_qs; + logic dio_pad_attr_4_invert_4_wd; + logic dio_pad_attr_4_virtual_od_en_4_qs; + logic dio_pad_attr_4_virtual_od_en_4_wd; + logic dio_pad_attr_4_pull_en_4_qs; + logic dio_pad_attr_4_pull_en_4_wd; + logic dio_pad_attr_4_pull_select_4_qs; + logic dio_pad_attr_4_pull_select_4_wd; + logic dio_pad_attr_4_keeper_en_4_qs; + logic dio_pad_attr_4_keeper_en_4_wd; + logic dio_pad_attr_4_schmitt_en_4_qs; + logic dio_pad_attr_4_schmitt_en_4_wd; + logic dio_pad_attr_4_od_en_4_qs; + logic dio_pad_attr_4_od_en_4_wd; + logic dio_pad_attr_4_input_disable_4_qs; + logic dio_pad_attr_4_input_disable_4_wd; + logic [1:0] dio_pad_attr_4_slew_rate_4_qs; + logic [1:0] dio_pad_attr_4_slew_rate_4_wd; + logic [3:0] dio_pad_attr_4_drive_strength_4_qs; + logic [3:0] dio_pad_attr_4_drive_strength_4_wd; + logic dio_pad_attr_5_re; + logic dio_pad_attr_5_we; + logic dio_pad_attr_5_invert_5_qs; + logic dio_pad_attr_5_invert_5_wd; + logic dio_pad_attr_5_virtual_od_en_5_qs; + logic dio_pad_attr_5_virtual_od_en_5_wd; + logic dio_pad_attr_5_pull_en_5_qs; + logic dio_pad_attr_5_pull_en_5_wd; + logic dio_pad_attr_5_pull_select_5_qs; + logic dio_pad_attr_5_pull_select_5_wd; + logic dio_pad_attr_5_keeper_en_5_qs; + logic dio_pad_attr_5_keeper_en_5_wd; + logic dio_pad_attr_5_schmitt_en_5_qs; + logic dio_pad_attr_5_schmitt_en_5_wd; + logic dio_pad_attr_5_od_en_5_qs; + logic dio_pad_attr_5_od_en_5_wd; + logic dio_pad_attr_5_input_disable_5_qs; + logic dio_pad_attr_5_input_disable_5_wd; + logic [1:0] dio_pad_attr_5_slew_rate_5_qs; + logic [1:0] dio_pad_attr_5_slew_rate_5_wd; + logic [3:0] dio_pad_attr_5_drive_strength_5_qs; + logic [3:0] dio_pad_attr_5_drive_strength_5_wd; + logic dio_pad_attr_6_re; + logic dio_pad_attr_6_we; + logic dio_pad_attr_6_invert_6_qs; + logic dio_pad_attr_6_invert_6_wd; + logic dio_pad_attr_6_virtual_od_en_6_qs; + logic dio_pad_attr_6_virtual_od_en_6_wd; + logic dio_pad_attr_6_pull_en_6_qs; + logic dio_pad_attr_6_pull_en_6_wd; + logic dio_pad_attr_6_pull_select_6_qs; + logic dio_pad_attr_6_pull_select_6_wd; + logic dio_pad_attr_6_keeper_en_6_qs; + logic dio_pad_attr_6_keeper_en_6_wd; + logic dio_pad_attr_6_schmitt_en_6_qs; + logic dio_pad_attr_6_schmitt_en_6_wd; + logic dio_pad_attr_6_od_en_6_qs; + logic dio_pad_attr_6_od_en_6_wd; + logic dio_pad_attr_6_input_disable_6_qs; + logic dio_pad_attr_6_input_disable_6_wd; + logic [1:0] dio_pad_attr_6_slew_rate_6_qs; + logic [1:0] dio_pad_attr_6_slew_rate_6_wd; + logic [3:0] dio_pad_attr_6_drive_strength_6_qs; + logic [3:0] dio_pad_attr_6_drive_strength_6_wd; + logic dio_pad_attr_7_re; + logic dio_pad_attr_7_we; + logic dio_pad_attr_7_invert_7_qs; + logic dio_pad_attr_7_invert_7_wd; + logic dio_pad_attr_7_virtual_od_en_7_qs; + logic dio_pad_attr_7_virtual_od_en_7_wd; + logic dio_pad_attr_7_pull_en_7_qs; + logic dio_pad_attr_7_pull_en_7_wd; + logic dio_pad_attr_7_pull_select_7_qs; + logic dio_pad_attr_7_pull_select_7_wd; + logic dio_pad_attr_7_keeper_en_7_qs; + logic dio_pad_attr_7_keeper_en_7_wd; + logic dio_pad_attr_7_schmitt_en_7_qs; + logic dio_pad_attr_7_schmitt_en_7_wd; + logic dio_pad_attr_7_od_en_7_qs; + logic dio_pad_attr_7_od_en_7_wd; + logic dio_pad_attr_7_input_disable_7_qs; + logic dio_pad_attr_7_input_disable_7_wd; + logic [1:0] dio_pad_attr_7_slew_rate_7_qs; + logic [1:0] dio_pad_attr_7_slew_rate_7_wd; + logic [3:0] dio_pad_attr_7_drive_strength_7_qs; + logic [3:0] dio_pad_attr_7_drive_strength_7_wd; + logic dio_pad_attr_8_re; + logic dio_pad_attr_8_we; + logic dio_pad_attr_8_invert_8_qs; + logic dio_pad_attr_8_invert_8_wd; + logic dio_pad_attr_8_virtual_od_en_8_qs; + logic dio_pad_attr_8_virtual_od_en_8_wd; + logic dio_pad_attr_8_pull_en_8_qs; + logic dio_pad_attr_8_pull_en_8_wd; + logic dio_pad_attr_8_pull_select_8_qs; + logic dio_pad_attr_8_pull_select_8_wd; + logic dio_pad_attr_8_keeper_en_8_qs; + logic dio_pad_attr_8_keeper_en_8_wd; + logic dio_pad_attr_8_schmitt_en_8_qs; + logic dio_pad_attr_8_schmitt_en_8_wd; + logic dio_pad_attr_8_od_en_8_qs; + logic dio_pad_attr_8_od_en_8_wd; + logic dio_pad_attr_8_input_disable_8_qs; + logic dio_pad_attr_8_input_disable_8_wd; + logic [1:0] dio_pad_attr_8_slew_rate_8_qs; + logic [1:0] dio_pad_attr_8_slew_rate_8_wd; + logic [3:0] dio_pad_attr_8_drive_strength_8_qs; + logic [3:0] dio_pad_attr_8_drive_strength_8_wd; + logic dio_pad_attr_9_re; + logic dio_pad_attr_9_we; + logic dio_pad_attr_9_invert_9_qs; + logic dio_pad_attr_9_invert_9_wd; + logic dio_pad_attr_9_virtual_od_en_9_qs; + logic dio_pad_attr_9_virtual_od_en_9_wd; + logic dio_pad_attr_9_pull_en_9_qs; + logic dio_pad_attr_9_pull_en_9_wd; + logic dio_pad_attr_9_pull_select_9_qs; + logic dio_pad_attr_9_pull_select_9_wd; + logic dio_pad_attr_9_keeper_en_9_qs; + logic dio_pad_attr_9_keeper_en_9_wd; + logic dio_pad_attr_9_schmitt_en_9_qs; + logic dio_pad_attr_9_schmitt_en_9_wd; + logic dio_pad_attr_9_od_en_9_qs; + logic dio_pad_attr_9_od_en_9_wd; + logic dio_pad_attr_9_input_disable_9_qs; + logic dio_pad_attr_9_input_disable_9_wd; + logic [1:0] dio_pad_attr_9_slew_rate_9_qs; + logic [1:0] dio_pad_attr_9_slew_rate_9_wd; + logic [3:0] dio_pad_attr_9_drive_strength_9_qs; + logic [3:0] dio_pad_attr_9_drive_strength_9_wd; + logic dio_pad_attr_10_re; + logic dio_pad_attr_10_we; + logic dio_pad_attr_10_invert_10_qs; + logic dio_pad_attr_10_invert_10_wd; + logic dio_pad_attr_10_virtual_od_en_10_qs; + logic dio_pad_attr_10_virtual_od_en_10_wd; + logic dio_pad_attr_10_pull_en_10_qs; + logic dio_pad_attr_10_pull_en_10_wd; + logic dio_pad_attr_10_pull_select_10_qs; + logic dio_pad_attr_10_pull_select_10_wd; + logic dio_pad_attr_10_keeper_en_10_qs; + logic dio_pad_attr_10_keeper_en_10_wd; + logic dio_pad_attr_10_schmitt_en_10_qs; + logic dio_pad_attr_10_schmitt_en_10_wd; + logic dio_pad_attr_10_od_en_10_qs; + logic dio_pad_attr_10_od_en_10_wd; + logic dio_pad_attr_10_input_disable_10_qs; + logic dio_pad_attr_10_input_disable_10_wd; + logic [1:0] dio_pad_attr_10_slew_rate_10_qs; + logic [1:0] dio_pad_attr_10_slew_rate_10_wd; + logic [3:0] dio_pad_attr_10_drive_strength_10_qs; + logic [3:0] dio_pad_attr_10_drive_strength_10_wd; + logic dio_pad_attr_11_re; + logic dio_pad_attr_11_we; + logic dio_pad_attr_11_invert_11_qs; + logic dio_pad_attr_11_invert_11_wd; + logic dio_pad_attr_11_virtual_od_en_11_qs; + logic dio_pad_attr_11_virtual_od_en_11_wd; + logic dio_pad_attr_11_pull_en_11_qs; + logic dio_pad_attr_11_pull_en_11_wd; + logic dio_pad_attr_11_pull_select_11_qs; + logic dio_pad_attr_11_pull_select_11_wd; + logic dio_pad_attr_11_keeper_en_11_qs; + logic dio_pad_attr_11_keeper_en_11_wd; + logic dio_pad_attr_11_schmitt_en_11_qs; + logic dio_pad_attr_11_schmitt_en_11_wd; + logic dio_pad_attr_11_od_en_11_qs; + logic dio_pad_attr_11_od_en_11_wd; + logic dio_pad_attr_11_input_disable_11_qs; + logic dio_pad_attr_11_input_disable_11_wd; + logic [1:0] dio_pad_attr_11_slew_rate_11_qs; + logic [1:0] dio_pad_attr_11_slew_rate_11_wd; + logic [3:0] dio_pad_attr_11_drive_strength_11_qs; + logic [3:0] dio_pad_attr_11_drive_strength_11_wd; + logic dio_pad_attr_12_re; + logic dio_pad_attr_12_we; + logic dio_pad_attr_12_invert_12_qs; + logic dio_pad_attr_12_invert_12_wd; + logic dio_pad_attr_12_virtual_od_en_12_qs; + logic dio_pad_attr_12_virtual_od_en_12_wd; + logic dio_pad_attr_12_pull_en_12_qs; + logic dio_pad_attr_12_pull_en_12_wd; + logic dio_pad_attr_12_pull_select_12_qs; + logic dio_pad_attr_12_pull_select_12_wd; + logic dio_pad_attr_12_keeper_en_12_qs; + logic dio_pad_attr_12_keeper_en_12_wd; + logic dio_pad_attr_12_schmitt_en_12_qs; + logic dio_pad_attr_12_schmitt_en_12_wd; + logic dio_pad_attr_12_od_en_12_qs; + logic dio_pad_attr_12_od_en_12_wd; + logic dio_pad_attr_12_input_disable_12_qs; + logic dio_pad_attr_12_input_disable_12_wd; + logic [1:0] dio_pad_attr_12_slew_rate_12_qs; + logic [1:0] dio_pad_attr_12_slew_rate_12_wd; + logic [3:0] dio_pad_attr_12_drive_strength_12_qs; + logic [3:0] dio_pad_attr_12_drive_strength_12_wd; + logic dio_pad_attr_13_re; + logic dio_pad_attr_13_we; + logic dio_pad_attr_13_invert_13_qs; + logic dio_pad_attr_13_invert_13_wd; + logic dio_pad_attr_13_virtual_od_en_13_qs; + logic dio_pad_attr_13_virtual_od_en_13_wd; + logic dio_pad_attr_13_pull_en_13_qs; + logic dio_pad_attr_13_pull_en_13_wd; + logic dio_pad_attr_13_pull_select_13_qs; + logic dio_pad_attr_13_pull_select_13_wd; + logic dio_pad_attr_13_keeper_en_13_qs; + logic dio_pad_attr_13_keeper_en_13_wd; + logic dio_pad_attr_13_schmitt_en_13_qs; + logic dio_pad_attr_13_schmitt_en_13_wd; + logic dio_pad_attr_13_od_en_13_qs; + logic dio_pad_attr_13_od_en_13_wd; + logic dio_pad_attr_13_input_disable_13_qs; + logic dio_pad_attr_13_input_disable_13_wd; + logic [1:0] dio_pad_attr_13_slew_rate_13_qs; + logic [1:0] dio_pad_attr_13_slew_rate_13_wd; + logic [3:0] dio_pad_attr_13_drive_strength_13_qs; + logic [3:0] dio_pad_attr_13_drive_strength_13_wd; + logic mio_pad_sleep_status_0_we; + logic mio_pad_sleep_status_0_en_0_qs; + logic mio_pad_sleep_status_0_en_0_wd; + logic mio_pad_sleep_status_0_en_1_qs; + logic mio_pad_sleep_status_0_en_1_wd; + logic mio_pad_sleep_status_0_en_2_qs; + logic mio_pad_sleep_status_0_en_2_wd; + logic mio_pad_sleep_status_0_en_3_qs; + logic mio_pad_sleep_status_0_en_3_wd; + logic mio_pad_sleep_status_0_en_4_qs; + logic mio_pad_sleep_status_0_en_4_wd; + logic mio_pad_sleep_status_0_en_5_qs; + logic mio_pad_sleep_status_0_en_5_wd; + logic mio_pad_sleep_status_0_en_6_qs; + logic mio_pad_sleep_status_0_en_6_wd; + logic mio_pad_sleep_status_0_en_7_qs; + logic mio_pad_sleep_status_0_en_7_wd; + logic mio_pad_sleep_status_0_en_8_qs; + logic mio_pad_sleep_status_0_en_8_wd; + logic mio_pad_sleep_status_0_en_9_qs; + logic mio_pad_sleep_status_0_en_9_wd; + logic mio_pad_sleep_status_0_en_10_qs; + logic mio_pad_sleep_status_0_en_10_wd; + logic mio_pad_sleep_status_0_en_11_qs; + logic mio_pad_sleep_status_0_en_11_wd; + logic mio_pad_sleep_status_0_en_12_qs; + logic mio_pad_sleep_status_0_en_12_wd; + logic mio_pad_sleep_status_0_en_13_qs; + logic mio_pad_sleep_status_0_en_13_wd; + logic mio_pad_sleep_status_0_en_14_qs; + logic mio_pad_sleep_status_0_en_14_wd; + logic mio_pad_sleep_status_0_en_15_qs; + logic mio_pad_sleep_status_0_en_15_wd; + logic mio_pad_sleep_status_0_en_16_qs; + logic mio_pad_sleep_status_0_en_16_wd; + logic mio_pad_sleep_status_0_en_17_qs; + logic mio_pad_sleep_status_0_en_17_wd; + logic mio_pad_sleep_status_0_en_18_qs; + logic mio_pad_sleep_status_0_en_18_wd; + logic mio_pad_sleep_status_0_en_19_qs; + logic mio_pad_sleep_status_0_en_19_wd; + logic mio_pad_sleep_status_0_en_20_qs; + logic mio_pad_sleep_status_0_en_20_wd; + logic mio_pad_sleep_status_0_en_21_qs; + logic mio_pad_sleep_status_0_en_21_wd; + logic mio_pad_sleep_status_0_en_22_qs; + logic mio_pad_sleep_status_0_en_22_wd; + logic mio_pad_sleep_status_0_en_23_qs; + logic mio_pad_sleep_status_0_en_23_wd; + logic mio_pad_sleep_status_0_en_24_qs; + logic mio_pad_sleep_status_0_en_24_wd; + logic mio_pad_sleep_status_0_en_25_qs; + logic mio_pad_sleep_status_0_en_25_wd; + logic mio_pad_sleep_status_0_en_26_qs; + logic mio_pad_sleep_status_0_en_26_wd; + logic mio_pad_sleep_status_0_en_27_qs; + logic mio_pad_sleep_status_0_en_27_wd; + logic mio_pad_sleep_status_0_en_28_qs; + logic mio_pad_sleep_status_0_en_28_wd; + logic mio_pad_sleep_status_0_en_29_qs; + logic mio_pad_sleep_status_0_en_29_wd; + logic mio_pad_sleep_status_0_en_30_qs; + logic mio_pad_sleep_status_0_en_30_wd; + logic mio_pad_sleep_status_0_en_31_qs; + logic mio_pad_sleep_status_0_en_31_wd; + logic mio_pad_sleep_status_1_we; + logic mio_pad_sleep_status_1_en_32_qs; + logic mio_pad_sleep_status_1_en_32_wd; + logic mio_pad_sleep_status_1_en_33_qs; + logic mio_pad_sleep_status_1_en_33_wd; + logic mio_pad_sleep_status_1_en_34_qs; + logic mio_pad_sleep_status_1_en_34_wd; + logic mio_pad_sleep_status_1_en_35_qs; + logic mio_pad_sleep_status_1_en_35_wd; + logic mio_pad_sleep_status_1_en_36_qs; + logic mio_pad_sleep_status_1_en_36_wd; + logic mio_pad_sleep_status_1_en_37_qs; + logic mio_pad_sleep_status_1_en_37_wd; + logic mio_pad_sleep_status_1_en_38_qs; + logic mio_pad_sleep_status_1_en_38_wd; + logic mio_pad_sleep_status_1_en_39_qs; + logic mio_pad_sleep_status_1_en_39_wd; + logic mio_pad_sleep_status_1_en_40_qs; + logic mio_pad_sleep_status_1_en_40_wd; + logic mio_pad_sleep_status_1_en_41_qs; + logic mio_pad_sleep_status_1_en_41_wd; + logic mio_pad_sleep_status_1_en_42_qs; + logic mio_pad_sleep_status_1_en_42_wd; + logic mio_pad_sleep_status_1_en_43_qs; + logic mio_pad_sleep_status_1_en_43_wd; + logic mio_pad_sleep_status_1_en_44_qs; + logic mio_pad_sleep_status_1_en_44_wd; + logic mio_pad_sleep_status_1_en_45_qs; + logic mio_pad_sleep_status_1_en_45_wd; + logic mio_pad_sleep_status_1_en_46_qs; + logic mio_pad_sleep_status_1_en_46_wd; + logic mio_pad_sleep_regwen_0_we; + logic mio_pad_sleep_regwen_0_qs; + logic mio_pad_sleep_regwen_0_wd; + logic mio_pad_sleep_regwen_1_we; + logic mio_pad_sleep_regwen_1_qs; + logic mio_pad_sleep_regwen_1_wd; + logic mio_pad_sleep_regwen_2_we; + logic mio_pad_sleep_regwen_2_qs; + logic mio_pad_sleep_regwen_2_wd; + logic mio_pad_sleep_regwen_3_we; + logic mio_pad_sleep_regwen_3_qs; + logic mio_pad_sleep_regwen_3_wd; + logic mio_pad_sleep_regwen_4_we; + logic mio_pad_sleep_regwen_4_qs; + logic mio_pad_sleep_regwen_4_wd; + logic mio_pad_sleep_regwen_5_we; + logic mio_pad_sleep_regwen_5_qs; + logic mio_pad_sleep_regwen_5_wd; + logic mio_pad_sleep_regwen_6_we; + logic mio_pad_sleep_regwen_6_qs; + logic mio_pad_sleep_regwen_6_wd; + logic mio_pad_sleep_regwen_7_we; + logic mio_pad_sleep_regwen_7_qs; + logic mio_pad_sleep_regwen_7_wd; + logic mio_pad_sleep_regwen_8_we; + logic mio_pad_sleep_regwen_8_qs; + logic mio_pad_sleep_regwen_8_wd; + logic mio_pad_sleep_regwen_9_we; + logic mio_pad_sleep_regwen_9_qs; + logic mio_pad_sleep_regwen_9_wd; + logic mio_pad_sleep_regwen_10_we; + logic mio_pad_sleep_regwen_10_qs; + logic mio_pad_sleep_regwen_10_wd; + logic mio_pad_sleep_regwen_11_we; + logic mio_pad_sleep_regwen_11_qs; + logic mio_pad_sleep_regwen_11_wd; + logic mio_pad_sleep_regwen_12_we; + logic mio_pad_sleep_regwen_12_qs; + logic mio_pad_sleep_regwen_12_wd; + logic mio_pad_sleep_regwen_13_we; + logic mio_pad_sleep_regwen_13_qs; + logic mio_pad_sleep_regwen_13_wd; + logic mio_pad_sleep_regwen_14_we; + logic mio_pad_sleep_regwen_14_qs; + logic mio_pad_sleep_regwen_14_wd; + logic mio_pad_sleep_regwen_15_we; + logic mio_pad_sleep_regwen_15_qs; + logic mio_pad_sleep_regwen_15_wd; + logic mio_pad_sleep_regwen_16_we; + logic mio_pad_sleep_regwen_16_qs; + logic mio_pad_sleep_regwen_16_wd; + logic mio_pad_sleep_regwen_17_we; + logic mio_pad_sleep_regwen_17_qs; + logic mio_pad_sleep_regwen_17_wd; + logic mio_pad_sleep_regwen_18_we; + logic mio_pad_sleep_regwen_18_qs; + logic mio_pad_sleep_regwen_18_wd; + logic mio_pad_sleep_regwen_19_we; + logic mio_pad_sleep_regwen_19_qs; + logic mio_pad_sleep_regwen_19_wd; + logic mio_pad_sleep_regwen_20_we; + logic mio_pad_sleep_regwen_20_qs; + logic mio_pad_sleep_regwen_20_wd; + logic mio_pad_sleep_regwen_21_we; + logic mio_pad_sleep_regwen_21_qs; + logic mio_pad_sleep_regwen_21_wd; + logic mio_pad_sleep_regwen_22_we; + logic mio_pad_sleep_regwen_22_qs; + logic mio_pad_sleep_regwen_22_wd; + logic mio_pad_sleep_regwen_23_we; + logic mio_pad_sleep_regwen_23_qs; + logic mio_pad_sleep_regwen_23_wd; + logic mio_pad_sleep_regwen_24_we; + logic mio_pad_sleep_regwen_24_qs; + logic mio_pad_sleep_regwen_24_wd; + logic mio_pad_sleep_regwen_25_we; + logic mio_pad_sleep_regwen_25_qs; + logic mio_pad_sleep_regwen_25_wd; + logic mio_pad_sleep_regwen_26_we; + logic mio_pad_sleep_regwen_26_qs; + logic mio_pad_sleep_regwen_26_wd; + logic mio_pad_sleep_regwen_27_we; + logic mio_pad_sleep_regwen_27_qs; + logic mio_pad_sleep_regwen_27_wd; + logic mio_pad_sleep_regwen_28_we; + logic mio_pad_sleep_regwen_28_qs; + logic mio_pad_sleep_regwen_28_wd; + logic mio_pad_sleep_regwen_29_we; + logic mio_pad_sleep_regwen_29_qs; + logic mio_pad_sleep_regwen_29_wd; + logic mio_pad_sleep_regwen_30_we; + logic mio_pad_sleep_regwen_30_qs; + logic mio_pad_sleep_regwen_30_wd; + logic mio_pad_sleep_regwen_31_we; + logic mio_pad_sleep_regwen_31_qs; + logic mio_pad_sleep_regwen_31_wd; + logic mio_pad_sleep_regwen_32_we; + logic mio_pad_sleep_regwen_32_qs; + logic mio_pad_sleep_regwen_32_wd; + logic mio_pad_sleep_regwen_33_we; + logic mio_pad_sleep_regwen_33_qs; + logic mio_pad_sleep_regwen_33_wd; + logic mio_pad_sleep_regwen_34_we; + logic mio_pad_sleep_regwen_34_qs; + logic mio_pad_sleep_regwen_34_wd; + logic mio_pad_sleep_regwen_35_we; + logic mio_pad_sleep_regwen_35_qs; + logic mio_pad_sleep_regwen_35_wd; + logic mio_pad_sleep_regwen_36_we; + logic mio_pad_sleep_regwen_36_qs; + logic mio_pad_sleep_regwen_36_wd; + logic mio_pad_sleep_regwen_37_we; + logic mio_pad_sleep_regwen_37_qs; + logic mio_pad_sleep_regwen_37_wd; + logic mio_pad_sleep_regwen_38_we; + logic mio_pad_sleep_regwen_38_qs; + logic mio_pad_sleep_regwen_38_wd; + logic mio_pad_sleep_regwen_39_we; + logic mio_pad_sleep_regwen_39_qs; + logic mio_pad_sleep_regwen_39_wd; + logic mio_pad_sleep_regwen_40_we; + logic mio_pad_sleep_regwen_40_qs; + logic mio_pad_sleep_regwen_40_wd; + logic mio_pad_sleep_regwen_41_we; + logic mio_pad_sleep_regwen_41_qs; + logic mio_pad_sleep_regwen_41_wd; + logic mio_pad_sleep_regwen_42_we; + logic mio_pad_sleep_regwen_42_qs; + logic mio_pad_sleep_regwen_42_wd; + logic mio_pad_sleep_regwen_43_we; + logic mio_pad_sleep_regwen_43_qs; + logic mio_pad_sleep_regwen_43_wd; + logic mio_pad_sleep_regwen_44_we; + logic mio_pad_sleep_regwen_44_qs; + logic mio_pad_sleep_regwen_44_wd; + logic mio_pad_sleep_regwen_45_we; + logic mio_pad_sleep_regwen_45_qs; + logic mio_pad_sleep_regwen_45_wd; + logic mio_pad_sleep_regwen_46_we; + logic mio_pad_sleep_regwen_46_qs; + logic mio_pad_sleep_regwen_46_wd; + logic mio_pad_sleep_en_0_we; + logic mio_pad_sleep_en_0_qs; + logic mio_pad_sleep_en_0_wd; + logic mio_pad_sleep_en_1_we; + logic mio_pad_sleep_en_1_qs; + logic mio_pad_sleep_en_1_wd; + logic mio_pad_sleep_en_2_we; + logic mio_pad_sleep_en_2_qs; + logic mio_pad_sleep_en_2_wd; + logic mio_pad_sleep_en_3_we; + logic mio_pad_sleep_en_3_qs; + logic mio_pad_sleep_en_3_wd; + logic mio_pad_sleep_en_4_we; + logic mio_pad_sleep_en_4_qs; + logic mio_pad_sleep_en_4_wd; + logic mio_pad_sleep_en_5_we; + logic mio_pad_sleep_en_5_qs; + logic mio_pad_sleep_en_5_wd; + logic mio_pad_sleep_en_6_we; + logic mio_pad_sleep_en_6_qs; + logic mio_pad_sleep_en_6_wd; + logic mio_pad_sleep_en_7_we; + logic mio_pad_sleep_en_7_qs; + logic mio_pad_sleep_en_7_wd; + logic mio_pad_sleep_en_8_we; + logic mio_pad_sleep_en_8_qs; + logic mio_pad_sleep_en_8_wd; + logic mio_pad_sleep_en_9_we; + logic mio_pad_sleep_en_9_qs; + logic mio_pad_sleep_en_9_wd; + logic mio_pad_sleep_en_10_we; + logic mio_pad_sleep_en_10_qs; + logic mio_pad_sleep_en_10_wd; + logic mio_pad_sleep_en_11_we; + logic mio_pad_sleep_en_11_qs; + logic mio_pad_sleep_en_11_wd; + logic mio_pad_sleep_en_12_we; + logic mio_pad_sleep_en_12_qs; + logic mio_pad_sleep_en_12_wd; + logic mio_pad_sleep_en_13_we; + logic mio_pad_sleep_en_13_qs; + logic mio_pad_sleep_en_13_wd; + logic mio_pad_sleep_en_14_we; + logic mio_pad_sleep_en_14_qs; + logic mio_pad_sleep_en_14_wd; + logic mio_pad_sleep_en_15_we; + logic mio_pad_sleep_en_15_qs; + logic mio_pad_sleep_en_15_wd; + logic mio_pad_sleep_en_16_we; + logic mio_pad_sleep_en_16_qs; + logic mio_pad_sleep_en_16_wd; + logic mio_pad_sleep_en_17_we; + logic mio_pad_sleep_en_17_qs; + logic mio_pad_sleep_en_17_wd; + logic mio_pad_sleep_en_18_we; + logic mio_pad_sleep_en_18_qs; + logic mio_pad_sleep_en_18_wd; + logic mio_pad_sleep_en_19_we; + logic mio_pad_sleep_en_19_qs; + logic mio_pad_sleep_en_19_wd; + logic mio_pad_sleep_en_20_we; + logic mio_pad_sleep_en_20_qs; + logic mio_pad_sleep_en_20_wd; + logic mio_pad_sleep_en_21_we; + logic mio_pad_sleep_en_21_qs; + logic mio_pad_sleep_en_21_wd; + logic mio_pad_sleep_en_22_we; + logic mio_pad_sleep_en_22_qs; + logic mio_pad_sleep_en_22_wd; + logic mio_pad_sleep_en_23_we; + logic mio_pad_sleep_en_23_qs; + logic mio_pad_sleep_en_23_wd; + logic mio_pad_sleep_en_24_we; + logic mio_pad_sleep_en_24_qs; + logic mio_pad_sleep_en_24_wd; + logic mio_pad_sleep_en_25_we; + logic mio_pad_sleep_en_25_qs; + logic mio_pad_sleep_en_25_wd; + logic mio_pad_sleep_en_26_we; + logic mio_pad_sleep_en_26_qs; + logic mio_pad_sleep_en_26_wd; + logic mio_pad_sleep_en_27_we; + logic mio_pad_sleep_en_27_qs; + logic mio_pad_sleep_en_27_wd; + logic mio_pad_sleep_en_28_we; + logic mio_pad_sleep_en_28_qs; + logic mio_pad_sleep_en_28_wd; + logic mio_pad_sleep_en_29_we; + logic mio_pad_sleep_en_29_qs; + logic mio_pad_sleep_en_29_wd; + logic mio_pad_sleep_en_30_we; + logic mio_pad_sleep_en_30_qs; + logic mio_pad_sleep_en_30_wd; + logic mio_pad_sleep_en_31_we; + logic mio_pad_sleep_en_31_qs; + logic mio_pad_sleep_en_31_wd; + logic mio_pad_sleep_en_32_we; + logic mio_pad_sleep_en_32_qs; + logic mio_pad_sleep_en_32_wd; + logic mio_pad_sleep_en_33_we; + logic mio_pad_sleep_en_33_qs; + logic mio_pad_sleep_en_33_wd; + logic mio_pad_sleep_en_34_we; + logic mio_pad_sleep_en_34_qs; + logic mio_pad_sleep_en_34_wd; + logic mio_pad_sleep_en_35_we; + logic mio_pad_sleep_en_35_qs; + logic mio_pad_sleep_en_35_wd; + logic mio_pad_sleep_en_36_we; + logic mio_pad_sleep_en_36_qs; + logic mio_pad_sleep_en_36_wd; + logic mio_pad_sleep_en_37_we; + logic mio_pad_sleep_en_37_qs; + logic mio_pad_sleep_en_37_wd; + logic mio_pad_sleep_en_38_we; + logic mio_pad_sleep_en_38_qs; + logic mio_pad_sleep_en_38_wd; + logic mio_pad_sleep_en_39_we; + logic mio_pad_sleep_en_39_qs; + logic mio_pad_sleep_en_39_wd; + logic mio_pad_sleep_en_40_we; + logic mio_pad_sleep_en_40_qs; + logic mio_pad_sleep_en_40_wd; + logic mio_pad_sleep_en_41_we; + logic mio_pad_sleep_en_41_qs; + logic mio_pad_sleep_en_41_wd; + logic mio_pad_sleep_en_42_we; + logic mio_pad_sleep_en_42_qs; + logic mio_pad_sleep_en_42_wd; + logic mio_pad_sleep_en_43_we; + logic mio_pad_sleep_en_43_qs; + logic mio_pad_sleep_en_43_wd; + logic mio_pad_sleep_en_44_we; + logic mio_pad_sleep_en_44_qs; + logic mio_pad_sleep_en_44_wd; + logic mio_pad_sleep_en_45_we; + logic mio_pad_sleep_en_45_qs; + logic mio_pad_sleep_en_45_wd; + logic mio_pad_sleep_en_46_we; + logic mio_pad_sleep_en_46_qs; + logic mio_pad_sleep_en_46_wd; + logic mio_pad_sleep_mode_0_we; + logic [1:0] mio_pad_sleep_mode_0_qs; + logic [1:0] mio_pad_sleep_mode_0_wd; + logic mio_pad_sleep_mode_1_we; + logic [1:0] mio_pad_sleep_mode_1_qs; + logic [1:0] mio_pad_sleep_mode_1_wd; + logic mio_pad_sleep_mode_2_we; + logic [1:0] mio_pad_sleep_mode_2_qs; + logic [1:0] mio_pad_sleep_mode_2_wd; + logic mio_pad_sleep_mode_3_we; + logic [1:0] mio_pad_sleep_mode_3_qs; + logic [1:0] mio_pad_sleep_mode_3_wd; + logic mio_pad_sleep_mode_4_we; + logic [1:0] mio_pad_sleep_mode_4_qs; + logic [1:0] mio_pad_sleep_mode_4_wd; + logic mio_pad_sleep_mode_5_we; + logic [1:0] mio_pad_sleep_mode_5_qs; + logic [1:0] mio_pad_sleep_mode_5_wd; + logic mio_pad_sleep_mode_6_we; + logic [1:0] mio_pad_sleep_mode_6_qs; + logic [1:0] mio_pad_sleep_mode_6_wd; + logic mio_pad_sleep_mode_7_we; + logic [1:0] mio_pad_sleep_mode_7_qs; + logic [1:0] mio_pad_sleep_mode_7_wd; + logic mio_pad_sleep_mode_8_we; + logic [1:0] mio_pad_sleep_mode_8_qs; + logic [1:0] mio_pad_sleep_mode_8_wd; + logic mio_pad_sleep_mode_9_we; + logic [1:0] mio_pad_sleep_mode_9_qs; + logic [1:0] mio_pad_sleep_mode_9_wd; + logic mio_pad_sleep_mode_10_we; + logic [1:0] mio_pad_sleep_mode_10_qs; + logic [1:0] mio_pad_sleep_mode_10_wd; + logic mio_pad_sleep_mode_11_we; + logic [1:0] mio_pad_sleep_mode_11_qs; + logic [1:0] mio_pad_sleep_mode_11_wd; + logic mio_pad_sleep_mode_12_we; + logic [1:0] mio_pad_sleep_mode_12_qs; + logic [1:0] mio_pad_sleep_mode_12_wd; + logic mio_pad_sleep_mode_13_we; + logic [1:0] mio_pad_sleep_mode_13_qs; + logic [1:0] mio_pad_sleep_mode_13_wd; + logic mio_pad_sleep_mode_14_we; + logic [1:0] mio_pad_sleep_mode_14_qs; + logic [1:0] mio_pad_sleep_mode_14_wd; + logic mio_pad_sleep_mode_15_we; + logic [1:0] mio_pad_sleep_mode_15_qs; + logic [1:0] mio_pad_sleep_mode_15_wd; + logic mio_pad_sleep_mode_16_we; + logic [1:0] mio_pad_sleep_mode_16_qs; + logic [1:0] mio_pad_sleep_mode_16_wd; + logic mio_pad_sleep_mode_17_we; + logic [1:0] mio_pad_sleep_mode_17_qs; + logic [1:0] mio_pad_sleep_mode_17_wd; + logic mio_pad_sleep_mode_18_we; + logic [1:0] mio_pad_sleep_mode_18_qs; + logic [1:0] mio_pad_sleep_mode_18_wd; + logic mio_pad_sleep_mode_19_we; + logic [1:0] mio_pad_sleep_mode_19_qs; + logic [1:0] mio_pad_sleep_mode_19_wd; + logic mio_pad_sleep_mode_20_we; + logic [1:0] mio_pad_sleep_mode_20_qs; + logic [1:0] mio_pad_sleep_mode_20_wd; + logic mio_pad_sleep_mode_21_we; + logic [1:0] mio_pad_sleep_mode_21_qs; + logic [1:0] mio_pad_sleep_mode_21_wd; + logic mio_pad_sleep_mode_22_we; + logic [1:0] mio_pad_sleep_mode_22_qs; + logic [1:0] mio_pad_sleep_mode_22_wd; + logic mio_pad_sleep_mode_23_we; + logic [1:0] mio_pad_sleep_mode_23_qs; + logic [1:0] mio_pad_sleep_mode_23_wd; + logic mio_pad_sleep_mode_24_we; + logic [1:0] mio_pad_sleep_mode_24_qs; + logic [1:0] mio_pad_sleep_mode_24_wd; + logic mio_pad_sleep_mode_25_we; + logic [1:0] mio_pad_sleep_mode_25_qs; + logic [1:0] mio_pad_sleep_mode_25_wd; + logic mio_pad_sleep_mode_26_we; + logic [1:0] mio_pad_sleep_mode_26_qs; + logic [1:0] mio_pad_sleep_mode_26_wd; + logic mio_pad_sleep_mode_27_we; + logic [1:0] mio_pad_sleep_mode_27_qs; + logic [1:0] mio_pad_sleep_mode_27_wd; + logic mio_pad_sleep_mode_28_we; + logic [1:0] mio_pad_sleep_mode_28_qs; + logic [1:0] mio_pad_sleep_mode_28_wd; + logic mio_pad_sleep_mode_29_we; + logic [1:0] mio_pad_sleep_mode_29_qs; + logic [1:0] mio_pad_sleep_mode_29_wd; + logic mio_pad_sleep_mode_30_we; + logic [1:0] mio_pad_sleep_mode_30_qs; + logic [1:0] mio_pad_sleep_mode_30_wd; + logic mio_pad_sleep_mode_31_we; + logic [1:0] mio_pad_sleep_mode_31_qs; + logic [1:0] mio_pad_sleep_mode_31_wd; + logic mio_pad_sleep_mode_32_we; + logic [1:0] mio_pad_sleep_mode_32_qs; + logic [1:0] mio_pad_sleep_mode_32_wd; + logic mio_pad_sleep_mode_33_we; + logic [1:0] mio_pad_sleep_mode_33_qs; + logic [1:0] mio_pad_sleep_mode_33_wd; + logic mio_pad_sleep_mode_34_we; + logic [1:0] mio_pad_sleep_mode_34_qs; + logic [1:0] mio_pad_sleep_mode_34_wd; + logic mio_pad_sleep_mode_35_we; + logic [1:0] mio_pad_sleep_mode_35_qs; + logic [1:0] mio_pad_sleep_mode_35_wd; + logic mio_pad_sleep_mode_36_we; + logic [1:0] mio_pad_sleep_mode_36_qs; + logic [1:0] mio_pad_sleep_mode_36_wd; + logic mio_pad_sleep_mode_37_we; + logic [1:0] mio_pad_sleep_mode_37_qs; + logic [1:0] mio_pad_sleep_mode_37_wd; + logic mio_pad_sleep_mode_38_we; + logic [1:0] mio_pad_sleep_mode_38_qs; + logic [1:0] mio_pad_sleep_mode_38_wd; + logic mio_pad_sleep_mode_39_we; + logic [1:0] mio_pad_sleep_mode_39_qs; + logic [1:0] mio_pad_sleep_mode_39_wd; + logic mio_pad_sleep_mode_40_we; + logic [1:0] mio_pad_sleep_mode_40_qs; + logic [1:0] mio_pad_sleep_mode_40_wd; + logic mio_pad_sleep_mode_41_we; + logic [1:0] mio_pad_sleep_mode_41_qs; + logic [1:0] mio_pad_sleep_mode_41_wd; + logic mio_pad_sleep_mode_42_we; + logic [1:0] mio_pad_sleep_mode_42_qs; + logic [1:0] mio_pad_sleep_mode_42_wd; + logic mio_pad_sleep_mode_43_we; + logic [1:0] mio_pad_sleep_mode_43_qs; + logic [1:0] mio_pad_sleep_mode_43_wd; + logic mio_pad_sleep_mode_44_we; + logic [1:0] mio_pad_sleep_mode_44_qs; + logic [1:0] mio_pad_sleep_mode_44_wd; + logic mio_pad_sleep_mode_45_we; + logic [1:0] mio_pad_sleep_mode_45_qs; + logic [1:0] mio_pad_sleep_mode_45_wd; + logic mio_pad_sleep_mode_46_we; + logic [1:0] mio_pad_sleep_mode_46_qs; + logic [1:0] mio_pad_sleep_mode_46_wd; + logic dio_pad_sleep_status_we; + logic dio_pad_sleep_status_en_0_qs; + logic dio_pad_sleep_status_en_0_wd; + logic dio_pad_sleep_status_en_1_qs; + logic dio_pad_sleep_status_en_1_wd; + logic dio_pad_sleep_status_en_2_qs; + logic dio_pad_sleep_status_en_2_wd; + logic dio_pad_sleep_status_en_3_qs; + logic dio_pad_sleep_status_en_3_wd; + logic dio_pad_sleep_status_en_4_qs; + logic dio_pad_sleep_status_en_4_wd; + logic dio_pad_sleep_status_en_5_qs; + logic dio_pad_sleep_status_en_5_wd; + logic dio_pad_sleep_status_en_6_qs; + logic dio_pad_sleep_status_en_6_wd; + logic dio_pad_sleep_status_en_7_qs; + logic dio_pad_sleep_status_en_7_wd; + logic dio_pad_sleep_status_en_8_qs; + logic dio_pad_sleep_status_en_8_wd; + logic dio_pad_sleep_status_en_9_qs; + logic dio_pad_sleep_status_en_9_wd; + logic dio_pad_sleep_status_en_10_qs; + logic dio_pad_sleep_status_en_10_wd; + logic dio_pad_sleep_status_en_11_qs; + logic dio_pad_sleep_status_en_11_wd; + logic dio_pad_sleep_status_en_12_qs; + logic dio_pad_sleep_status_en_12_wd; + logic dio_pad_sleep_status_en_13_qs; + logic dio_pad_sleep_status_en_13_wd; + logic dio_pad_sleep_regwen_0_we; + logic dio_pad_sleep_regwen_0_qs; + logic dio_pad_sleep_regwen_0_wd; + logic dio_pad_sleep_regwen_1_we; + logic dio_pad_sleep_regwen_1_qs; + logic dio_pad_sleep_regwen_1_wd; + logic dio_pad_sleep_regwen_2_we; + logic dio_pad_sleep_regwen_2_qs; + logic dio_pad_sleep_regwen_2_wd; + logic dio_pad_sleep_regwen_3_we; + logic dio_pad_sleep_regwen_3_qs; + logic dio_pad_sleep_regwen_3_wd; + logic dio_pad_sleep_regwen_4_we; + logic dio_pad_sleep_regwen_4_qs; + logic dio_pad_sleep_regwen_4_wd; + logic dio_pad_sleep_regwen_5_we; + logic dio_pad_sleep_regwen_5_qs; + logic dio_pad_sleep_regwen_5_wd; + logic dio_pad_sleep_regwen_6_we; + logic dio_pad_sleep_regwen_6_qs; + logic dio_pad_sleep_regwen_6_wd; + logic dio_pad_sleep_regwen_7_we; + logic dio_pad_sleep_regwen_7_qs; + logic dio_pad_sleep_regwen_7_wd; + logic dio_pad_sleep_regwen_8_we; + logic dio_pad_sleep_regwen_8_qs; + logic dio_pad_sleep_regwen_8_wd; + logic dio_pad_sleep_regwen_9_we; + logic dio_pad_sleep_regwen_9_qs; + logic dio_pad_sleep_regwen_9_wd; + logic dio_pad_sleep_regwen_10_we; + logic dio_pad_sleep_regwen_10_qs; + logic dio_pad_sleep_regwen_10_wd; + logic dio_pad_sleep_regwen_11_we; + logic dio_pad_sleep_regwen_11_qs; + logic dio_pad_sleep_regwen_11_wd; + logic dio_pad_sleep_regwen_12_we; + logic dio_pad_sleep_regwen_12_qs; + logic dio_pad_sleep_regwen_12_wd; + logic dio_pad_sleep_regwen_13_we; + logic dio_pad_sleep_regwen_13_qs; + logic dio_pad_sleep_regwen_13_wd; + logic dio_pad_sleep_en_0_we; + logic dio_pad_sleep_en_0_qs; + logic dio_pad_sleep_en_0_wd; + logic dio_pad_sleep_en_1_we; + logic dio_pad_sleep_en_1_qs; + logic dio_pad_sleep_en_1_wd; + logic dio_pad_sleep_en_2_we; + logic dio_pad_sleep_en_2_qs; + logic dio_pad_sleep_en_2_wd; + logic dio_pad_sleep_en_3_we; + logic dio_pad_sleep_en_3_qs; + logic dio_pad_sleep_en_3_wd; + logic dio_pad_sleep_en_4_we; + logic dio_pad_sleep_en_4_qs; + logic dio_pad_sleep_en_4_wd; + logic dio_pad_sleep_en_5_we; + logic dio_pad_sleep_en_5_qs; + logic dio_pad_sleep_en_5_wd; + logic dio_pad_sleep_en_6_we; + logic dio_pad_sleep_en_6_qs; + logic dio_pad_sleep_en_6_wd; + logic dio_pad_sleep_en_7_we; + logic dio_pad_sleep_en_7_qs; + logic dio_pad_sleep_en_7_wd; + logic dio_pad_sleep_en_8_we; + logic dio_pad_sleep_en_8_qs; + logic dio_pad_sleep_en_8_wd; + logic dio_pad_sleep_en_9_we; + logic dio_pad_sleep_en_9_qs; + logic dio_pad_sleep_en_9_wd; + logic dio_pad_sleep_en_10_we; + logic dio_pad_sleep_en_10_qs; + logic dio_pad_sleep_en_10_wd; + logic dio_pad_sleep_en_11_we; + logic dio_pad_sleep_en_11_qs; + logic dio_pad_sleep_en_11_wd; + logic dio_pad_sleep_en_12_we; + logic dio_pad_sleep_en_12_qs; + logic dio_pad_sleep_en_12_wd; + logic dio_pad_sleep_en_13_we; + logic dio_pad_sleep_en_13_qs; + logic dio_pad_sleep_en_13_wd; + logic dio_pad_sleep_mode_0_we; + logic [1:0] dio_pad_sleep_mode_0_qs; + logic [1:0] dio_pad_sleep_mode_0_wd; + logic dio_pad_sleep_mode_1_we; + logic [1:0] dio_pad_sleep_mode_1_qs; + logic [1:0] dio_pad_sleep_mode_1_wd; + logic dio_pad_sleep_mode_2_we; + logic [1:0] dio_pad_sleep_mode_2_qs; + logic [1:0] dio_pad_sleep_mode_2_wd; + logic dio_pad_sleep_mode_3_we; + logic [1:0] dio_pad_sleep_mode_3_qs; + logic [1:0] dio_pad_sleep_mode_3_wd; + logic dio_pad_sleep_mode_4_we; + logic [1:0] dio_pad_sleep_mode_4_qs; + logic [1:0] dio_pad_sleep_mode_4_wd; + logic dio_pad_sleep_mode_5_we; + logic [1:0] dio_pad_sleep_mode_5_qs; + logic [1:0] dio_pad_sleep_mode_5_wd; + logic dio_pad_sleep_mode_6_we; + logic [1:0] dio_pad_sleep_mode_6_qs; + logic [1:0] dio_pad_sleep_mode_6_wd; + logic dio_pad_sleep_mode_7_we; + logic [1:0] dio_pad_sleep_mode_7_qs; + logic [1:0] dio_pad_sleep_mode_7_wd; + logic dio_pad_sleep_mode_8_we; + logic [1:0] dio_pad_sleep_mode_8_qs; + logic [1:0] dio_pad_sleep_mode_8_wd; + logic dio_pad_sleep_mode_9_we; + logic [1:0] dio_pad_sleep_mode_9_qs; + logic [1:0] dio_pad_sleep_mode_9_wd; + logic dio_pad_sleep_mode_10_we; + logic [1:0] dio_pad_sleep_mode_10_qs; + logic [1:0] dio_pad_sleep_mode_10_wd; + logic dio_pad_sleep_mode_11_we; + logic [1:0] dio_pad_sleep_mode_11_qs; + logic [1:0] dio_pad_sleep_mode_11_wd; + logic dio_pad_sleep_mode_12_we; + logic [1:0] dio_pad_sleep_mode_12_qs; + logic [1:0] dio_pad_sleep_mode_12_wd; + logic dio_pad_sleep_mode_13_we; + logic [1:0] dio_pad_sleep_mode_13_qs; + logic [1:0] dio_pad_sleep_mode_13_wd; + logic wkup_detector_regwen_0_we; + logic wkup_detector_regwen_0_qs; + logic wkup_detector_regwen_0_wd; + logic wkup_detector_regwen_1_we; + logic wkup_detector_regwen_1_qs; + logic wkup_detector_regwen_1_wd; + logic wkup_detector_regwen_2_we; + logic wkup_detector_regwen_2_qs; + logic wkup_detector_regwen_2_wd; + logic wkup_detector_regwen_3_we; + logic wkup_detector_regwen_3_qs; + logic wkup_detector_regwen_3_wd; + logic wkup_detector_regwen_4_we; + logic wkup_detector_regwen_4_qs; + logic wkup_detector_regwen_4_wd; + logic wkup_detector_regwen_5_we; + logic wkup_detector_regwen_5_qs; + logic wkup_detector_regwen_5_wd; + logic wkup_detector_regwen_6_we; + logic wkup_detector_regwen_6_qs; + logic wkup_detector_regwen_6_wd; + logic wkup_detector_regwen_7_we; + logic wkup_detector_regwen_7_qs; + logic wkup_detector_regwen_7_wd; + logic wkup_detector_en_0_we; + logic [0:0] wkup_detector_en_0_qs; + logic wkup_detector_en_0_busy; + logic wkup_detector_en_1_we; + logic [0:0] wkup_detector_en_1_qs; + logic wkup_detector_en_1_busy; + logic wkup_detector_en_2_we; + logic [0:0] wkup_detector_en_2_qs; + logic wkup_detector_en_2_busy; + logic wkup_detector_en_3_we; + logic [0:0] wkup_detector_en_3_qs; + logic wkup_detector_en_3_busy; + logic wkup_detector_en_4_we; + logic [0:0] wkup_detector_en_4_qs; + logic wkup_detector_en_4_busy; + logic wkup_detector_en_5_we; + logic [0:0] wkup_detector_en_5_qs; + logic wkup_detector_en_5_busy; + logic wkup_detector_en_6_we; + logic [0:0] wkup_detector_en_6_qs; + logic wkup_detector_en_6_busy; + logic wkup_detector_en_7_we; + logic [0:0] wkup_detector_en_7_qs; + logic wkup_detector_en_7_busy; + logic wkup_detector_0_we; + logic [4:0] wkup_detector_0_qs; + logic wkup_detector_0_busy; + logic wkup_detector_1_we; + logic [4:0] wkup_detector_1_qs; + logic wkup_detector_1_busy; + logic wkup_detector_2_we; + logic [4:0] wkup_detector_2_qs; + logic wkup_detector_2_busy; + logic wkup_detector_3_we; + logic [4:0] wkup_detector_3_qs; + logic wkup_detector_3_busy; + logic wkup_detector_4_we; + logic [4:0] wkup_detector_4_qs; + logic wkup_detector_4_busy; + logic wkup_detector_5_we; + logic [4:0] wkup_detector_5_qs; + logic wkup_detector_5_busy; + logic wkup_detector_6_we; + logic [4:0] wkup_detector_6_qs; + logic wkup_detector_6_busy; + logic wkup_detector_7_we; + logic [4:0] wkup_detector_7_qs; + logic wkup_detector_7_busy; + logic wkup_detector_cnt_th_0_we; + logic [7:0] wkup_detector_cnt_th_0_qs; + logic wkup_detector_cnt_th_0_busy; + logic wkup_detector_cnt_th_1_we; + logic [7:0] wkup_detector_cnt_th_1_qs; + logic wkup_detector_cnt_th_1_busy; + logic wkup_detector_cnt_th_2_we; + logic [7:0] wkup_detector_cnt_th_2_qs; + logic wkup_detector_cnt_th_2_busy; + logic wkup_detector_cnt_th_3_we; + logic [7:0] wkup_detector_cnt_th_3_qs; + logic wkup_detector_cnt_th_3_busy; + logic wkup_detector_cnt_th_4_we; + logic [7:0] wkup_detector_cnt_th_4_qs; + logic wkup_detector_cnt_th_4_busy; + logic wkup_detector_cnt_th_5_we; + logic [7:0] wkup_detector_cnt_th_5_qs; + logic wkup_detector_cnt_th_5_busy; + logic wkup_detector_cnt_th_6_we; + logic [7:0] wkup_detector_cnt_th_6_qs; + logic wkup_detector_cnt_th_6_busy; + logic wkup_detector_cnt_th_7_we; + logic [7:0] wkup_detector_cnt_th_7_qs; + logic wkup_detector_cnt_th_7_busy; + logic wkup_detector_padsel_0_we; + logic [5:0] wkup_detector_padsel_0_qs; + logic [5:0] wkup_detector_padsel_0_wd; + logic wkup_detector_padsel_1_we; + logic [5:0] wkup_detector_padsel_1_qs; + logic [5:0] wkup_detector_padsel_1_wd; + logic wkup_detector_padsel_2_we; + logic [5:0] wkup_detector_padsel_2_qs; + logic [5:0] wkup_detector_padsel_2_wd; + logic wkup_detector_padsel_3_we; + logic [5:0] wkup_detector_padsel_3_qs; + logic [5:0] wkup_detector_padsel_3_wd; + logic wkup_detector_padsel_4_we; + logic [5:0] wkup_detector_padsel_4_qs; + logic [5:0] wkup_detector_padsel_4_wd; + logic wkup_detector_padsel_5_we; + logic [5:0] wkup_detector_padsel_5_qs; + logic [5:0] wkup_detector_padsel_5_wd; + logic wkup_detector_padsel_6_we; + logic [5:0] wkup_detector_padsel_6_qs; + logic [5:0] wkup_detector_padsel_6_wd; + logic wkup_detector_padsel_7_we; + logic [5:0] wkup_detector_padsel_7_qs; + logic [5:0] wkup_detector_padsel_7_wd; + logic wkup_cause_we; + logic [7:0] wkup_cause_qs; + logic wkup_cause_busy; + // Define register CDC handling. + // CDC handling is done on a per-reg instead of per-field boundary. + + logic aon_wkup_detector_en_0_qs_int; + logic [0:0] aon_wkup_detector_en_0_qs; + logic [0:0] aon_wkup_detector_en_0_wdata; + logic aon_wkup_detector_en_0_we; + logic unused_aon_wkup_detector_en_0_wdata; + logic aon_wkup_detector_en_0_regwen; + + always_comb begin + aon_wkup_detector_en_0_qs = 1'h0; + aon_wkup_detector_en_0_qs = aon_wkup_detector_en_0_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_0_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_0_qs), + .src_we_i (wkup_detector_en_0_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_0_busy), + .src_qs_o (wkup_detector_en_0_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_0_qs), + .dst_we_o (aon_wkup_detector_en_0_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_0_regwen), + .dst_wd_o (aon_wkup_detector_en_0_wdata) + ); + assign unused_aon_wkup_detector_en_0_wdata = + ^aon_wkup_detector_en_0_wdata; + + logic aon_wkup_detector_en_1_qs_int; + logic [0:0] aon_wkup_detector_en_1_qs; + logic [0:0] aon_wkup_detector_en_1_wdata; + logic aon_wkup_detector_en_1_we; + logic unused_aon_wkup_detector_en_1_wdata; + logic aon_wkup_detector_en_1_regwen; + + always_comb begin + aon_wkup_detector_en_1_qs = 1'h0; + aon_wkup_detector_en_1_qs = aon_wkup_detector_en_1_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_1_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_1_qs), + .src_we_i (wkup_detector_en_1_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_1_busy), + .src_qs_o (wkup_detector_en_1_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_1_qs), + .dst_we_o (aon_wkup_detector_en_1_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_1_regwen), + .dst_wd_o (aon_wkup_detector_en_1_wdata) + ); + assign unused_aon_wkup_detector_en_1_wdata = + ^aon_wkup_detector_en_1_wdata; + + logic aon_wkup_detector_en_2_qs_int; + logic [0:0] aon_wkup_detector_en_2_qs; + logic [0:0] aon_wkup_detector_en_2_wdata; + logic aon_wkup_detector_en_2_we; + logic unused_aon_wkup_detector_en_2_wdata; + logic aon_wkup_detector_en_2_regwen; + + always_comb begin + aon_wkup_detector_en_2_qs = 1'h0; + aon_wkup_detector_en_2_qs = aon_wkup_detector_en_2_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_2_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_2_qs), + .src_we_i (wkup_detector_en_2_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_2_busy), + .src_qs_o (wkup_detector_en_2_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_2_qs), + .dst_we_o (aon_wkup_detector_en_2_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_2_regwen), + .dst_wd_o (aon_wkup_detector_en_2_wdata) + ); + assign unused_aon_wkup_detector_en_2_wdata = + ^aon_wkup_detector_en_2_wdata; + + logic aon_wkup_detector_en_3_qs_int; + logic [0:0] aon_wkup_detector_en_3_qs; + logic [0:0] aon_wkup_detector_en_3_wdata; + logic aon_wkup_detector_en_3_we; + logic unused_aon_wkup_detector_en_3_wdata; + logic aon_wkup_detector_en_3_regwen; + + always_comb begin + aon_wkup_detector_en_3_qs = 1'h0; + aon_wkup_detector_en_3_qs = aon_wkup_detector_en_3_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_3_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_3_qs), + .src_we_i (wkup_detector_en_3_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_3_busy), + .src_qs_o (wkup_detector_en_3_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_3_qs), + .dst_we_o (aon_wkup_detector_en_3_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_3_regwen), + .dst_wd_o (aon_wkup_detector_en_3_wdata) + ); + assign unused_aon_wkup_detector_en_3_wdata = + ^aon_wkup_detector_en_3_wdata; + + logic aon_wkup_detector_en_4_qs_int; + logic [0:0] aon_wkup_detector_en_4_qs; + logic [0:0] aon_wkup_detector_en_4_wdata; + logic aon_wkup_detector_en_4_we; + logic unused_aon_wkup_detector_en_4_wdata; + logic aon_wkup_detector_en_4_regwen; + + always_comb begin + aon_wkup_detector_en_4_qs = 1'h0; + aon_wkup_detector_en_4_qs = aon_wkup_detector_en_4_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_4_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_4_qs), + .src_we_i (wkup_detector_en_4_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_4_busy), + .src_qs_o (wkup_detector_en_4_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_4_qs), + .dst_we_o (aon_wkup_detector_en_4_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_4_regwen), + .dst_wd_o (aon_wkup_detector_en_4_wdata) + ); + assign unused_aon_wkup_detector_en_4_wdata = + ^aon_wkup_detector_en_4_wdata; + + logic aon_wkup_detector_en_5_qs_int; + logic [0:0] aon_wkup_detector_en_5_qs; + logic [0:0] aon_wkup_detector_en_5_wdata; + logic aon_wkup_detector_en_5_we; + logic unused_aon_wkup_detector_en_5_wdata; + logic aon_wkup_detector_en_5_regwen; + + always_comb begin + aon_wkup_detector_en_5_qs = 1'h0; + aon_wkup_detector_en_5_qs = aon_wkup_detector_en_5_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_5_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_5_qs), + .src_we_i (wkup_detector_en_5_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_5_busy), + .src_qs_o (wkup_detector_en_5_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_5_qs), + .dst_we_o (aon_wkup_detector_en_5_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_5_regwen), + .dst_wd_o (aon_wkup_detector_en_5_wdata) + ); + assign unused_aon_wkup_detector_en_5_wdata = + ^aon_wkup_detector_en_5_wdata; + + logic aon_wkup_detector_en_6_qs_int; + logic [0:0] aon_wkup_detector_en_6_qs; + logic [0:0] aon_wkup_detector_en_6_wdata; + logic aon_wkup_detector_en_6_we; + logic unused_aon_wkup_detector_en_6_wdata; + logic aon_wkup_detector_en_6_regwen; + + always_comb begin + aon_wkup_detector_en_6_qs = 1'h0; + aon_wkup_detector_en_6_qs = aon_wkup_detector_en_6_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_6_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_6_qs), + .src_we_i (wkup_detector_en_6_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_6_busy), + .src_qs_o (wkup_detector_en_6_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_6_qs), + .dst_we_o (aon_wkup_detector_en_6_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_6_regwen), + .dst_wd_o (aon_wkup_detector_en_6_wdata) + ); + assign unused_aon_wkup_detector_en_6_wdata = + ^aon_wkup_detector_en_6_wdata; + + logic aon_wkup_detector_en_7_qs_int; + logic [0:0] aon_wkup_detector_en_7_qs; + logic [0:0] aon_wkup_detector_en_7_wdata; + logic aon_wkup_detector_en_7_we; + logic unused_aon_wkup_detector_en_7_wdata; + logic aon_wkup_detector_en_7_regwen; + + always_comb begin + aon_wkup_detector_en_7_qs = 1'h0; + aon_wkup_detector_en_7_qs = aon_wkup_detector_en_7_qs_int; + end + + prim_reg_cdc #( + .DataWidth(1), + .ResetVal(1'h0), + .BitMask(1'h1), + .DstWrReq(0) + ) u_wkup_detector_en_7_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_7_qs), + .src_we_i (wkup_detector_en_7_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[0:0]), + .src_busy_o (wkup_detector_en_7_busy), + .src_qs_o (wkup_detector_en_7_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_en_7_qs), + .dst_we_o (aon_wkup_detector_en_7_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_en_7_regwen), + .dst_wd_o (aon_wkup_detector_en_7_wdata) + ); + assign unused_aon_wkup_detector_en_7_wdata = + ^aon_wkup_detector_en_7_wdata; + + logic [2:0] aon_wkup_detector_0_mode_0_qs_int; + logic aon_wkup_detector_0_filter_0_qs_int; + logic aon_wkup_detector_0_miodio_0_qs_int; + logic [4:0] aon_wkup_detector_0_qs; + logic [4:0] aon_wkup_detector_0_wdata; + logic aon_wkup_detector_0_we; + logic unused_aon_wkup_detector_0_wdata; + logic aon_wkup_detector_0_regwen; + + always_comb begin + aon_wkup_detector_0_qs = 5'h0; + aon_wkup_detector_0_qs[2:0] = aon_wkup_detector_0_mode_0_qs_int; + aon_wkup_detector_0_qs[3] = aon_wkup_detector_0_filter_0_qs_int; + aon_wkup_detector_0_qs[4] = aon_wkup_detector_0_miodio_0_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_0_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_0_qs), + .src_we_i (wkup_detector_0_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_0_busy), + .src_qs_o (wkup_detector_0_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_0_qs), + .dst_we_o (aon_wkup_detector_0_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_0_regwen), + .dst_wd_o (aon_wkup_detector_0_wdata) + ); + assign unused_aon_wkup_detector_0_wdata = + ^aon_wkup_detector_0_wdata; + + logic [2:0] aon_wkup_detector_1_mode_1_qs_int; + logic aon_wkup_detector_1_filter_1_qs_int; + logic aon_wkup_detector_1_miodio_1_qs_int; + logic [4:0] aon_wkup_detector_1_qs; + logic [4:0] aon_wkup_detector_1_wdata; + logic aon_wkup_detector_1_we; + logic unused_aon_wkup_detector_1_wdata; + logic aon_wkup_detector_1_regwen; + + always_comb begin + aon_wkup_detector_1_qs = 5'h0; + aon_wkup_detector_1_qs[2:0] = aon_wkup_detector_1_mode_1_qs_int; + aon_wkup_detector_1_qs[3] = aon_wkup_detector_1_filter_1_qs_int; + aon_wkup_detector_1_qs[4] = aon_wkup_detector_1_miodio_1_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_1_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_1_qs), + .src_we_i (wkup_detector_1_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_1_busy), + .src_qs_o (wkup_detector_1_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_1_qs), + .dst_we_o (aon_wkup_detector_1_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_1_regwen), + .dst_wd_o (aon_wkup_detector_1_wdata) + ); + assign unused_aon_wkup_detector_1_wdata = + ^aon_wkup_detector_1_wdata; + + logic [2:0] aon_wkup_detector_2_mode_2_qs_int; + logic aon_wkup_detector_2_filter_2_qs_int; + logic aon_wkup_detector_2_miodio_2_qs_int; + logic [4:0] aon_wkup_detector_2_qs; + logic [4:0] aon_wkup_detector_2_wdata; + logic aon_wkup_detector_2_we; + logic unused_aon_wkup_detector_2_wdata; + logic aon_wkup_detector_2_regwen; + + always_comb begin + aon_wkup_detector_2_qs = 5'h0; + aon_wkup_detector_2_qs[2:0] = aon_wkup_detector_2_mode_2_qs_int; + aon_wkup_detector_2_qs[3] = aon_wkup_detector_2_filter_2_qs_int; + aon_wkup_detector_2_qs[4] = aon_wkup_detector_2_miodio_2_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_2_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_2_qs), + .src_we_i (wkup_detector_2_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_2_busy), + .src_qs_o (wkup_detector_2_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_2_qs), + .dst_we_o (aon_wkup_detector_2_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_2_regwen), + .dst_wd_o (aon_wkup_detector_2_wdata) + ); + assign unused_aon_wkup_detector_2_wdata = + ^aon_wkup_detector_2_wdata; + + logic [2:0] aon_wkup_detector_3_mode_3_qs_int; + logic aon_wkup_detector_3_filter_3_qs_int; + logic aon_wkup_detector_3_miodio_3_qs_int; + logic [4:0] aon_wkup_detector_3_qs; + logic [4:0] aon_wkup_detector_3_wdata; + logic aon_wkup_detector_3_we; + logic unused_aon_wkup_detector_3_wdata; + logic aon_wkup_detector_3_regwen; + + always_comb begin + aon_wkup_detector_3_qs = 5'h0; + aon_wkup_detector_3_qs[2:0] = aon_wkup_detector_3_mode_3_qs_int; + aon_wkup_detector_3_qs[3] = aon_wkup_detector_3_filter_3_qs_int; + aon_wkup_detector_3_qs[4] = aon_wkup_detector_3_miodio_3_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_3_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_3_qs), + .src_we_i (wkup_detector_3_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_3_busy), + .src_qs_o (wkup_detector_3_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_3_qs), + .dst_we_o (aon_wkup_detector_3_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_3_regwen), + .dst_wd_o (aon_wkup_detector_3_wdata) + ); + assign unused_aon_wkup_detector_3_wdata = + ^aon_wkup_detector_3_wdata; + + logic [2:0] aon_wkup_detector_4_mode_4_qs_int; + logic aon_wkup_detector_4_filter_4_qs_int; + logic aon_wkup_detector_4_miodio_4_qs_int; + logic [4:0] aon_wkup_detector_4_qs; + logic [4:0] aon_wkup_detector_4_wdata; + logic aon_wkup_detector_4_we; + logic unused_aon_wkup_detector_4_wdata; + logic aon_wkup_detector_4_regwen; + + always_comb begin + aon_wkup_detector_4_qs = 5'h0; + aon_wkup_detector_4_qs[2:0] = aon_wkup_detector_4_mode_4_qs_int; + aon_wkup_detector_4_qs[3] = aon_wkup_detector_4_filter_4_qs_int; + aon_wkup_detector_4_qs[4] = aon_wkup_detector_4_miodio_4_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_4_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_4_qs), + .src_we_i (wkup_detector_4_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_4_busy), + .src_qs_o (wkup_detector_4_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_4_qs), + .dst_we_o (aon_wkup_detector_4_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_4_regwen), + .dst_wd_o (aon_wkup_detector_4_wdata) + ); + assign unused_aon_wkup_detector_4_wdata = + ^aon_wkup_detector_4_wdata; + + logic [2:0] aon_wkup_detector_5_mode_5_qs_int; + logic aon_wkup_detector_5_filter_5_qs_int; + logic aon_wkup_detector_5_miodio_5_qs_int; + logic [4:0] aon_wkup_detector_5_qs; + logic [4:0] aon_wkup_detector_5_wdata; + logic aon_wkup_detector_5_we; + logic unused_aon_wkup_detector_5_wdata; + logic aon_wkup_detector_5_regwen; + + always_comb begin + aon_wkup_detector_5_qs = 5'h0; + aon_wkup_detector_5_qs[2:0] = aon_wkup_detector_5_mode_5_qs_int; + aon_wkup_detector_5_qs[3] = aon_wkup_detector_5_filter_5_qs_int; + aon_wkup_detector_5_qs[4] = aon_wkup_detector_5_miodio_5_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_5_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_5_qs), + .src_we_i (wkup_detector_5_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_5_busy), + .src_qs_o (wkup_detector_5_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_5_qs), + .dst_we_o (aon_wkup_detector_5_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_5_regwen), + .dst_wd_o (aon_wkup_detector_5_wdata) + ); + assign unused_aon_wkup_detector_5_wdata = + ^aon_wkup_detector_5_wdata; + + logic [2:0] aon_wkup_detector_6_mode_6_qs_int; + logic aon_wkup_detector_6_filter_6_qs_int; + logic aon_wkup_detector_6_miodio_6_qs_int; + logic [4:0] aon_wkup_detector_6_qs; + logic [4:0] aon_wkup_detector_6_wdata; + logic aon_wkup_detector_6_we; + logic unused_aon_wkup_detector_6_wdata; + logic aon_wkup_detector_6_regwen; + + always_comb begin + aon_wkup_detector_6_qs = 5'h0; + aon_wkup_detector_6_qs[2:0] = aon_wkup_detector_6_mode_6_qs_int; + aon_wkup_detector_6_qs[3] = aon_wkup_detector_6_filter_6_qs_int; + aon_wkup_detector_6_qs[4] = aon_wkup_detector_6_miodio_6_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_6_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_6_qs), + .src_we_i (wkup_detector_6_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_6_busy), + .src_qs_o (wkup_detector_6_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_6_qs), + .dst_we_o (aon_wkup_detector_6_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_6_regwen), + .dst_wd_o (aon_wkup_detector_6_wdata) + ); + assign unused_aon_wkup_detector_6_wdata = + ^aon_wkup_detector_6_wdata; + + logic [2:0] aon_wkup_detector_7_mode_7_qs_int; + logic aon_wkup_detector_7_filter_7_qs_int; + logic aon_wkup_detector_7_miodio_7_qs_int; + logic [4:0] aon_wkup_detector_7_qs; + logic [4:0] aon_wkup_detector_7_wdata; + logic aon_wkup_detector_7_we; + logic unused_aon_wkup_detector_7_wdata; + logic aon_wkup_detector_7_regwen; + + always_comb begin + aon_wkup_detector_7_qs = 5'h0; + aon_wkup_detector_7_qs[2:0] = aon_wkup_detector_7_mode_7_qs_int; + aon_wkup_detector_7_qs[3] = aon_wkup_detector_7_filter_7_qs_int; + aon_wkup_detector_7_qs[4] = aon_wkup_detector_7_miodio_7_qs_int; + end + + prim_reg_cdc #( + .DataWidth(5), + .ResetVal(5'h0), + .BitMask(5'h1f), + .DstWrReq(0) + ) u_wkup_detector_7_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_7_qs), + .src_we_i (wkup_detector_7_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[4:0]), + .src_busy_o (wkup_detector_7_busy), + .src_qs_o (wkup_detector_7_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_7_qs), + .dst_we_o (aon_wkup_detector_7_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_7_regwen), + .dst_wd_o (aon_wkup_detector_7_wdata) + ); + assign unused_aon_wkup_detector_7_wdata = + ^aon_wkup_detector_7_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_0_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_0_qs; + logic [7:0] aon_wkup_detector_cnt_th_0_wdata; + logic aon_wkup_detector_cnt_th_0_we; + logic unused_aon_wkup_detector_cnt_th_0_wdata; + logic aon_wkup_detector_cnt_th_0_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_0_qs = 8'h0; + aon_wkup_detector_cnt_th_0_qs = aon_wkup_detector_cnt_th_0_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_0_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_0_qs), + .src_we_i (wkup_detector_cnt_th_0_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_0_busy), + .src_qs_o (wkup_detector_cnt_th_0_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_0_qs), + .dst_we_o (aon_wkup_detector_cnt_th_0_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_0_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_0_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_0_wdata = + ^aon_wkup_detector_cnt_th_0_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_1_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_1_qs; + logic [7:0] aon_wkup_detector_cnt_th_1_wdata; + logic aon_wkup_detector_cnt_th_1_we; + logic unused_aon_wkup_detector_cnt_th_1_wdata; + logic aon_wkup_detector_cnt_th_1_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_1_qs = 8'h0; + aon_wkup_detector_cnt_th_1_qs = aon_wkup_detector_cnt_th_1_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_1_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_1_qs), + .src_we_i (wkup_detector_cnt_th_1_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_1_busy), + .src_qs_o (wkup_detector_cnt_th_1_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_1_qs), + .dst_we_o (aon_wkup_detector_cnt_th_1_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_1_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_1_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_1_wdata = + ^aon_wkup_detector_cnt_th_1_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_2_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_2_qs; + logic [7:0] aon_wkup_detector_cnt_th_2_wdata; + logic aon_wkup_detector_cnt_th_2_we; + logic unused_aon_wkup_detector_cnt_th_2_wdata; + logic aon_wkup_detector_cnt_th_2_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_2_qs = 8'h0; + aon_wkup_detector_cnt_th_2_qs = aon_wkup_detector_cnt_th_2_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_2_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_2_qs), + .src_we_i (wkup_detector_cnt_th_2_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_2_busy), + .src_qs_o (wkup_detector_cnt_th_2_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_2_qs), + .dst_we_o (aon_wkup_detector_cnt_th_2_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_2_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_2_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_2_wdata = + ^aon_wkup_detector_cnt_th_2_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_3_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_3_qs; + logic [7:0] aon_wkup_detector_cnt_th_3_wdata; + logic aon_wkup_detector_cnt_th_3_we; + logic unused_aon_wkup_detector_cnt_th_3_wdata; + logic aon_wkup_detector_cnt_th_3_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_3_qs = 8'h0; + aon_wkup_detector_cnt_th_3_qs = aon_wkup_detector_cnt_th_3_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_3_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_3_qs), + .src_we_i (wkup_detector_cnt_th_3_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_3_busy), + .src_qs_o (wkup_detector_cnt_th_3_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_3_qs), + .dst_we_o (aon_wkup_detector_cnt_th_3_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_3_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_3_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_3_wdata = + ^aon_wkup_detector_cnt_th_3_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_4_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_4_qs; + logic [7:0] aon_wkup_detector_cnt_th_4_wdata; + logic aon_wkup_detector_cnt_th_4_we; + logic unused_aon_wkup_detector_cnt_th_4_wdata; + logic aon_wkup_detector_cnt_th_4_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_4_qs = 8'h0; + aon_wkup_detector_cnt_th_4_qs = aon_wkup_detector_cnt_th_4_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_4_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_4_qs), + .src_we_i (wkup_detector_cnt_th_4_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_4_busy), + .src_qs_o (wkup_detector_cnt_th_4_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_4_qs), + .dst_we_o (aon_wkup_detector_cnt_th_4_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_4_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_4_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_4_wdata = + ^aon_wkup_detector_cnt_th_4_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_5_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_5_qs; + logic [7:0] aon_wkup_detector_cnt_th_5_wdata; + logic aon_wkup_detector_cnt_th_5_we; + logic unused_aon_wkup_detector_cnt_th_5_wdata; + logic aon_wkup_detector_cnt_th_5_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_5_qs = 8'h0; + aon_wkup_detector_cnt_th_5_qs = aon_wkup_detector_cnt_th_5_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_5_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_5_qs), + .src_we_i (wkup_detector_cnt_th_5_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_5_busy), + .src_qs_o (wkup_detector_cnt_th_5_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_5_qs), + .dst_we_o (aon_wkup_detector_cnt_th_5_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_5_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_5_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_5_wdata = + ^aon_wkup_detector_cnt_th_5_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_6_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_6_qs; + logic [7:0] aon_wkup_detector_cnt_th_6_wdata; + logic aon_wkup_detector_cnt_th_6_we; + logic unused_aon_wkup_detector_cnt_th_6_wdata; + logic aon_wkup_detector_cnt_th_6_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_6_qs = 8'h0; + aon_wkup_detector_cnt_th_6_qs = aon_wkup_detector_cnt_th_6_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_6_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_6_qs), + .src_we_i (wkup_detector_cnt_th_6_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_6_busy), + .src_qs_o (wkup_detector_cnt_th_6_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_6_qs), + .dst_we_o (aon_wkup_detector_cnt_th_6_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_6_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_6_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_6_wdata = + ^aon_wkup_detector_cnt_th_6_wdata; + + logic [7:0] aon_wkup_detector_cnt_th_7_qs_int; + logic [7:0] aon_wkup_detector_cnt_th_7_qs; + logic [7:0] aon_wkup_detector_cnt_th_7_wdata; + logic aon_wkup_detector_cnt_th_7_we; + logic unused_aon_wkup_detector_cnt_th_7_wdata; + logic aon_wkup_detector_cnt_th_7_regwen; + + always_comb begin + aon_wkup_detector_cnt_th_7_qs = 8'h0; + aon_wkup_detector_cnt_th_7_qs = aon_wkup_detector_cnt_th_7_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(0) + ) u_wkup_detector_cnt_th_7_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i (wkup_detector_regwen_7_qs), + .src_we_i (wkup_detector_cnt_th_7_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_detector_cnt_th_7_busy), + .src_qs_o (wkup_detector_cnt_th_7_qs), // for software read back + .dst_update_i ('0), + .dst_ds_i ('0), + .dst_qs_i (aon_wkup_detector_cnt_th_7_qs), + .dst_we_o (aon_wkup_detector_cnt_th_7_we), + .dst_re_o (), + .dst_regwen_o (aon_wkup_detector_cnt_th_7_regwen), + .dst_wd_o (aon_wkup_detector_cnt_th_7_wdata) + ); + assign unused_aon_wkup_detector_cnt_th_7_wdata = + ^aon_wkup_detector_cnt_th_7_wdata; + + logic aon_wkup_cause_cause_0_ds_int; + logic aon_wkup_cause_cause_0_qs_int; + logic aon_wkup_cause_cause_1_ds_int; + logic aon_wkup_cause_cause_1_qs_int; + logic aon_wkup_cause_cause_2_ds_int; + logic aon_wkup_cause_cause_2_qs_int; + logic aon_wkup_cause_cause_3_ds_int; + logic aon_wkup_cause_cause_3_qs_int; + logic aon_wkup_cause_cause_4_ds_int; + logic aon_wkup_cause_cause_4_qs_int; + logic aon_wkup_cause_cause_5_ds_int; + logic aon_wkup_cause_cause_5_qs_int; + logic aon_wkup_cause_cause_6_ds_int; + logic aon_wkup_cause_cause_6_qs_int; + logic aon_wkup_cause_cause_7_ds_int; + logic aon_wkup_cause_cause_7_qs_int; + logic [7:0] aon_wkup_cause_ds; + logic aon_wkup_cause_qe; + logic [7:0] aon_wkup_cause_qs; + logic [7:0] aon_wkup_cause_wdata; + logic aon_wkup_cause_we; + logic unused_aon_wkup_cause_wdata; + + always_comb begin + aon_wkup_cause_qs = 8'h0; + aon_wkup_cause_ds = 8'h0; + aon_wkup_cause_ds[0] = aon_wkup_cause_cause_0_ds_int; + aon_wkup_cause_qs[0] = aon_wkup_cause_cause_0_qs_int; + aon_wkup_cause_ds[1] = aon_wkup_cause_cause_1_ds_int; + aon_wkup_cause_qs[1] = aon_wkup_cause_cause_1_qs_int; + aon_wkup_cause_ds[2] = aon_wkup_cause_cause_2_ds_int; + aon_wkup_cause_qs[2] = aon_wkup_cause_cause_2_qs_int; + aon_wkup_cause_ds[3] = aon_wkup_cause_cause_3_ds_int; + aon_wkup_cause_qs[3] = aon_wkup_cause_cause_3_qs_int; + aon_wkup_cause_ds[4] = aon_wkup_cause_cause_4_ds_int; + aon_wkup_cause_qs[4] = aon_wkup_cause_cause_4_qs_int; + aon_wkup_cause_ds[5] = aon_wkup_cause_cause_5_ds_int; + aon_wkup_cause_qs[5] = aon_wkup_cause_cause_5_qs_int; + aon_wkup_cause_ds[6] = aon_wkup_cause_cause_6_ds_int; + aon_wkup_cause_qs[6] = aon_wkup_cause_cause_6_qs_int; + aon_wkup_cause_ds[7] = aon_wkup_cause_cause_7_ds_int; + aon_wkup_cause_qs[7] = aon_wkup_cause_cause_7_qs_int; + end + + prim_reg_cdc #( + .DataWidth(8), + .ResetVal(8'h0), + .BitMask(8'hff), + .DstWrReq(1) + ) u_wkup_cause_cdc ( + .clk_src_i (clk_i), + .rst_src_ni (rst_ni), + .clk_dst_i (clk_aon_i), + .rst_dst_ni (rst_aon_ni), + .src_regwen_i ('0), + .src_we_i (wkup_cause_we), + .src_re_i ('0), + .src_wd_i (reg_wdata[7:0]), + .src_busy_o (wkup_cause_busy), + .src_qs_o (wkup_cause_qs), // for software read back + .dst_update_i (aon_wkup_cause_qe), + .dst_ds_i (aon_wkup_cause_ds), + .dst_qs_i (aon_wkup_cause_qs), + .dst_we_o (aon_wkup_cause_we), + .dst_re_o (), + .dst_regwen_o (), + .dst_wd_o (aon_wkup_cause_wdata) + ); + assign unused_aon_wkup_cause_wdata = + ^aon_wkup_cause_wdata; + + // Register instances + // 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; + + + // Subregister 0 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_0_we), + .wd (mio_periph_insel_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_0_qs) + ); + + + // Subregister 1 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_1_we), + .wd (mio_periph_insel_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_1_qs) + ); + + + // Subregister 2 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_2_we), + .wd (mio_periph_insel_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_2_qs) + ); + + + // Subregister 3 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_3_we), + .wd (mio_periph_insel_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_3_qs) + ); + + + // Subregister 4 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_4_we), + .wd (mio_periph_insel_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_4_qs) + ); + + + // Subregister 5 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_5_we), + .wd (mio_periph_insel_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_5_qs) + ); + + + // Subregister 6 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_6_we), + .wd (mio_periph_insel_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_6_qs) + ); + + + // Subregister 7 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_7_we), + .wd (mio_periph_insel_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_7_qs) + ); + + + // Subregister 8 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_8_we), + .wd (mio_periph_insel_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_8_qs) + ); + + + // Subregister 9 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_9_we), + .wd (mio_periph_insel_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_9_qs) + ); + + + // Subregister 10 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_10]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_10_we), + .wd (mio_periph_insel_regwen_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_10_qs) + ); + + + // Subregister 11 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_11]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_11_we), + .wd (mio_periph_insel_regwen_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_11_qs) + ); + + + // Subregister 12 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_12]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_12_we), + .wd (mio_periph_insel_regwen_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_12_qs) + ); + + + // Subregister 13 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_13]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_13_we), + .wd (mio_periph_insel_regwen_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_13_qs) + ); + + + // Subregister 14 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_14]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_14_we), + .wd (mio_periph_insel_regwen_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_14_qs) + ); + + + // Subregister 15 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_15]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_15_we), + .wd (mio_periph_insel_regwen_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_15_qs) + ); + + + // Subregister 16 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_16]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_16_we), + .wd (mio_periph_insel_regwen_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_16_qs) + ); + + + // Subregister 17 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_17]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_17_we), + .wd (mio_periph_insel_regwen_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_17_qs) + ); + + + // Subregister 18 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_18]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_18_we), + .wd (mio_periph_insel_regwen_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_18_qs) + ); + + + // Subregister 19 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_19]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_19_we), + .wd (mio_periph_insel_regwen_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_19_qs) + ); + + + // Subregister 20 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_20]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_20_we), + .wd (mio_periph_insel_regwen_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_20_qs) + ); + + + // Subregister 21 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_21]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_21_we), + .wd (mio_periph_insel_regwen_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_21_qs) + ); + + + // Subregister 22 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_22]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_22_we), + .wd (mio_periph_insel_regwen_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_22_qs) + ); + + + // Subregister 23 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_23]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_23_we), + .wd (mio_periph_insel_regwen_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_23_qs) + ); + + + // Subregister 24 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_24]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_24_we), + .wd (mio_periph_insel_regwen_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_24_qs) + ); + + + // Subregister 25 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_25]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_25_we), + .wd (mio_periph_insel_regwen_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_25_qs) + ); + + + // Subregister 26 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_26]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_26_we), + .wd (mio_periph_insel_regwen_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_26_qs) + ); + + + // Subregister 27 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_27]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_27_we), + .wd (mio_periph_insel_regwen_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_27_qs) + ); + + + // Subregister 28 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_28]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_28_we), + .wd (mio_periph_insel_regwen_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_28_qs) + ); + + + // Subregister 29 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_29]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_29_we), + .wd (mio_periph_insel_regwen_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_29_qs) + ); + + + // Subregister 30 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_30]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_30_we), + .wd (mio_periph_insel_regwen_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_30_qs) + ); + + + // Subregister 31 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_31]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_31_we), + .wd (mio_periph_insel_regwen_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_31_qs) + ); + + + // Subregister 32 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_32]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_32_we), + .wd (mio_periph_insel_regwen_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_32_qs) + ); + + + // Subregister 33 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_33]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_33_we), + .wd (mio_periph_insel_regwen_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_33_qs) + ); + + + // Subregister 34 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_34]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_34_we), + .wd (mio_periph_insel_regwen_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_34_qs) + ); + + + // Subregister 35 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_35]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_35_we), + .wd (mio_periph_insel_regwen_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_35_qs) + ); + + + // Subregister 36 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_36]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_36_we), + .wd (mio_periph_insel_regwen_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_36_qs) + ); + + + // Subregister 37 of Multireg mio_periph_insel_regwen + // R[mio_periph_insel_regwen_37]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_periph_insel_regwen_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_regwen_37_we), + .wd (mio_periph_insel_regwen_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_regwen_37_qs) + ); + + + // Subregister 0 of Multireg mio_periph_insel + // R[mio_periph_insel_0]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_0_gated_we; + assign mio_periph_insel_0_gated_we = mio_periph_insel_0_we & mio_periph_insel_regwen_0_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_0_gated_we), + .wd (mio_periph_insel_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[0].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_0_qs) + ); + + + // Subregister 1 of Multireg mio_periph_insel + // R[mio_periph_insel_1]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_1_gated_we; + assign mio_periph_insel_1_gated_we = mio_periph_insel_1_we & mio_periph_insel_regwen_1_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_1_gated_we), + .wd (mio_periph_insel_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[1].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_1_qs) + ); + + + // Subregister 2 of Multireg mio_periph_insel + // R[mio_periph_insel_2]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_2_gated_we; + assign mio_periph_insel_2_gated_we = mio_periph_insel_2_we & mio_periph_insel_regwen_2_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_2_gated_we), + .wd (mio_periph_insel_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[2].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_2_qs) + ); + + + // Subregister 3 of Multireg mio_periph_insel + // R[mio_periph_insel_3]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_3_gated_we; + assign mio_periph_insel_3_gated_we = mio_periph_insel_3_we & mio_periph_insel_regwen_3_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_3_gated_we), + .wd (mio_periph_insel_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[3].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_3_qs) + ); + + + // Subregister 4 of Multireg mio_periph_insel + // R[mio_periph_insel_4]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_4_gated_we; + assign mio_periph_insel_4_gated_we = mio_periph_insel_4_we & mio_periph_insel_regwen_4_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_4_gated_we), + .wd (mio_periph_insel_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[4].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_4_qs) + ); + + + // Subregister 5 of Multireg mio_periph_insel + // R[mio_periph_insel_5]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_5_gated_we; + assign mio_periph_insel_5_gated_we = mio_periph_insel_5_we & mio_periph_insel_regwen_5_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_5_gated_we), + .wd (mio_periph_insel_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[5].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_5_qs) + ); + + + // Subregister 6 of Multireg mio_periph_insel + // R[mio_periph_insel_6]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_6_gated_we; + assign mio_periph_insel_6_gated_we = mio_periph_insel_6_we & mio_periph_insel_regwen_6_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_6_gated_we), + .wd (mio_periph_insel_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[6].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_6_qs) + ); + + + // Subregister 7 of Multireg mio_periph_insel + // R[mio_periph_insel_7]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_7_gated_we; + assign mio_periph_insel_7_gated_we = mio_periph_insel_7_we & mio_periph_insel_regwen_7_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_7_gated_we), + .wd (mio_periph_insel_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[7].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_7_qs) + ); + + + // Subregister 8 of Multireg mio_periph_insel + // R[mio_periph_insel_8]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_8_gated_we; + assign mio_periph_insel_8_gated_we = mio_periph_insel_8_we & mio_periph_insel_regwen_8_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_8_gated_we), + .wd (mio_periph_insel_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[8].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_8_qs) + ); + + + // Subregister 9 of Multireg mio_periph_insel + // R[mio_periph_insel_9]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_9_gated_we; + assign mio_periph_insel_9_gated_we = mio_periph_insel_9_we & mio_periph_insel_regwen_9_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_9_gated_we), + .wd (mio_periph_insel_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[9].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_9_qs) + ); + + + // Subregister 10 of Multireg mio_periph_insel + // R[mio_periph_insel_10]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_10_gated_we; + assign mio_periph_insel_10_gated_we = mio_periph_insel_10_we & mio_periph_insel_regwen_10_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_10_gated_we), + .wd (mio_periph_insel_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[10].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_10_qs) + ); + + + // Subregister 11 of Multireg mio_periph_insel + // R[mio_periph_insel_11]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_11_gated_we; + assign mio_periph_insel_11_gated_we = mio_periph_insel_11_we & mio_periph_insel_regwen_11_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_11_gated_we), + .wd (mio_periph_insel_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[11].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_11_qs) + ); + + + // Subregister 12 of Multireg mio_periph_insel + // R[mio_periph_insel_12]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_12_gated_we; + assign mio_periph_insel_12_gated_we = mio_periph_insel_12_we & mio_periph_insel_regwen_12_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_12_gated_we), + .wd (mio_periph_insel_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[12].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_12_qs) + ); + + + // Subregister 13 of Multireg mio_periph_insel + // R[mio_periph_insel_13]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_13_gated_we; + assign mio_periph_insel_13_gated_we = mio_periph_insel_13_we & mio_periph_insel_regwen_13_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_13_gated_we), + .wd (mio_periph_insel_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[13].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_13_qs) + ); + + + // Subregister 14 of Multireg mio_periph_insel + // R[mio_periph_insel_14]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_14_gated_we; + assign mio_periph_insel_14_gated_we = mio_periph_insel_14_we & mio_periph_insel_regwen_14_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_14_gated_we), + .wd (mio_periph_insel_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[14].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_14_qs) + ); + + + // Subregister 15 of Multireg mio_periph_insel + // R[mio_periph_insel_15]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_15_gated_we; + assign mio_periph_insel_15_gated_we = mio_periph_insel_15_we & mio_periph_insel_regwen_15_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_15_gated_we), + .wd (mio_periph_insel_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[15].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_15_qs) + ); + + + // Subregister 16 of Multireg mio_periph_insel + // R[mio_periph_insel_16]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_16_gated_we; + assign mio_periph_insel_16_gated_we = mio_periph_insel_16_we & mio_periph_insel_regwen_16_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_16_gated_we), + .wd (mio_periph_insel_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[16].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_16_qs) + ); + + + // Subregister 17 of Multireg mio_periph_insel + // R[mio_periph_insel_17]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_17_gated_we; + assign mio_periph_insel_17_gated_we = mio_periph_insel_17_we & mio_periph_insel_regwen_17_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_17_gated_we), + .wd (mio_periph_insel_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[17].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_17_qs) + ); + + + // Subregister 18 of Multireg mio_periph_insel + // R[mio_periph_insel_18]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_18_gated_we; + assign mio_periph_insel_18_gated_we = mio_periph_insel_18_we & mio_periph_insel_regwen_18_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_18_gated_we), + .wd (mio_periph_insel_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[18].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_18_qs) + ); + + + // Subregister 19 of Multireg mio_periph_insel + // R[mio_periph_insel_19]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_19_gated_we; + assign mio_periph_insel_19_gated_we = mio_periph_insel_19_we & mio_periph_insel_regwen_19_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_19_gated_we), + .wd (mio_periph_insel_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[19].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_19_qs) + ); + + + // Subregister 20 of Multireg mio_periph_insel + // R[mio_periph_insel_20]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_20_gated_we; + assign mio_periph_insel_20_gated_we = mio_periph_insel_20_we & mio_periph_insel_regwen_20_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_20_gated_we), + .wd (mio_periph_insel_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[20].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_20_qs) + ); + + + // Subregister 21 of Multireg mio_periph_insel + // R[mio_periph_insel_21]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_21_gated_we; + assign mio_periph_insel_21_gated_we = mio_periph_insel_21_we & mio_periph_insel_regwen_21_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_21_gated_we), + .wd (mio_periph_insel_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[21].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_21_qs) + ); + + + // Subregister 22 of Multireg mio_periph_insel + // R[mio_periph_insel_22]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_22_gated_we; + assign mio_periph_insel_22_gated_we = mio_periph_insel_22_we & mio_periph_insel_regwen_22_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_22_gated_we), + .wd (mio_periph_insel_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[22].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_22_qs) + ); + + + // Subregister 23 of Multireg mio_periph_insel + // R[mio_periph_insel_23]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_23_gated_we; + assign mio_periph_insel_23_gated_we = mio_periph_insel_23_we & mio_periph_insel_regwen_23_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_23_gated_we), + .wd (mio_periph_insel_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[23].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_23_qs) + ); + + + // Subregister 24 of Multireg mio_periph_insel + // R[mio_periph_insel_24]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_24_gated_we; + assign mio_periph_insel_24_gated_we = mio_periph_insel_24_we & mio_periph_insel_regwen_24_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_24_gated_we), + .wd (mio_periph_insel_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[24].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_24_qs) + ); + + + // Subregister 25 of Multireg mio_periph_insel + // R[mio_periph_insel_25]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_25_gated_we; + assign mio_periph_insel_25_gated_we = mio_periph_insel_25_we & mio_periph_insel_regwen_25_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_25_gated_we), + .wd (mio_periph_insel_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[25].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_25_qs) + ); + + + // Subregister 26 of Multireg mio_periph_insel + // R[mio_periph_insel_26]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_26_gated_we; + assign mio_periph_insel_26_gated_we = mio_periph_insel_26_we & mio_periph_insel_regwen_26_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_26_gated_we), + .wd (mio_periph_insel_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[26].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_26_qs) + ); + + + // Subregister 27 of Multireg mio_periph_insel + // R[mio_periph_insel_27]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_27_gated_we; + assign mio_periph_insel_27_gated_we = mio_periph_insel_27_we & mio_periph_insel_regwen_27_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_27_gated_we), + .wd (mio_periph_insel_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[27].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_27_qs) + ); + + + // Subregister 28 of Multireg mio_periph_insel + // R[mio_periph_insel_28]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_28_gated_we; + assign mio_periph_insel_28_gated_we = mio_periph_insel_28_we & mio_periph_insel_regwen_28_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_28_gated_we), + .wd (mio_periph_insel_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[28].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_28_qs) + ); + + + // Subregister 29 of Multireg mio_periph_insel + // R[mio_periph_insel_29]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_29_gated_we; + assign mio_periph_insel_29_gated_we = mio_periph_insel_29_we & mio_periph_insel_regwen_29_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_29_gated_we), + .wd (mio_periph_insel_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[29].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_29_qs) + ); + + + // Subregister 30 of Multireg mio_periph_insel + // R[mio_periph_insel_30]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_30_gated_we; + assign mio_periph_insel_30_gated_we = mio_periph_insel_30_we & mio_periph_insel_regwen_30_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_30_gated_we), + .wd (mio_periph_insel_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[30].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_30_qs) + ); + + + // Subregister 31 of Multireg mio_periph_insel + // R[mio_periph_insel_31]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_31_gated_we; + assign mio_periph_insel_31_gated_we = mio_periph_insel_31_we & mio_periph_insel_regwen_31_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_31_gated_we), + .wd (mio_periph_insel_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[31].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_31_qs) + ); + + + // Subregister 32 of Multireg mio_periph_insel + // R[mio_periph_insel_32]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_32_gated_we; + assign mio_periph_insel_32_gated_we = mio_periph_insel_32_we & mio_periph_insel_regwen_32_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_32_gated_we), + .wd (mio_periph_insel_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[32].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_32_qs) + ); + + + // Subregister 33 of Multireg mio_periph_insel + // R[mio_periph_insel_33]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_33_gated_we; + assign mio_periph_insel_33_gated_we = mio_periph_insel_33_we & mio_periph_insel_regwen_33_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_33_gated_we), + .wd (mio_periph_insel_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[33].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_33_qs) + ); + + + // Subregister 34 of Multireg mio_periph_insel + // R[mio_periph_insel_34]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_34_gated_we; + assign mio_periph_insel_34_gated_we = mio_periph_insel_34_we & mio_periph_insel_regwen_34_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_34_gated_we), + .wd (mio_periph_insel_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[34].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_34_qs) + ); + + + // Subregister 35 of Multireg mio_periph_insel + // R[mio_periph_insel_35]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_35_gated_we; + assign mio_periph_insel_35_gated_we = mio_periph_insel_35_we & mio_periph_insel_regwen_35_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_35_gated_we), + .wd (mio_periph_insel_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[35].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_35_qs) + ); + + + // Subregister 36 of Multireg mio_periph_insel + // R[mio_periph_insel_36]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_36_gated_we; + assign mio_periph_insel_36_gated_we = mio_periph_insel_36_we & mio_periph_insel_regwen_36_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_36_gated_we), + .wd (mio_periph_insel_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[36].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_36_qs) + ); + + + // Subregister 37 of Multireg mio_periph_insel + // R[mio_periph_insel_37]: V(False) + // Create REGWEN-gated WE signal + logic mio_periph_insel_37_gated_we; + assign mio_periph_insel_37_gated_we = mio_periph_insel_37_we & mio_periph_insel_regwen_37_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_mio_periph_insel_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_periph_insel_37_gated_we), + .wd (mio_periph_insel_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_periph_insel[37].q), + .ds (), + + // to register interface (read) + .qs (mio_periph_insel_37_qs) + ); + + + // Subregister 0 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_0_we), + .wd (mio_outsel_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_0_qs) + ); + + + // Subregister 1 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_1_we), + .wd (mio_outsel_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_1_qs) + ); + + + // Subregister 2 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_2_we), + .wd (mio_outsel_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_2_qs) + ); + + + // Subregister 3 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_3_we), + .wd (mio_outsel_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_3_qs) + ); + + + // Subregister 4 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_4_we), + .wd (mio_outsel_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_4_qs) + ); + + + // Subregister 5 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_5_we), + .wd (mio_outsel_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_5_qs) + ); + + + // Subregister 6 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_6_we), + .wd (mio_outsel_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_6_qs) + ); + + + // Subregister 7 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_7_we), + .wd (mio_outsel_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_7_qs) + ); + + + // Subregister 8 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_8_we), + .wd (mio_outsel_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_8_qs) + ); + + + // Subregister 9 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_9_we), + .wd (mio_outsel_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_9_qs) + ); + + + // Subregister 10 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_10]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_10_we), + .wd (mio_outsel_regwen_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_10_qs) + ); + + + // Subregister 11 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_11]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_11_we), + .wd (mio_outsel_regwen_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_11_qs) + ); + + + // Subregister 12 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_12]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_12_we), + .wd (mio_outsel_regwen_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_12_qs) + ); + + + // Subregister 13 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_13]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_13_we), + .wd (mio_outsel_regwen_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_13_qs) + ); + + + // Subregister 14 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_14]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_14_we), + .wd (mio_outsel_regwen_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_14_qs) + ); + + + // Subregister 15 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_15]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_15_we), + .wd (mio_outsel_regwen_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_15_qs) + ); + + + // Subregister 16 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_16]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_16_we), + .wd (mio_outsel_regwen_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_16_qs) + ); + + + // Subregister 17 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_17]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_17_we), + .wd (mio_outsel_regwen_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_17_qs) + ); + + + // Subregister 18 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_18]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_18_we), + .wd (mio_outsel_regwen_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_18_qs) + ); + + + // Subregister 19 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_19]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_19_we), + .wd (mio_outsel_regwen_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_19_qs) + ); + + + // Subregister 20 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_20]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_20_we), + .wd (mio_outsel_regwen_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_20_qs) + ); + + + // Subregister 21 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_21]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_21_we), + .wd (mio_outsel_regwen_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_21_qs) + ); + + + // Subregister 22 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_22]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_22_we), + .wd (mio_outsel_regwen_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_22_qs) + ); + + + // Subregister 23 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_23]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_23_we), + .wd (mio_outsel_regwen_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_23_qs) + ); + + + // Subregister 24 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_24]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_24_we), + .wd (mio_outsel_regwen_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_24_qs) + ); + + + // Subregister 25 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_25]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_25_we), + .wd (mio_outsel_regwen_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_25_qs) + ); + + + // Subregister 26 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_26]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_26_we), + .wd (mio_outsel_regwen_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_26_qs) + ); + + + // Subregister 27 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_27]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_27_we), + .wd (mio_outsel_regwen_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_27_qs) + ); + + + // Subregister 28 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_28]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_28_we), + .wd (mio_outsel_regwen_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_28_qs) + ); + + + // Subregister 29 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_29]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_29_we), + .wd (mio_outsel_regwen_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_29_qs) + ); + + + // Subregister 30 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_30]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_30_we), + .wd (mio_outsel_regwen_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_30_qs) + ); + + + // Subregister 31 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_31]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_31_we), + .wd (mio_outsel_regwen_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_31_qs) + ); + + + // Subregister 32 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_32]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_32_we), + .wd (mio_outsel_regwen_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_32_qs) + ); + + + // Subregister 33 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_33]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_33_we), + .wd (mio_outsel_regwen_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_33_qs) + ); + + + // Subregister 34 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_34]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_34_we), + .wd (mio_outsel_regwen_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_34_qs) + ); + + + // Subregister 35 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_35]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_35_we), + .wd (mio_outsel_regwen_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_35_qs) + ); + + + // Subregister 36 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_36]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_36_we), + .wd (mio_outsel_regwen_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_36_qs) + ); + + + // Subregister 37 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_37]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_37_we), + .wd (mio_outsel_regwen_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_37_qs) + ); + + + // Subregister 38 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_38]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_38_we), + .wd (mio_outsel_regwen_38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_38_qs) + ); + + + // Subregister 39 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_39]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_39_we), + .wd (mio_outsel_regwen_39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_39_qs) + ); + + + // Subregister 40 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_40]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_40_we), + .wd (mio_outsel_regwen_40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_40_qs) + ); + + + // Subregister 41 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_41]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_41_we), + .wd (mio_outsel_regwen_41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_41_qs) + ); + + + // Subregister 42 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_42]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_42_we), + .wd (mio_outsel_regwen_42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_42_qs) + ); + + + // Subregister 43 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_43]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_43_we), + .wd (mio_outsel_regwen_43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_43_qs) + ); + + + // Subregister 44 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_44]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_44_we), + .wd (mio_outsel_regwen_44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_44_qs) + ); + + + // Subregister 45 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_45]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_45_we), + .wd (mio_outsel_regwen_45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_45_qs) + ); + + + // Subregister 46 of Multireg mio_outsel_regwen + // R[mio_outsel_regwen_46]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_outsel_regwen_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_regwen_46_we), + .wd (mio_outsel_regwen_46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_outsel_regwen_46_qs) + ); + + + // Subregister 0 of Multireg mio_outsel + // R[mio_outsel_0]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_0_gated_we; + assign mio_outsel_0_gated_we = mio_outsel_0_we & mio_outsel_regwen_0_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_0_gated_we), + .wd (mio_outsel_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[0].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_0_qs) + ); + + + // Subregister 1 of Multireg mio_outsel + // R[mio_outsel_1]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_1_gated_we; + assign mio_outsel_1_gated_we = mio_outsel_1_we & mio_outsel_regwen_1_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_1_gated_we), + .wd (mio_outsel_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[1].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_1_qs) + ); + + + // Subregister 2 of Multireg mio_outsel + // R[mio_outsel_2]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_2_gated_we; + assign mio_outsel_2_gated_we = mio_outsel_2_we & mio_outsel_regwen_2_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_2_gated_we), + .wd (mio_outsel_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[2].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_2_qs) + ); + + + // Subregister 3 of Multireg mio_outsel + // R[mio_outsel_3]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_3_gated_we; + assign mio_outsel_3_gated_we = mio_outsel_3_we & mio_outsel_regwen_3_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_3_gated_we), + .wd (mio_outsel_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[3].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_3_qs) + ); + + + // Subregister 4 of Multireg mio_outsel + // R[mio_outsel_4]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_4_gated_we; + assign mio_outsel_4_gated_we = mio_outsel_4_we & mio_outsel_regwen_4_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_4_gated_we), + .wd (mio_outsel_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[4].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_4_qs) + ); + + + // Subregister 5 of Multireg mio_outsel + // R[mio_outsel_5]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_5_gated_we; + assign mio_outsel_5_gated_we = mio_outsel_5_we & mio_outsel_regwen_5_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_5_gated_we), + .wd (mio_outsel_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[5].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_5_qs) + ); + + + // Subregister 6 of Multireg mio_outsel + // R[mio_outsel_6]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_6_gated_we; + assign mio_outsel_6_gated_we = mio_outsel_6_we & mio_outsel_regwen_6_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_6_gated_we), + .wd (mio_outsel_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[6].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_6_qs) + ); + + + // Subregister 7 of Multireg mio_outsel + // R[mio_outsel_7]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_7_gated_we; + assign mio_outsel_7_gated_we = mio_outsel_7_we & mio_outsel_regwen_7_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_7_gated_we), + .wd (mio_outsel_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[7].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_7_qs) + ); + + + // Subregister 8 of Multireg mio_outsel + // R[mio_outsel_8]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_8_gated_we; + assign mio_outsel_8_gated_we = mio_outsel_8_we & mio_outsel_regwen_8_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_8_gated_we), + .wd (mio_outsel_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[8].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_8_qs) + ); + + + // Subregister 9 of Multireg mio_outsel + // R[mio_outsel_9]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_9_gated_we; + assign mio_outsel_9_gated_we = mio_outsel_9_we & mio_outsel_regwen_9_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_9_gated_we), + .wd (mio_outsel_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[9].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_9_qs) + ); + + + // Subregister 10 of Multireg mio_outsel + // R[mio_outsel_10]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_10_gated_we; + assign mio_outsel_10_gated_we = mio_outsel_10_we & mio_outsel_regwen_10_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_10_gated_we), + .wd (mio_outsel_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[10].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_10_qs) + ); + + + // Subregister 11 of Multireg mio_outsel + // R[mio_outsel_11]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_11_gated_we; + assign mio_outsel_11_gated_we = mio_outsel_11_we & mio_outsel_regwen_11_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_11_gated_we), + .wd (mio_outsel_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[11].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_11_qs) + ); + + + // Subregister 12 of Multireg mio_outsel + // R[mio_outsel_12]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_12_gated_we; + assign mio_outsel_12_gated_we = mio_outsel_12_we & mio_outsel_regwen_12_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_12_gated_we), + .wd (mio_outsel_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[12].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_12_qs) + ); + + + // Subregister 13 of Multireg mio_outsel + // R[mio_outsel_13]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_13_gated_we; + assign mio_outsel_13_gated_we = mio_outsel_13_we & mio_outsel_regwen_13_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_13_gated_we), + .wd (mio_outsel_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[13].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_13_qs) + ); + + + // Subregister 14 of Multireg mio_outsel + // R[mio_outsel_14]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_14_gated_we; + assign mio_outsel_14_gated_we = mio_outsel_14_we & mio_outsel_regwen_14_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_14_gated_we), + .wd (mio_outsel_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[14].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_14_qs) + ); + + + // Subregister 15 of Multireg mio_outsel + // R[mio_outsel_15]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_15_gated_we; + assign mio_outsel_15_gated_we = mio_outsel_15_we & mio_outsel_regwen_15_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_15_gated_we), + .wd (mio_outsel_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[15].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_15_qs) + ); + + + // Subregister 16 of Multireg mio_outsel + // R[mio_outsel_16]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_16_gated_we; + assign mio_outsel_16_gated_we = mio_outsel_16_we & mio_outsel_regwen_16_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_16_gated_we), + .wd (mio_outsel_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[16].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_16_qs) + ); + + + // Subregister 17 of Multireg mio_outsel + // R[mio_outsel_17]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_17_gated_we; + assign mio_outsel_17_gated_we = mio_outsel_17_we & mio_outsel_regwen_17_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_17_gated_we), + .wd (mio_outsel_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[17].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_17_qs) + ); + + + // Subregister 18 of Multireg mio_outsel + // R[mio_outsel_18]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_18_gated_we; + assign mio_outsel_18_gated_we = mio_outsel_18_we & mio_outsel_regwen_18_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_18_gated_we), + .wd (mio_outsel_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[18].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_18_qs) + ); + + + // Subregister 19 of Multireg mio_outsel + // R[mio_outsel_19]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_19_gated_we; + assign mio_outsel_19_gated_we = mio_outsel_19_we & mio_outsel_regwen_19_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_19_gated_we), + .wd (mio_outsel_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[19].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_19_qs) + ); + + + // Subregister 20 of Multireg mio_outsel + // R[mio_outsel_20]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_20_gated_we; + assign mio_outsel_20_gated_we = mio_outsel_20_we & mio_outsel_regwen_20_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_20_gated_we), + .wd (mio_outsel_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[20].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_20_qs) + ); + + + // Subregister 21 of Multireg mio_outsel + // R[mio_outsel_21]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_21_gated_we; + assign mio_outsel_21_gated_we = mio_outsel_21_we & mio_outsel_regwen_21_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_21_gated_we), + .wd (mio_outsel_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[21].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_21_qs) + ); + + + // Subregister 22 of Multireg mio_outsel + // R[mio_outsel_22]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_22_gated_we; + assign mio_outsel_22_gated_we = mio_outsel_22_we & mio_outsel_regwen_22_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_22_gated_we), + .wd (mio_outsel_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[22].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_22_qs) + ); + + + // Subregister 23 of Multireg mio_outsel + // R[mio_outsel_23]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_23_gated_we; + assign mio_outsel_23_gated_we = mio_outsel_23_we & mio_outsel_regwen_23_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_23_gated_we), + .wd (mio_outsel_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[23].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_23_qs) + ); + + + // Subregister 24 of Multireg mio_outsel + // R[mio_outsel_24]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_24_gated_we; + assign mio_outsel_24_gated_we = mio_outsel_24_we & mio_outsel_regwen_24_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_24_gated_we), + .wd (mio_outsel_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[24].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_24_qs) + ); + + + // Subregister 25 of Multireg mio_outsel + // R[mio_outsel_25]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_25_gated_we; + assign mio_outsel_25_gated_we = mio_outsel_25_we & mio_outsel_regwen_25_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_25_gated_we), + .wd (mio_outsel_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[25].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_25_qs) + ); + + + // Subregister 26 of Multireg mio_outsel + // R[mio_outsel_26]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_26_gated_we; + assign mio_outsel_26_gated_we = mio_outsel_26_we & mio_outsel_regwen_26_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_26_gated_we), + .wd (mio_outsel_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[26].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_26_qs) + ); + + + // Subregister 27 of Multireg mio_outsel + // R[mio_outsel_27]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_27_gated_we; + assign mio_outsel_27_gated_we = mio_outsel_27_we & mio_outsel_regwen_27_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_27_gated_we), + .wd (mio_outsel_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[27].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_27_qs) + ); + + + // Subregister 28 of Multireg mio_outsel + // R[mio_outsel_28]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_28_gated_we; + assign mio_outsel_28_gated_we = mio_outsel_28_we & mio_outsel_regwen_28_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_28_gated_we), + .wd (mio_outsel_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[28].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_28_qs) + ); + + + // Subregister 29 of Multireg mio_outsel + // R[mio_outsel_29]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_29_gated_we; + assign mio_outsel_29_gated_we = mio_outsel_29_we & mio_outsel_regwen_29_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_29_gated_we), + .wd (mio_outsel_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[29].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_29_qs) + ); + + + // Subregister 30 of Multireg mio_outsel + // R[mio_outsel_30]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_30_gated_we; + assign mio_outsel_30_gated_we = mio_outsel_30_we & mio_outsel_regwen_30_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_30_gated_we), + .wd (mio_outsel_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[30].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_30_qs) + ); + + + // Subregister 31 of Multireg mio_outsel + // R[mio_outsel_31]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_31_gated_we; + assign mio_outsel_31_gated_we = mio_outsel_31_we & mio_outsel_regwen_31_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_31_gated_we), + .wd (mio_outsel_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[31].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_31_qs) + ); + + + // Subregister 32 of Multireg mio_outsel + // R[mio_outsel_32]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_32_gated_we; + assign mio_outsel_32_gated_we = mio_outsel_32_we & mio_outsel_regwen_32_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_32_gated_we), + .wd (mio_outsel_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[32].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_32_qs) + ); + + + // Subregister 33 of Multireg mio_outsel + // R[mio_outsel_33]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_33_gated_we; + assign mio_outsel_33_gated_we = mio_outsel_33_we & mio_outsel_regwen_33_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_33_gated_we), + .wd (mio_outsel_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[33].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_33_qs) + ); + + + // Subregister 34 of Multireg mio_outsel + // R[mio_outsel_34]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_34_gated_we; + assign mio_outsel_34_gated_we = mio_outsel_34_we & mio_outsel_regwen_34_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_34_gated_we), + .wd (mio_outsel_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[34].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_34_qs) + ); + + + // Subregister 35 of Multireg mio_outsel + // R[mio_outsel_35]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_35_gated_we; + assign mio_outsel_35_gated_we = mio_outsel_35_we & mio_outsel_regwen_35_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_35_gated_we), + .wd (mio_outsel_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[35].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_35_qs) + ); + + + // Subregister 36 of Multireg mio_outsel + // R[mio_outsel_36]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_36_gated_we; + assign mio_outsel_36_gated_we = mio_outsel_36_we & mio_outsel_regwen_36_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_36_gated_we), + .wd (mio_outsel_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[36].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_36_qs) + ); + + + // Subregister 37 of Multireg mio_outsel + // R[mio_outsel_37]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_37_gated_we; + assign mio_outsel_37_gated_we = mio_outsel_37_we & mio_outsel_regwen_37_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_37_gated_we), + .wd (mio_outsel_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[37].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_37_qs) + ); + + + // Subregister 38 of Multireg mio_outsel + // R[mio_outsel_38]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_38_gated_we; + assign mio_outsel_38_gated_we = mio_outsel_38_we & mio_outsel_regwen_38_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_38_gated_we), + .wd (mio_outsel_38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[38].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_38_qs) + ); + + + // Subregister 39 of Multireg mio_outsel + // R[mio_outsel_39]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_39_gated_we; + assign mio_outsel_39_gated_we = mio_outsel_39_we & mio_outsel_regwen_39_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_39_gated_we), + .wd (mio_outsel_39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[39].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_39_qs) + ); + + + // Subregister 40 of Multireg mio_outsel + // R[mio_outsel_40]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_40_gated_we; + assign mio_outsel_40_gated_we = mio_outsel_40_we & mio_outsel_regwen_40_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_40_gated_we), + .wd (mio_outsel_40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[40].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_40_qs) + ); + + + // Subregister 41 of Multireg mio_outsel + // R[mio_outsel_41]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_41_gated_we; + assign mio_outsel_41_gated_we = mio_outsel_41_we & mio_outsel_regwen_41_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_41_gated_we), + .wd (mio_outsel_41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[41].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_41_qs) + ); + + + // Subregister 42 of Multireg mio_outsel + // R[mio_outsel_42]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_42_gated_we; + assign mio_outsel_42_gated_we = mio_outsel_42_we & mio_outsel_regwen_42_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_42_gated_we), + .wd (mio_outsel_42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[42].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_42_qs) + ); + + + // Subregister 43 of Multireg mio_outsel + // R[mio_outsel_43]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_43_gated_we; + assign mio_outsel_43_gated_we = mio_outsel_43_we & mio_outsel_regwen_43_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_43_gated_we), + .wd (mio_outsel_43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[43].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_43_qs) + ); + + + // Subregister 44 of Multireg mio_outsel + // R[mio_outsel_44]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_44_gated_we; + assign mio_outsel_44_gated_we = mio_outsel_44_we & mio_outsel_regwen_44_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_44_gated_we), + .wd (mio_outsel_44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[44].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_44_qs) + ); + + + // Subregister 45 of Multireg mio_outsel + // R[mio_outsel_45]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_45_gated_we; + assign mio_outsel_45_gated_we = mio_outsel_45_we & mio_outsel_regwen_45_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_45_gated_we), + .wd (mio_outsel_45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[45].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_45_qs) + ); + + + // Subregister 46 of Multireg mio_outsel + // R[mio_outsel_46]: V(False) + // Create REGWEN-gated WE signal + logic mio_outsel_46_gated_we; + assign mio_outsel_46_gated_we = mio_outsel_46_we & mio_outsel_regwen_46_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h2), + .Mubi (1'b0) + ) u_mio_outsel_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_outsel_46_gated_we), + .wd (mio_outsel_46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_outsel[46].q), + .ds (), + + // to register interface (read) + .qs (mio_outsel_46_qs) + ); + + + // Subregister 0 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_0_we), + .wd (mio_pad_attr_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_0_qs) + ); + + + // Subregister 1 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_1_we), + .wd (mio_pad_attr_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_1_qs) + ); + + + // Subregister 2 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_2_we), + .wd (mio_pad_attr_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_2_qs) + ); + + + // Subregister 3 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_3_we), + .wd (mio_pad_attr_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_3_qs) + ); + + + // Subregister 4 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_4_we), + .wd (mio_pad_attr_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_4_qs) + ); + + + // Subregister 5 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_5_we), + .wd (mio_pad_attr_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_5_qs) + ); + + + // Subregister 6 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_6_we), + .wd (mio_pad_attr_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_6_qs) + ); + + + // Subregister 7 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_7_we), + .wd (mio_pad_attr_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_7_qs) + ); + + + // Subregister 8 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_8_we), + .wd (mio_pad_attr_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_8_qs) + ); + + + // Subregister 9 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_9_we), + .wd (mio_pad_attr_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_9_qs) + ); + + + // Subregister 10 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_10]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_10_we), + .wd (mio_pad_attr_regwen_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_10_qs) + ); + + + // Subregister 11 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_11]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_11_we), + .wd (mio_pad_attr_regwen_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_11_qs) + ); + + + // Subregister 12 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_12]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_12_we), + .wd (mio_pad_attr_regwen_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_12_qs) + ); + + + // Subregister 13 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_13]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_13_we), + .wd (mio_pad_attr_regwen_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_13_qs) + ); + + + // Subregister 14 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_14]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_14_we), + .wd (mio_pad_attr_regwen_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_14_qs) + ); + + + // Subregister 15 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_15]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_15_we), + .wd (mio_pad_attr_regwen_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_15_qs) + ); + + + // Subregister 16 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_16]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_16_we), + .wd (mio_pad_attr_regwen_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_16_qs) + ); + + + // Subregister 17 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_17]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_17_we), + .wd (mio_pad_attr_regwen_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_17_qs) + ); + + + // Subregister 18 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_18]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_18_we), + .wd (mio_pad_attr_regwen_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_18_qs) + ); + + + // Subregister 19 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_19]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_19_we), + .wd (mio_pad_attr_regwen_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_19_qs) + ); + + + // Subregister 20 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_20]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_20_we), + .wd (mio_pad_attr_regwen_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_20_qs) + ); + + + // Subregister 21 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_21]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_21_we), + .wd (mio_pad_attr_regwen_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_21_qs) + ); + + + // Subregister 22 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_22]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_22_we), + .wd (mio_pad_attr_regwen_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_22_qs) + ); + + + // Subregister 23 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_23]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_23_we), + .wd (mio_pad_attr_regwen_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_23_qs) + ); + + + // Subregister 24 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_24]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_24_we), + .wd (mio_pad_attr_regwen_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_24_qs) + ); + + + // Subregister 25 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_25]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_25_we), + .wd (mio_pad_attr_regwen_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_25_qs) + ); + + + // Subregister 26 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_26]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_26_we), + .wd (mio_pad_attr_regwen_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_26_qs) + ); + + + // Subregister 27 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_27]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_27_we), + .wd (mio_pad_attr_regwen_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_27_qs) + ); + + + // Subregister 28 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_28]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_28_we), + .wd (mio_pad_attr_regwen_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_28_qs) + ); + + + // Subregister 29 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_29]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_29_we), + .wd (mio_pad_attr_regwen_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_29_qs) + ); + + + // Subregister 30 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_30]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_30_we), + .wd (mio_pad_attr_regwen_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_30_qs) + ); + + + // Subregister 31 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_31]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_31_we), + .wd (mio_pad_attr_regwen_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_31_qs) + ); + + + // Subregister 32 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_32]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_32_we), + .wd (mio_pad_attr_regwen_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_32_qs) + ); + + + // Subregister 33 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_33]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_33_we), + .wd (mio_pad_attr_regwen_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_33_qs) + ); + + + // Subregister 34 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_34]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_34_we), + .wd (mio_pad_attr_regwen_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_34_qs) + ); + + + // Subregister 35 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_35]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_35_we), + .wd (mio_pad_attr_regwen_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_35_qs) + ); + + + // Subregister 36 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_36]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_36_we), + .wd (mio_pad_attr_regwen_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_36_qs) + ); + + + // Subregister 37 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_37]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_37_we), + .wd (mio_pad_attr_regwen_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_37_qs) + ); + + + // Subregister 38 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_38]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_38_we), + .wd (mio_pad_attr_regwen_38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_38_qs) + ); + + + // Subregister 39 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_39]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_39_we), + .wd (mio_pad_attr_regwen_39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_39_qs) + ); + + + // Subregister 40 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_40]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_40_we), + .wd (mio_pad_attr_regwen_40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_40_qs) + ); + + + // Subregister 41 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_41]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_41_we), + .wd (mio_pad_attr_regwen_41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_41_qs) + ); + + + // Subregister 42 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_42]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_42_we), + .wd (mio_pad_attr_regwen_42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_42_qs) + ); + + + // Subregister 43 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_43]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_43_we), + .wd (mio_pad_attr_regwen_43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_43_qs) + ); + + + // Subregister 44 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_44]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_44_we), + .wd (mio_pad_attr_regwen_44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_44_qs) + ); + + + // Subregister 45 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_45]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_45_we), + .wd (mio_pad_attr_regwen_45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_45_qs) + ); + + + // Subregister 46 of Multireg mio_pad_attr_regwen + // R[mio_pad_attr_regwen_46]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_attr_regwen_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_attr_regwen_46_we), + .wd (mio_pad_attr_regwen_46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_attr_regwen_46_qs) + ); + + + // Subregister 0 of Multireg mio_pad_attr + // R[mio_pad_attr_0]: V(True) + logic mio_pad_attr_0_qe; + logic [9:0] mio_pad_attr_0_flds_we; + assign mio_pad_attr_0_qe = &mio_pad_attr_0_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_0_gated_we; + assign mio_pad_attr_0_gated_we = mio_pad_attr_0_we & mio_pad_attr_regwen_0_qs; + // F[invert_0]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_invert_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_invert_0_wd), + .d (hw2reg.mio_pad_attr[0].invert.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[0]), + .q (reg2hw.mio_pad_attr[0].invert.q), + .ds (), + .qs (mio_pad_attr_0_invert_0_qs) + ); + assign reg2hw.mio_pad_attr[0].invert.qe = mio_pad_attr_0_qe; + + // F[virtual_od_en_0]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_virtual_od_en_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_virtual_od_en_0_wd), + .d (hw2reg.mio_pad_attr[0].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[1]), + .q (reg2hw.mio_pad_attr[0].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_0_virtual_od_en_0_qs) + ); + assign reg2hw.mio_pad_attr[0].virtual_od_en.qe = mio_pad_attr_0_qe; + + // F[pull_en_0]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_pull_en_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_pull_en_0_wd), + .d (hw2reg.mio_pad_attr[0].pull_en.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[2]), + .q (reg2hw.mio_pad_attr[0].pull_en.q), + .ds (), + .qs (mio_pad_attr_0_pull_en_0_qs) + ); + assign reg2hw.mio_pad_attr[0].pull_en.qe = mio_pad_attr_0_qe; + + // F[pull_select_0]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_pull_select_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_pull_select_0_wd), + .d (hw2reg.mio_pad_attr[0].pull_select.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[3]), + .q (reg2hw.mio_pad_attr[0].pull_select.q), + .ds (), + .qs (mio_pad_attr_0_pull_select_0_qs) + ); + assign reg2hw.mio_pad_attr[0].pull_select.qe = mio_pad_attr_0_qe; + + // F[keeper_en_0]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_keeper_en_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_keeper_en_0_wd), + .d (hw2reg.mio_pad_attr[0].keeper_en.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[4]), + .q (reg2hw.mio_pad_attr[0].keeper_en.q), + .ds (), + .qs (mio_pad_attr_0_keeper_en_0_qs) + ); + assign reg2hw.mio_pad_attr[0].keeper_en.qe = mio_pad_attr_0_qe; + + // F[schmitt_en_0]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_schmitt_en_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_schmitt_en_0_wd), + .d (hw2reg.mio_pad_attr[0].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[5]), + .q (reg2hw.mio_pad_attr[0].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_0_schmitt_en_0_qs) + ); + assign reg2hw.mio_pad_attr[0].schmitt_en.qe = mio_pad_attr_0_qe; + + // F[od_en_0]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_od_en_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_od_en_0_wd), + .d (hw2reg.mio_pad_attr[0].od_en.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[6]), + .q (reg2hw.mio_pad_attr[0].od_en.q), + .ds (), + .qs (mio_pad_attr_0_od_en_0_qs) + ); + assign reg2hw.mio_pad_attr[0].od_en.qe = mio_pad_attr_0_qe; + + // F[input_disable_0]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_0_input_disable_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_input_disable_0_wd), + .d (hw2reg.mio_pad_attr[0].input_disable.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[7]), + .q (reg2hw.mio_pad_attr[0].input_disable.q), + .ds (), + .qs (mio_pad_attr_0_input_disable_0_qs) + ); + assign reg2hw.mio_pad_attr[0].input_disable.qe = mio_pad_attr_0_qe; + + // F[slew_rate_0]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_0_slew_rate_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_slew_rate_0_wd), + .d (hw2reg.mio_pad_attr[0].slew_rate.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[8]), + .q (reg2hw.mio_pad_attr[0].slew_rate.q), + .ds (), + .qs (mio_pad_attr_0_slew_rate_0_qs) + ); + assign reg2hw.mio_pad_attr[0].slew_rate.qe = mio_pad_attr_0_qe; + + // F[drive_strength_0]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_0_drive_strength_0 ( + .re (mio_pad_attr_0_re), + .we (mio_pad_attr_0_gated_we), + .wd (mio_pad_attr_0_drive_strength_0_wd), + .d (hw2reg.mio_pad_attr[0].drive_strength.d), + .qre (), + .qe (mio_pad_attr_0_flds_we[9]), + .q (reg2hw.mio_pad_attr[0].drive_strength.q), + .ds (), + .qs (mio_pad_attr_0_drive_strength_0_qs) + ); + assign reg2hw.mio_pad_attr[0].drive_strength.qe = mio_pad_attr_0_qe; + + + // Subregister 1 of Multireg mio_pad_attr + // R[mio_pad_attr_1]: V(True) + logic mio_pad_attr_1_qe; + logic [9:0] mio_pad_attr_1_flds_we; + assign mio_pad_attr_1_qe = &mio_pad_attr_1_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_1_gated_we; + assign mio_pad_attr_1_gated_we = mio_pad_attr_1_we & mio_pad_attr_regwen_1_qs; + // F[invert_1]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_invert_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_invert_1_wd), + .d (hw2reg.mio_pad_attr[1].invert.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[0]), + .q (reg2hw.mio_pad_attr[1].invert.q), + .ds (), + .qs (mio_pad_attr_1_invert_1_qs) + ); + assign reg2hw.mio_pad_attr[1].invert.qe = mio_pad_attr_1_qe; + + // F[virtual_od_en_1]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_virtual_od_en_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_virtual_od_en_1_wd), + .d (hw2reg.mio_pad_attr[1].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[1]), + .q (reg2hw.mio_pad_attr[1].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_1_virtual_od_en_1_qs) + ); + assign reg2hw.mio_pad_attr[1].virtual_od_en.qe = mio_pad_attr_1_qe; + + // F[pull_en_1]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_pull_en_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_pull_en_1_wd), + .d (hw2reg.mio_pad_attr[1].pull_en.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[2]), + .q (reg2hw.mio_pad_attr[1].pull_en.q), + .ds (), + .qs (mio_pad_attr_1_pull_en_1_qs) + ); + assign reg2hw.mio_pad_attr[1].pull_en.qe = mio_pad_attr_1_qe; + + // F[pull_select_1]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_pull_select_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_pull_select_1_wd), + .d (hw2reg.mio_pad_attr[1].pull_select.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[3]), + .q (reg2hw.mio_pad_attr[1].pull_select.q), + .ds (), + .qs (mio_pad_attr_1_pull_select_1_qs) + ); + assign reg2hw.mio_pad_attr[1].pull_select.qe = mio_pad_attr_1_qe; + + // F[keeper_en_1]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_keeper_en_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_keeper_en_1_wd), + .d (hw2reg.mio_pad_attr[1].keeper_en.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[4]), + .q (reg2hw.mio_pad_attr[1].keeper_en.q), + .ds (), + .qs (mio_pad_attr_1_keeper_en_1_qs) + ); + assign reg2hw.mio_pad_attr[1].keeper_en.qe = mio_pad_attr_1_qe; + + // F[schmitt_en_1]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_schmitt_en_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_schmitt_en_1_wd), + .d (hw2reg.mio_pad_attr[1].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[5]), + .q (reg2hw.mio_pad_attr[1].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_1_schmitt_en_1_qs) + ); + assign reg2hw.mio_pad_attr[1].schmitt_en.qe = mio_pad_attr_1_qe; + + // F[od_en_1]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_od_en_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_od_en_1_wd), + .d (hw2reg.mio_pad_attr[1].od_en.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[6]), + .q (reg2hw.mio_pad_attr[1].od_en.q), + .ds (), + .qs (mio_pad_attr_1_od_en_1_qs) + ); + assign reg2hw.mio_pad_attr[1].od_en.qe = mio_pad_attr_1_qe; + + // F[input_disable_1]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_1_input_disable_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_input_disable_1_wd), + .d (hw2reg.mio_pad_attr[1].input_disable.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[7]), + .q (reg2hw.mio_pad_attr[1].input_disable.q), + .ds (), + .qs (mio_pad_attr_1_input_disable_1_qs) + ); + assign reg2hw.mio_pad_attr[1].input_disable.qe = mio_pad_attr_1_qe; + + // F[slew_rate_1]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_1_slew_rate_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_slew_rate_1_wd), + .d (hw2reg.mio_pad_attr[1].slew_rate.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[8]), + .q (reg2hw.mio_pad_attr[1].slew_rate.q), + .ds (), + .qs (mio_pad_attr_1_slew_rate_1_qs) + ); + assign reg2hw.mio_pad_attr[1].slew_rate.qe = mio_pad_attr_1_qe; + + // F[drive_strength_1]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_1_drive_strength_1 ( + .re (mio_pad_attr_1_re), + .we (mio_pad_attr_1_gated_we), + .wd (mio_pad_attr_1_drive_strength_1_wd), + .d (hw2reg.mio_pad_attr[1].drive_strength.d), + .qre (), + .qe (mio_pad_attr_1_flds_we[9]), + .q (reg2hw.mio_pad_attr[1].drive_strength.q), + .ds (), + .qs (mio_pad_attr_1_drive_strength_1_qs) + ); + assign reg2hw.mio_pad_attr[1].drive_strength.qe = mio_pad_attr_1_qe; + + + // Subregister 2 of Multireg mio_pad_attr + // R[mio_pad_attr_2]: V(True) + logic mio_pad_attr_2_qe; + logic [9:0] mio_pad_attr_2_flds_we; + assign mio_pad_attr_2_qe = &mio_pad_attr_2_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_2_gated_we; + assign mio_pad_attr_2_gated_we = mio_pad_attr_2_we & mio_pad_attr_regwen_2_qs; + // F[invert_2]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_invert_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_invert_2_wd), + .d (hw2reg.mio_pad_attr[2].invert.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[0]), + .q (reg2hw.mio_pad_attr[2].invert.q), + .ds (), + .qs (mio_pad_attr_2_invert_2_qs) + ); + assign reg2hw.mio_pad_attr[2].invert.qe = mio_pad_attr_2_qe; + + // F[virtual_od_en_2]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_virtual_od_en_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_virtual_od_en_2_wd), + .d (hw2reg.mio_pad_attr[2].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[1]), + .q (reg2hw.mio_pad_attr[2].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_2_virtual_od_en_2_qs) + ); + assign reg2hw.mio_pad_attr[2].virtual_od_en.qe = mio_pad_attr_2_qe; + + // F[pull_en_2]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_pull_en_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_pull_en_2_wd), + .d (hw2reg.mio_pad_attr[2].pull_en.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[2]), + .q (reg2hw.mio_pad_attr[2].pull_en.q), + .ds (), + .qs (mio_pad_attr_2_pull_en_2_qs) + ); + assign reg2hw.mio_pad_attr[2].pull_en.qe = mio_pad_attr_2_qe; + + // F[pull_select_2]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_pull_select_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_pull_select_2_wd), + .d (hw2reg.mio_pad_attr[2].pull_select.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[3]), + .q (reg2hw.mio_pad_attr[2].pull_select.q), + .ds (), + .qs (mio_pad_attr_2_pull_select_2_qs) + ); + assign reg2hw.mio_pad_attr[2].pull_select.qe = mio_pad_attr_2_qe; + + // F[keeper_en_2]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_keeper_en_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_keeper_en_2_wd), + .d (hw2reg.mio_pad_attr[2].keeper_en.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[4]), + .q (reg2hw.mio_pad_attr[2].keeper_en.q), + .ds (), + .qs (mio_pad_attr_2_keeper_en_2_qs) + ); + assign reg2hw.mio_pad_attr[2].keeper_en.qe = mio_pad_attr_2_qe; + + // F[schmitt_en_2]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_schmitt_en_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_schmitt_en_2_wd), + .d (hw2reg.mio_pad_attr[2].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[5]), + .q (reg2hw.mio_pad_attr[2].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_2_schmitt_en_2_qs) + ); + assign reg2hw.mio_pad_attr[2].schmitt_en.qe = mio_pad_attr_2_qe; + + // F[od_en_2]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_od_en_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_od_en_2_wd), + .d (hw2reg.mio_pad_attr[2].od_en.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[6]), + .q (reg2hw.mio_pad_attr[2].od_en.q), + .ds (), + .qs (mio_pad_attr_2_od_en_2_qs) + ); + assign reg2hw.mio_pad_attr[2].od_en.qe = mio_pad_attr_2_qe; + + // F[input_disable_2]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_2_input_disable_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_input_disable_2_wd), + .d (hw2reg.mio_pad_attr[2].input_disable.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[7]), + .q (reg2hw.mio_pad_attr[2].input_disable.q), + .ds (), + .qs (mio_pad_attr_2_input_disable_2_qs) + ); + assign reg2hw.mio_pad_attr[2].input_disable.qe = mio_pad_attr_2_qe; + + // F[slew_rate_2]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_2_slew_rate_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_slew_rate_2_wd), + .d (hw2reg.mio_pad_attr[2].slew_rate.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[8]), + .q (reg2hw.mio_pad_attr[2].slew_rate.q), + .ds (), + .qs (mio_pad_attr_2_slew_rate_2_qs) + ); + assign reg2hw.mio_pad_attr[2].slew_rate.qe = mio_pad_attr_2_qe; + + // F[drive_strength_2]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_2_drive_strength_2 ( + .re (mio_pad_attr_2_re), + .we (mio_pad_attr_2_gated_we), + .wd (mio_pad_attr_2_drive_strength_2_wd), + .d (hw2reg.mio_pad_attr[2].drive_strength.d), + .qre (), + .qe (mio_pad_attr_2_flds_we[9]), + .q (reg2hw.mio_pad_attr[2].drive_strength.q), + .ds (), + .qs (mio_pad_attr_2_drive_strength_2_qs) + ); + assign reg2hw.mio_pad_attr[2].drive_strength.qe = mio_pad_attr_2_qe; + + + // Subregister 3 of Multireg mio_pad_attr + // R[mio_pad_attr_3]: V(True) + logic mio_pad_attr_3_qe; + logic [9:0] mio_pad_attr_3_flds_we; + assign mio_pad_attr_3_qe = &mio_pad_attr_3_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_3_gated_we; + assign mio_pad_attr_3_gated_we = mio_pad_attr_3_we & mio_pad_attr_regwen_3_qs; + // F[invert_3]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_invert_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_invert_3_wd), + .d (hw2reg.mio_pad_attr[3].invert.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[0]), + .q (reg2hw.mio_pad_attr[3].invert.q), + .ds (), + .qs (mio_pad_attr_3_invert_3_qs) + ); + assign reg2hw.mio_pad_attr[3].invert.qe = mio_pad_attr_3_qe; + + // F[virtual_od_en_3]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_virtual_od_en_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_virtual_od_en_3_wd), + .d (hw2reg.mio_pad_attr[3].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[1]), + .q (reg2hw.mio_pad_attr[3].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_3_virtual_od_en_3_qs) + ); + assign reg2hw.mio_pad_attr[3].virtual_od_en.qe = mio_pad_attr_3_qe; + + // F[pull_en_3]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_pull_en_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_pull_en_3_wd), + .d (hw2reg.mio_pad_attr[3].pull_en.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[2]), + .q (reg2hw.mio_pad_attr[3].pull_en.q), + .ds (), + .qs (mio_pad_attr_3_pull_en_3_qs) + ); + assign reg2hw.mio_pad_attr[3].pull_en.qe = mio_pad_attr_3_qe; + + // F[pull_select_3]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_pull_select_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_pull_select_3_wd), + .d (hw2reg.mio_pad_attr[3].pull_select.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[3]), + .q (reg2hw.mio_pad_attr[3].pull_select.q), + .ds (), + .qs (mio_pad_attr_3_pull_select_3_qs) + ); + assign reg2hw.mio_pad_attr[3].pull_select.qe = mio_pad_attr_3_qe; + + // F[keeper_en_3]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_keeper_en_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_keeper_en_3_wd), + .d (hw2reg.mio_pad_attr[3].keeper_en.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[4]), + .q (reg2hw.mio_pad_attr[3].keeper_en.q), + .ds (), + .qs (mio_pad_attr_3_keeper_en_3_qs) + ); + assign reg2hw.mio_pad_attr[3].keeper_en.qe = mio_pad_attr_3_qe; + + // F[schmitt_en_3]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_schmitt_en_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_schmitt_en_3_wd), + .d (hw2reg.mio_pad_attr[3].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[5]), + .q (reg2hw.mio_pad_attr[3].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_3_schmitt_en_3_qs) + ); + assign reg2hw.mio_pad_attr[3].schmitt_en.qe = mio_pad_attr_3_qe; + + // F[od_en_3]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_od_en_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_od_en_3_wd), + .d (hw2reg.mio_pad_attr[3].od_en.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[6]), + .q (reg2hw.mio_pad_attr[3].od_en.q), + .ds (), + .qs (mio_pad_attr_3_od_en_3_qs) + ); + assign reg2hw.mio_pad_attr[3].od_en.qe = mio_pad_attr_3_qe; + + // F[input_disable_3]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_3_input_disable_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_input_disable_3_wd), + .d (hw2reg.mio_pad_attr[3].input_disable.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[7]), + .q (reg2hw.mio_pad_attr[3].input_disable.q), + .ds (), + .qs (mio_pad_attr_3_input_disable_3_qs) + ); + assign reg2hw.mio_pad_attr[3].input_disable.qe = mio_pad_attr_3_qe; + + // F[slew_rate_3]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_3_slew_rate_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_slew_rate_3_wd), + .d (hw2reg.mio_pad_attr[3].slew_rate.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[8]), + .q (reg2hw.mio_pad_attr[3].slew_rate.q), + .ds (), + .qs (mio_pad_attr_3_slew_rate_3_qs) + ); + assign reg2hw.mio_pad_attr[3].slew_rate.qe = mio_pad_attr_3_qe; + + // F[drive_strength_3]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_3_drive_strength_3 ( + .re (mio_pad_attr_3_re), + .we (mio_pad_attr_3_gated_we), + .wd (mio_pad_attr_3_drive_strength_3_wd), + .d (hw2reg.mio_pad_attr[3].drive_strength.d), + .qre (), + .qe (mio_pad_attr_3_flds_we[9]), + .q (reg2hw.mio_pad_attr[3].drive_strength.q), + .ds (), + .qs (mio_pad_attr_3_drive_strength_3_qs) + ); + assign reg2hw.mio_pad_attr[3].drive_strength.qe = mio_pad_attr_3_qe; + + + // Subregister 4 of Multireg mio_pad_attr + // R[mio_pad_attr_4]: V(True) + logic mio_pad_attr_4_qe; + logic [9:0] mio_pad_attr_4_flds_we; + assign mio_pad_attr_4_qe = &mio_pad_attr_4_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_4_gated_we; + assign mio_pad_attr_4_gated_we = mio_pad_attr_4_we & mio_pad_attr_regwen_4_qs; + // F[invert_4]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_invert_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_invert_4_wd), + .d (hw2reg.mio_pad_attr[4].invert.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[0]), + .q (reg2hw.mio_pad_attr[4].invert.q), + .ds (), + .qs (mio_pad_attr_4_invert_4_qs) + ); + assign reg2hw.mio_pad_attr[4].invert.qe = mio_pad_attr_4_qe; + + // F[virtual_od_en_4]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_virtual_od_en_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_virtual_od_en_4_wd), + .d (hw2reg.mio_pad_attr[4].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[1]), + .q (reg2hw.mio_pad_attr[4].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_4_virtual_od_en_4_qs) + ); + assign reg2hw.mio_pad_attr[4].virtual_od_en.qe = mio_pad_attr_4_qe; + + // F[pull_en_4]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_pull_en_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_pull_en_4_wd), + .d (hw2reg.mio_pad_attr[4].pull_en.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[2]), + .q (reg2hw.mio_pad_attr[4].pull_en.q), + .ds (), + .qs (mio_pad_attr_4_pull_en_4_qs) + ); + assign reg2hw.mio_pad_attr[4].pull_en.qe = mio_pad_attr_4_qe; + + // F[pull_select_4]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_pull_select_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_pull_select_4_wd), + .d (hw2reg.mio_pad_attr[4].pull_select.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[3]), + .q (reg2hw.mio_pad_attr[4].pull_select.q), + .ds (), + .qs (mio_pad_attr_4_pull_select_4_qs) + ); + assign reg2hw.mio_pad_attr[4].pull_select.qe = mio_pad_attr_4_qe; + + // F[keeper_en_4]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_keeper_en_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_keeper_en_4_wd), + .d (hw2reg.mio_pad_attr[4].keeper_en.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[4]), + .q (reg2hw.mio_pad_attr[4].keeper_en.q), + .ds (), + .qs (mio_pad_attr_4_keeper_en_4_qs) + ); + assign reg2hw.mio_pad_attr[4].keeper_en.qe = mio_pad_attr_4_qe; + + // F[schmitt_en_4]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_schmitt_en_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_schmitt_en_4_wd), + .d (hw2reg.mio_pad_attr[4].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[5]), + .q (reg2hw.mio_pad_attr[4].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_4_schmitt_en_4_qs) + ); + assign reg2hw.mio_pad_attr[4].schmitt_en.qe = mio_pad_attr_4_qe; + + // F[od_en_4]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_od_en_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_od_en_4_wd), + .d (hw2reg.mio_pad_attr[4].od_en.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[6]), + .q (reg2hw.mio_pad_attr[4].od_en.q), + .ds (), + .qs (mio_pad_attr_4_od_en_4_qs) + ); + assign reg2hw.mio_pad_attr[4].od_en.qe = mio_pad_attr_4_qe; + + // F[input_disable_4]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_4_input_disable_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_input_disable_4_wd), + .d (hw2reg.mio_pad_attr[4].input_disable.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[7]), + .q (reg2hw.mio_pad_attr[4].input_disable.q), + .ds (), + .qs (mio_pad_attr_4_input_disable_4_qs) + ); + assign reg2hw.mio_pad_attr[4].input_disable.qe = mio_pad_attr_4_qe; + + // F[slew_rate_4]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_4_slew_rate_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_slew_rate_4_wd), + .d (hw2reg.mio_pad_attr[4].slew_rate.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[8]), + .q (reg2hw.mio_pad_attr[4].slew_rate.q), + .ds (), + .qs (mio_pad_attr_4_slew_rate_4_qs) + ); + assign reg2hw.mio_pad_attr[4].slew_rate.qe = mio_pad_attr_4_qe; + + // F[drive_strength_4]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_4_drive_strength_4 ( + .re (mio_pad_attr_4_re), + .we (mio_pad_attr_4_gated_we), + .wd (mio_pad_attr_4_drive_strength_4_wd), + .d (hw2reg.mio_pad_attr[4].drive_strength.d), + .qre (), + .qe (mio_pad_attr_4_flds_we[9]), + .q (reg2hw.mio_pad_attr[4].drive_strength.q), + .ds (), + .qs (mio_pad_attr_4_drive_strength_4_qs) + ); + assign reg2hw.mio_pad_attr[4].drive_strength.qe = mio_pad_attr_4_qe; + + + // Subregister 5 of Multireg mio_pad_attr + // R[mio_pad_attr_5]: V(True) + logic mio_pad_attr_5_qe; + logic [9:0] mio_pad_attr_5_flds_we; + assign mio_pad_attr_5_qe = &mio_pad_attr_5_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_5_gated_we; + assign mio_pad_attr_5_gated_we = mio_pad_attr_5_we & mio_pad_attr_regwen_5_qs; + // F[invert_5]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_invert_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_invert_5_wd), + .d (hw2reg.mio_pad_attr[5].invert.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[0]), + .q (reg2hw.mio_pad_attr[5].invert.q), + .ds (), + .qs (mio_pad_attr_5_invert_5_qs) + ); + assign reg2hw.mio_pad_attr[5].invert.qe = mio_pad_attr_5_qe; + + // F[virtual_od_en_5]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_virtual_od_en_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_virtual_od_en_5_wd), + .d (hw2reg.mio_pad_attr[5].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[1]), + .q (reg2hw.mio_pad_attr[5].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_5_virtual_od_en_5_qs) + ); + assign reg2hw.mio_pad_attr[5].virtual_od_en.qe = mio_pad_attr_5_qe; + + // F[pull_en_5]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_pull_en_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_pull_en_5_wd), + .d (hw2reg.mio_pad_attr[5].pull_en.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[2]), + .q (reg2hw.mio_pad_attr[5].pull_en.q), + .ds (), + .qs (mio_pad_attr_5_pull_en_5_qs) + ); + assign reg2hw.mio_pad_attr[5].pull_en.qe = mio_pad_attr_5_qe; + + // F[pull_select_5]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_pull_select_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_pull_select_5_wd), + .d (hw2reg.mio_pad_attr[5].pull_select.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[3]), + .q (reg2hw.mio_pad_attr[5].pull_select.q), + .ds (), + .qs (mio_pad_attr_5_pull_select_5_qs) + ); + assign reg2hw.mio_pad_attr[5].pull_select.qe = mio_pad_attr_5_qe; + + // F[keeper_en_5]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_keeper_en_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_keeper_en_5_wd), + .d (hw2reg.mio_pad_attr[5].keeper_en.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[4]), + .q (reg2hw.mio_pad_attr[5].keeper_en.q), + .ds (), + .qs (mio_pad_attr_5_keeper_en_5_qs) + ); + assign reg2hw.mio_pad_attr[5].keeper_en.qe = mio_pad_attr_5_qe; + + // F[schmitt_en_5]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_schmitt_en_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_schmitt_en_5_wd), + .d (hw2reg.mio_pad_attr[5].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[5]), + .q (reg2hw.mio_pad_attr[5].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_5_schmitt_en_5_qs) + ); + assign reg2hw.mio_pad_attr[5].schmitt_en.qe = mio_pad_attr_5_qe; + + // F[od_en_5]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_od_en_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_od_en_5_wd), + .d (hw2reg.mio_pad_attr[5].od_en.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[6]), + .q (reg2hw.mio_pad_attr[5].od_en.q), + .ds (), + .qs (mio_pad_attr_5_od_en_5_qs) + ); + assign reg2hw.mio_pad_attr[5].od_en.qe = mio_pad_attr_5_qe; + + // F[input_disable_5]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_5_input_disable_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_input_disable_5_wd), + .d (hw2reg.mio_pad_attr[5].input_disable.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[7]), + .q (reg2hw.mio_pad_attr[5].input_disable.q), + .ds (), + .qs (mio_pad_attr_5_input_disable_5_qs) + ); + assign reg2hw.mio_pad_attr[5].input_disable.qe = mio_pad_attr_5_qe; + + // F[slew_rate_5]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_5_slew_rate_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_slew_rate_5_wd), + .d (hw2reg.mio_pad_attr[5].slew_rate.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[8]), + .q (reg2hw.mio_pad_attr[5].slew_rate.q), + .ds (), + .qs (mio_pad_attr_5_slew_rate_5_qs) + ); + assign reg2hw.mio_pad_attr[5].slew_rate.qe = mio_pad_attr_5_qe; + + // F[drive_strength_5]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_5_drive_strength_5 ( + .re (mio_pad_attr_5_re), + .we (mio_pad_attr_5_gated_we), + .wd (mio_pad_attr_5_drive_strength_5_wd), + .d (hw2reg.mio_pad_attr[5].drive_strength.d), + .qre (), + .qe (mio_pad_attr_5_flds_we[9]), + .q (reg2hw.mio_pad_attr[5].drive_strength.q), + .ds (), + .qs (mio_pad_attr_5_drive_strength_5_qs) + ); + assign reg2hw.mio_pad_attr[5].drive_strength.qe = mio_pad_attr_5_qe; + + + // Subregister 6 of Multireg mio_pad_attr + // R[mio_pad_attr_6]: V(True) + logic mio_pad_attr_6_qe; + logic [9:0] mio_pad_attr_6_flds_we; + assign mio_pad_attr_6_qe = &mio_pad_attr_6_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_6_gated_we; + assign mio_pad_attr_6_gated_we = mio_pad_attr_6_we & mio_pad_attr_regwen_6_qs; + // F[invert_6]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_invert_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_invert_6_wd), + .d (hw2reg.mio_pad_attr[6].invert.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[0]), + .q (reg2hw.mio_pad_attr[6].invert.q), + .ds (), + .qs (mio_pad_attr_6_invert_6_qs) + ); + assign reg2hw.mio_pad_attr[6].invert.qe = mio_pad_attr_6_qe; + + // F[virtual_od_en_6]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_virtual_od_en_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_virtual_od_en_6_wd), + .d (hw2reg.mio_pad_attr[6].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[1]), + .q (reg2hw.mio_pad_attr[6].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_6_virtual_od_en_6_qs) + ); + assign reg2hw.mio_pad_attr[6].virtual_od_en.qe = mio_pad_attr_6_qe; + + // F[pull_en_6]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_pull_en_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_pull_en_6_wd), + .d (hw2reg.mio_pad_attr[6].pull_en.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[2]), + .q (reg2hw.mio_pad_attr[6].pull_en.q), + .ds (), + .qs (mio_pad_attr_6_pull_en_6_qs) + ); + assign reg2hw.mio_pad_attr[6].pull_en.qe = mio_pad_attr_6_qe; + + // F[pull_select_6]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_pull_select_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_pull_select_6_wd), + .d (hw2reg.mio_pad_attr[6].pull_select.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[3]), + .q (reg2hw.mio_pad_attr[6].pull_select.q), + .ds (), + .qs (mio_pad_attr_6_pull_select_6_qs) + ); + assign reg2hw.mio_pad_attr[6].pull_select.qe = mio_pad_attr_6_qe; + + // F[keeper_en_6]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_keeper_en_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_keeper_en_6_wd), + .d (hw2reg.mio_pad_attr[6].keeper_en.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[4]), + .q (reg2hw.mio_pad_attr[6].keeper_en.q), + .ds (), + .qs (mio_pad_attr_6_keeper_en_6_qs) + ); + assign reg2hw.mio_pad_attr[6].keeper_en.qe = mio_pad_attr_6_qe; + + // F[schmitt_en_6]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_schmitt_en_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_schmitt_en_6_wd), + .d (hw2reg.mio_pad_attr[6].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[5]), + .q (reg2hw.mio_pad_attr[6].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_6_schmitt_en_6_qs) + ); + assign reg2hw.mio_pad_attr[6].schmitt_en.qe = mio_pad_attr_6_qe; + + // F[od_en_6]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_od_en_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_od_en_6_wd), + .d (hw2reg.mio_pad_attr[6].od_en.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[6]), + .q (reg2hw.mio_pad_attr[6].od_en.q), + .ds (), + .qs (mio_pad_attr_6_od_en_6_qs) + ); + assign reg2hw.mio_pad_attr[6].od_en.qe = mio_pad_attr_6_qe; + + // F[input_disable_6]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_6_input_disable_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_input_disable_6_wd), + .d (hw2reg.mio_pad_attr[6].input_disable.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[7]), + .q (reg2hw.mio_pad_attr[6].input_disable.q), + .ds (), + .qs (mio_pad_attr_6_input_disable_6_qs) + ); + assign reg2hw.mio_pad_attr[6].input_disable.qe = mio_pad_attr_6_qe; + + // F[slew_rate_6]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_6_slew_rate_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_slew_rate_6_wd), + .d (hw2reg.mio_pad_attr[6].slew_rate.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[8]), + .q (reg2hw.mio_pad_attr[6].slew_rate.q), + .ds (), + .qs (mio_pad_attr_6_slew_rate_6_qs) + ); + assign reg2hw.mio_pad_attr[6].slew_rate.qe = mio_pad_attr_6_qe; + + // F[drive_strength_6]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_6_drive_strength_6 ( + .re (mio_pad_attr_6_re), + .we (mio_pad_attr_6_gated_we), + .wd (mio_pad_attr_6_drive_strength_6_wd), + .d (hw2reg.mio_pad_attr[6].drive_strength.d), + .qre (), + .qe (mio_pad_attr_6_flds_we[9]), + .q (reg2hw.mio_pad_attr[6].drive_strength.q), + .ds (), + .qs (mio_pad_attr_6_drive_strength_6_qs) + ); + assign reg2hw.mio_pad_attr[6].drive_strength.qe = mio_pad_attr_6_qe; + + + // Subregister 7 of Multireg mio_pad_attr + // R[mio_pad_attr_7]: V(True) + logic mio_pad_attr_7_qe; + logic [9:0] mio_pad_attr_7_flds_we; + assign mio_pad_attr_7_qe = &mio_pad_attr_7_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_7_gated_we; + assign mio_pad_attr_7_gated_we = mio_pad_attr_7_we & mio_pad_attr_regwen_7_qs; + // F[invert_7]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_invert_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_invert_7_wd), + .d (hw2reg.mio_pad_attr[7].invert.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[0]), + .q (reg2hw.mio_pad_attr[7].invert.q), + .ds (), + .qs (mio_pad_attr_7_invert_7_qs) + ); + assign reg2hw.mio_pad_attr[7].invert.qe = mio_pad_attr_7_qe; + + // F[virtual_od_en_7]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_virtual_od_en_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_virtual_od_en_7_wd), + .d (hw2reg.mio_pad_attr[7].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[1]), + .q (reg2hw.mio_pad_attr[7].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_7_virtual_od_en_7_qs) + ); + assign reg2hw.mio_pad_attr[7].virtual_od_en.qe = mio_pad_attr_7_qe; + + // F[pull_en_7]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_pull_en_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_pull_en_7_wd), + .d (hw2reg.mio_pad_attr[7].pull_en.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[2]), + .q (reg2hw.mio_pad_attr[7].pull_en.q), + .ds (), + .qs (mio_pad_attr_7_pull_en_7_qs) + ); + assign reg2hw.mio_pad_attr[7].pull_en.qe = mio_pad_attr_7_qe; + + // F[pull_select_7]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_pull_select_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_pull_select_7_wd), + .d (hw2reg.mio_pad_attr[7].pull_select.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[3]), + .q (reg2hw.mio_pad_attr[7].pull_select.q), + .ds (), + .qs (mio_pad_attr_7_pull_select_7_qs) + ); + assign reg2hw.mio_pad_attr[7].pull_select.qe = mio_pad_attr_7_qe; + + // F[keeper_en_7]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_keeper_en_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_keeper_en_7_wd), + .d (hw2reg.mio_pad_attr[7].keeper_en.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[4]), + .q (reg2hw.mio_pad_attr[7].keeper_en.q), + .ds (), + .qs (mio_pad_attr_7_keeper_en_7_qs) + ); + assign reg2hw.mio_pad_attr[7].keeper_en.qe = mio_pad_attr_7_qe; + + // F[schmitt_en_7]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_schmitt_en_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_schmitt_en_7_wd), + .d (hw2reg.mio_pad_attr[7].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[5]), + .q (reg2hw.mio_pad_attr[7].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_7_schmitt_en_7_qs) + ); + assign reg2hw.mio_pad_attr[7].schmitt_en.qe = mio_pad_attr_7_qe; + + // F[od_en_7]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_od_en_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_od_en_7_wd), + .d (hw2reg.mio_pad_attr[7].od_en.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[6]), + .q (reg2hw.mio_pad_attr[7].od_en.q), + .ds (), + .qs (mio_pad_attr_7_od_en_7_qs) + ); + assign reg2hw.mio_pad_attr[7].od_en.qe = mio_pad_attr_7_qe; + + // F[input_disable_7]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_7_input_disable_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_input_disable_7_wd), + .d (hw2reg.mio_pad_attr[7].input_disable.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[7]), + .q (reg2hw.mio_pad_attr[7].input_disable.q), + .ds (), + .qs (mio_pad_attr_7_input_disable_7_qs) + ); + assign reg2hw.mio_pad_attr[7].input_disable.qe = mio_pad_attr_7_qe; + + // F[slew_rate_7]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_7_slew_rate_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_slew_rate_7_wd), + .d (hw2reg.mio_pad_attr[7].slew_rate.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[8]), + .q (reg2hw.mio_pad_attr[7].slew_rate.q), + .ds (), + .qs (mio_pad_attr_7_slew_rate_7_qs) + ); + assign reg2hw.mio_pad_attr[7].slew_rate.qe = mio_pad_attr_7_qe; + + // F[drive_strength_7]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_7_drive_strength_7 ( + .re (mio_pad_attr_7_re), + .we (mio_pad_attr_7_gated_we), + .wd (mio_pad_attr_7_drive_strength_7_wd), + .d (hw2reg.mio_pad_attr[7].drive_strength.d), + .qre (), + .qe (mio_pad_attr_7_flds_we[9]), + .q (reg2hw.mio_pad_attr[7].drive_strength.q), + .ds (), + .qs (mio_pad_attr_7_drive_strength_7_qs) + ); + assign reg2hw.mio_pad_attr[7].drive_strength.qe = mio_pad_attr_7_qe; + + + // Subregister 8 of Multireg mio_pad_attr + // R[mio_pad_attr_8]: V(True) + logic mio_pad_attr_8_qe; + logic [9:0] mio_pad_attr_8_flds_we; + assign mio_pad_attr_8_qe = &mio_pad_attr_8_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_8_gated_we; + assign mio_pad_attr_8_gated_we = mio_pad_attr_8_we & mio_pad_attr_regwen_8_qs; + // F[invert_8]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_invert_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_invert_8_wd), + .d (hw2reg.mio_pad_attr[8].invert.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[0]), + .q (reg2hw.mio_pad_attr[8].invert.q), + .ds (), + .qs (mio_pad_attr_8_invert_8_qs) + ); + assign reg2hw.mio_pad_attr[8].invert.qe = mio_pad_attr_8_qe; + + // F[virtual_od_en_8]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_virtual_od_en_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_virtual_od_en_8_wd), + .d (hw2reg.mio_pad_attr[8].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[1]), + .q (reg2hw.mio_pad_attr[8].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_8_virtual_od_en_8_qs) + ); + assign reg2hw.mio_pad_attr[8].virtual_od_en.qe = mio_pad_attr_8_qe; + + // F[pull_en_8]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_pull_en_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_pull_en_8_wd), + .d (hw2reg.mio_pad_attr[8].pull_en.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[2]), + .q (reg2hw.mio_pad_attr[8].pull_en.q), + .ds (), + .qs (mio_pad_attr_8_pull_en_8_qs) + ); + assign reg2hw.mio_pad_attr[8].pull_en.qe = mio_pad_attr_8_qe; + + // F[pull_select_8]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_pull_select_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_pull_select_8_wd), + .d (hw2reg.mio_pad_attr[8].pull_select.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[3]), + .q (reg2hw.mio_pad_attr[8].pull_select.q), + .ds (), + .qs (mio_pad_attr_8_pull_select_8_qs) + ); + assign reg2hw.mio_pad_attr[8].pull_select.qe = mio_pad_attr_8_qe; + + // F[keeper_en_8]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_keeper_en_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_keeper_en_8_wd), + .d (hw2reg.mio_pad_attr[8].keeper_en.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[4]), + .q (reg2hw.mio_pad_attr[8].keeper_en.q), + .ds (), + .qs (mio_pad_attr_8_keeper_en_8_qs) + ); + assign reg2hw.mio_pad_attr[8].keeper_en.qe = mio_pad_attr_8_qe; + + // F[schmitt_en_8]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_schmitt_en_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_schmitt_en_8_wd), + .d (hw2reg.mio_pad_attr[8].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[5]), + .q (reg2hw.mio_pad_attr[8].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_8_schmitt_en_8_qs) + ); + assign reg2hw.mio_pad_attr[8].schmitt_en.qe = mio_pad_attr_8_qe; + + // F[od_en_8]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_od_en_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_od_en_8_wd), + .d (hw2reg.mio_pad_attr[8].od_en.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[6]), + .q (reg2hw.mio_pad_attr[8].od_en.q), + .ds (), + .qs (mio_pad_attr_8_od_en_8_qs) + ); + assign reg2hw.mio_pad_attr[8].od_en.qe = mio_pad_attr_8_qe; + + // F[input_disable_8]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_8_input_disable_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_input_disable_8_wd), + .d (hw2reg.mio_pad_attr[8].input_disable.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[7]), + .q (reg2hw.mio_pad_attr[8].input_disable.q), + .ds (), + .qs (mio_pad_attr_8_input_disable_8_qs) + ); + assign reg2hw.mio_pad_attr[8].input_disable.qe = mio_pad_attr_8_qe; + + // F[slew_rate_8]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_8_slew_rate_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_slew_rate_8_wd), + .d (hw2reg.mio_pad_attr[8].slew_rate.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[8]), + .q (reg2hw.mio_pad_attr[8].slew_rate.q), + .ds (), + .qs (mio_pad_attr_8_slew_rate_8_qs) + ); + assign reg2hw.mio_pad_attr[8].slew_rate.qe = mio_pad_attr_8_qe; + + // F[drive_strength_8]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_8_drive_strength_8 ( + .re (mio_pad_attr_8_re), + .we (mio_pad_attr_8_gated_we), + .wd (mio_pad_attr_8_drive_strength_8_wd), + .d (hw2reg.mio_pad_attr[8].drive_strength.d), + .qre (), + .qe (mio_pad_attr_8_flds_we[9]), + .q (reg2hw.mio_pad_attr[8].drive_strength.q), + .ds (), + .qs (mio_pad_attr_8_drive_strength_8_qs) + ); + assign reg2hw.mio_pad_attr[8].drive_strength.qe = mio_pad_attr_8_qe; + + + // Subregister 9 of Multireg mio_pad_attr + // R[mio_pad_attr_9]: V(True) + logic mio_pad_attr_9_qe; + logic [9:0] mio_pad_attr_9_flds_we; + assign mio_pad_attr_9_qe = &mio_pad_attr_9_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_9_gated_we; + assign mio_pad_attr_9_gated_we = mio_pad_attr_9_we & mio_pad_attr_regwen_9_qs; + // F[invert_9]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_invert_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_invert_9_wd), + .d (hw2reg.mio_pad_attr[9].invert.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[0]), + .q (reg2hw.mio_pad_attr[9].invert.q), + .ds (), + .qs (mio_pad_attr_9_invert_9_qs) + ); + assign reg2hw.mio_pad_attr[9].invert.qe = mio_pad_attr_9_qe; + + // F[virtual_od_en_9]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_virtual_od_en_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_virtual_od_en_9_wd), + .d (hw2reg.mio_pad_attr[9].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[1]), + .q (reg2hw.mio_pad_attr[9].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_9_virtual_od_en_9_qs) + ); + assign reg2hw.mio_pad_attr[9].virtual_od_en.qe = mio_pad_attr_9_qe; + + // F[pull_en_9]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_pull_en_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_pull_en_9_wd), + .d (hw2reg.mio_pad_attr[9].pull_en.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[2]), + .q (reg2hw.mio_pad_attr[9].pull_en.q), + .ds (), + .qs (mio_pad_attr_9_pull_en_9_qs) + ); + assign reg2hw.mio_pad_attr[9].pull_en.qe = mio_pad_attr_9_qe; + + // F[pull_select_9]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_pull_select_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_pull_select_9_wd), + .d (hw2reg.mio_pad_attr[9].pull_select.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[3]), + .q (reg2hw.mio_pad_attr[9].pull_select.q), + .ds (), + .qs (mio_pad_attr_9_pull_select_9_qs) + ); + assign reg2hw.mio_pad_attr[9].pull_select.qe = mio_pad_attr_9_qe; + + // F[keeper_en_9]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_keeper_en_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_keeper_en_9_wd), + .d (hw2reg.mio_pad_attr[9].keeper_en.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[4]), + .q (reg2hw.mio_pad_attr[9].keeper_en.q), + .ds (), + .qs (mio_pad_attr_9_keeper_en_9_qs) + ); + assign reg2hw.mio_pad_attr[9].keeper_en.qe = mio_pad_attr_9_qe; + + // F[schmitt_en_9]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_schmitt_en_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_schmitt_en_9_wd), + .d (hw2reg.mio_pad_attr[9].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[5]), + .q (reg2hw.mio_pad_attr[9].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_9_schmitt_en_9_qs) + ); + assign reg2hw.mio_pad_attr[9].schmitt_en.qe = mio_pad_attr_9_qe; + + // F[od_en_9]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_od_en_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_od_en_9_wd), + .d (hw2reg.mio_pad_attr[9].od_en.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[6]), + .q (reg2hw.mio_pad_attr[9].od_en.q), + .ds (), + .qs (mio_pad_attr_9_od_en_9_qs) + ); + assign reg2hw.mio_pad_attr[9].od_en.qe = mio_pad_attr_9_qe; + + // F[input_disable_9]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_9_input_disable_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_input_disable_9_wd), + .d (hw2reg.mio_pad_attr[9].input_disable.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[7]), + .q (reg2hw.mio_pad_attr[9].input_disable.q), + .ds (), + .qs (mio_pad_attr_9_input_disable_9_qs) + ); + assign reg2hw.mio_pad_attr[9].input_disable.qe = mio_pad_attr_9_qe; + + // F[slew_rate_9]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_9_slew_rate_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_slew_rate_9_wd), + .d (hw2reg.mio_pad_attr[9].slew_rate.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[8]), + .q (reg2hw.mio_pad_attr[9].slew_rate.q), + .ds (), + .qs (mio_pad_attr_9_slew_rate_9_qs) + ); + assign reg2hw.mio_pad_attr[9].slew_rate.qe = mio_pad_attr_9_qe; + + // F[drive_strength_9]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_9_drive_strength_9 ( + .re (mio_pad_attr_9_re), + .we (mio_pad_attr_9_gated_we), + .wd (mio_pad_attr_9_drive_strength_9_wd), + .d (hw2reg.mio_pad_attr[9].drive_strength.d), + .qre (), + .qe (mio_pad_attr_9_flds_we[9]), + .q (reg2hw.mio_pad_attr[9].drive_strength.q), + .ds (), + .qs (mio_pad_attr_9_drive_strength_9_qs) + ); + assign reg2hw.mio_pad_attr[9].drive_strength.qe = mio_pad_attr_9_qe; + + + // Subregister 10 of Multireg mio_pad_attr + // R[mio_pad_attr_10]: V(True) + logic mio_pad_attr_10_qe; + logic [9:0] mio_pad_attr_10_flds_we; + assign mio_pad_attr_10_qe = &mio_pad_attr_10_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_10_gated_we; + assign mio_pad_attr_10_gated_we = mio_pad_attr_10_we & mio_pad_attr_regwen_10_qs; + // F[invert_10]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_invert_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_invert_10_wd), + .d (hw2reg.mio_pad_attr[10].invert.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[0]), + .q (reg2hw.mio_pad_attr[10].invert.q), + .ds (), + .qs (mio_pad_attr_10_invert_10_qs) + ); + assign reg2hw.mio_pad_attr[10].invert.qe = mio_pad_attr_10_qe; + + // F[virtual_od_en_10]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_virtual_od_en_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_virtual_od_en_10_wd), + .d (hw2reg.mio_pad_attr[10].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[1]), + .q (reg2hw.mio_pad_attr[10].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_10_virtual_od_en_10_qs) + ); + assign reg2hw.mio_pad_attr[10].virtual_od_en.qe = mio_pad_attr_10_qe; + + // F[pull_en_10]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_pull_en_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_pull_en_10_wd), + .d (hw2reg.mio_pad_attr[10].pull_en.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[2]), + .q (reg2hw.mio_pad_attr[10].pull_en.q), + .ds (), + .qs (mio_pad_attr_10_pull_en_10_qs) + ); + assign reg2hw.mio_pad_attr[10].pull_en.qe = mio_pad_attr_10_qe; + + // F[pull_select_10]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_pull_select_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_pull_select_10_wd), + .d (hw2reg.mio_pad_attr[10].pull_select.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[3]), + .q (reg2hw.mio_pad_attr[10].pull_select.q), + .ds (), + .qs (mio_pad_attr_10_pull_select_10_qs) + ); + assign reg2hw.mio_pad_attr[10].pull_select.qe = mio_pad_attr_10_qe; + + // F[keeper_en_10]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_keeper_en_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_keeper_en_10_wd), + .d (hw2reg.mio_pad_attr[10].keeper_en.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[4]), + .q (reg2hw.mio_pad_attr[10].keeper_en.q), + .ds (), + .qs (mio_pad_attr_10_keeper_en_10_qs) + ); + assign reg2hw.mio_pad_attr[10].keeper_en.qe = mio_pad_attr_10_qe; + + // F[schmitt_en_10]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_schmitt_en_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_schmitt_en_10_wd), + .d (hw2reg.mio_pad_attr[10].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[5]), + .q (reg2hw.mio_pad_attr[10].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_10_schmitt_en_10_qs) + ); + assign reg2hw.mio_pad_attr[10].schmitt_en.qe = mio_pad_attr_10_qe; + + // F[od_en_10]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_od_en_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_od_en_10_wd), + .d (hw2reg.mio_pad_attr[10].od_en.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[6]), + .q (reg2hw.mio_pad_attr[10].od_en.q), + .ds (), + .qs (mio_pad_attr_10_od_en_10_qs) + ); + assign reg2hw.mio_pad_attr[10].od_en.qe = mio_pad_attr_10_qe; + + // F[input_disable_10]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_10_input_disable_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_input_disable_10_wd), + .d (hw2reg.mio_pad_attr[10].input_disable.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[7]), + .q (reg2hw.mio_pad_attr[10].input_disable.q), + .ds (), + .qs (mio_pad_attr_10_input_disable_10_qs) + ); + assign reg2hw.mio_pad_attr[10].input_disable.qe = mio_pad_attr_10_qe; + + // F[slew_rate_10]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_10_slew_rate_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_slew_rate_10_wd), + .d (hw2reg.mio_pad_attr[10].slew_rate.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[8]), + .q (reg2hw.mio_pad_attr[10].slew_rate.q), + .ds (), + .qs (mio_pad_attr_10_slew_rate_10_qs) + ); + assign reg2hw.mio_pad_attr[10].slew_rate.qe = mio_pad_attr_10_qe; + + // F[drive_strength_10]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_10_drive_strength_10 ( + .re (mio_pad_attr_10_re), + .we (mio_pad_attr_10_gated_we), + .wd (mio_pad_attr_10_drive_strength_10_wd), + .d (hw2reg.mio_pad_attr[10].drive_strength.d), + .qre (), + .qe (mio_pad_attr_10_flds_we[9]), + .q (reg2hw.mio_pad_attr[10].drive_strength.q), + .ds (), + .qs (mio_pad_attr_10_drive_strength_10_qs) + ); + assign reg2hw.mio_pad_attr[10].drive_strength.qe = mio_pad_attr_10_qe; + + + // Subregister 11 of Multireg mio_pad_attr + // R[mio_pad_attr_11]: V(True) + logic mio_pad_attr_11_qe; + logic [9:0] mio_pad_attr_11_flds_we; + assign mio_pad_attr_11_qe = &mio_pad_attr_11_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_11_gated_we; + assign mio_pad_attr_11_gated_we = mio_pad_attr_11_we & mio_pad_attr_regwen_11_qs; + // F[invert_11]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_invert_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_invert_11_wd), + .d (hw2reg.mio_pad_attr[11].invert.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[0]), + .q (reg2hw.mio_pad_attr[11].invert.q), + .ds (), + .qs (mio_pad_attr_11_invert_11_qs) + ); + assign reg2hw.mio_pad_attr[11].invert.qe = mio_pad_attr_11_qe; + + // F[virtual_od_en_11]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_virtual_od_en_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_virtual_od_en_11_wd), + .d (hw2reg.mio_pad_attr[11].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[1]), + .q (reg2hw.mio_pad_attr[11].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_11_virtual_od_en_11_qs) + ); + assign reg2hw.mio_pad_attr[11].virtual_od_en.qe = mio_pad_attr_11_qe; + + // F[pull_en_11]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_pull_en_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_pull_en_11_wd), + .d (hw2reg.mio_pad_attr[11].pull_en.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[2]), + .q (reg2hw.mio_pad_attr[11].pull_en.q), + .ds (), + .qs (mio_pad_attr_11_pull_en_11_qs) + ); + assign reg2hw.mio_pad_attr[11].pull_en.qe = mio_pad_attr_11_qe; + + // F[pull_select_11]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_pull_select_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_pull_select_11_wd), + .d (hw2reg.mio_pad_attr[11].pull_select.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[3]), + .q (reg2hw.mio_pad_attr[11].pull_select.q), + .ds (), + .qs (mio_pad_attr_11_pull_select_11_qs) + ); + assign reg2hw.mio_pad_attr[11].pull_select.qe = mio_pad_attr_11_qe; + + // F[keeper_en_11]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_keeper_en_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_keeper_en_11_wd), + .d (hw2reg.mio_pad_attr[11].keeper_en.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[4]), + .q (reg2hw.mio_pad_attr[11].keeper_en.q), + .ds (), + .qs (mio_pad_attr_11_keeper_en_11_qs) + ); + assign reg2hw.mio_pad_attr[11].keeper_en.qe = mio_pad_attr_11_qe; + + // F[schmitt_en_11]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_schmitt_en_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_schmitt_en_11_wd), + .d (hw2reg.mio_pad_attr[11].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[5]), + .q (reg2hw.mio_pad_attr[11].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_11_schmitt_en_11_qs) + ); + assign reg2hw.mio_pad_attr[11].schmitt_en.qe = mio_pad_attr_11_qe; + + // F[od_en_11]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_od_en_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_od_en_11_wd), + .d (hw2reg.mio_pad_attr[11].od_en.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[6]), + .q (reg2hw.mio_pad_attr[11].od_en.q), + .ds (), + .qs (mio_pad_attr_11_od_en_11_qs) + ); + assign reg2hw.mio_pad_attr[11].od_en.qe = mio_pad_attr_11_qe; + + // F[input_disable_11]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_11_input_disable_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_input_disable_11_wd), + .d (hw2reg.mio_pad_attr[11].input_disable.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[7]), + .q (reg2hw.mio_pad_attr[11].input_disable.q), + .ds (), + .qs (mio_pad_attr_11_input_disable_11_qs) + ); + assign reg2hw.mio_pad_attr[11].input_disable.qe = mio_pad_attr_11_qe; + + // F[slew_rate_11]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_11_slew_rate_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_slew_rate_11_wd), + .d (hw2reg.mio_pad_attr[11].slew_rate.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[8]), + .q (reg2hw.mio_pad_attr[11].slew_rate.q), + .ds (), + .qs (mio_pad_attr_11_slew_rate_11_qs) + ); + assign reg2hw.mio_pad_attr[11].slew_rate.qe = mio_pad_attr_11_qe; + + // F[drive_strength_11]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_11_drive_strength_11 ( + .re (mio_pad_attr_11_re), + .we (mio_pad_attr_11_gated_we), + .wd (mio_pad_attr_11_drive_strength_11_wd), + .d (hw2reg.mio_pad_attr[11].drive_strength.d), + .qre (), + .qe (mio_pad_attr_11_flds_we[9]), + .q (reg2hw.mio_pad_attr[11].drive_strength.q), + .ds (), + .qs (mio_pad_attr_11_drive_strength_11_qs) + ); + assign reg2hw.mio_pad_attr[11].drive_strength.qe = mio_pad_attr_11_qe; + + + // Subregister 12 of Multireg mio_pad_attr + // R[mio_pad_attr_12]: V(True) + logic mio_pad_attr_12_qe; + logic [9:0] mio_pad_attr_12_flds_we; + assign mio_pad_attr_12_qe = &mio_pad_attr_12_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_12_gated_we; + assign mio_pad_attr_12_gated_we = mio_pad_attr_12_we & mio_pad_attr_regwen_12_qs; + // F[invert_12]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_invert_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_invert_12_wd), + .d (hw2reg.mio_pad_attr[12].invert.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[0]), + .q (reg2hw.mio_pad_attr[12].invert.q), + .ds (), + .qs (mio_pad_attr_12_invert_12_qs) + ); + assign reg2hw.mio_pad_attr[12].invert.qe = mio_pad_attr_12_qe; + + // F[virtual_od_en_12]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_virtual_od_en_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_virtual_od_en_12_wd), + .d (hw2reg.mio_pad_attr[12].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[1]), + .q (reg2hw.mio_pad_attr[12].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_12_virtual_od_en_12_qs) + ); + assign reg2hw.mio_pad_attr[12].virtual_od_en.qe = mio_pad_attr_12_qe; + + // F[pull_en_12]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_pull_en_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_pull_en_12_wd), + .d (hw2reg.mio_pad_attr[12].pull_en.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[2]), + .q (reg2hw.mio_pad_attr[12].pull_en.q), + .ds (), + .qs (mio_pad_attr_12_pull_en_12_qs) + ); + assign reg2hw.mio_pad_attr[12].pull_en.qe = mio_pad_attr_12_qe; + + // F[pull_select_12]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_pull_select_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_pull_select_12_wd), + .d (hw2reg.mio_pad_attr[12].pull_select.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[3]), + .q (reg2hw.mio_pad_attr[12].pull_select.q), + .ds (), + .qs (mio_pad_attr_12_pull_select_12_qs) + ); + assign reg2hw.mio_pad_attr[12].pull_select.qe = mio_pad_attr_12_qe; + + // F[keeper_en_12]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_keeper_en_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_keeper_en_12_wd), + .d (hw2reg.mio_pad_attr[12].keeper_en.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[4]), + .q (reg2hw.mio_pad_attr[12].keeper_en.q), + .ds (), + .qs (mio_pad_attr_12_keeper_en_12_qs) + ); + assign reg2hw.mio_pad_attr[12].keeper_en.qe = mio_pad_attr_12_qe; + + // F[schmitt_en_12]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_schmitt_en_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_schmitt_en_12_wd), + .d (hw2reg.mio_pad_attr[12].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[5]), + .q (reg2hw.mio_pad_attr[12].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_12_schmitt_en_12_qs) + ); + assign reg2hw.mio_pad_attr[12].schmitt_en.qe = mio_pad_attr_12_qe; + + // F[od_en_12]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_od_en_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_od_en_12_wd), + .d (hw2reg.mio_pad_attr[12].od_en.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[6]), + .q (reg2hw.mio_pad_attr[12].od_en.q), + .ds (), + .qs (mio_pad_attr_12_od_en_12_qs) + ); + assign reg2hw.mio_pad_attr[12].od_en.qe = mio_pad_attr_12_qe; + + // F[input_disable_12]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_12_input_disable_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_input_disable_12_wd), + .d (hw2reg.mio_pad_attr[12].input_disable.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[7]), + .q (reg2hw.mio_pad_attr[12].input_disable.q), + .ds (), + .qs (mio_pad_attr_12_input_disable_12_qs) + ); + assign reg2hw.mio_pad_attr[12].input_disable.qe = mio_pad_attr_12_qe; + + // F[slew_rate_12]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_12_slew_rate_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_slew_rate_12_wd), + .d (hw2reg.mio_pad_attr[12].slew_rate.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[8]), + .q (reg2hw.mio_pad_attr[12].slew_rate.q), + .ds (), + .qs (mio_pad_attr_12_slew_rate_12_qs) + ); + assign reg2hw.mio_pad_attr[12].slew_rate.qe = mio_pad_attr_12_qe; + + // F[drive_strength_12]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_12_drive_strength_12 ( + .re (mio_pad_attr_12_re), + .we (mio_pad_attr_12_gated_we), + .wd (mio_pad_attr_12_drive_strength_12_wd), + .d (hw2reg.mio_pad_attr[12].drive_strength.d), + .qre (), + .qe (mio_pad_attr_12_flds_we[9]), + .q (reg2hw.mio_pad_attr[12].drive_strength.q), + .ds (), + .qs (mio_pad_attr_12_drive_strength_12_qs) + ); + assign reg2hw.mio_pad_attr[12].drive_strength.qe = mio_pad_attr_12_qe; + + + // Subregister 13 of Multireg mio_pad_attr + // R[mio_pad_attr_13]: V(True) + logic mio_pad_attr_13_qe; + logic [9:0] mio_pad_attr_13_flds_we; + assign mio_pad_attr_13_qe = &mio_pad_attr_13_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_13_gated_we; + assign mio_pad_attr_13_gated_we = mio_pad_attr_13_we & mio_pad_attr_regwen_13_qs; + // F[invert_13]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_invert_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_invert_13_wd), + .d (hw2reg.mio_pad_attr[13].invert.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[0]), + .q (reg2hw.mio_pad_attr[13].invert.q), + .ds (), + .qs (mio_pad_attr_13_invert_13_qs) + ); + assign reg2hw.mio_pad_attr[13].invert.qe = mio_pad_attr_13_qe; + + // F[virtual_od_en_13]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_virtual_od_en_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_virtual_od_en_13_wd), + .d (hw2reg.mio_pad_attr[13].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[1]), + .q (reg2hw.mio_pad_attr[13].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_13_virtual_od_en_13_qs) + ); + assign reg2hw.mio_pad_attr[13].virtual_od_en.qe = mio_pad_attr_13_qe; + + // F[pull_en_13]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_pull_en_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_pull_en_13_wd), + .d (hw2reg.mio_pad_attr[13].pull_en.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[2]), + .q (reg2hw.mio_pad_attr[13].pull_en.q), + .ds (), + .qs (mio_pad_attr_13_pull_en_13_qs) + ); + assign reg2hw.mio_pad_attr[13].pull_en.qe = mio_pad_attr_13_qe; + + // F[pull_select_13]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_pull_select_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_pull_select_13_wd), + .d (hw2reg.mio_pad_attr[13].pull_select.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[3]), + .q (reg2hw.mio_pad_attr[13].pull_select.q), + .ds (), + .qs (mio_pad_attr_13_pull_select_13_qs) + ); + assign reg2hw.mio_pad_attr[13].pull_select.qe = mio_pad_attr_13_qe; + + // F[keeper_en_13]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_keeper_en_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_keeper_en_13_wd), + .d (hw2reg.mio_pad_attr[13].keeper_en.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[4]), + .q (reg2hw.mio_pad_attr[13].keeper_en.q), + .ds (), + .qs (mio_pad_attr_13_keeper_en_13_qs) + ); + assign reg2hw.mio_pad_attr[13].keeper_en.qe = mio_pad_attr_13_qe; + + // F[schmitt_en_13]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_schmitt_en_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_schmitt_en_13_wd), + .d (hw2reg.mio_pad_attr[13].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[5]), + .q (reg2hw.mio_pad_attr[13].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_13_schmitt_en_13_qs) + ); + assign reg2hw.mio_pad_attr[13].schmitt_en.qe = mio_pad_attr_13_qe; + + // F[od_en_13]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_od_en_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_od_en_13_wd), + .d (hw2reg.mio_pad_attr[13].od_en.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[6]), + .q (reg2hw.mio_pad_attr[13].od_en.q), + .ds (), + .qs (mio_pad_attr_13_od_en_13_qs) + ); + assign reg2hw.mio_pad_attr[13].od_en.qe = mio_pad_attr_13_qe; + + // F[input_disable_13]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_13_input_disable_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_input_disable_13_wd), + .d (hw2reg.mio_pad_attr[13].input_disable.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[7]), + .q (reg2hw.mio_pad_attr[13].input_disable.q), + .ds (), + .qs (mio_pad_attr_13_input_disable_13_qs) + ); + assign reg2hw.mio_pad_attr[13].input_disable.qe = mio_pad_attr_13_qe; + + // F[slew_rate_13]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_13_slew_rate_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_slew_rate_13_wd), + .d (hw2reg.mio_pad_attr[13].slew_rate.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[8]), + .q (reg2hw.mio_pad_attr[13].slew_rate.q), + .ds (), + .qs (mio_pad_attr_13_slew_rate_13_qs) + ); + assign reg2hw.mio_pad_attr[13].slew_rate.qe = mio_pad_attr_13_qe; + + // F[drive_strength_13]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_13_drive_strength_13 ( + .re (mio_pad_attr_13_re), + .we (mio_pad_attr_13_gated_we), + .wd (mio_pad_attr_13_drive_strength_13_wd), + .d (hw2reg.mio_pad_attr[13].drive_strength.d), + .qre (), + .qe (mio_pad_attr_13_flds_we[9]), + .q (reg2hw.mio_pad_attr[13].drive_strength.q), + .ds (), + .qs (mio_pad_attr_13_drive_strength_13_qs) + ); + assign reg2hw.mio_pad_attr[13].drive_strength.qe = mio_pad_attr_13_qe; + + + // Subregister 14 of Multireg mio_pad_attr + // R[mio_pad_attr_14]: V(True) + logic mio_pad_attr_14_qe; + logic [9:0] mio_pad_attr_14_flds_we; + assign mio_pad_attr_14_qe = &mio_pad_attr_14_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_14_gated_we; + assign mio_pad_attr_14_gated_we = mio_pad_attr_14_we & mio_pad_attr_regwen_14_qs; + // F[invert_14]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_invert_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_invert_14_wd), + .d (hw2reg.mio_pad_attr[14].invert.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[0]), + .q (reg2hw.mio_pad_attr[14].invert.q), + .ds (), + .qs (mio_pad_attr_14_invert_14_qs) + ); + assign reg2hw.mio_pad_attr[14].invert.qe = mio_pad_attr_14_qe; + + // F[virtual_od_en_14]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_virtual_od_en_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_virtual_od_en_14_wd), + .d (hw2reg.mio_pad_attr[14].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[1]), + .q (reg2hw.mio_pad_attr[14].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_14_virtual_od_en_14_qs) + ); + assign reg2hw.mio_pad_attr[14].virtual_od_en.qe = mio_pad_attr_14_qe; + + // F[pull_en_14]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_pull_en_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_pull_en_14_wd), + .d (hw2reg.mio_pad_attr[14].pull_en.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[2]), + .q (reg2hw.mio_pad_attr[14].pull_en.q), + .ds (), + .qs (mio_pad_attr_14_pull_en_14_qs) + ); + assign reg2hw.mio_pad_attr[14].pull_en.qe = mio_pad_attr_14_qe; + + // F[pull_select_14]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_pull_select_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_pull_select_14_wd), + .d (hw2reg.mio_pad_attr[14].pull_select.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[3]), + .q (reg2hw.mio_pad_attr[14].pull_select.q), + .ds (), + .qs (mio_pad_attr_14_pull_select_14_qs) + ); + assign reg2hw.mio_pad_attr[14].pull_select.qe = mio_pad_attr_14_qe; + + // F[keeper_en_14]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_keeper_en_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_keeper_en_14_wd), + .d (hw2reg.mio_pad_attr[14].keeper_en.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[4]), + .q (reg2hw.mio_pad_attr[14].keeper_en.q), + .ds (), + .qs (mio_pad_attr_14_keeper_en_14_qs) + ); + assign reg2hw.mio_pad_attr[14].keeper_en.qe = mio_pad_attr_14_qe; + + // F[schmitt_en_14]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_schmitt_en_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_schmitt_en_14_wd), + .d (hw2reg.mio_pad_attr[14].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[5]), + .q (reg2hw.mio_pad_attr[14].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_14_schmitt_en_14_qs) + ); + assign reg2hw.mio_pad_attr[14].schmitt_en.qe = mio_pad_attr_14_qe; + + // F[od_en_14]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_od_en_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_od_en_14_wd), + .d (hw2reg.mio_pad_attr[14].od_en.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[6]), + .q (reg2hw.mio_pad_attr[14].od_en.q), + .ds (), + .qs (mio_pad_attr_14_od_en_14_qs) + ); + assign reg2hw.mio_pad_attr[14].od_en.qe = mio_pad_attr_14_qe; + + // F[input_disable_14]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_14_input_disable_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_input_disable_14_wd), + .d (hw2reg.mio_pad_attr[14].input_disable.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[7]), + .q (reg2hw.mio_pad_attr[14].input_disable.q), + .ds (), + .qs (mio_pad_attr_14_input_disable_14_qs) + ); + assign reg2hw.mio_pad_attr[14].input_disable.qe = mio_pad_attr_14_qe; + + // F[slew_rate_14]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_14_slew_rate_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_slew_rate_14_wd), + .d (hw2reg.mio_pad_attr[14].slew_rate.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[8]), + .q (reg2hw.mio_pad_attr[14].slew_rate.q), + .ds (), + .qs (mio_pad_attr_14_slew_rate_14_qs) + ); + assign reg2hw.mio_pad_attr[14].slew_rate.qe = mio_pad_attr_14_qe; + + // F[drive_strength_14]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_14_drive_strength_14 ( + .re (mio_pad_attr_14_re), + .we (mio_pad_attr_14_gated_we), + .wd (mio_pad_attr_14_drive_strength_14_wd), + .d (hw2reg.mio_pad_attr[14].drive_strength.d), + .qre (), + .qe (mio_pad_attr_14_flds_we[9]), + .q (reg2hw.mio_pad_attr[14].drive_strength.q), + .ds (), + .qs (mio_pad_attr_14_drive_strength_14_qs) + ); + assign reg2hw.mio_pad_attr[14].drive_strength.qe = mio_pad_attr_14_qe; + + + // Subregister 15 of Multireg mio_pad_attr + // R[mio_pad_attr_15]: V(True) + logic mio_pad_attr_15_qe; + logic [9:0] mio_pad_attr_15_flds_we; + assign mio_pad_attr_15_qe = &mio_pad_attr_15_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_15_gated_we; + assign mio_pad_attr_15_gated_we = mio_pad_attr_15_we & mio_pad_attr_regwen_15_qs; + // F[invert_15]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_invert_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_invert_15_wd), + .d (hw2reg.mio_pad_attr[15].invert.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[0]), + .q (reg2hw.mio_pad_attr[15].invert.q), + .ds (), + .qs (mio_pad_attr_15_invert_15_qs) + ); + assign reg2hw.mio_pad_attr[15].invert.qe = mio_pad_attr_15_qe; + + // F[virtual_od_en_15]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_virtual_od_en_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_virtual_od_en_15_wd), + .d (hw2reg.mio_pad_attr[15].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[1]), + .q (reg2hw.mio_pad_attr[15].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_15_virtual_od_en_15_qs) + ); + assign reg2hw.mio_pad_attr[15].virtual_od_en.qe = mio_pad_attr_15_qe; + + // F[pull_en_15]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_pull_en_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_pull_en_15_wd), + .d (hw2reg.mio_pad_attr[15].pull_en.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[2]), + .q (reg2hw.mio_pad_attr[15].pull_en.q), + .ds (), + .qs (mio_pad_attr_15_pull_en_15_qs) + ); + assign reg2hw.mio_pad_attr[15].pull_en.qe = mio_pad_attr_15_qe; + + // F[pull_select_15]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_pull_select_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_pull_select_15_wd), + .d (hw2reg.mio_pad_attr[15].pull_select.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[3]), + .q (reg2hw.mio_pad_attr[15].pull_select.q), + .ds (), + .qs (mio_pad_attr_15_pull_select_15_qs) + ); + assign reg2hw.mio_pad_attr[15].pull_select.qe = mio_pad_attr_15_qe; + + // F[keeper_en_15]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_keeper_en_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_keeper_en_15_wd), + .d (hw2reg.mio_pad_attr[15].keeper_en.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[4]), + .q (reg2hw.mio_pad_attr[15].keeper_en.q), + .ds (), + .qs (mio_pad_attr_15_keeper_en_15_qs) + ); + assign reg2hw.mio_pad_attr[15].keeper_en.qe = mio_pad_attr_15_qe; + + // F[schmitt_en_15]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_schmitt_en_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_schmitt_en_15_wd), + .d (hw2reg.mio_pad_attr[15].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[5]), + .q (reg2hw.mio_pad_attr[15].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_15_schmitt_en_15_qs) + ); + assign reg2hw.mio_pad_attr[15].schmitt_en.qe = mio_pad_attr_15_qe; + + // F[od_en_15]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_od_en_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_od_en_15_wd), + .d (hw2reg.mio_pad_attr[15].od_en.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[6]), + .q (reg2hw.mio_pad_attr[15].od_en.q), + .ds (), + .qs (mio_pad_attr_15_od_en_15_qs) + ); + assign reg2hw.mio_pad_attr[15].od_en.qe = mio_pad_attr_15_qe; + + // F[input_disable_15]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_15_input_disable_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_input_disable_15_wd), + .d (hw2reg.mio_pad_attr[15].input_disable.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[7]), + .q (reg2hw.mio_pad_attr[15].input_disable.q), + .ds (), + .qs (mio_pad_attr_15_input_disable_15_qs) + ); + assign reg2hw.mio_pad_attr[15].input_disable.qe = mio_pad_attr_15_qe; + + // F[slew_rate_15]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_15_slew_rate_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_slew_rate_15_wd), + .d (hw2reg.mio_pad_attr[15].slew_rate.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[8]), + .q (reg2hw.mio_pad_attr[15].slew_rate.q), + .ds (), + .qs (mio_pad_attr_15_slew_rate_15_qs) + ); + assign reg2hw.mio_pad_attr[15].slew_rate.qe = mio_pad_attr_15_qe; + + // F[drive_strength_15]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_15_drive_strength_15 ( + .re (mio_pad_attr_15_re), + .we (mio_pad_attr_15_gated_we), + .wd (mio_pad_attr_15_drive_strength_15_wd), + .d (hw2reg.mio_pad_attr[15].drive_strength.d), + .qre (), + .qe (mio_pad_attr_15_flds_we[9]), + .q (reg2hw.mio_pad_attr[15].drive_strength.q), + .ds (), + .qs (mio_pad_attr_15_drive_strength_15_qs) + ); + assign reg2hw.mio_pad_attr[15].drive_strength.qe = mio_pad_attr_15_qe; + + + // Subregister 16 of Multireg mio_pad_attr + // R[mio_pad_attr_16]: V(True) + logic mio_pad_attr_16_qe; + logic [9:0] mio_pad_attr_16_flds_we; + assign mio_pad_attr_16_qe = &mio_pad_attr_16_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_16_gated_we; + assign mio_pad_attr_16_gated_we = mio_pad_attr_16_we & mio_pad_attr_regwen_16_qs; + // F[invert_16]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_invert_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_invert_16_wd), + .d (hw2reg.mio_pad_attr[16].invert.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[0]), + .q (reg2hw.mio_pad_attr[16].invert.q), + .ds (), + .qs (mio_pad_attr_16_invert_16_qs) + ); + assign reg2hw.mio_pad_attr[16].invert.qe = mio_pad_attr_16_qe; + + // F[virtual_od_en_16]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_virtual_od_en_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_virtual_od_en_16_wd), + .d (hw2reg.mio_pad_attr[16].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[1]), + .q (reg2hw.mio_pad_attr[16].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_16_virtual_od_en_16_qs) + ); + assign reg2hw.mio_pad_attr[16].virtual_od_en.qe = mio_pad_attr_16_qe; + + // F[pull_en_16]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_pull_en_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_pull_en_16_wd), + .d (hw2reg.mio_pad_attr[16].pull_en.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[2]), + .q (reg2hw.mio_pad_attr[16].pull_en.q), + .ds (), + .qs (mio_pad_attr_16_pull_en_16_qs) + ); + assign reg2hw.mio_pad_attr[16].pull_en.qe = mio_pad_attr_16_qe; + + // F[pull_select_16]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_pull_select_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_pull_select_16_wd), + .d (hw2reg.mio_pad_attr[16].pull_select.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[3]), + .q (reg2hw.mio_pad_attr[16].pull_select.q), + .ds (), + .qs (mio_pad_attr_16_pull_select_16_qs) + ); + assign reg2hw.mio_pad_attr[16].pull_select.qe = mio_pad_attr_16_qe; + + // F[keeper_en_16]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_keeper_en_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_keeper_en_16_wd), + .d (hw2reg.mio_pad_attr[16].keeper_en.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[4]), + .q (reg2hw.mio_pad_attr[16].keeper_en.q), + .ds (), + .qs (mio_pad_attr_16_keeper_en_16_qs) + ); + assign reg2hw.mio_pad_attr[16].keeper_en.qe = mio_pad_attr_16_qe; + + // F[schmitt_en_16]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_schmitt_en_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_schmitt_en_16_wd), + .d (hw2reg.mio_pad_attr[16].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[5]), + .q (reg2hw.mio_pad_attr[16].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_16_schmitt_en_16_qs) + ); + assign reg2hw.mio_pad_attr[16].schmitt_en.qe = mio_pad_attr_16_qe; + + // F[od_en_16]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_od_en_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_od_en_16_wd), + .d (hw2reg.mio_pad_attr[16].od_en.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[6]), + .q (reg2hw.mio_pad_attr[16].od_en.q), + .ds (), + .qs (mio_pad_attr_16_od_en_16_qs) + ); + assign reg2hw.mio_pad_attr[16].od_en.qe = mio_pad_attr_16_qe; + + // F[input_disable_16]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_16_input_disable_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_input_disable_16_wd), + .d (hw2reg.mio_pad_attr[16].input_disable.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[7]), + .q (reg2hw.mio_pad_attr[16].input_disable.q), + .ds (), + .qs (mio_pad_attr_16_input_disable_16_qs) + ); + assign reg2hw.mio_pad_attr[16].input_disable.qe = mio_pad_attr_16_qe; + + // F[slew_rate_16]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_16_slew_rate_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_slew_rate_16_wd), + .d (hw2reg.mio_pad_attr[16].slew_rate.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[8]), + .q (reg2hw.mio_pad_attr[16].slew_rate.q), + .ds (), + .qs (mio_pad_attr_16_slew_rate_16_qs) + ); + assign reg2hw.mio_pad_attr[16].slew_rate.qe = mio_pad_attr_16_qe; + + // F[drive_strength_16]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_16_drive_strength_16 ( + .re (mio_pad_attr_16_re), + .we (mio_pad_attr_16_gated_we), + .wd (mio_pad_attr_16_drive_strength_16_wd), + .d (hw2reg.mio_pad_attr[16].drive_strength.d), + .qre (), + .qe (mio_pad_attr_16_flds_we[9]), + .q (reg2hw.mio_pad_attr[16].drive_strength.q), + .ds (), + .qs (mio_pad_attr_16_drive_strength_16_qs) + ); + assign reg2hw.mio_pad_attr[16].drive_strength.qe = mio_pad_attr_16_qe; + + + // Subregister 17 of Multireg mio_pad_attr + // R[mio_pad_attr_17]: V(True) + logic mio_pad_attr_17_qe; + logic [9:0] mio_pad_attr_17_flds_we; + assign mio_pad_attr_17_qe = &mio_pad_attr_17_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_17_gated_we; + assign mio_pad_attr_17_gated_we = mio_pad_attr_17_we & mio_pad_attr_regwen_17_qs; + // F[invert_17]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_invert_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_invert_17_wd), + .d (hw2reg.mio_pad_attr[17].invert.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[0]), + .q (reg2hw.mio_pad_attr[17].invert.q), + .ds (), + .qs (mio_pad_attr_17_invert_17_qs) + ); + assign reg2hw.mio_pad_attr[17].invert.qe = mio_pad_attr_17_qe; + + // F[virtual_od_en_17]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_virtual_od_en_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_virtual_od_en_17_wd), + .d (hw2reg.mio_pad_attr[17].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[1]), + .q (reg2hw.mio_pad_attr[17].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_17_virtual_od_en_17_qs) + ); + assign reg2hw.mio_pad_attr[17].virtual_od_en.qe = mio_pad_attr_17_qe; + + // F[pull_en_17]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_pull_en_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_pull_en_17_wd), + .d (hw2reg.mio_pad_attr[17].pull_en.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[2]), + .q (reg2hw.mio_pad_attr[17].pull_en.q), + .ds (), + .qs (mio_pad_attr_17_pull_en_17_qs) + ); + assign reg2hw.mio_pad_attr[17].pull_en.qe = mio_pad_attr_17_qe; + + // F[pull_select_17]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_pull_select_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_pull_select_17_wd), + .d (hw2reg.mio_pad_attr[17].pull_select.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[3]), + .q (reg2hw.mio_pad_attr[17].pull_select.q), + .ds (), + .qs (mio_pad_attr_17_pull_select_17_qs) + ); + assign reg2hw.mio_pad_attr[17].pull_select.qe = mio_pad_attr_17_qe; + + // F[keeper_en_17]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_keeper_en_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_keeper_en_17_wd), + .d (hw2reg.mio_pad_attr[17].keeper_en.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[4]), + .q (reg2hw.mio_pad_attr[17].keeper_en.q), + .ds (), + .qs (mio_pad_attr_17_keeper_en_17_qs) + ); + assign reg2hw.mio_pad_attr[17].keeper_en.qe = mio_pad_attr_17_qe; + + // F[schmitt_en_17]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_schmitt_en_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_schmitt_en_17_wd), + .d (hw2reg.mio_pad_attr[17].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[5]), + .q (reg2hw.mio_pad_attr[17].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_17_schmitt_en_17_qs) + ); + assign reg2hw.mio_pad_attr[17].schmitt_en.qe = mio_pad_attr_17_qe; + + // F[od_en_17]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_od_en_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_od_en_17_wd), + .d (hw2reg.mio_pad_attr[17].od_en.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[6]), + .q (reg2hw.mio_pad_attr[17].od_en.q), + .ds (), + .qs (mio_pad_attr_17_od_en_17_qs) + ); + assign reg2hw.mio_pad_attr[17].od_en.qe = mio_pad_attr_17_qe; + + // F[input_disable_17]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_17_input_disable_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_input_disable_17_wd), + .d (hw2reg.mio_pad_attr[17].input_disable.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[7]), + .q (reg2hw.mio_pad_attr[17].input_disable.q), + .ds (), + .qs (mio_pad_attr_17_input_disable_17_qs) + ); + assign reg2hw.mio_pad_attr[17].input_disable.qe = mio_pad_attr_17_qe; + + // F[slew_rate_17]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_17_slew_rate_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_slew_rate_17_wd), + .d (hw2reg.mio_pad_attr[17].slew_rate.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[8]), + .q (reg2hw.mio_pad_attr[17].slew_rate.q), + .ds (), + .qs (mio_pad_attr_17_slew_rate_17_qs) + ); + assign reg2hw.mio_pad_attr[17].slew_rate.qe = mio_pad_attr_17_qe; + + // F[drive_strength_17]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_17_drive_strength_17 ( + .re (mio_pad_attr_17_re), + .we (mio_pad_attr_17_gated_we), + .wd (mio_pad_attr_17_drive_strength_17_wd), + .d (hw2reg.mio_pad_attr[17].drive_strength.d), + .qre (), + .qe (mio_pad_attr_17_flds_we[9]), + .q (reg2hw.mio_pad_attr[17].drive_strength.q), + .ds (), + .qs (mio_pad_attr_17_drive_strength_17_qs) + ); + assign reg2hw.mio_pad_attr[17].drive_strength.qe = mio_pad_attr_17_qe; + + + // Subregister 18 of Multireg mio_pad_attr + // R[mio_pad_attr_18]: V(True) + logic mio_pad_attr_18_qe; + logic [9:0] mio_pad_attr_18_flds_we; + assign mio_pad_attr_18_qe = &mio_pad_attr_18_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_18_gated_we; + assign mio_pad_attr_18_gated_we = mio_pad_attr_18_we & mio_pad_attr_regwen_18_qs; + // F[invert_18]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_invert_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_invert_18_wd), + .d (hw2reg.mio_pad_attr[18].invert.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[0]), + .q (reg2hw.mio_pad_attr[18].invert.q), + .ds (), + .qs (mio_pad_attr_18_invert_18_qs) + ); + assign reg2hw.mio_pad_attr[18].invert.qe = mio_pad_attr_18_qe; + + // F[virtual_od_en_18]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_virtual_od_en_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_virtual_od_en_18_wd), + .d (hw2reg.mio_pad_attr[18].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[1]), + .q (reg2hw.mio_pad_attr[18].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_18_virtual_od_en_18_qs) + ); + assign reg2hw.mio_pad_attr[18].virtual_od_en.qe = mio_pad_attr_18_qe; + + // F[pull_en_18]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_pull_en_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_pull_en_18_wd), + .d (hw2reg.mio_pad_attr[18].pull_en.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[2]), + .q (reg2hw.mio_pad_attr[18].pull_en.q), + .ds (), + .qs (mio_pad_attr_18_pull_en_18_qs) + ); + assign reg2hw.mio_pad_attr[18].pull_en.qe = mio_pad_attr_18_qe; + + // F[pull_select_18]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_pull_select_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_pull_select_18_wd), + .d (hw2reg.mio_pad_attr[18].pull_select.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[3]), + .q (reg2hw.mio_pad_attr[18].pull_select.q), + .ds (), + .qs (mio_pad_attr_18_pull_select_18_qs) + ); + assign reg2hw.mio_pad_attr[18].pull_select.qe = mio_pad_attr_18_qe; + + // F[keeper_en_18]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_keeper_en_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_keeper_en_18_wd), + .d (hw2reg.mio_pad_attr[18].keeper_en.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[4]), + .q (reg2hw.mio_pad_attr[18].keeper_en.q), + .ds (), + .qs (mio_pad_attr_18_keeper_en_18_qs) + ); + assign reg2hw.mio_pad_attr[18].keeper_en.qe = mio_pad_attr_18_qe; + + // F[schmitt_en_18]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_schmitt_en_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_schmitt_en_18_wd), + .d (hw2reg.mio_pad_attr[18].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[5]), + .q (reg2hw.mio_pad_attr[18].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_18_schmitt_en_18_qs) + ); + assign reg2hw.mio_pad_attr[18].schmitt_en.qe = mio_pad_attr_18_qe; + + // F[od_en_18]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_od_en_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_od_en_18_wd), + .d (hw2reg.mio_pad_attr[18].od_en.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[6]), + .q (reg2hw.mio_pad_attr[18].od_en.q), + .ds (), + .qs (mio_pad_attr_18_od_en_18_qs) + ); + assign reg2hw.mio_pad_attr[18].od_en.qe = mio_pad_attr_18_qe; + + // F[input_disable_18]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_18_input_disable_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_input_disable_18_wd), + .d (hw2reg.mio_pad_attr[18].input_disable.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[7]), + .q (reg2hw.mio_pad_attr[18].input_disable.q), + .ds (), + .qs (mio_pad_attr_18_input_disable_18_qs) + ); + assign reg2hw.mio_pad_attr[18].input_disable.qe = mio_pad_attr_18_qe; + + // F[slew_rate_18]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_18_slew_rate_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_slew_rate_18_wd), + .d (hw2reg.mio_pad_attr[18].slew_rate.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[8]), + .q (reg2hw.mio_pad_attr[18].slew_rate.q), + .ds (), + .qs (mio_pad_attr_18_slew_rate_18_qs) + ); + assign reg2hw.mio_pad_attr[18].slew_rate.qe = mio_pad_attr_18_qe; + + // F[drive_strength_18]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_18_drive_strength_18 ( + .re (mio_pad_attr_18_re), + .we (mio_pad_attr_18_gated_we), + .wd (mio_pad_attr_18_drive_strength_18_wd), + .d (hw2reg.mio_pad_attr[18].drive_strength.d), + .qre (), + .qe (mio_pad_attr_18_flds_we[9]), + .q (reg2hw.mio_pad_attr[18].drive_strength.q), + .ds (), + .qs (mio_pad_attr_18_drive_strength_18_qs) + ); + assign reg2hw.mio_pad_attr[18].drive_strength.qe = mio_pad_attr_18_qe; + + + // Subregister 19 of Multireg mio_pad_attr + // R[mio_pad_attr_19]: V(True) + logic mio_pad_attr_19_qe; + logic [9:0] mio_pad_attr_19_flds_we; + assign mio_pad_attr_19_qe = &mio_pad_attr_19_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_19_gated_we; + assign mio_pad_attr_19_gated_we = mio_pad_attr_19_we & mio_pad_attr_regwen_19_qs; + // F[invert_19]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_invert_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_invert_19_wd), + .d (hw2reg.mio_pad_attr[19].invert.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[0]), + .q (reg2hw.mio_pad_attr[19].invert.q), + .ds (), + .qs (mio_pad_attr_19_invert_19_qs) + ); + assign reg2hw.mio_pad_attr[19].invert.qe = mio_pad_attr_19_qe; + + // F[virtual_od_en_19]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_virtual_od_en_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_virtual_od_en_19_wd), + .d (hw2reg.mio_pad_attr[19].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[1]), + .q (reg2hw.mio_pad_attr[19].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_19_virtual_od_en_19_qs) + ); + assign reg2hw.mio_pad_attr[19].virtual_od_en.qe = mio_pad_attr_19_qe; + + // F[pull_en_19]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_pull_en_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_pull_en_19_wd), + .d (hw2reg.mio_pad_attr[19].pull_en.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[2]), + .q (reg2hw.mio_pad_attr[19].pull_en.q), + .ds (), + .qs (mio_pad_attr_19_pull_en_19_qs) + ); + assign reg2hw.mio_pad_attr[19].pull_en.qe = mio_pad_attr_19_qe; + + // F[pull_select_19]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_pull_select_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_pull_select_19_wd), + .d (hw2reg.mio_pad_attr[19].pull_select.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[3]), + .q (reg2hw.mio_pad_attr[19].pull_select.q), + .ds (), + .qs (mio_pad_attr_19_pull_select_19_qs) + ); + assign reg2hw.mio_pad_attr[19].pull_select.qe = mio_pad_attr_19_qe; + + // F[keeper_en_19]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_keeper_en_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_keeper_en_19_wd), + .d (hw2reg.mio_pad_attr[19].keeper_en.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[4]), + .q (reg2hw.mio_pad_attr[19].keeper_en.q), + .ds (), + .qs (mio_pad_attr_19_keeper_en_19_qs) + ); + assign reg2hw.mio_pad_attr[19].keeper_en.qe = mio_pad_attr_19_qe; + + // F[schmitt_en_19]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_schmitt_en_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_schmitt_en_19_wd), + .d (hw2reg.mio_pad_attr[19].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[5]), + .q (reg2hw.mio_pad_attr[19].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_19_schmitt_en_19_qs) + ); + assign reg2hw.mio_pad_attr[19].schmitt_en.qe = mio_pad_attr_19_qe; + + // F[od_en_19]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_od_en_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_od_en_19_wd), + .d (hw2reg.mio_pad_attr[19].od_en.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[6]), + .q (reg2hw.mio_pad_attr[19].od_en.q), + .ds (), + .qs (mio_pad_attr_19_od_en_19_qs) + ); + assign reg2hw.mio_pad_attr[19].od_en.qe = mio_pad_attr_19_qe; + + // F[input_disable_19]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_19_input_disable_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_input_disable_19_wd), + .d (hw2reg.mio_pad_attr[19].input_disable.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[7]), + .q (reg2hw.mio_pad_attr[19].input_disable.q), + .ds (), + .qs (mio_pad_attr_19_input_disable_19_qs) + ); + assign reg2hw.mio_pad_attr[19].input_disable.qe = mio_pad_attr_19_qe; + + // F[slew_rate_19]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_19_slew_rate_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_slew_rate_19_wd), + .d (hw2reg.mio_pad_attr[19].slew_rate.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[8]), + .q (reg2hw.mio_pad_attr[19].slew_rate.q), + .ds (), + .qs (mio_pad_attr_19_slew_rate_19_qs) + ); + assign reg2hw.mio_pad_attr[19].slew_rate.qe = mio_pad_attr_19_qe; + + // F[drive_strength_19]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_19_drive_strength_19 ( + .re (mio_pad_attr_19_re), + .we (mio_pad_attr_19_gated_we), + .wd (mio_pad_attr_19_drive_strength_19_wd), + .d (hw2reg.mio_pad_attr[19].drive_strength.d), + .qre (), + .qe (mio_pad_attr_19_flds_we[9]), + .q (reg2hw.mio_pad_attr[19].drive_strength.q), + .ds (), + .qs (mio_pad_attr_19_drive_strength_19_qs) + ); + assign reg2hw.mio_pad_attr[19].drive_strength.qe = mio_pad_attr_19_qe; + + + // Subregister 20 of Multireg mio_pad_attr + // R[mio_pad_attr_20]: V(True) + logic mio_pad_attr_20_qe; + logic [9:0] mio_pad_attr_20_flds_we; + assign mio_pad_attr_20_qe = &mio_pad_attr_20_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_20_gated_we; + assign mio_pad_attr_20_gated_we = mio_pad_attr_20_we & mio_pad_attr_regwen_20_qs; + // F[invert_20]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_invert_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_invert_20_wd), + .d (hw2reg.mio_pad_attr[20].invert.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[0]), + .q (reg2hw.mio_pad_attr[20].invert.q), + .ds (), + .qs (mio_pad_attr_20_invert_20_qs) + ); + assign reg2hw.mio_pad_attr[20].invert.qe = mio_pad_attr_20_qe; + + // F[virtual_od_en_20]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_virtual_od_en_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_virtual_od_en_20_wd), + .d (hw2reg.mio_pad_attr[20].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[1]), + .q (reg2hw.mio_pad_attr[20].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_20_virtual_od_en_20_qs) + ); + assign reg2hw.mio_pad_attr[20].virtual_od_en.qe = mio_pad_attr_20_qe; + + // F[pull_en_20]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_pull_en_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_pull_en_20_wd), + .d (hw2reg.mio_pad_attr[20].pull_en.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[2]), + .q (reg2hw.mio_pad_attr[20].pull_en.q), + .ds (), + .qs (mio_pad_attr_20_pull_en_20_qs) + ); + assign reg2hw.mio_pad_attr[20].pull_en.qe = mio_pad_attr_20_qe; + + // F[pull_select_20]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_pull_select_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_pull_select_20_wd), + .d (hw2reg.mio_pad_attr[20].pull_select.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[3]), + .q (reg2hw.mio_pad_attr[20].pull_select.q), + .ds (), + .qs (mio_pad_attr_20_pull_select_20_qs) + ); + assign reg2hw.mio_pad_attr[20].pull_select.qe = mio_pad_attr_20_qe; + + // F[keeper_en_20]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_keeper_en_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_keeper_en_20_wd), + .d (hw2reg.mio_pad_attr[20].keeper_en.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[4]), + .q (reg2hw.mio_pad_attr[20].keeper_en.q), + .ds (), + .qs (mio_pad_attr_20_keeper_en_20_qs) + ); + assign reg2hw.mio_pad_attr[20].keeper_en.qe = mio_pad_attr_20_qe; + + // F[schmitt_en_20]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_schmitt_en_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_schmitt_en_20_wd), + .d (hw2reg.mio_pad_attr[20].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[5]), + .q (reg2hw.mio_pad_attr[20].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_20_schmitt_en_20_qs) + ); + assign reg2hw.mio_pad_attr[20].schmitt_en.qe = mio_pad_attr_20_qe; + + // F[od_en_20]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_od_en_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_od_en_20_wd), + .d (hw2reg.mio_pad_attr[20].od_en.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[6]), + .q (reg2hw.mio_pad_attr[20].od_en.q), + .ds (), + .qs (mio_pad_attr_20_od_en_20_qs) + ); + assign reg2hw.mio_pad_attr[20].od_en.qe = mio_pad_attr_20_qe; + + // F[input_disable_20]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_20_input_disable_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_input_disable_20_wd), + .d (hw2reg.mio_pad_attr[20].input_disable.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[7]), + .q (reg2hw.mio_pad_attr[20].input_disable.q), + .ds (), + .qs (mio_pad_attr_20_input_disable_20_qs) + ); + assign reg2hw.mio_pad_attr[20].input_disable.qe = mio_pad_attr_20_qe; + + // F[slew_rate_20]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_20_slew_rate_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_slew_rate_20_wd), + .d (hw2reg.mio_pad_attr[20].slew_rate.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[8]), + .q (reg2hw.mio_pad_attr[20].slew_rate.q), + .ds (), + .qs (mio_pad_attr_20_slew_rate_20_qs) + ); + assign reg2hw.mio_pad_attr[20].slew_rate.qe = mio_pad_attr_20_qe; + + // F[drive_strength_20]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_20_drive_strength_20 ( + .re (mio_pad_attr_20_re), + .we (mio_pad_attr_20_gated_we), + .wd (mio_pad_attr_20_drive_strength_20_wd), + .d (hw2reg.mio_pad_attr[20].drive_strength.d), + .qre (), + .qe (mio_pad_attr_20_flds_we[9]), + .q (reg2hw.mio_pad_attr[20].drive_strength.q), + .ds (), + .qs (mio_pad_attr_20_drive_strength_20_qs) + ); + assign reg2hw.mio_pad_attr[20].drive_strength.qe = mio_pad_attr_20_qe; + + + // Subregister 21 of Multireg mio_pad_attr + // R[mio_pad_attr_21]: V(True) + logic mio_pad_attr_21_qe; + logic [9:0] mio_pad_attr_21_flds_we; + assign mio_pad_attr_21_qe = &mio_pad_attr_21_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_21_gated_we; + assign mio_pad_attr_21_gated_we = mio_pad_attr_21_we & mio_pad_attr_regwen_21_qs; + // F[invert_21]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_invert_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_invert_21_wd), + .d (hw2reg.mio_pad_attr[21].invert.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[0]), + .q (reg2hw.mio_pad_attr[21].invert.q), + .ds (), + .qs (mio_pad_attr_21_invert_21_qs) + ); + assign reg2hw.mio_pad_attr[21].invert.qe = mio_pad_attr_21_qe; + + // F[virtual_od_en_21]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_virtual_od_en_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_virtual_od_en_21_wd), + .d (hw2reg.mio_pad_attr[21].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[1]), + .q (reg2hw.mio_pad_attr[21].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_21_virtual_od_en_21_qs) + ); + assign reg2hw.mio_pad_attr[21].virtual_od_en.qe = mio_pad_attr_21_qe; + + // F[pull_en_21]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_pull_en_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_pull_en_21_wd), + .d (hw2reg.mio_pad_attr[21].pull_en.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[2]), + .q (reg2hw.mio_pad_attr[21].pull_en.q), + .ds (), + .qs (mio_pad_attr_21_pull_en_21_qs) + ); + assign reg2hw.mio_pad_attr[21].pull_en.qe = mio_pad_attr_21_qe; + + // F[pull_select_21]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_pull_select_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_pull_select_21_wd), + .d (hw2reg.mio_pad_attr[21].pull_select.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[3]), + .q (reg2hw.mio_pad_attr[21].pull_select.q), + .ds (), + .qs (mio_pad_attr_21_pull_select_21_qs) + ); + assign reg2hw.mio_pad_attr[21].pull_select.qe = mio_pad_attr_21_qe; + + // F[keeper_en_21]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_keeper_en_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_keeper_en_21_wd), + .d (hw2reg.mio_pad_attr[21].keeper_en.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[4]), + .q (reg2hw.mio_pad_attr[21].keeper_en.q), + .ds (), + .qs (mio_pad_attr_21_keeper_en_21_qs) + ); + assign reg2hw.mio_pad_attr[21].keeper_en.qe = mio_pad_attr_21_qe; + + // F[schmitt_en_21]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_schmitt_en_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_schmitt_en_21_wd), + .d (hw2reg.mio_pad_attr[21].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[5]), + .q (reg2hw.mio_pad_attr[21].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_21_schmitt_en_21_qs) + ); + assign reg2hw.mio_pad_attr[21].schmitt_en.qe = mio_pad_attr_21_qe; + + // F[od_en_21]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_od_en_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_od_en_21_wd), + .d (hw2reg.mio_pad_attr[21].od_en.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[6]), + .q (reg2hw.mio_pad_attr[21].od_en.q), + .ds (), + .qs (mio_pad_attr_21_od_en_21_qs) + ); + assign reg2hw.mio_pad_attr[21].od_en.qe = mio_pad_attr_21_qe; + + // F[input_disable_21]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_21_input_disable_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_input_disable_21_wd), + .d (hw2reg.mio_pad_attr[21].input_disable.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[7]), + .q (reg2hw.mio_pad_attr[21].input_disable.q), + .ds (), + .qs (mio_pad_attr_21_input_disable_21_qs) + ); + assign reg2hw.mio_pad_attr[21].input_disable.qe = mio_pad_attr_21_qe; + + // F[slew_rate_21]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_21_slew_rate_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_slew_rate_21_wd), + .d (hw2reg.mio_pad_attr[21].slew_rate.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[8]), + .q (reg2hw.mio_pad_attr[21].slew_rate.q), + .ds (), + .qs (mio_pad_attr_21_slew_rate_21_qs) + ); + assign reg2hw.mio_pad_attr[21].slew_rate.qe = mio_pad_attr_21_qe; + + // F[drive_strength_21]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_21_drive_strength_21 ( + .re (mio_pad_attr_21_re), + .we (mio_pad_attr_21_gated_we), + .wd (mio_pad_attr_21_drive_strength_21_wd), + .d (hw2reg.mio_pad_attr[21].drive_strength.d), + .qre (), + .qe (mio_pad_attr_21_flds_we[9]), + .q (reg2hw.mio_pad_attr[21].drive_strength.q), + .ds (), + .qs (mio_pad_attr_21_drive_strength_21_qs) + ); + assign reg2hw.mio_pad_attr[21].drive_strength.qe = mio_pad_attr_21_qe; + + + // Subregister 22 of Multireg mio_pad_attr + // R[mio_pad_attr_22]: V(True) + logic mio_pad_attr_22_qe; + logic [9:0] mio_pad_attr_22_flds_we; + assign mio_pad_attr_22_qe = &mio_pad_attr_22_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_22_gated_we; + assign mio_pad_attr_22_gated_we = mio_pad_attr_22_we & mio_pad_attr_regwen_22_qs; + // F[invert_22]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_invert_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_invert_22_wd), + .d (hw2reg.mio_pad_attr[22].invert.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[0]), + .q (reg2hw.mio_pad_attr[22].invert.q), + .ds (), + .qs (mio_pad_attr_22_invert_22_qs) + ); + assign reg2hw.mio_pad_attr[22].invert.qe = mio_pad_attr_22_qe; + + // F[virtual_od_en_22]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_virtual_od_en_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_virtual_od_en_22_wd), + .d (hw2reg.mio_pad_attr[22].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[1]), + .q (reg2hw.mio_pad_attr[22].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_22_virtual_od_en_22_qs) + ); + assign reg2hw.mio_pad_attr[22].virtual_od_en.qe = mio_pad_attr_22_qe; + + // F[pull_en_22]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_pull_en_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_pull_en_22_wd), + .d (hw2reg.mio_pad_attr[22].pull_en.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[2]), + .q (reg2hw.mio_pad_attr[22].pull_en.q), + .ds (), + .qs (mio_pad_attr_22_pull_en_22_qs) + ); + assign reg2hw.mio_pad_attr[22].pull_en.qe = mio_pad_attr_22_qe; + + // F[pull_select_22]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_pull_select_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_pull_select_22_wd), + .d (hw2reg.mio_pad_attr[22].pull_select.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[3]), + .q (reg2hw.mio_pad_attr[22].pull_select.q), + .ds (), + .qs (mio_pad_attr_22_pull_select_22_qs) + ); + assign reg2hw.mio_pad_attr[22].pull_select.qe = mio_pad_attr_22_qe; + + // F[keeper_en_22]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_keeper_en_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_keeper_en_22_wd), + .d (hw2reg.mio_pad_attr[22].keeper_en.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[4]), + .q (reg2hw.mio_pad_attr[22].keeper_en.q), + .ds (), + .qs (mio_pad_attr_22_keeper_en_22_qs) + ); + assign reg2hw.mio_pad_attr[22].keeper_en.qe = mio_pad_attr_22_qe; + + // F[schmitt_en_22]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_schmitt_en_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_schmitt_en_22_wd), + .d (hw2reg.mio_pad_attr[22].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[5]), + .q (reg2hw.mio_pad_attr[22].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_22_schmitt_en_22_qs) + ); + assign reg2hw.mio_pad_attr[22].schmitt_en.qe = mio_pad_attr_22_qe; + + // F[od_en_22]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_od_en_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_od_en_22_wd), + .d (hw2reg.mio_pad_attr[22].od_en.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[6]), + .q (reg2hw.mio_pad_attr[22].od_en.q), + .ds (), + .qs (mio_pad_attr_22_od_en_22_qs) + ); + assign reg2hw.mio_pad_attr[22].od_en.qe = mio_pad_attr_22_qe; + + // F[input_disable_22]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_22_input_disable_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_input_disable_22_wd), + .d (hw2reg.mio_pad_attr[22].input_disable.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[7]), + .q (reg2hw.mio_pad_attr[22].input_disable.q), + .ds (), + .qs (mio_pad_attr_22_input_disable_22_qs) + ); + assign reg2hw.mio_pad_attr[22].input_disable.qe = mio_pad_attr_22_qe; + + // F[slew_rate_22]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_22_slew_rate_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_slew_rate_22_wd), + .d (hw2reg.mio_pad_attr[22].slew_rate.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[8]), + .q (reg2hw.mio_pad_attr[22].slew_rate.q), + .ds (), + .qs (mio_pad_attr_22_slew_rate_22_qs) + ); + assign reg2hw.mio_pad_attr[22].slew_rate.qe = mio_pad_attr_22_qe; + + // F[drive_strength_22]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_22_drive_strength_22 ( + .re (mio_pad_attr_22_re), + .we (mio_pad_attr_22_gated_we), + .wd (mio_pad_attr_22_drive_strength_22_wd), + .d (hw2reg.mio_pad_attr[22].drive_strength.d), + .qre (), + .qe (mio_pad_attr_22_flds_we[9]), + .q (reg2hw.mio_pad_attr[22].drive_strength.q), + .ds (), + .qs (mio_pad_attr_22_drive_strength_22_qs) + ); + assign reg2hw.mio_pad_attr[22].drive_strength.qe = mio_pad_attr_22_qe; + + + // Subregister 23 of Multireg mio_pad_attr + // R[mio_pad_attr_23]: V(True) + logic mio_pad_attr_23_qe; + logic [9:0] mio_pad_attr_23_flds_we; + assign mio_pad_attr_23_qe = &mio_pad_attr_23_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_23_gated_we; + assign mio_pad_attr_23_gated_we = mio_pad_attr_23_we & mio_pad_attr_regwen_23_qs; + // F[invert_23]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_invert_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_invert_23_wd), + .d (hw2reg.mio_pad_attr[23].invert.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[0]), + .q (reg2hw.mio_pad_attr[23].invert.q), + .ds (), + .qs (mio_pad_attr_23_invert_23_qs) + ); + assign reg2hw.mio_pad_attr[23].invert.qe = mio_pad_attr_23_qe; + + // F[virtual_od_en_23]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_virtual_od_en_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_virtual_od_en_23_wd), + .d (hw2reg.mio_pad_attr[23].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[1]), + .q (reg2hw.mio_pad_attr[23].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_23_virtual_od_en_23_qs) + ); + assign reg2hw.mio_pad_attr[23].virtual_od_en.qe = mio_pad_attr_23_qe; + + // F[pull_en_23]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_pull_en_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_pull_en_23_wd), + .d (hw2reg.mio_pad_attr[23].pull_en.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[2]), + .q (reg2hw.mio_pad_attr[23].pull_en.q), + .ds (), + .qs (mio_pad_attr_23_pull_en_23_qs) + ); + assign reg2hw.mio_pad_attr[23].pull_en.qe = mio_pad_attr_23_qe; + + // F[pull_select_23]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_pull_select_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_pull_select_23_wd), + .d (hw2reg.mio_pad_attr[23].pull_select.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[3]), + .q (reg2hw.mio_pad_attr[23].pull_select.q), + .ds (), + .qs (mio_pad_attr_23_pull_select_23_qs) + ); + assign reg2hw.mio_pad_attr[23].pull_select.qe = mio_pad_attr_23_qe; + + // F[keeper_en_23]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_keeper_en_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_keeper_en_23_wd), + .d (hw2reg.mio_pad_attr[23].keeper_en.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[4]), + .q (reg2hw.mio_pad_attr[23].keeper_en.q), + .ds (), + .qs (mio_pad_attr_23_keeper_en_23_qs) + ); + assign reg2hw.mio_pad_attr[23].keeper_en.qe = mio_pad_attr_23_qe; + + // F[schmitt_en_23]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_schmitt_en_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_schmitt_en_23_wd), + .d (hw2reg.mio_pad_attr[23].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[5]), + .q (reg2hw.mio_pad_attr[23].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_23_schmitt_en_23_qs) + ); + assign reg2hw.mio_pad_attr[23].schmitt_en.qe = mio_pad_attr_23_qe; + + // F[od_en_23]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_od_en_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_od_en_23_wd), + .d (hw2reg.mio_pad_attr[23].od_en.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[6]), + .q (reg2hw.mio_pad_attr[23].od_en.q), + .ds (), + .qs (mio_pad_attr_23_od_en_23_qs) + ); + assign reg2hw.mio_pad_attr[23].od_en.qe = mio_pad_attr_23_qe; + + // F[input_disable_23]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_23_input_disable_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_input_disable_23_wd), + .d (hw2reg.mio_pad_attr[23].input_disable.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[7]), + .q (reg2hw.mio_pad_attr[23].input_disable.q), + .ds (), + .qs (mio_pad_attr_23_input_disable_23_qs) + ); + assign reg2hw.mio_pad_attr[23].input_disable.qe = mio_pad_attr_23_qe; + + // F[slew_rate_23]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_23_slew_rate_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_slew_rate_23_wd), + .d (hw2reg.mio_pad_attr[23].slew_rate.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[8]), + .q (reg2hw.mio_pad_attr[23].slew_rate.q), + .ds (), + .qs (mio_pad_attr_23_slew_rate_23_qs) + ); + assign reg2hw.mio_pad_attr[23].slew_rate.qe = mio_pad_attr_23_qe; + + // F[drive_strength_23]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_23_drive_strength_23 ( + .re (mio_pad_attr_23_re), + .we (mio_pad_attr_23_gated_we), + .wd (mio_pad_attr_23_drive_strength_23_wd), + .d (hw2reg.mio_pad_attr[23].drive_strength.d), + .qre (), + .qe (mio_pad_attr_23_flds_we[9]), + .q (reg2hw.mio_pad_attr[23].drive_strength.q), + .ds (), + .qs (mio_pad_attr_23_drive_strength_23_qs) + ); + assign reg2hw.mio_pad_attr[23].drive_strength.qe = mio_pad_attr_23_qe; + + + // Subregister 24 of Multireg mio_pad_attr + // R[mio_pad_attr_24]: V(True) + logic mio_pad_attr_24_qe; + logic [9:0] mio_pad_attr_24_flds_we; + assign mio_pad_attr_24_qe = &mio_pad_attr_24_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_24_gated_we; + assign mio_pad_attr_24_gated_we = mio_pad_attr_24_we & mio_pad_attr_regwen_24_qs; + // F[invert_24]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_invert_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_invert_24_wd), + .d (hw2reg.mio_pad_attr[24].invert.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[0]), + .q (reg2hw.mio_pad_attr[24].invert.q), + .ds (), + .qs (mio_pad_attr_24_invert_24_qs) + ); + assign reg2hw.mio_pad_attr[24].invert.qe = mio_pad_attr_24_qe; + + // F[virtual_od_en_24]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_virtual_od_en_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_virtual_od_en_24_wd), + .d (hw2reg.mio_pad_attr[24].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[1]), + .q (reg2hw.mio_pad_attr[24].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_24_virtual_od_en_24_qs) + ); + assign reg2hw.mio_pad_attr[24].virtual_od_en.qe = mio_pad_attr_24_qe; + + // F[pull_en_24]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_pull_en_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_pull_en_24_wd), + .d (hw2reg.mio_pad_attr[24].pull_en.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[2]), + .q (reg2hw.mio_pad_attr[24].pull_en.q), + .ds (), + .qs (mio_pad_attr_24_pull_en_24_qs) + ); + assign reg2hw.mio_pad_attr[24].pull_en.qe = mio_pad_attr_24_qe; + + // F[pull_select_24]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_pull_select_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_pull_select_24_wd), + .d (hw2reg.mio_pad_attr[24].pull_select.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[3]), + .q (reg2hw.mio_pad_attr[24].pull_select.q), + .ds (), + .qs (mio_pad_attr_24_pull_select_24_qs) + ); + assign reg2hw.mio_pad_attr[24].pull_select.qe = mio_pad_attr_24_qe; + + // F[keeper_en_24]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_keeper_en_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_keeper_en_24_wd), + .d (hw2reg.mio_pad_attr[24].keeper_en.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[4]), + .q (reg2hw.mio_pad_attr[24].keeper_en.q), + .ds (), + .qs (mio_pad_attr_24_keeper_en_24_qs) + ); + assign reg2hw.mio_pad_attr[24].keeper_en.qe = mio_pad_attr_24_qe; + + // F[schmitt_en_24]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_schmitt_en_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_schmitt_en_24_wd), + .d (hw2reg.mio_pad_attr[24].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[5]), + .q (reg2hw.mio_pad_attr[24].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_24_schmitt_en_24_qs) + ); + assign reg2hw.mio_pad_attr[24].schmitt_en.qe = mio_pad_attr_24_qe; + + // F[od_en_24]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_od_en_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_od_en_24_wd), + .d (hw2reg.mio_pad_attr[24].od_en.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[6]), + .q (reg2hw.mio_pad_attr[24].od_en.q), + .ds (), + .qs (mio_pad_attr_24_od_en_24_qs) + ); + assign reg2hw.mio_pad_attr[24].od_en.qe = mio_pad_attr_24_qe; + + // F[input_disable_24]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_24_input_disable_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_input_disable_24_wd), + .d (hw2reg.mio_pad_attr[24].input_disable.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[7]), + .q (reg2hw.mio_pad_attr[24].input_disable.q), + .ds (), + .qs (mio_pad_attr_24_input_disable_24_qs) + ); + assign reg2hw.mio_pad_attr[24].input_disable.qe = mio_pad_attr_24_qe; + + // F[slew_rate_24]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_24_slew_rate_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_slew_rate_24_wd), + .d (hw2reg.mio_pad_attr[24].slew_rate.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[8]), + .q (reg2hw.mio_pad_attr[24].slew_rate.q), + .ds (), + .qs (mio_pad_attr_24_slew_rate_24_qs) + ); + assign reg2hw.mio_pad_attr[24].slew_rate.qe = mio_pad_attr_24_qe; + + // F[drive_strength_24]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_24_drive_strength_24 ( + .re (mio_pad_attr_24_re), + .we (mio_pad_attr_24_gated_we), + .wd (mio_pad_attr_24_drive_strength_24_wd), + .d (hw2reg.mio_pad_attr[24].drive_strength.d), + .qre (), + .qe (mio_pad_attr_24_flds_we[9]), + .q (reg2hw.mio_pad_attr[24].drive_strength.q), + .ds (), + .qs (mio_pad_attr_24_drive_strength_24_qs) + ); + assign reg2hw.mio_pad_attr[24].drive_strength.qe = mio_pad_attr_24_qe; + + + // Subregister 25 of Multireg mio_pad_attr + // R[mio_pad_attr_25]: V(True) + logic mio_pad_attr_25_qe; + logic [9:0] mio_pad_attr_25_flds_we; + assign mio_pad_attr_25_qe = &mio_pad_attr_25_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_25_gated_we; + assign mio_pad_attr_25_gated_we = mio_pad_attr_25_we & mio_pad_attr_regwen_25_qs; + // F[invert_25]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_invert_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_invert_25_wd), + .d (hw2reg.mio_pad_attr[25].invert.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[0]), + .q (reg2hw.mio_pad_attr[25].invert.q), + .ds (), + .qs (mio_pad_attr_25_invert_25_qs) + ); + assign reg2hw.mio_pad_attr[25].invert.qe = mio_pad_attr_25_qe; + + // F[virtual_od_en_25]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_virtual_od_en_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_virtual_od_en_25_wd), + .d (hw2reg.mio_pad_attr[25].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[1]), + .q (reg2hw.mio_pad_attr[25].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_25_virtual_od_en_25_qs) + ); + assign reg2hw.mio_pad_attr[25].virtual_od_en.qe = mio_pad_attr_25_qe; + + // F[pull_en_25]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_pull_en_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_pull_en_25_wd), + .d (hw2reg.mio_pad_attr[25].pull_en.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[2]), + .q (reg2hw.mio_pad_attr[25].pull_en.q), + .ds (), + .qs (mio_pad_attr_25_pull_en_25_qs) + ); + assign reg2hw.mio_pad_attr[25].pull_en.qe = mio_pad_attr_25_qe; + + // F[pull_select_25]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_pull_select_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_pull_select_25_wd), + .d (hw2reg.mio_pad_attr[25].pull_select.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[3]), + .q (reg2hw.mio_pad_attr[25].pull_select.q), + .ds (), + .qs (mio_pad_attr_25_pull_select_25_qs) + ); + assign reg2hw.mio_pad_attr[25].pull_select.qe = mio_pad_attr_25_qe; + + // F[keeper_en_25]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_keeper_en_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_keeper_en_25_wd), + .d (hw2reg.mio_pad_attr[25].keeper_en.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[4]), + .q (reg2hw.mio_pad_attr[25].keeper_en.q), + .ds (), + .qs (mio_pad_attr_25_keeper_en_25_qs) + ); + assign reg2hw.mio_pad_attr[25].keeper_en.qe = mio_pad_attr_25_qe; + + // F[schmitt_en_25]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_schmitt_en_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_schmitt_en_25_wd), + .d (hw2reg.mio_pad_attr[25].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[5]), + .q (reg2hw.mio_pad_attr[25].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_25_schmitt_en_25_qs) + ); + assign reg2hw.mio_pad_attr[25].schmitt_en.qe = mio_pad_attr_25_qe; + + // F[od_en_25]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_od_en_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_od_en_25_wd), + .d (hw2reg.mio_pad_attr[25].od_en.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[6]), + .q (reg2hw.mio_pad_attr[25].od_en.q), + .ds (), + .qs (mio_pad_attr_25_od_en_25_qs) + ); + assign reg2hw.mio_pad_attr[25].od_en.qe = mio_pad_attr_25_qe; + + // F[input_disable_25]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_25_input_disable_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_input_disable_25_wd), + .d (hw2reg.mio_pad_attr[25].input_disable.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[7]), + .q (reg2hw.mio_pad_attr[25].input_disable.q), + .ds (), + .qs (mio_pad_attr_25_input_disable_25_qs) + ); + assign reg2hw.mio_pad_attr[25].input_disable.qe = mio_pad_attr_25_qe; + + // F[slew_rate_25]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_25_slew_rate_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_slew_rate_25_wd), + .d (hw2reg.mio_pad_attr[25].slew_rate.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[8]), + .q (reg2hw.mio_pad_attr[25].slew_rate.q), + .ds (), + .qs (mio_pad_attr_25_slew_rate_25_qs) + ); + assign reg2hw.mio_pad_attr[25].slew_rate.qe = mio_pad_attr_25_qe; + + // F[drive_strength_25]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_25_drive_strength_25 ( + .re (mio_pad_attr_25_re), + .we (mio_pad_attr_25_gated_we), + .wd (mio_pad_attr_25_drive_strength_25_wd), + .d (hw2reg.mio_pad_attr[25].drive_strength.d), + .qre (), + .qe (mio_pad_attr_25_flds_we[9]), + .q (reg2hw.mio_pad_attr[25].drive_strength.q), + .ds (), + .qs (mio_pad_attr_25_drive_strength_25_qs) + ); + assign reg2hw.mio_pad_attr[25].drive_strength.qe = mio_pad_attr_25_qe; + + + // Subregister 26 of Multireg mio_pad_attr + // R[mio_pad_attr_26]: V(True) + logic mio_pad_attr_26_qe; + logic [9:0] mio_pad_attr_26_flds_we; + assign mio_pad_attr_26_qe = &mio_pad_attr_26_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_26_gated_we; + assign mio_pad_attr_26_gated_we = mio_pad_attr_26_we & mio_pad_attr_regwen_26_qs; + // F[invert_26]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_invert_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_invert_26_wd), + .d (hw2reg.mio_pad_attr[26].invert.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[0]), + .q (reg2hw.mio_pad_attr[26].invert.q), + .ds (), + .qs (mio_pad_attr_26_invert_26_qs) + ); + assign reg2hw.mio_pad_attr[26].invert.qe = mio_pad_attr_26_qe; + + // F[virtual_od_en_26]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_virtual_od_en_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_virtual_od_en_26_wd), + .d (hw2reg.mio_pad_attr[26].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[1]), + .q (reg2hw.mio_pad_attr[26].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_26_virtual_od_en_26_qs) + ); + assign reg2hw.mio_pad_attr[26].virtual_od_en.qe = mio_pad_attr_26_qe; + + // F[pull_en_26]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_pull_en_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_pull_en_26_wd), + .d (hw2reg.mio_pad_attr[26].pull_en.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[2]), + .q (reg2hw.mio_pad_attr[26].pull_en.q), + .ds (), + .qs (mio_pad_attr_26_pull_en_26_qs) + ); + assign reg2hw.mio_pad_attr[26].pull_en.qe = mio_pad_attr_26_qe; + + // F[pull_select_26]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_pull_select_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_pull_select_26_wd), + .d (hw2reg.mio_pad_attr[26].pull_select.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[3]), + .q (reg2hw.mio_pad_attr[26].pull_select.q), + .ds (), + .qs (mio_pad_attr_26_pull_select_26_qs) + ); + assign reg2hw.mio_pad_attr[26].pull_select.qe = mio_pad_attr_26_qe; + + // F[keeper_en_26]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_keeper_en_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_keeper_en_26_wd), + .d (hw2reg.mio_pad_attr[26].keeper_en.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[4]), + .q (reg2hw.mio_pad_attr[26].keeper_en.q), + .ds (), + .qs (mio_pad_attr_26_keeper_en_26_qs) + ); + assign reg2hw.mio_pad_attr[26].keeper_en.qe = mio_pad_attr_26_qe; + + // F[schmitt_en_26]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_schmitt_en_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_schmitt_en_26_wd), + .d (hw2reg.mio_pad_attr[26].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[5]), + .q (reg2hw.mio_pad_attr[26].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_26_schmitt_en_26_qs) + ); + assign reg2hw.mio_pad_attr[26].schmitt_en.qe = mio_pad_attr_26_qe; + + // F[od_en_26]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_od_en_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_od_en_26_wd), + .d (hw2reg.mio_pad_attr[26].od_en.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[6]), + .q (reg2hw.mio_pad_attr[26].od_en.q), + .ds (), + .qs (mio_pad_attr_26_od_en_26_qs) + ); + assign reg2hw.mio_pad_attr[26].od_en.qe = mio_pad_attr_26_qe; + + // F[input_disable_26]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_26_input_disable_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_input_disable_26_wd), + .d (hw2reg.mio_pad_attr[26].input_disable.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[7]), + .q (reg2hw.mio_pad_attr[26].input_disable.q), + .ds (), + .qs (mio_pad_attr_26_input_disable_26_qs) + ); + assign reg2hw.mio_pad_attr[26].input_disable.qe = mio_pad_attr_26_qe; + + // F[slew_rate_26]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_26_slew_rate_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_slew_rate_26_wd), + .d (hw2reg.mio_pad_attr[26].slew_rate.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[8]), + .q (reg2hw.mio_pad_attr[26].slew_rate.q), + .ds (), + .qs (mio_pad_attr_26_slew_rate_26_qs) + ); + assign reg2hw.mio_pad_attr[26].slew_rate.qe = mio_pad_attr_26_qe; + + // F[drive_strength_26]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_26_drive_strength_26 ( + .re (mio_pad_attr_26_re), + .we (mio_pad_attr_26_gated_we), + .wd (mio_pad_attr_26_drive_strength_26_wd), + .d (hw2reg.mio_pad_attr[26].drive_strength.d), + .qre (), + .qe (mio_pad_attr_26_flds_we[9]), + .q (reg2hw.mio_pad_attr[26].drive_strength.q), + .ds (), + .qs (mio_pad_attr_26_drive_strength_26_qs) + ); + assign reg2hw.mio_pad_attr[26].drive_strength.qe = mio_pad_attr_26_qe; + + + // Subregister 27 of Multireg mio_pad_attr + // R[mio_pad_attr_27]: V(True) + logic mio_pad_attr_27_qe; + logic [9:0] mio_pad_attr_27_flds_we; + assign mio_pad_attr_27_qe = &mio_pad_attr_27_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_27_gated_we; + assign mio_pad_attr_27_gated_we = mio_pad_attr_27_we & mio_pad_attr_regwen_27_qs; + // F[invert_27]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_invert_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_invert_27_wd), + .d (hw2reg.mio_pad_attr[27].invert.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[0]), + .q (reg2hw.mio_pad_attr[27].invert.q), + .ds (), + .qs (mio_pad_attr_27_invert_27_qs) + ); + assign reg2hw.mio_pad_attr[27].invert.qe = mio_pad_attr_27_qe; + + // F[virtual_od_en_27]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_virtual_od_en_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_virtual_od_en_27_wd), + .d (hw2reg.mio_pad_attr[27].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[1]), + .q (reg2hw.mio_pad_attr[27].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_27_virtual_od_en_27_qs) + ); + assign reg2hw.mio_pad_attr[27].virtual_od_en.qe = mio_pad_attr_27_qe; + + // F[pull_en_27]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_pull_en_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_pull_en_27_wd), + .d (hw2reg.mio_pad_attr[27].pull_en.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[2]), + .q (reg2hw.mio_pad_attr[27].pull_en.q), + .ds (), + .qs (mio_pad_attr_27_pull_en_27_qs) + ); + assign reg2hw.mio_pad_attr[27].pull_en.qe = mio_pad_attr_27_qe; + + // F[pull_select_27]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_pull_select_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_pull_select_27_wd), + .d (hw2reg.mio_pad_attr[27].pull_select.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[3]), + .q (reg2hw.mio_pad_attr[27].pull_select.q), + .ds (), + .qs (mio_pad_attr_27_pull_select_27_qs) + ); + assign reg2hw.mio_pad_attr[27].pull_select.qe = mio_pad_attr_27_qe; + + // F[keeper_en_27]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_keeper_en_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_keeper_en_27_wd), + .d (hw2reg.mio_pad_attr[27].keeper_en.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[4]), + .q (reg2hw.mio_pad_attr[27].keeper_en.q), + .ds (), + .qs (mio_pad_attr_27_keeper_en_27_qs) + ); + assign reg2hw.mio_pad_attr[27].keeper_en.qe = mio_pad_attr_27_qe; + + // F[schmitt_en_27]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_schmitt_en_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_schmitt_en_27_wd), + .d (hw2reg.mio_pad_attr[27].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[5]), + .q (reg2hw.mio_pad_attr[27].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_27_schmitt_en_27_qs) + ); + assign reg2hw.mio_pad_attr[27].schmitt_en.qe = mio_pad_attr_27_qe; + + // F[od_en_27]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_od_en_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_od_en_27_wd), + .d (hw2reg.mio_pad_attr[27].od_en.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[6]), + .q (reg2hw.mio_pad_attr[27].od_en.q), + .ds (), + .qs (mio_pad_attr_27_od_en_27_qs) + ); + assign reg2hw.mio_pad_attr[27].od_en.qe = mio_pad_attr_27_qe; + + // F[input_disable_27]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_27_input_disable_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_input_disable_27_wd), + .d (hw2reg.mio_pad_attr[27].input_disable.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[7]), + .q (reg2hw.mio_pad_attr[27].input_disable.q), + .ds (), + .qs (mio_pad_attr_27_input_disable_27_qs) + ); + assign reg2hw.mio_pad_attr[27].input_disable.qe = mio_pad_attr_27_qe; + + // F[slew_rate_27]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_27_slew_rate_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_slew_rate_27_wd), + .d (hw2reg.mio_pad_attr[27].slew_rate.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[8]), + .q (reg2hw.mio_pad_attr[27].slew_rate.q), + .ds (), + .qs (mio_pad_attr_27_slew_rate_27_qs) + ); + assign reg2hw.mio_pad_attr[27].slew_rate.qe = mio_pad_attr_27_qe; + + // F[drive_strength_27]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_27_drive_strength_27 ( + .re (mio_pad_attr_27_re), + .we (mio_pad_attr_27_gated_we), + .wd (mio_pad_attr_27_drive_strength_27_wd), + .d (hw2reg.mio_pad_attr[27].drive_strength.d), + .qre (), + .qe (mio_pad_attr_27_flds_we[9]), + .q (reg2hw.mio_pad_attr[27].drive_strength.q), + .ds (), + .qs (mio_pad_attr_27_drive_strength_27_qs) + ); + assign reg2hw.mio_pad_attr[27].drive_strength.qe = mio_pad_attr_27_qe; + + + // Subregister 28 of Multireg mio_pad_attr + // R[mio_pad_attr_28]: V(True) + logic mio_pad_attr_28_qe; + logic [9:0] mio_pad_attr_28_flds_we; + assign mio_pad_attr_28_qe = &mio_pad_attr_28_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_28_gated_we; + assign mio_pad_attr_28_gated_we = mio_pad_attr_28_we & mio_pad_attr_regwen_28_qs; + // F[invert_28]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_invert_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_invert_28_wd), + .d (hw2reg.mio_pad_attr[28].invert.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[0]), + .q (reg2hw.mio_pad_attr[28].invert.q), + .ds (), + .qs (mio_pad_attr_28_invert_28_qs) + ); + assign reg2hw.mio_pad_attr[28].invert.qe = mio_pad_attr_28_qe; + + // F[virtual_od_en_28]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_virtual_od_en_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_virtual_od_en_28_wd), + .d (hw2reg.mio_pad_attr[28].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[1]), + .q (reg2hw.mio_pad_attr[28].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_28_virtual_od_en_28_qs) + ); + assign reg2hw.mio_pad_attr[28].virtual_od_en.qe = mio_pad_attr_28_qe; + + // F[pull_en_28]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_pull_en_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_pull_en_28_wd), + .d (hw2reg.mio_pad_attr[28].pull_en.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[2]), + .q (reg2hw.mio_pad_attr[28].pull_en.q), + .ds (), + .qs (mio_pad_attr_28_pull_en_28_qs) + ); + assign reg2hw.mio_pad_attr[28].pull_en.qe = mio_pad_attr_28_qe; + + // F[pull_select_28]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_pull_select_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_pull_select_28_wd), + .d (hw2reg.mio_pad_attr[28].pull_select.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[3]), + .q (reg2hw.mio_pad_attr[28].pull_select.q), + .ds (), + .qs (mio_pad_attr_28_pull_select_28_qs) + ); + assign reg2hw.mio_pad_attr[28].pull_select.qe = mio_pad_attr_28_qe; + + // F[keeper_en_28]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_keeper_en_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_keeper_en_28_wd), + .d (hw2reg.mio_pad_attr[28].keeper_en.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[4]), + .q (reg2hw.mio_pad_attr[28].keeper_en.q), + .ds (), + .qs (mio_pad_attr_28_keeper_en_28_qs) + ); + assign reg2hw.mio_pad_attr[28].keeper_en.qe = mio_pad_attr_28_qe; + + // F[schmitt_en_28]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_schmitt_en_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_schmitt_en_28_wd), + .d (hw2reg.mio_pad_attr[28].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[5]), + .q (reg2hw.mio_pad_attr[28].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_28_schmitt_en_28_qs) + ); + assign reg2hw.mio_pad_attr[28].schmitt_en.qe = mio_pad_attr_28_qe; + + // F[od_en_28]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_od_en_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_od_en_28_wd), + .d (hw2reg.mio_pad_attr[28].od_en.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[6]), + .q (reg2hw.mio_pad_attr[28].od_en.q), + .ds (), + .qs (mio_pad_attr_28_od_en_28_qs) + ); + assign reg2hw.mio_pad_attr[28].od_en.qe = mio_pad_attr_28_qe; + + // F[input_disable_28]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_28_input_disable_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_input_disable_28_wd), + .d (hw2reg.mio_pad_attr[28].input_disable.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[7]), + .q (reg2hw.mio_pad_attr[28].input_disable.q), + .ds (), + .qs (mio_pad_attr_28_input_disable_28_qs) + ); + assign reg2hw.mio_pad_attr[28].input_disable.qe = mio_pad_attr_28_qe; + + // F[slew_rate_28]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_28_slew_rate_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_slew_rate_28_wd), + .d (hw2reg.mio_pad_attr[28].slew_rate.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[8]), + .q (reg2hw.mio_pad_attr[28].slew_rate.q), + .ds (), + .qs (mio_pad_attr_28_slew_rate_28_qs) + ); + assign reg2hw.mio_pad_attr[28].slew_rate.qe = mio_pad_attr_28_qe; + + // F[drive_strength_28]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_28_drive_strength_28 ( + .re (mio_pad_attr_28_re), + .we (mio_pad_attr_28_gated_we), + .wd (mio_pad_attr_28_drive_strength_28_wd), + .d (hw2reg.mio_pad_attr[28].drive_strength.d), + .qre (), + .qe (mio_pad_attr_28_flds_we[9]), + .q (reg2hw.mio_pad_attr[28].drive_strength.q), + .ds (), + .qs (mio_pad_attr_28_drive_strength_28_qs) + ); + assign reg2hw.mio_pad_attr[28].drive_strength.qe = mio_pad_attr_28_qe; + + + // Subregister 29 of Multireg mio_pad_attr + // R[mio_pad_attr_29]: V(True) + logic mio_pad_attr_29_qe; + logic [9:0] mio_pad_attr_29_flds_we; + assign mio_pad_attr_29_qe = &mio_pad_attr_29_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_29_gated_we; + assign mio_pad_attr_29_gated_we = mio_pad_attr_29_we & mio_pad_attr_regwen_29_qs; + // F[invert_29]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_invert_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_invert_29_wd), + .d (hw2reg.mio_pad_attr[29].invert.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[0]), + .q (reg2hw.mio_pad_attr[29].invert.q), + .ds (), + .qs (mio_pad_attr_29_invert_29_qs) + ); + assign reg2hw.mio_pad_attr[29].invert.qe = mio_pad_attr_29_qe; + + // F[virtual_od_en_29]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_virtual_od_en_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_virtual_od_en_29_wd), + .d (hw2reg.mio_pad_attr[29].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[1]), + .q (reg2hw.mio_pad_attr[29].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_29_virtual_od_en_29_qs) + ); + assign reg2hw.mio_pad_attr[29].virtual_od_en.qe = mio_pad_attr_29_qe; + + // F[pull_en_29]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_pull_en_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_pull_en_29_wd), + .d (hw2reg.mio_pad_attr[29].pull_en.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[2]), + .q (reg2hw.mio_pad_attr[29].pull_en.q), + .ds (), + .qs (mio_pad_attr_29_pull_en_29_qs) + ); + assign reg2hw.mio_pad_attr[29].pull_en.qe = mio_pad_attr_29_qe; + + // F[pull_select_29]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_pull_select_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_pull_select_29_wd), + .d (hw2reg.mio_pad_attr[29].pull_select.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[3]), + .q (reg2hw.mio_pad_attr[29].pull_select.q), + .ds (), + .qs (mio_pad_attr_29_pull_select_29_qs) + ); + assign reg2hw.mio_pad_attr[29].pull_select.qe = mio_pad_attr_29_qe; + + // F[keeper_en_29]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_keeper_en_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_keeper_en_29_wd), + .d (hw2reg.mio_pad_attr[29].keeper_en.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[4]), + .q (reg2hw.mio_pad_attr[29].keeper_en.q), + .ds (), + .qs (mio_pad_attr_29_keeper_en_29_qs) + ); + assign reg2hw.mio_pad_attr[29].keeper_en.qe = mio_pad_attr_29_qe; + + // F[schmitt_en_29]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_schmitt_en_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_schmitt_en_29_wd), + .d (hw2reg.mio_pad_attr[29].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[5]), + .q (reg2hw.mio_pad_attr[29].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_29_schmitt_en_29_qs) + ); + assign reg2hw.mio_pad_attr[29].schmitt_en.qe = mio_pad_attr_29_qe; + + // F[od_en_29]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_od_en_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_od_en_29_wd), + .d (hw2reg.mio_pad_attr[29].od_en.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[6]), + .q (reg2hw.mio_pad_attr[29].od_en.q), + .ds (), + .qs (mio_pad_attr_29_od_en_29_qs) + ); + assign reg2hw.mio_pad_attr[29].od_en.qe = mio_pad_attr_29_qe; + + // F[input_disable_29]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_29_input_disable_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_input_disable_29_wd), + .d (hw2reg.mio_pad_attr[29].input_disable.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[7]), + .q (reg2hw.mio_pad_attr[29].input_disable.q), + .ds (), + .qs (mio_pad_attr_29_input_disable_29_qs) + ); + assign reg2hw.mio_pad_attr[29].input_disable.qe = mio_pad_attr_29_qe; + + // F[slew_rate_29]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_29_slew_rate_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_slew_rate_29_wd), + .d (hw2reg.mio_pad_attr[29].slew_rate.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[8]), + .q (reg2hw.mio_pad_attr[29].slew_rate.q), + .ds (), + .qs (mio_pad_attr_29_slew_rate_29_qs) + ); + assign reg2hw.mio_pad_attr[29].slew_rate.qe = mio_pad_attr_29_qe; + + // F[drive_strength_29]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_29_drive_strength_29 ( + .re (mio_pad_attr_29_re), + .we (mio_pad_attr_29_gated_we), + .wd (mio_pad_attr_29_drive_strength_29_wd), + .d (hw2reg.mio_pad_attr[29].drive_strength.d), + .qre (), + .qe (mio_pad_attr_29_flds_we[9]), + .q (reg2hw.mio_pad_attr[29].drive_strength.q), + .ds (), + .qs (mio_pad_attr_29_drive_strength_29_qs) + ); + assign reg2hw.mio_pad_attr[29].drive_strength.qe = mio_pad_attr_29_qe; + + + // Subregister 30 of Multireg mio_pad_attr + // R[mio_pad_attr_30]: V(True) + logic mio_pad_attr_30_qe; + logic [9:0] mio_pad_attr_30_flds_we; + assign mio_pad_attr_30_qe = &mio_pad_attr_30_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_30_gated_we; + assign mio_pad_attr_30_gated_we = mio_pad_attr_30_we & mio_pad_attr_regwen_30_qs; + // F[invert_30]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_invert_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_invert_30_wd), + .d (hw2reg.mio_pad_attr[30].invert.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[0]), + .q (reg2hw.mio_pad_attr[30].invert.q), + .ds (), + .qs (mio_pad_attr_30_invert_30_qs) + ); + assign reg2hw.mio_pad_attr[30].invert.qe = mio_pad_attr_30_qe; + + // F[virtual_od_en_30]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_virtual_od_en_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_virtual_od_en_30_wd), + .d (hw2reg.mio_pad_attr[30].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[1]), + .q (reg2hw.mio_pad_attr[30].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_30_virtual_od_en_30_qs) + ); + assign reg2hw.mio_pad_attr[30].virtual_od_en.qe = mio_pad_attr_30_qe; + + // F[pull_en_30]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_pull_en_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_pull_en_30_wd), + .d (hw2reg.mio_pad_attr[30].pull_en.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[2]), + .q (reg2hw.mio_pad_attr[30].pull_en.q), + .ds (), + .qs (mio_pad_attr_30_pull_en_30_qs) + ); + assign reg2hw.mio_pad_attr[30].pull_en.qe = mio_pad_attr_30_qe; + + // F[pull_select_30]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_pull_select_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_pull_select_30_wd), + .d (hw2reg.mio_pad_attr[30].pull_select.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[3]), + .q (reg2hw.mio_pad_attr[30].pull_select.q), + .ds (), + .qs (mio_pad_attr_30_pull_select_30_qs) + ); + assign reg2hw.mio_pad_attr[30].pull_select.qe = mio_pad_attr_30_qe; + + // F[keeper_en_30]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_keeper_en_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_keeper_en_30_wd), + .d (hw2reg.mio_pad_attr[30].keeper_en.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[4]), + .q (reg2hw.mio_pad_attr[30].keeper_en.q), + .ds (), + .qs (mio_pad_attr_30_keeper_en_30_qs) + ); + assign reg2hw.mio_pad_attr[30].keeper_en.qe = mio_pad_attr_30_qe; + + // F[schmitt_en_30]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_schmitt_en_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_schmitt_en_30_wd), + .d (hw2reg.mio_pad_attr[30].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[5]), + .q (reg2hw.mio_pad_attr[30].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_30_schmitt_en_30_qs) + ); + assign reg2hw.mio_pad_attr[30].schmitt_en.qe = mio_pad_attr_30_qe; + + // F[od_en_30]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_od_en_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_od_en_30_wd), + .d (hw2reg.mio_pad_attr[30].od_en.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[6]), + .q (reg2hw.mio_pad_attr[30].od_en.q), + .ds (), + .qs (mio_pad_attr_30_od_en_30_qs) + ); + assign reg2hw.mio_pad_attr[30].od_en.qe = mio_pad_attr_30_qe; + + // F[input_disable_30]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_30_input_disable_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_input_disable_30_wd), + .d (hw2reg.mio_pad_attr[30].input_disable.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[7]), + .q (reg2hw.mio_pad_attr[30].input_disable.q), + .ds (), + .qs (mio_pad_attr_30_input_disable_30_qs) + ); + assign reg2hw.mio_pad_attr[30].input_disable.qe = mio_pad_attr_30_qe; + + // F[slew_rate_30]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_30_slew_rate_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_slew_rate_30_wd), + .d (hw2reg.mio_pad_attr[30].slew_rate.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[8]), + .q (reg2hw.mio_pad_attr[30].slew_rate.q), + .ds (), + .qs (mio_pad_attr_30_slew_rate_30_qs) + ); + assign reg2hw.mio_pad_attr[30].slew_rate.qe = mio_pad_attr_30_qe; + + // F[drive_strength_30]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_30_drive_strength_30 ( + .re (mio_pad_attr_30_re), + .we (mio_pad_attr_30_gated_we), + .wd (mio_pad_attr_30_drive_strength_30_wd), + .d (hw2reg.mio_pad_attr[30].drive_strength.d), + .qre (), + .qe (mio_pad_attr_30_flds_we[9]), + .q (reg2hw.mio_pad_attr[30].drive_strength.q), + .ds (), + .qs (mio_pad_attr_30_drive_strength_30_qs) + ); + assign reg2hw.mio_pad_attr[30].drive_strength.qe = mio_pad_attr_30_qe; + + + // Subregister 31 of Multireg mio_pad_attr + // R[mio_pad_attr_31]: V(True) + logic mio_pad_attr_31_qe; + logic [9:0] mio_pad_attr_31_flds_we; + assign mio_pad_attr_31_qe = &mio_pad_attr_31_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_31_gated_we; + assign mio_pad_attr_31_gated_we = mio_pad_attr_31_we & mio_pad_attr_regwen_31_qs; + // F[invert_31]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_invert_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_invert_31_wd), + .d (hw2reg.mio_pad_attr[31].invert.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[0]), + .q (reg2hw.mio_pad_attr[31].invert.q), + .ds (), + .qs (mio_pad_attr_31_invert_31_qs) + ); + assign reg2hw.mio_pad_attr[31].invert.qe = mio_pad_attr_31_qe; + + // F[virtual_od_en_31]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_virtual_od_en_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_virtual_od_en_31_wd), + .d (hw2reg.mio_pad_attr[31].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[1]), + .q (reg2hw.mio_pad_attr[31].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_31_virtual_od_en_31_qs) + ); + assign reg2hw.mio_pad_attr[31].virtual_od_en.qe = mio_pad_attr_31_qe; + + // F[pull_en_31]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_pull_en_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_pull_en_31_wd), + .d (hw2reg.mio_pad_attr[31].pull_en.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[2]), + .q (reg2hw.mio_pad_attr[31].pull_en.q), + .ds (), + .qs (mio_pad_attr_31_pull_en_31_qs) + ); + assign reg2hw.mio_pad_attr[31].pull_en.qe = mio_pad_attr_31_qe; + + // F[pull_select_31]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_pull_select_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_pull_select_31_wd), + .d (hw2reg.mio_pad_attr[31].pull_select.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[3]), + .q (reg2hw.mio_pad_attr[31].pull_select.q), + .ds (), + .qs (mio_pad_attr_31_pull_select_31_qs) + ); + assign reg2hw.mio_pad_attr[31].pull_select.qe = mio_pad_attr_31_qe; + + // F[keeper_en_31]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_keeper_en_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_keeper_en_31_wd), + .d (hw2reg.mio_pad_attr[31].keeper_en.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[4]), + .q (reg2hw.mio_pad_attr[31].keeper_en.q), + .ds (), + .qs (mio_pad_attr_31_keeper_en_31_qs) + ); + assign reg2hw.mio_pad_attr[31].keeper_en.qe = mio_pad_attr_31_qe; + + // F[schmitt_en_31]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_schmitt_en_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_schmitt_en_31_wd), + .d (hw2reg.mio_pad_attr[31].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[5]), + .q (reg2hw.mio_pad_attr[31].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_31_schmitt_en_31_qs) + ); + assign reg2hw.mio_pad_attr[31].schmitt_en.qe = mio_pad_attr_31_qe; + + // F[od_en_31]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_od_en_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_od_en_31_wd), + .d (hw2reg.mio_pad_attr[31].od_en.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[6]), + .q (reg2hw.mio_pad_attr[31].od_en.q), + .ds (), + .qs (mio_pad_attr_31_od_en_31_qs) + ); + assign reg2hw.mio_pad_attr[31].od_en.qe = mio_pad_attr_31_qe; + + // F[input_disable_31]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_31_input_disable_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_input_disable_31_wd), + .d (hw2reg.mio_pad_attr[31].input_disable.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[7]), + .q (reg2hw.mio_pad_attr[31].input_disable.q), + .ds (), + .qs (mio_pad_attr_31_input_disable_31_qs) + ); + assign reg2hw.mio_pad_attr[31].input_disable.qe = mio_pad_attr_31_qe; + + // F[slew_rate_31]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_31_slew_rate_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_slew_rate_31_wd), + .d (hw2reg.mio_pad_attr[31].slew_rate.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[8]), + .q (reg2hw.mio_pad_attr[31].slew_rate.q), + .ds (), + .qs (mio_pad_attr_31_slew_rate_31_qs) + ); + assign reg2hw.mio_pad_attr[31].slew_rate.qe = mio_pad_attr_31_qe; + + // F[drive_strength_31]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_31_drive_strength_31 ( + .re (mio_pad_attr_31_re), + .we (mio_pad_attr_31_gated_we), + .wd (mio_pad_attr_31_drive_strength_31_wd), + .d (hw2reg.mio_pad_attr[31].drive_strength.d), + .qre (), + .qe (mio_pad_attr_31_flds_we[9]), + .q (reg2hw.mio_pad_attr[31].drive_strength.q), + .ds (), + .qs (mio_pad_attr_31_drive_strength_31_qs) + ); + assign reg2hw.mio_pad_attr[31].drive_strength.qe = mio_pad_attr_31_qe; + + + // Subregister 32 of Multireg mio_pad_attr + // R[mio_pad_attr_32]: V(True) + logic mio_pad_attr_32_qe; + logic [9:0] mio_pad_attr_32_flds_we; + assign mio_pad_attr_32_qe = &mio_pad_attr_32_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_32_gated_we; + assign mio_pad_attr_32_gated_we = mio_pad_attr_32_we & mio_pad_attr_regwen_32_qs; + // F[invert_32]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_invert_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_invert_32_wd), + .d (hw2reg.mio_pad_attr[32].invert.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[0]), + .q (reg2hw.mio_pad_attr[32].invert.q), + .ds (), + .qs (mio_pad_attr_32_invert_32_qs) + ); + assign reg2hw.mio_pad_attr[32].invert.qe = mio_pad_attr_32_qe; + + // F[virtual_od_en_32]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_virtual_od_en_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_virtual_od_en_32_wd), + .d (hw2reg.mio_pad_attr[32].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[1]), + .q (reg2hw.mio_pad_attr[32].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_32_virtual_od_en_32_qs) + ); + assign reg2hw.mio_pad_attr[32].virtual_od_en.qe = mio_pad_attr_32_qe; + + // F[pull_en_32]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_pull_en_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_pull_en_32_wd), + .d (hw2reg.mio_pad_attr[32].pull_en.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[2]), + .q (reg2hw.mio_pad_attr[32].pull_en.q), + .ds (), + .qs (mio_pad_attr_32_pull_en_32_qs) + ); + assign reg2hw.mio_pad_attr[32].pull_en.qe = mio_pad_attr_32_qe; + + // F[pull_select_32]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_pull_select_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_pull_select_32_wd), + .d (hw2reg.mio_pad_attr[32].pull_select.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[3]), + .q (reg2hw.mio_pad_attr[32].pull_select.q), + .ds (), + .qs (mio_pad_attr_32_pull_select_32_qs) + ); + assign reg2hw.mio_pad_attr[32].pull_select.qe = mio_pad_attr_32_qe; + + // F[keeper_en_32]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_keeper_en_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_keeper_en_32_wd), + .d (hw2reg.mio_pad_attr[32].keeper_en.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[4]), + .q (reg2hw.mio_pad_attr[32].keeper_en.q), + .ds (), + .qs (mio_pad_attr_32_keeper_en_32_qs) + ); + assign reg2hw.mio_pad_attr[32].keeper_en.qe = mio_pad_attr_32_qe; + + // F[schmitt_en_32]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_schmitt_en_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_schmitt_en_32_wd), + .d (hw2reg.mio_pad_attr[32].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[5]), + .q (reg2hw.mio_pad_attr[32].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_32_schmitt_en_32_qs) + ); + assign reg2hw.mio_pad_attr[32].schmitt_en.qe = mio_pad_attr_32_qe; + + // F[od_en_32]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_od_en_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_od_en_32_wd), + .d (hw2reg.mio_pad_attr[32].od_en.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[6]), + .q (reg2hw.mio_pad_attr[32].od_en.q), + .ds (), + .qs (mio_pad_attr_32_od_en_32_qs) + ); + assign reg2hw.mio_pad_attr[32].od_en.qe = mio_pad_attr_32_qe; + + // F[input_disable_32]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_32_input_disable_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_input_disable_32_wd), + .d (hw2reg.mio_pad_attr[32].input_disable.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[7]), + .q (reg2hw.mio_pad_attr[32].input_disable.q), + .ds (), + .qs (mio_pad_attr_32_input_disable_32_qs) + ); + assign reg2hw.mio_pad_attr[32].input_disable.qe = mio_pad_attr_32_qe; + + // F[slew_rate_32]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_32_slew_rate_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_slew_rate_32_wd), + .d (hw2reg.mio_pad_attr[32].slew_rate.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[8]), + .q (reg2hw.mio_pad_attr[32].slew_rate.q), + .ds (), + .qs (mio_pad_attr_32_slew_rate_32_qs) + ); + assign reg2hw.mio_pad_attr[32].slew_rate.qe = mio_pad_attr_32_qe; + + // F[drive_strength_32]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_32_drive_strength_32 ( + .re (mio_pad_attr_32_re), + .we (mio_pad_attr_32_gated_we), + .wd (mio_pad_attr_32_drive_strength_32_wd), + .d (hw2reg.mio_pad_attr[32].drive_strength.d), + .qre (), + .qe (mio_pad_attr_32_flds_we[9]), + .q (reg2hw.mio_pad_attr[32].drive_strength.q), + .ds (), + .qs (mio_pad_attr_32_drive_strength_32_qs) + ); + assign reg2hw.mio_pad_attr[32].drive_strength.qe = mio_pad_attr_32_qe; + + + // Subregister 33 of Multireg mio_pad_attr + // R[mio_pad_attr_33]: V(True) + logic mio_pad_attr_33_qe; + logic [9:0] mio_pad_attr_33_flds_we; + assign mio_pad_attr_33_qe = &mio_pad_attr_33_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_33_gated_we; + assign mio_pad_attr_33_gated_we = mio_pad_attr_33_we & mio_pad_attr_regwen_33_qs; + // F[invert_33]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_invert_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_invert_33_wd), + .d (hw2reg.mio_pad_attr[33].invert.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[0]), + .q (reg2hw.mio_pad_attr[33].invert.q), + .ds (), + .qs (mio_pad_attr_33_invert_33_qs) + ); + assign reg2hw.mio_pad_attr[33].invert.qe = mio_pad_attr_33_qe; + + // F[virtual_od_en_33]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_virtual_od_en_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_virtual_od_en_33_wd), + .d (hw2reg.mio_pad_attr[33].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[1]), + .q (reg2hw.mio_pad_attr[33].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_33_virtual_od_en_33_qs) + ); + assign reg2hw.mio_pad_attr[33].virtual_od_en.qe = mio_pad_attr_33_qe; + + // F[pull_en_33]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_pull_en_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_pull_en_33_wd), + .d (hw2reg.mio_pad_attr[33].pull_en.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[2]), + .q (reg2hw.mio_pad_attr[33].pull_en.q), + .ds (), + .qs (mio_pad_attr_33_pull_en_33_qs) + ); + assign reg2hw.mio_pad_attr[33].pull_en.qe = mio_pad_attr_33_qe; + + // F[pull_select_33]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_pull_select_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_pull_select_33_wd), + .d (hw2reg.mio_pad_attr[33].pull_select.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[3]), + .q (reg2hw.mio_pad_attr[33].pull_select.q), + .ds (), + .qs (mio_pad_attr_33_pull_select_33_qs) + ); + assign reg2hw.mio_pad_attr[33].pull_select.qe = mio_pad_attr_33_qe; + + // F[keeper_en_33]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_keeper_en_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_keeper_en_33_wd), + .d (hw2reg.mio_pad_attr[33].keeper_en.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[4]), + .q (reg2hw.mio_pad_attr[33].keeper_en.q), + .ds (), + .qs (mio_pad_attr_33_keeper_en_33_qs) + ); + assign reg2hw.mio_pad_attr[33].keeper_en.qe = mio_pad_attr_33_qe; + + // F[schmitt_en_33]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_schmitt_en_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_schmitt_en_33_wd), + .d (hw2reg.mio_pad_attr[33].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[5]), + .q (reg2hw.mio_pad_attr[33].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_33_schmitt_en_33_qs) + ); + assign reg2hw.mio_pad_attr[33].schmitt_en.qe = mio_pad_attr_33_qe; + + // F[od_en_33]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_od_en_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_od_en_33_wd), + .d (hw2reg.mio_pad_attr[33].od_en.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[6]), + .q (reg2hw.mio_pad_attr[33].od_en.q), + .ds (), + .qs (mio_pad_attr_33_od_en_33_qs) + ); + assign reg2hw.mio_pad_attr[33].od_en.qe = mio_pad_attr_33_qe; + + // F[input_disable_33]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_33_input_disable_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_input_disable_33_wd), + .d (hw2reg.mio_pad_attr[33].input_disable.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[7]), + .q (reg2hw.mio_pad_attr[33].input_disable.q), + .ds (), + .qs (mio_pad_attr_33_input_disable_33_qs) + ); + assign reg2hw.mio_pad_attr[33].input_disable.qe = mio_pad_attr_33_qe; + + // F[slew_rate_33]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_33_slew_rate_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_slew_rate_33_wd), + .d (hw2reg.mio_pad_attr[33].slew_rate.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[8]), + .q (reg2hw.mio_pad_attr[33].slew_rate.q), + .ds (), + .qs (mio_pad_attr_33_slew_rate_33_qs) + ); + assign reg2hw.mio_pad_attr[33].slew_rate.qe = mio_pad_attr_33_qe; + + // F[drive_strength_33]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_33_drive_strength_33 ( + .re (mio_pad_attr_33_re), + .we (mio_pad_attr_33_gated_we), + .wd (mio_pad_attr_33_drive_strength_33_wd), + .d (hw2reg.mio_pad_attr[33].drive_strength.d), + .qre (), + .qe (mio_pad_attr_33_flds_we[9]), + .q (reg2hw.mio_pad_attr[33].drive_strength.q), + .ds (), + .qs (mio_pad_attr_33_drive_strength_33_qs) + ); + assign reg2hw.mio_pad_attr[33].drive_strength.qe = mio_pad_attr_33_qe; + + + // Subregister 34 of Multireg mio_pad_attr + // R[mio_pad_attr_34]: V(True) + logic mio_pad_attr_34_qe; + logic [9:0] mio_pad_attr_34_flds_we; + assign mio_pad_attr_34_qe = &mio_pad_attr_34_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_34_gated_we; + assign mio_pad_attr_34_gated_we = mio_pad_attr_34_we & mio_pad_attr_regwen_34_qs; + // F[invert_34]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_invert_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_invert_34_wd), + .d (hw2reg.mio_pad_attr[34].invert.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[0]), + .q (reg2hw.mio_pad_attr[34].invert.q), + .ds (), + .qs (mio_pad_attr_34_invert_34_qs) + ); + assign reg2hw.mio_pad_attr[34].invert.qe = mio_pad_attr_34_qe; + + // F[virtual_od_en_34]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_virtual_od_en_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_virtual_od_en_34_wd), + .d (hw2reg.mio_pad_attr[34].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[1]), + .q (reg2hw.mio_pad_attr[34].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_34_virtual_od_en_34_qs) + ); + assign reg2hw.mio_pad_attr[34].virtual_od_en.qe = mio_pad_attr_34_qe; + + // F[pull_en_34]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_pull_en_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_pull_en_34_wd), + .d (hw2reg.mio_pad_attr[34].pull_en.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[2]), + .q (reg2hw.mio_pad_attr[34].pull_en.q), + .ds (), + .qs (mio_pad_attr_34_pull_en_34_qs) + ); + assign reg2hw.mio_pad_attr[34].pull_en.qe = mio_pad_attr_34_qe; + + // F[pull_select_34]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_pull_select_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_pull_select_34_wd), + .d (hw2reg.mio_pad_attr[34].pull_select.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[3]), + .q (reg2hw.mio_pad_attr[34].pull_select.q), + .ds (), + .qs (mio_pad_attr_34_pull_select_34_qs) + ); + assign reg2hw.mio_pad_attr[34].pull_select.qe = mio_pad_attr_34_qe; + + // F[keeper_en_34]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_keeper_en_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_keeper_en_34_wd), + .d (hw2reg.mio_pad_attr[34].keeper_en.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[4]), + .q (reg2hw.mio_pad_attr[34].keeper_en.q), + .ds (), + .qs (mio_pad_attr_34_keeper_en_34_qs) + ); + assign reg2hw.mio_pad_attr[34].keeper_en.qe = mio_pad_attr_34_qe; + + // F[schmitt_en_34]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_schmitt_en_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_schmitt_en_34_wd), + .d (hw2reg.mio_pad_attr[34].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[5]), + .q (reg2hw.mio_pad_attr[34].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_34_schmitt_en_34_qs) + ); + assign reg2hw.mio_pad_attr[34].schmitt_en.qe = mio_pad_attr_34_qe; + + // F[od_en_34]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_od_en_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_od_en_34_wd), + .d (hw2reg.mio_pad_attr[34].od_en.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[6]), + .q (reg2hw.mio_pad_attr[34].od_en.q), + .ds (), + .qs (mio_pad_attr_34_od_en_34_qs) + ); + assign reg2hw.mio_pad_attr[34].od_en.qe = mio_pad_attr_34_qe; + + // F[input_disable_34]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_34_input_disable_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_input_disable_34_wd), + .d (hw2reg.mio_pad_attr[34].input_disable.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[7]), + .q (reg2hw.mio_pad_attr[34].input_disable.q), + .ds (), + .qs (mio_pad_attr_34_input_disable_34_qs) + ); + assign reg2hw.mio_pad_attr[34].input_disable.qe = mio_pad_attr_34_qe; + + // F[slew_rate_34]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_34_slew_rate_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_slew_rate_34_wd), + .d (hw2reg.mio_pad_attr[34].slew_rate.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[8]), + .q (reg2hw.mio_pad_attr[34].slew_rate.q), + .ds (), + .qs (mio_pad_attr_34_slew_rate_34_qs) + ); + assign reg2hw.mio_pad_attr[34].slew_rate.qe = mio_pad_attr_34_qe; + + // F[drive_strength_34]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_34_drive_strength_34 ( + .re (mio_pad_attr_34_re), + .we (mio_pad_attr_34_gated_we), + .wd (mio_pad_attr_34_drive_strength_34_wd), + .d (hw2reg.mio_pad_attr[34].drive_strength.d), + .qre (), + .qe (mio_pad_attr_34_flds_we[9]), + .q (reg2hw.mio_pad_attr[34].drive_strength.q), + .ds (), + .qs (mio_pad_attr_34_drive_strength_34_qs) + ); + assign reg2hw.mio_pad_attr[34].drive_strength.qe = mio_pad_attr_34_qe; + + + // Subregister 35 of Multireg mio_pad_attr + // R[mio_pad_attr_35]: V(True) + logic mio_pad_attr_35_qe; + logic [9:0] mio_pad_attr_35_flds_we; + assign mio_pad_attr_35_qe = &mio_pad_attr_35_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_35_gated_we; + assign mio_pad_attr_35_gated_we = mio_pad_attr_35_we & mio_pad_attr_regwen_35_qs; + // F[invert_35]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_invert_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_invert_35_wd), + .d (hw2reg.mio_pad_attr[35].invert.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[0]), + .q (reg2hw.mio_pad_attr[35].invert.q), + .ds (), + .qs (mio_pad_attr_35_invert_35_qs) + ); + assign reg2hw.mio_pad_attr[35].invert.qe = mio_pad_attr_35_qe; + + // F[virtual_od_en_35]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_virtual_od_en_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_virtual_od_en_35_wd), + .d (hw2reg.mio_pad_attr[35].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[1]), + .q (reg2hw.mio_pad_attr[35].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_35_virtual_od_en_35_qs) + ); + assign reg2hw.mio_pad_attr[35].virtual_od_en.qe = mio_pad_attr_35_qe; + + // F[pull_en_35]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_pull_en_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_pull_en_35_wd), + .d (hw2reg.mio_pad_attr[35].pull_en.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[2]), + .q (reg2hw.mio_pad_attr[35].pull_en.q), + .ds (), + .qs (mio_pad_attr_35_pull_en_35_qs) + ); + assign reg2hw.mio_pad_attr[35].pull_en.qe = mio_pad_attr_35_qe; + + // F[pull_select_35]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_pull_select_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_pull_select_35_wd), + .d (hw2reg.mio_pad_attr[35].pull_select.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[3]), + .q (reg2hw.mio_pad_attr[35].pull_select.q), + .ds (), + .qs (mio_pad_attr_35_pull_select_35_qs) + ); + assign reg2hw.mio_pad_attr[35].pull_select.qe = mio_pad_attr_35_qe; + + // F[keeper_en_35]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_keeper_en_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_keeper_en_35_wd), + .d (hw2reg.mio_pad_attr[35].keeper_en.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[4]), + .q (reg2hw.mio_pad_attr[35].keeper_en.q), + .ds (), + .qs (mio_pad_attr_35_keeper_en_35_qs) + ); + assign reg2hw.mio_pad_attr[35].keeper_en.qe = mio_pad_attr_35_qe; + + // F[schmitt_en_35]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_schmitt_en_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_schmitt_en_35_wd), + .d (hw2reg.mio_pad_attr[35].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[5]), + .q (reg2hw.mio_pad_attr[35].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_35_schmitt_en_35_qs) + ); + assign reg2hw.mio_pad_attr[35].schmitt_en.qe = mio_pad_attr_35_qe; + + // F[od_en_35]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_od_en_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_od_en_35_wd), + .d (hw2reg.mio_pad_attr[35].od_en.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[6]), + .q (reg2hw.mio_pad_attr[35].od_en.q), + .ds (), + .qs (mio_pad_attr_35_od_en_35_qs) + ); + assign reg2hw.mio_pad_attr[35].od_en.qe = mio_pad_attr_35_qe; + + // F[input_disable_35]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_35_input_disable_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_input_disable_35_wd), + .d (hw2reg.mio_pad_attr[35].input_disable.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[7]), + .q (reg2hw.mio_pad_attr[35].input_disable.q), + .ds (), + .qs (mio_pad_attr_35_input_disable_35_qs) + ); + assign reg2hw.mio_pad_attr[35].input_disable.qe = mio_pad_attr_35_qe; + + // F[slew_rate_35]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_35_slew_rate_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_slew_rate_35_wd), + .d (hw2reg.mio_pad_attr[35].slew_rate.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[8]), + .q (reg2hw.mio_pad_attr[35].slew_rate.q), + .ds (), + .qs (mio_pad_attr_35_slew_rate_35_qs) + ); + assign reg2hw.mio_pad_attr[35].slew_rate.qe = mio_pad_attr_35_qe; + + // F[drive_strength_35]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_35_drive_strength_35 ( + .re (mio_pad_attr_35_re), + .we (mio_pad_attr_35_gated_we), + .wd (mio_pad_attr_35_drive_strength_35_wd), + .d (hw2reg.mio_pad_attr[35].drive_strength.d), + .qre (), + .qe (mio_pad_attr_35_flds_we[9]), + .q (reg2hw.mio_pad_attr[35].drive_strength.q), + .ds (), + .qs (mio_pad_attr_35_drive_strength_35_qs) + ); + assign reg2hw.mio_pad_attr[35].drive_strength.qe = mio_pad_attr_35_qe; + + + // Subregister 36 of Multireg mio_pad_attr + // R[mio_pad_attr_36]: V(True) + logic mio_pad_attr_36_qe; + logic [9:0] mio_pad_attr_36_flds_we; + assign mio_pad_attr_36_qe = &mio_pad_attr_36_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_36_gated_we; + assign mio_pad_attr_36_gated_we = mio_pad_attr_36_we & mio_pad_attr_regwen_36_qs; + // F[invert_36]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_invert_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_invert_36_wd), + .d (hw2reg.mio_pad_attr[36].invert.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[0]), + .q (reg2hw.mio_pad_attr[36].invert.q), + .ds (), + .qs (mio_pad_attr_36_invert_36_qs) + ); + assign reg2hw.mio_pad_attr[36].invert.qe = mio_pad_attr_36_qe; + + // F[virtual_od_en_36]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_virtual_od_en_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_virtual_od_en_36_wd), + .d (hw2reg.mio_pad_attr[36].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[1]), + .q (reg2hw.mio_pad_attr[36].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_36_virtual_od_en_36_qs) + ); + assign reg2hw.mio_pad_attr[36].virtual_od_en.qe = mio_pad_attr_36_qe; + + // F[pull_en_36]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_pull_en_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_pull_en_36_wd), + .d (hw2reg.mio_pad_attr[36].pull_en.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[2]), + .q (reg2hw.mio_pad_attr[36].pull_en.q), + .ds (), + .qs (mio_pad_attr_36_pull_en_36_qs) + ); + assign reg2hw.mio_pad_attr[36].pull_en.qe = mio_pad_attr_36_qe; + + // F[pull_select_36]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_pull_select_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_pull_select_36_wd), + .d (hw2reg.mio_pad_attr[36].pull_select.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[3]), + .q (reg2hw.mio_pad_attr[36].pull_select.q), + .ds (), + .qs (mio_pad_attr_36_pull_select_36_qs) + ); + assign reg2hw.mio_pad_attr[36].pull_select.qe = mio_pad_attr_36_qe; + + // F[keeper_en_36]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_keeper_en_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_keeper_en_36_wd), + .d (hw2reg.mio_pad_attr[36].keeper_en.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[4]), + .q (reg2hw.mio_pad_attr[36].keeper_en.q), + .ds (), + .qs (mio_pad_attr_36_keeper_en_36_qs) + ); + assign reg2hw.mio_pad_attr[36].keeper_en.qe = mio_pad_attr_36_qe; + + // F[schmitt_en_36]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_schmitt_en_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_schmitt_en_36_wd), + .d (hw2reg.mio_pad_attr[36].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[5]), + .q (reg2hw.mio_pad_attr[36].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_36_schmitt_en_36_qs) + ); + assign reg2hw.mio_pad_attr[36].schmitt_en.qe = mio_pad_attr_36_qe; + + // F[od_en_36]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_od_en_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_od_en_36_wd), + .d (hw2reg.mio_pad_attr[36].od_en.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[6]), + .q (reg2hw.mio_pad_attr[36].od_en.q), + .ds (), + .qs (mio_pad_attr_36_od_en_36_qs) + ); + assign reg2hw.mio_pad_attr[36].od_en.qe = mio_pad_attr_36_qe; + + // F[input_disable_36]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_36_input_disable_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_input_disable_36_wd), + .d (hw2reg.mio_pad_attr[36].input_disable.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[7]), + .q (reg2hw.mio_pad_attr[36].input_disable.q), + .ds (), + .qs (mio_pad_attr_36_input_disable_36_qs) + ); + assign reg2hw.mio_pad_attr[36].input_disable.qe = mio_pad_attr_36_qe; + + // F[slew_rate_36]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_36_slew_rate_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_slew_rate_36_wd), + .d (hw2reg.mio_pad_attr[36].slew_rate.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[8]), + .q (reg2hw.mio_pad_attr[36].slew_rate.q), + .ds (), + .qs (mio_pad_attr_36_slew_rate_36_qs) + ); + assign reg2hw.mio_pad_attr[36].slew_rate.qe = mio_pad_attr_36_qe; + + // F[drive_strength_36]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_36_drive_strength_36 ( + .re (mio_pad_attr_36_re), + .we (mio_pad_attr_36_gated_we), + .wd (mio_pad_attr_36_drive_strength_36_wd), + .d (hw2reg.mio_pad_attr[36].drive_strength.d), + .qre (), + .qe (mio_pad_attr_36_flds_we[9]), + .q (reg2hw.mio_pad_attr[36].drive_strength.q), + .ds (), + .qs (mio_pad_attr_36_drive_strength_36_qs) + ); + assign reg2hw.mio_pad_attr[36].drive_strength.qe = mio_pad_attr_36_qe; + + + // Subregister 37 of Multireg mio_pad_attr + // R[mio_pad_attr_37]: V(True) + logic mio_pad_attr_37_qe; + logic [9:0] mio_pad_attr_37_flds_we; + assign mio_pad_attr_37_qe = &mio_pad_attr_37_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_37_gated_we; + assign mio_pad_attr_37_gated_we = mio_pad_attr_37_we & mio_pad_attr_regwen_37_qs; + // F[invert_37]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_invert_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_invert_37_wd), + .d (hw2reg.mio_pad_attr[37].invert.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[0]), + .q (reg2hw.mio_pad_attr[37].invert.q), + .ds (), + .qs (mio_pad_attr_37_invert_37_qs) + ); + assign reg2hw.mio_pad_attr[37].invert.qe = mio_pad_attr_37_qe; + + // F[virtual_od_en_37]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_virtual_od_en_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_virtual_od_en_37_wd), + .d (hw2reg.mio_pad_attr[37].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[1]), + .q (reg2hw.mio_pad_attr[37].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_37_virtual_od_en_37_qs) + ); + assign reg2hw.mio_pad_attr[37].virtual_od_en.qe = mio_pad_attr_37_qe; + + // F[pull_en_37]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_pull_en_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_pull_en_37_wd), + .d (hw2reg.mio_pad_attr[37].pull_en.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[2]), + .q (reg2hw.mio_pad_attr[37].pull_en.q), + .ds (), + .qs (mio_pad_attr_37_pull_en_37_qs) + ); + assign reg2hw.mio_pad_attr[37].pull_en.qe = mio_pad_attr_37_qe; + + // F[pull_select_37]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_pull_select_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_pull_select_37_wd), + .d (hw2reg.mio_pad_attr[37].pull_select.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[3]), + .q (reg2hw.mio_pad_attr[37].pull_select.q), + .ds (), + .qs (mio_pad_attr_37_pull_select_37_qs) + ); + assign reg2hw.mio_pad_attr[37].pull_select.qe = mio_pad_attr_37_qe; + + // F[keeper_en_37]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_keeper_en_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_keeper_en_37_wd), + .d (hw2reg.mio_pad_attr[37].keeper_en.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[4]), + .q (reg2hw.mio_pad_attr[37].keeper_en.q), + .ds (), + .qs (mio_pad_attr_37_keeper_en_37_qs) + ); + assign reg2hw.mio_pad_attr[37].keeper_en.qe = mio_pad_attr_37_qe; + + // F[schmitt_en_37]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_schmitt_en_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_schmitt_en_37_wd), + .d (hw2reg.mio_pad_attr[37].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[5]), + .q (reg2hw.mio_pad_attr[37].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_37_schmitt_en_37_qs) + ); + assign reg2hw.mio_pad_attr[37].schmitt_en.qe = mio_pad_attr_37_qe; + + // F[od_en_37]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_od_en_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_od_en_37_wd), + .d (hw2reg.mio_pad_attr[37].od_en.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[6]), + .q (reg2hw.mio_pad_attr[37].od_en.q), + .ds (), + .qs (mio_pad_attr_37_od_en_37_qs) + ); + assign reg2hw.mio_pad_attr[37].od_en.qe = mio_pad_attr_37_qe; + + // F[input_disable_37]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_37_input_disable_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_input_disable_37_wd), + .d (hw2reg.mio_pad_attr[37].input_disable.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[7]), + .q (reg2hw.mio_pad_attr[37].input_disable.q), + .ds (), + .qs (mio_pad_attr_37_input_disable_37_qs) + ); + assign reg2hw.mio_pad_attr[37].input_disable.qe = mio_pad_attr_37_qe; + + // F[slew_rate_37]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_37_slew_rate_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_slew_rate_37_wd), + .d (hw2reg.mio_pad_attr[37].slew_rate.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[8]), + .q (reg2hw.mio_pad_attr[37].slew_rate.q), + .ds (), + .qs (mio_pad_attr_37_slew_rate_37_qs) + ); + assign reg2hw.mio_pad_attr[37].slew_rate.qe = mio_pad_attr_37_qe; + + // F[drive_strength_37]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_37_drive_strength_37 ( + .re (mio_pad_attr_37_re), + .we (mio_pad_attr_37_gated_we), + .wd (mio_pad_attr_37_drive_strength_37_wd), + .d (hw2reg.mio_pad_attr[37].drive_strength.d), + .qre (), + .qe (mio_pad_attr_37_flds_we[9]), + .q (reg2hw.mio_pad_attr[37].drive_strength.q), + .ds (), + .qs (mio_pad_attr_37_drive_strength_37_qs) + ); + assign reg2hw.mio_pad_attr[37].drive_strength.qe = mio_pad_attr_37_qe; + + + // Subregister 38 of Multireg mio_pad_attr + // R[mio_pad_attr_38]: V(True) + logic mio_pad_attr_38_qe; + logic [9:0] mio_pad_attr_38_flds_we; + assign mio_pad_attr_38_qe = &mio_pad_attr_38_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_38_gated_we; + assign mio_pad_attr_38_gated_we = mio_pad_attr_38_we & mio_pad_attr_regwen_38_qs; + // F[invert_38]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_invert_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_invert_38_wd), + .d (hw2reg.mio_pad_attr[38].invert.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[0]), + .q (reg2hw.mio_pad_attr[38].invert.q), + .ds (), + .qs (mio_pad_attr_38_invert_38_qs) + ); + assign reg2hw.mio_pad_attr[38].invert.qe = mio_pad_attr_38_qe; + + // F[virtual_od_en_38]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_virtual_od_en_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_virtual_od_en_38_wd), + .d (hw2reg.mio_pad_attr[38].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[1]), + .q (reg2hw.mio_pad_attr[38].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_38_virtual_od_en_38_qs) + ); + assign reg2hw.mio_pad_attr[38].virtual_od_en.qe = mio_pad_attr_38_qe; + + // F[pull_en_38]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_pull_en_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_pull_en_38_wd), + .d (hw2reg.mio_pad_attr[38].pull_en.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[2]), + .q (reg2hw.mio_pad_attr[38].pull_en.q), + .ds (), + .qs (mio_pad_attr_38_pull_en_38_qs) + ); + assign reg2hw.mio_pad_attr[38].pull_en.qe = mio_pad_attr_38_qe; + + // F[pull_select_38]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_pull_select_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_pull_select_38_wd), + .d (hw2reg.mio_pad_attr[38].pull_select.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[3]), + .q (reg2hw.mio_pad_attr[38].pull_select.q), + .ds (), + .qs (mio_pad_attr_38_pull_select_38_qs) + ); + assign reg2hw.mio_pad_attr[38].pull_select.qe = mio_pad_attr_38_qe; + + // F[keeper_en_38]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_keeper_en_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_keeper_en_38_wd), + .d (hw2reg.mio_pad_attr[38].keeper_en.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[4]), + .q (reg2hw.mio_pad_attr[38].keeper_en.q), + .ds (), + .qs (mio_pad_attr_38_keeper_en_38_qs) + ); + assign reg2hw.mio_pad_attr[38].keeper_en.qe = mio_pad_attr_38_qe; + + // F[schmitt_en_38]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_schmitt_en_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_schmitt_en_38_wd), + .d (hw2reg.mio_pad_attr[38].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[5]), + .q (reg2hw.mio_pad_attr[38].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_38_schmitt_en_38_qs) + ); + assign reg2hw.mio_pad_attr[38].schmitt_en.qe = mio_pad_attr_38_qe; + + // F[od_en_38]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_od_en_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_od_en_38_wd), + .d (hw2reg.mio_pad_attr[38].od_en.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[6]), + .q (reg2hw.mio_pad_attr[38].od_en.q), + .ds (), + .qs (mio_pad_attr_38_od_en_38_qs) + ); + assign reg2hw.mio_pad_attr[38].od_en.qe = mio_pad_attr_38_qe; + + // F[input_disable_38]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_38_input_disable_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_input_disable_38_wd), + .d (hw2reg.mio_pad_attr[38].input_disable.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[7]), + .q (reg2hw.mio_pad_attr[38].input_disable.q), + .ds (), + .qs (mio_pad_attr_38_input_disable_38_qs) + ); + assign reg2hw.mio_pad_attr[38].input_disable.qe = mio_pad_attr_38_qe; + + // F[slew_rate_38]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_38_slew_rate_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_slew_rate_38_wd), + .d (hw2reg.mio_pad_attr[38].slew_rate.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[8]), + .q (reg2hw.mio_pad_attr[38].slew_rate.q), + .ds (), + .qs (mio_pad_attr_38_slew_rate_38_qs) + ); + assign reg2hw.mio_pad_attr[38].slew_rate.qe = mio_pad_attr_38_qe; + + // F[drive_strength_38]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_38_drive_strength_38 ( + .re (mio_pad_attr_38_re), + .we (mio_pad_attr_38_gated_we), + .wd (mio_pad_attr_38_drive_strength_38_wd), + .d (hw2reg.mio_pad_attr[38].drive_strength.d), + .qre (), + .qe (mio_pad_attr_38_flds_we[9]), + .q (reg2hw.mio_pad_attr[38].drive_strength.q), + .ds (), + .qs (mio_pad_attr_38_drive_strength_38_qs) + ); + assign reg2hw.mio_pad_attr[38].drive_strength.qe = mio_pad_attr_38_qe; + + + // Subregister 39 of Multireg mio_pad_attr + // R[mio_pad_attr_39]: V(True) + logic mio_pad_attr_39_qe; + logic [9:0] mio_pad_attr_39_flds_we; + assign mio_pad_attr_39_qe = &mio_pad_attr_39_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_39_gated_we; + assign mio_pad_attr_39_gated_we = mio_pad_attr_39_we & mio_pad_attr_regwen_39_qs; + // F[invert_39]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_invert_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_invert_39_wd), + .d (hw2reg.mio_pad_attr[39].invert.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[0]), + .q (reg2hw.mio_pad_attr[39].invert.q), + .ds (), + .qs (mio_pad_attr_39_invert_39_qs) + ); + assign reg2hw.mio_pad_attr[39].invert.qe = mio_pad_attr_39_qe; + + // F[virtual_od_en_39]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_virtual_od_en_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_virtual_od_en_39_wd), + .d (hw2reg.mio_pad_attr[39].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[1]), + .q (reg2hw.mio_pad_attr[39].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_39_virtual_od_en_39_qs) + ); + assign reg2hw.mio_pad_attr[39].virtual_od_en.qe = mio_pad_attr_39_qe; + + // F[pull_en_39]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_pull_en_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_pull_en_39_wd), + .d (hw2reg.mio_pad_attr[39].pull_en.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[2]), + .q (reg2hw.mio_pad_attr[39].pull_en.q), + .ds (), + .qs (mio_pad_attr_39_pull_en_39_qs) + ); + assign reg2hw.mio_pad_attr[39].pull_en.qe = mio_pad_attr_39_qe; + + // F[pull_select_39]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_pull_select_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_pull_select_39_wd), + .d (hw2reg.mio_pad_attr[39].pull_select.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[3]), + .q (reg2hw.mio_pad_attr[39].pull_select.q), + .ds (), + .qs (mio_pad_attr_39_pull_select_39_qs) + ); + assign reg2hw.mio_pad_attr[39].pull_select.qe = mio_pad_attr_39_qe; + + // F[keeper_en_39]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_keeper_en_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_keeper_en_39_wd), + .d (hw2reg.mio_pad_attr[39].keeper_en.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[4]), + .q (reg2hw.mio_pad_attr[39].keeper_en.q), + .ds (), + .qs (mio_pad_attr_39_keeper_en_39_qs) + ); + assign reg2hw.mio_pad_attr[39].keeper_en.qe = mio_pad_attr_39_qe; + + // F[schmitt_en_39]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_schmitt_en_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_schmitt_en_39_wd), + .d (hw2reg.mio_pad_attr[39].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[5]), + .q (reg2hw.mio_pad_attr[39].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_39_schmitt_en_39_qs) + ); + assign reg2hw.mio_pad_attr[39].schmitt_en.qe = mio_pad_attr_39_qe; + + // F[od_en_39]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_od_en_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_od_en_39_wd), + .d (hw2reg.mio_pad_attr[39].od_en.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[6]), + .q (reg2hw.mio_pad_attr[39].od_en.q), + .ds (), + .qs (mio_pad_attr_39_od_en_39_qs) + ); + assign reg2hw.mio_pad_attr[39].od_en.qe = mio_pad_attr_39_qe; + + // F[input_disable_39]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_39_input_disable_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_input_disable_39_wd), + .d (hw2reg.mio_pad_attr[39].input_disable.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[7]), + .q (reg2hw.mio_pad_attr[39].input_disable.q), + .ds (), + .qs (mio_pad_attr_39_input_disable_39_qs) + ); + assign reg2hw.mio_pad_attr[39].input_disable.qe = mio_pad_attr_39_qe; + + // F[slew_rate_39]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_39_slew_rate_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_slew_rate_39_wd), + .d (hw2reg.mio_pad_attr[39].slew_rate.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[8]), + .q (reg2hw.mio_pad_attr[39].slew_rate.q), + .ds (), + .qs (mio_pad_attr_39_slew_rate_39_qs) + ); + assign reg2hw.mio_pad_attr[39].slew_rate.qe = mio_pad_attr_39_qe; + + // F[drive_strength_39]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_39_drive_strength_39 ( + .re (mio_pad_attr_39_re), + .we (mio_pad_attr_39_gated_we), + .wd (mio_pad_attr_39_drive_strength_39_wd), + .d (hw2reg.mio_pad_attr[39].drive_strength.d), + .qre (), + .qe (mio_pad_attr_39_flds_we[9]), + .q (reg2hw.mio_pad_attr[39].drive_strength.q), + .ds (), + .qs (mio_pad_attr_39_drive_strength_39_qs) + ); + assign reg2hw.mio_pad_attr[39].drive_strength.qe = mio_pad_attr_39_qe; + + + // Subregister 40 of Multireg mio_pad_attr + // R[mio_pad_attr_40]: V(True) + logic mio_pad_attr_40_qe; + logic [9:0] mio_pad_attr_40_flds_we; + assign mio_pad_attr_40_qe = &mio_pad_attr_40_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_40_gated_we; + assign mio_pad_attr_40_gated_we = mio_pad_attr_40_we & mio_pad_attr_regwen_40_qs; + // F[invert_40]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_invert_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_invert_40_wd), + .d (hw2reg.mio_pad_attr[40].invert.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[0]), + .q (reg2hw.mio_pad_attr[40].invert.q), + .ds (), + .qs (mio_pad_attr_40_invert_40_qs) + ); + assign reg2hw.mio_pad_attr[40].invert.qe = mio_pad_attr_40_qe; + + // F[virtual_od_en_40]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_virtual_od_en_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_virtual_od_en_40_wd), + .d (hw2reg.mio_pad_attr[40].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[1]), + .q (reg2hw.mio_pad_attr[40].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_40_virtual_od_en_40_qs) + ); + assign reg2hw.mio_pad_attr[40].virtual_od_en.qe = mio_pad_attr_40_qe; + + // F[pull_en_40]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_pull_en_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_pull_en_40_wd), + .d (hw2reg.mio_pad_attr[40].pull_en.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[2]), + .q (reg2hw.mio_pad_attr[40].pull_en.q), + .ds (), + .qs (mio_pad_attr_40_pull_en_40_qs) + ); + assign reg2hw.mio_pad_attr[40].pull_en.qe = mio_pad_attr_40_qe; + + // F[pull_select_40]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_pull_select_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_pull_select_40_wd), + .d (hw2reg.mio_pad_attr[40].pull_select.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[3]), + .q (reg2hw.mio_pad_attr[40].pull_select.q), + .ds (), + .qs (mio_pad_attr_40_pull_select_40_qs) + ); + assign reg2hw.mio_pad_attr[40].pull_select.qe = mio_pad_attr_40_qe; + + // F[keeper_en_40]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_keeper_en_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_keeper_en_40_wd), + .d (hw2reg.mio_pad_attr[40].keeper_en.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[4]), + .q (reg2hw.mio_pad_attr[40].keeper_en.q), + .ds (), + .qs (mio_pad_attr_40_keeper_en_40_qs) + ); + assign reg2hw.mio_pad_attr[40].keeper_en.qe = mio_pad_attr_40_qe; + + // F[schmitt_en_40]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_schmitt_en_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_schmitt_en_40_wd), + .d (hw2reg.mio_pad_attr[40].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[5]), + .q (reg2hw.mio_pad_attr[40].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_40_schmitt_en_40_qs) + ); + assign reg2hw.mio_pad_attr[40].schmitt_en.qe = mio_pad_attr_40_qe; + + // F[od_en_40]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_od_en_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_od_en_40_wd), + .d (hw2reg.mio_pad_attr[40].od_en.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[6]), + .q (reg2hw.mio_pad_attr[40].od_en.q), + .ds (), + .qs (mio_pad_attr_40_od_en_40_qs) + ); + assign reg2hw.mio_pad_attr[40].od_en.qe = mio_pad_attr_40_qe; + + // F[input_disable_40]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_40_input_disable_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_input_disable_40_wd), + .d (hw2reg.mio_pad_attr[40].input_disable.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[7]), + .q (reg2hw.mio_pad_attr[40].input_disable.q), + .ds (), + .qs (mio_pad_attr_40_input_disable_40_qs) + ); + assign reg2hw.mio_pad_attr[40].input_disable.qe = mio_pad_attr_40_qe; + + // F[slew_rate_40]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_40_slew_rate_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_slew_rate_40_wd), + .d (hw2reg.mio_pad_attr[40].slew_rate.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[8]), + .q (reg2hw.mio_pad_attr[40].slew_rate.q), + .ds (), + .qs (mio_pad_attr_40_slew_rate_40_qs) + ); + assign reg2hw.mio_pad_attr[40].slew_rate.qe = mio_pad_attr_40_qe; + + // F[drive_strength_40]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_40_drive_strength_40 ( + .re (mio_pad_attr_40_re), + .we (mio_pad_attr_40_gated_we), + .wd (mio_pad_attr_40_drive_strength_40_wd), + .d (hw2reg.mio_pad_attr[40].drive_strength.d), + .qre (), + .qe (mio_pad_attr_40_flds_we[9]), + .q (reg2hw.mio_pad_attr[40].drive_strength.q), + .ds (), + .qs (mio_pad_attr_40_drive_strength_40_qs) + ); + assign reg2hw.mio_pad_attr[40].drive_strength.qe = mio_pad_attr_40_qe; + + + // Subregister 41 of Multireg mio_pad_attr + // R[mio_pad_attr_41]: V(True) + logic mio_pad_attr_41_qe; + logic [9:0] mio_pad_attr_41_flds_we; + assign mio_pad_attr_41_qe = &mio_pad_attr_41_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_41_gated_we; + assign mio_pad_attr_41_gated_we = mio_pad_attr_41_we & mio_pad_attr_regwen_41_qs; + // F[invert_41]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_invert_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_invert_41_wd), + .d (hw2reg.mio_pad_attr[41].invert.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[0]), + .q (reg2hw.mio_pad_attr[41].invert.q), + .ds (), + .qs (mio_pad_attr_41_invert_41_qs) + ); + assign reg2hw.mio_pad_attr[41].invert.qe = mio_pad_attr_41_qe; + + // F[virtual_od_en_41]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_virtual_od_en_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_virtual_od_en_41_wd), + .d (hw2reg.mio_pad_attr[41].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[1]), + .q (reg2hw.mio_pad_attr[41].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_41_virtual_od_en_41_qs) + ); + assign reg2hw.mio_pad_attr[41].virtual_od_en.qe = mio_pad_attr_41_qe; + + // F[pull_en_41]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_pull_en_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_pull_en_41_wd), + .d (hw2reg.mio_pad_attr[41].pull_en.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[2]), + .q (reg2hw.mio_pad_attr[41].pull_en.q), + .ds (), + .qs (mio_pad_attr_41_pull_en_41_qs) + ); + assign reg2hw.mio_pad_attr[41].pull_en.qe = mio_pad_attr_41_qe; + + // F[pull_select_41]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_pull_select_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_pull_select_41_wd), + .d (hw2reg.mio_pad_attr[41].pull_select.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[3]), + .q (reg2hw.mio_pad_attr[41].pull_select.q), + .ds (), + .qs (mio_pad_attr_41_pull_select_41_qs) + ); + assign reg2hw.mio_pad_attr[41].pull_select.qe = mio_pad_attr_41_qe; + + // F[keeper_en_41]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_keeper_en_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_keeper_en_41_wd), + .d (hw2reg.mio_pad_attr[41].keeper_en.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[4]), + .q (reg2hw.mio_pad_attr[41].keeper_en.q), + .ds (), + .qs (mio_pad_attr_41_keeper_en_41_qs) + ); + assign reg2hw.mio_pad_attr[41].keeper_en.qe = mio_pad_attr_41_qe; + + // F[schmitt_en_41]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_schmitt_en_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_schmitt_en_41_wd), + .d (hw2reg.mio_pad_attr[41].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[5]), + .q (reg2hw.mio_pad_attr[41].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_41_schmitt_en_41_qs) + ); + assign reg2hw.mio_pad_attr[41].schmitt_en.qe = mio_pad_attr_41_qe; + + // F[od_en_41]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_od_en_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_od_en_41_wd), + .d (hw2reg.mio_pad_attr[41].od_en.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[6]), + .q (reg2hw.mio_pad_attr[41].od_en.q), + .ds (), + .qs (mio_pad_attr_41_od_en_41_qs) + ); + assign reg2hw.mio_pad_attr[41].od_en.qe = mio_pad_attr_41_qe; + + // F[input_disable_41]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_41_input_disable_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_input_disable_41_wd), + .d (hw2reg.mio_pad_attr[41].input_disable.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[7]), + .q (reg2hw.mio_pad_attr[41].input_disable.q), + .ds (), + .qs (mio_pad_attr_41_input_disable_41_qs) + ); + assign reg2hw.mio_pad_attr[41].input_disable.qe = mio_pad_attr_41_qe; + + // F[slew_rate_41]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_41_slew_rate_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_slew_rate_41_wd), + .d (hw2reg.mio_pad_attr[41].slew_rate.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[8]), + .q (reg2hw.mio_pad_attr[41].slew_rate.q), + .ds (), + .qs (mio_pad_attr_41_slew_rate_41_qs) + ); + assign reg2hw.mio_pad_attr[41].slew_rate.qe = mio_pad_attr_41_qe; + + // F[drive_strength_41]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_41_drive_strength_41 ( + .re (mio_pad_attr_41_re), + .we (mio_pad_attr_41_gated_we), + .wd (mio_pad_attr_41_drive_strength_41_wd), + .d (hw2reg.mio_pad_attr[41].drive_strength.d), + .qre (), + .qe (mio_pad_attr_41_flds_we[9]), + .q (reg2hw.mio_pad_attr[41].drive_strength.q), + .ds (), + .qs (mio_pad_attr_41_drive_strength_41_qs) + ); + assign reg2hw.mio_pad_attr[41].drive_strength.qe = mio_pad_attr_41_qe; + + + // Subregister 42 of Multireg mio_pad_attr + // R[mio_pad_attr_42]: V(True) + logic mio_pad_attr_42_qe; + logic [9:0] mio_pad_attr_42_flds_we; + assign mio_pad_attr_42_qe = &mio_pad_attr_42_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_42_gated_we; + assign mio_pad_attr_42_gated_we = mio_pad_attr_42_we & mio_pad_attr_regwen_42_qs; + // F[invert_42]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_invert_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_invert_42_wd), + .d (hw2reg.mio_pad_attr[42].invert.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[0]), + .q (reg2hw.mio_pad_attr[42].invert.q), + .ds (), + .qs (mio_pad_attr_42_invert_42_qs) + ); + assign reg2hw.mio_pad_attr[42].invert.qe = mio_pad_attr_42_qe; + + // F[virtual_od_en_42]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_virtual_od_en_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_virtual_od_en_42_wd), + .d (hw2reg.mio_pad_attr[42].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[1]), + .q (reg2hw.mio_pad_attr[42].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_42_virtual_od_en_42_qs) + ); + assign reg2hw.mio_pad_attr[42].virtual_od_en.qe = mio_pad_attr_42_qe; + + // F[pull_en_42]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_pull_en_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_pull_en_42_wd), + .d (hw2reg.mio_pad_attr[42].pull_en.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[2]), + .q (reg2hw.mio_pad_attr[42].pull_en.q), + .ds (), + .qs (mio_pad_attr_42_pull_en_42_qs) + ); + assign reg2hw.mio_pad_attr[42].pull_en.qe = mio_pad_attr_42_qe; + + // F[pull_select_42]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_pull_select_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_pull_select_42_wd), + .d (hw2reg.mio_pad_attr[42].pull_select.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[3]), + .q (reg2hw.mio_pad_attr[42].pull_select.q), + .ds (), + .qs (mio_pad_attr_42_pull_select_42_qs) + ); + assign reg2hw.mio_pad_attr[42].pull_select.qe = mio_pad_attr_42_qe; + + // F[keeper_en_42]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_keeper_en_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_keeper_en_42_wd), + .d (hw2reg.mio_pad_attr[42].keeper_en.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[4]), + .q (reg2hw.mio_pad_attr[42].keeper_en.q), + .ds (), + .qs (mio_pad_attr_42_keeper_en_42_qs) + ); + assign reg2hw.mio_pad_attr[42].keeper_en.qe = mio_pad_attr_42_qe; + + // F[schmitt_en_42]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_schmitt_en_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_schmitt_en_42_wd), + .d (hw2reg.mio_pad_attr[42].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[5]), + .q (reg2hw.mio_pad_attr[42].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_42_schmitt_en_42_qs) + ); + assign reg2hw.mio_pad_attr[42].schmitt_en.qe = mio_pad_attr_42_qe; + + // F[od_en_42]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_od_en_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_od_en_42_wd), + .d (hw2reg.mio_pad_attr[42].od_en.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[6]), + .q (reg2hw.mio_pad_attr[42].od_en.q), + .ds (), + .qs (mio_pad_attr_42_od_en_42_qs) + ); + assign reg2hw.mio_pad_attr[42].od_en.qe = mio_pad_attr_42_qe; + + // F[input_disable_42]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_42_input_disable_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_input_disable_42_wd), + .d (hw2reg.mio_pad_attr[42].input_disable.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[7]), + .q (reg2hw.mio_pad_attr[42].input_disable.q), + .ds (), + .qs (mio_pad_attr_42_input_disable_42_qs) + ); + assign reg2hw.mio_pad_attr[42].input_disable.qe = mio_pad_attr_42_qe; + + // F[slew_rate_42]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_42_slew_rate_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_slew_rate_42_wd), + .d (hw2reg.mio_pad_attr[42].slew_rate.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[8]), + .q (reg2hw.mio_pad_attr[42].slew_rate.q), + .ds (), + .qs (mio_pad_attr_42_slew_rate_42_qs) + ); + assign reg2hw.mio_pad_attr[42].slew_rate.qe = mio_pad_attr_42_qe; + + // F[drive_strength_42]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_42_drive_strength_42 ( + .re (mio_pad_attr_42_re), + .we (mio_pad_attr_42_gated_we), + .wd (mio_pad_attr_42_drive_strength_42_wd), + .d (hw2reg.mio_pad_attr[42].drive_strength.d), + .qre (), + .qe (mio_pad_attr_42_flds_we[9]), + .q (reg2hw.mio_pad_attr[42].drive_strength.q), + .ds (), + .qs (mio_pad_attr_42_drive_strength_42_qs) + ); + assign reg2hw.mio_pad_attr[42].drive_strength.qe = mio_pad_attr_42_qe; + + + // Subregister 43 of Multireg mio_pad_attr + // R[mio_pad_attr_43]: V(True) + logic mio_pad_attr_43_qe; + logic [9:0] mio_pad_attr_43_flds_we; + assign mio_pad_attr_43_qe = &mio_pad_attr_43_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_43_gated_we; + assign mio_pad_attr_43_gated_we = mio_pad_attr_43_we & mio_pad_attr_regwen_43_qs; + // F[invert_43]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_invert_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_invert_43_wd), + .d (hw2reg.mio_pad_attr[43].invert.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[0]), + .q (reg2hw.mio_pad_attr[43].invert.q), + .ds (), + .qs (mio_pad_attr_43_invert_43_qs) + ); + assign reg2hw.mio_pad_attr[43].invert.qe = mio_pad_attr_43_qe; + + // F[virtual_od_en_43]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_virtual_od_en_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_virtual_od_en_43_wd), + .d (hw2reg.mio_pad_attr[43].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[1]), + .q (reg2hw.mio_pad_attr[43].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_43_virtual_od_en_43_qs) + ); + assign reg2hw.mio_pad_attr[43].virtual_od_en.qe = mio_pad_attr_43_qe; + + // F[pull_en_43]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_pull_en_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_pull_en_43_wd), + .d (hw2reg.mio_pad_attr[43].pull_en.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[2]), + .q (reg2hw.mio_pad_attr[43].pull_en.q), + .ds (), + .qs (mio_pad_attr_43_pull_en_43_qs) + ); + assign reg2hw.mio_pad_attr[43].pull_en.qe = mio_pad_attr_43_qe; + + // F[pull_select_43]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_pull_select_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_pull_select_43_wd), + .d (hw2reg.mio_pad_attr[43].pull_select.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[3]), + .q (reg2hw.mio_pad_attr[43].pull_select.q), + .ds (), + .qs (mio_pad_attr_43_pull_select_43_qs) + ); + assign reg2hw.mio_pad_attr[43].pull_select.qe = mio_pad_attr_43_qe; + + // F[keeper_en_43]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_keeper_en_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_keeper_en_43_wd), + .d (hw2reg.mio_pad_attr[43].keeper_en.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[4]), + .q (reg2hw.mio_pad_attr[43].keeper_en.q), + .ds (), + .qs (mio_pad_attr_43_keeper_en_43_qs) + ); + assign reg2hw.mio_pad_attr[43].keeper_en.qe = mio_pad_attr_43_qe; + + // F[schmitt_en_43]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_schmitt_en_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_schmitt_en_43_wd), + .d (hw2reg.mio_pad_attr[43].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[5]), + .q (reg2hw.mio_pad_attr[43].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_43_schmitt_en_43_qs) + ); + assign reg2hw.mio_pad_attr[43].schmitt_en.qe = mio_pad_attr_43_qe; + + // F[od_en_43]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_od_en_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_od_en_43_wd), + .d (hw2reg.mio_pad_attr[43].od_en.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[6]), + .q (reg2hw.mio_pad_attr[43].od_en.q), + .ds (), + .qs (mio_pad_attr_43_od_en_43_qs) + ); + assign reg2hw.mio_pad_attr[43].od_en.qe = mio_pad_attr_43_qe; + + // F[input_disable_43]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_43_input_disable_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_input_disable_43_wd), + .d (hw2reg.mio_pad_attr[43].input_disable.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[7]), + .q (reg2hw.mio_pad_attr[43].input_disable.q), + .ds (), + .qs (mio_pad_attr_43_input_disable_43_qs) + ); + assign reg2hw.mio_pad_attr[43].input_disable.qe = mio_pad_attr_43_qe; + + // F[slew_rate_43]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_43_slew_rate_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_slew_rate_43_wd), + .d (hw2reg.mio_pad_attr[43].slew_rate.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[8]), + .q (reg2hw.mio_pad_attr[43].slew_rate.q), + .ds (), + .qs (mio_pad_attr_43_slew_rate_43_qs) + ); + assign reg2hw.mio_pad_attr[43].slew_rate.qe = mio_pad_attr_43_qe; + + // F[drive_strength_43]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_43_drive_strength_43 ( + .re (mio_pad_attr_43_re), + .we (mio_pad_attr_43_gated_we), + .wd (mio_pad_attr_43_drive_strength_43_wd), + .d (hw2reg.mio_pad_attr[43].drive_strength.d), + .qre (), + .qe (mio_pad_attr_43_flds_we[9]), + .q (reg2hw.mio_pad_attr[43].drive_strength.q), + .ds (), + .qs (mio_pad_attr_43_drive_strength_43_qs) + ); + assign reg2hw.mio_pad_attr[43].drive_strength.qe = mio_pad_attr_43_qe; + + + // Subregister 44 of Multireg mio_pad_attr + // R[mio_pad_attr_44]: V(True) + logic mio_pad_attr_44_qe; + logic [9:0] mio_pad_attr_44_flds_we; + assign mio_pad_attr_44_qe = &mio_pad_attr_44_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_44_gated_we; + assign mio_pad_attr_44_gated_we = mio_pad_attr_44_we & mio_pad_attr_regwen_44_qs; + // F[invert_44]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_invert_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_invert_44_wd), + .d (hw2reg.mio_pad_attr[44].invert.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[0]), + .q (reg2hw.mio_pad_attr[44].invert.q), + .ds (), + .qs (mio_pad_attr_44_invert_44_qs) + ); + assign reg2hw.mio_pad_attr[44].invert.qe = mio_pad_attr_44_qe; + + // F[virtual_od_en_44]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_virtual_od_en_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_virtual_od_en_44_wd), + .d (hw2reg.mio_pad_attr[44].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[1]), + .q (reg2hw.mio_pad_attr[44].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_44_virtual_od_en_44_qs) + ); + assign reg2hw.mio_pad_attr[44].virtual_od_en.qe = mio_pad_attr_44_qe; + + // F[pull_en_44]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_pull_en_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_pull_en_44_wd), + .d (hw2reg.mio_pad_attr[44].pull_en.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[2]), + .q (reg2hw.mio_pad_attr[44].pull_en.q), + .ds (), + .qs (mio_pad_attr_44_pull_en_44_qs) + ); + assign reg2hw.mio_pad_attr[44].pull_en.qe = mio_pad_attr_44_qe; + + // F[pull_select_44]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_pull_select_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_pull_select_44_wd), + .d (hw2reg.mio_pad_attr[44].pull_select.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[3]), + .q (reg2hw.mio_pad_attr[44].pull_select.q), + .ds (), + .qs (mio_pad_attr_44_pull_select_44_qs) + ); + assign reg2hw.mio_pad_attr[44].pull_select.qe = mio_pad_attr_44_qe; + + // F[keeper_en_44]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_keeper_en_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_keeper_en_44_wd), + .d (hw2reg.mio_pad_attr[44].keeper_en.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[4]), + .q (reg2hw.mio_pad_attr[44].keeper_en.q), + .ds (), + .qs (mio_pad_attr_44_keeper_en_44_qs) + ); + assign reg2hw.mio_pad_attr[44].keeper_en.qe = mio_pad_attr_44_qe; + + // F[schmitt_en_44]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_schmitt_en_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_schmitt_en_44_wd), + .d (hw2reg.mio_pad_attr[44].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[5]), + .q (reg2hw.mio_pad_attr[44].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_44_schmitt_en_44_qs) + ); + assign reg2hw.mio_pad_attr[44].schmitt_en.qe = mio_pad_attr_44_qe; + + // F[od_en_44]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_od_en_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_od_en_44_wd), + .d (hw2reg.mio_pad_attr[44].od_en.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[6]), + .q (reg2hw.mio_pad_attr[44].od_en.q), + .ds (), + .qs (mio_pad_attr_44_od_en_44_qs) + ); + assign reg2hw.mio_pad_attr[44].od_en.qe = mio_pad_attr_44_qe; + + // F[input_disable_44]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_44_input_disable_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_input_disable_44_wd), + .d (hw2reg.mio_pad_attr[44].input_disable.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[7]), + .q (reg2hw.mio_pad_attr[44].input_disable.q), + .ds (), + .qs (mio_pad_attr_44_input_disable_44_qs) + ); + assign reg2hw.mio_pad_attr[44].input_disable.qe = mio_pad_attr_44_qe; + + // F[slew_rate_44]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_44_slew_rate_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_slew_rate_44_wd), + .d (hw2reg.mio_pad_attr[44].slew_rate.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[8]), + .q (reg2hw.mio_pad_attr[44].slew_rate.q), + .ds (), + .qs (mio_pad_attr_44_slew_rate_44_qs) + ); + assign reg2hw.mio_pad_attr[44].slew_rate.qe = mio_pad_attr_44_qe; + + // F[drive_strength_44]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_44_drive_strength_44 ( + .re (mio_pad_attr_44_re), + .we (mio_pad_attr_44_gated_we), + .wd (mio_pad_attr_44_drive_strength_44_wd), + .d (hw2reg.mio_pad_attr[44].drive_strength.d), + .qre (), + .qe (mio_pad_attr_44_flds_we[9]), + .q (reg2hw.mio_pad_attr[44].drive_strength.q), + .ds (), + .qs (mio_pad_attr_44_drive_strength_44_qs) + ); + assign reg2hw.mio_pad_attr[44].drive_strength.qe = mio_pad_attr_44_qe; + + + // Subregister 45 of Multireg mio_pad_attr + // R[mio_pad_attr_45]: V(True) + logic mio_pad_attr_45_qe; + logic [9:0] mio_pad_attr_45_flds_we; + assign mio_pad_attr_45_qe = &mio_pad_attr_45_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_45_gated_we; + assign mio_pad_attr_45_gated_we = mio_pad_attr_45_we & mio_pad_attr_regwen_45_qs; + // F[invert_45]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_invert_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_invert_45_wd), + .d (hw2reg.mio_pad_attr[45].invert.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[0]), + .q (reg2hw.mio_pad_attr[45].invert.q), + .ds (), + .qs (mio_pad_attr_45_invert_45_qs) + ); + assign reg2hw.mio_pad_attr[45].invert.qe = mio_pad_attr_45_qe; + + // F[virtual_od_en_45]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_virtual_od_en_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_virtual_od_en_45_wd), + .d (hw2reg.mio_pad_attr[45].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[1]), + .q (reg2hw.mio_pad_attr[45].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_45_virtual_od_en_45_qs) + ); + assign reg2hw.mio_pad_attr[45].virtual_od_en.qe = mio_pad_attr_45_qe; + + // F[pull_en_45]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_pull_en_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_pull_en_45_wd), + .d (hw2reg.mio_pad_attr[45].pull_en.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[2]), + .q (reg2hw.mio_pad_attr[45].pull_en.q), + .ds (), + .qs (mio_pad_attr_45_pull_en_45_qs) + ); + assign reg2hw.mio_pad_attr[45].pull_en.qe = mio_pad_attr_45_qe; + + // F[pull_select_45]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_pull_select_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_pull_select_45_wd), + .d (hw2reg.mio_pad_attr[45].pull_select.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[3]), + .q (reg2hw.mio_pad_attr[45].pull_select.q), + .ds (), + .qs (mio_pad_attr_45_pull_select_45_qs) + ); + assign reg2hw.mio_pad_attr[45].pull_select.qe = mio_pad_attr_45_qe; + + // F[keeper_en_45]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_keeper_en_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_keeper_en_45_wd), + .d (hw2reg.mio_pad_attr[45].keeper_en.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[4]), + .q (reg2hw.mio_pad_attr[45].keeper_en.q), + .ds (), + .qs (mio_pad_attr_45_keeper_en_45_qs) + ); + assign reg2hw.mio_pad_attr[45].keeper_en.qe = mio_pad_attr_45_qe; + + // F[schmitt_en_45]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_schmitt_en_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_schmitt_en_45_wd), + .d (hw2reg.mio_pad_attr[45].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[5]), + .q (reg2hw.mio_pad_attr[45].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_45_schmitt_en_45_qs) + ); + assign reg2hw.mio_pad_attr[45].schmitt_en.qe = mio_pad_attr_45_qe; + + // F[od_en_45]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_od_en_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_od_en_45_wd), + .d (hw2reg.mio_pad_attr[45].od_en.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[6]), + .q (reg2hw.mio_pad_attr[45].od_en.q), + .ds (), + .qs (mio_pad_attr_45_od_en_45_qs) + ); + assign reg2hw.mio_pad_attr[45].od_en.qe = mio_pad_attr_45_qe; + + // F[input_disable_45]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_45_input_disable_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_input_disable_45_wd), + .d (hw2reg.mio_pad_attr[45].input_disable.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[7]), + .q (reg2hw.mio_pad_attr[45].input_disable.q), + .ds (), + .qs (mio_pad_attr_45_input_disable_45_qs) + ); + assign reg2hw.mio_pad_attr[45].input_disable.qe = mio_pad_attr_45_qe; + + // F[slew_rate_45]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_45_slew_rate_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_slew_rate_45_wd), + .d (hw2reg.mio_pad_attr[45].slew_rate.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[8]), + .q (reg2hw.mio_pad_attr[45].slew_rate.q), + .ds (), + .qs (mio_pad_attr_45_slew_rate_45_qs) + ); + assign reg2hw.mio_pad_attr[45].slew_rate.qe = mio_pad_attr_45_qe; + + // F[drive_strength_45]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_45_drive_strength_45 ( + .re (mio_pad_attr_45_re), + .we (mio_pad_attr_45_gated_we), + .wd (mio_pad_attr_45_drive_strength_45_wd), + .d (hw2reg.mio_pad_attr[45].drive_strength.d), + .qre (), + .qe (mio_pad_attr_45_flds_we[9]), + .q (reg2hw.mio_pad_attr[45].drive_strength.q), + .ds (), + .qs (mio_pad_attr_45_drive_strength_45_qs) + ); + assign reg2hw.mio_pad_attr[45].drive_strength.qe = mio_pad_attr_45_qe; + + + // Subregister 46 of Multireg mio_pad_attr + // R[mio_pad_attr_46]: V(True) + logic mio_pad_attr_46_qe; + logic [9:0] mio_pad_attr_46_flds_we; + assign mio_pad_attr_46_qe = &mio_pad_attr_46_flds_we; + // Create REGWEN-gated WE signal + logic mio_pad_attr_46_gated_we; + assign mio_pad_attr_46_gated_we = mio_pad_attr_46_we & mio_pad_attr_regwen_46_qs; + // F[invert_46]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_invert_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_invert_46_wd), + .d (hw2reg.mio_pad_attr[46].invert.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[0]), + .q (reg2hw.mio_pad_attr[46].invert.q), + .ds (), + .qs (mio_pad_attr_46_invert_46_qs) + ); + assign reg2hw.mio_pad_attr[46].invert.qe = mio_pad_attr_46_qe; + + // F[virtual_od_en_46]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_virtual_od_en_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_virtual_od_en_46_wd), + .d (hw2reg.mio_pad_attr[46].virtual_od_en.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[1]), + .q (reg2hw.mio_pad_attr[46].virtual_od_en.q), + .ds (), + .qs (mio_pad_attr_46_virtual_od_en_46_qs) + ); + assign reg2hw.mio_pad_attr[46].virtual_od_en.qe = mio_pad_attr_46_qe; + + // F[pull_en_46]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_pull_en_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_pull_en_46_wd), + .d (hw2reg.mio_pad_attr[46].pull_en.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[2]), + .q (reg2hw.mio_pad_attr[46].pull_en.q), + .ds (), + .qs (mio_pad_attr_46_pull_en_46_qs) + ); + assign reg2hw.mio_pad_attr[46].pull_en.qe = mio_pad_attr_46_qe; + + // F[pull_select_46]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_pull_select_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_pull_select_46_wd), + .d (hw2reg.mio_pad_attr[46].pull_select.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[3]), + .q (reg2hw.mio_pad_attr[46].pull_select.q), + .ds (), + .qs (mio_pad_attr_46_pull_select_46_qs) + ); + assign reg2hw.mio_pad_attr[46].pull_select.qe = mio_pad_attr_46_qe; + + // F[keeper_en_46]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_keeper_en_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_keeper_en_46_wd), + .d (hw2reg.mio_pad_attr[46].keeper_en.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[4]), + .q (reg2hw.mio_pad_attr[46].keeper_en.q), + .ds (), + .qs (mio_pad_attr_46_keeper_en_46_qs) + ); + assign reg2hw.mio_pad_attr[46].keeper_en.qe = mio_pad_attr_46_qe; + + // F[schmitt_en_46]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_schmitt_en_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_schmitt_en_46_wd), + .d (hw2reg.mio_pad_attr[46].schmitt_en.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[5]), + .q (reg2hw.mio_pad_attr[46].schmitt_en.q), + .ds (), + .qs (mio_pad_attr_46_schmitt_en_46_qs) + ); + assign reg2hw.mio_pad_attr[46].schmitt_en.qe = mio_pad_attr_46_qe; + + // F[od_en_46]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_od_en_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_od_en_46_wd), + .d (hw2reg.mio_pad_attr[46].od_en.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[6]), + .q (reg2hw.mio_pad_attr[46].od_en.q), + .ds (), + .qs (mio_pad_attr_46_od_en_46_qs) + ); + assign reg2hw.mio_pad_attr[46].od_en.qe = mio_pad_attr_46_qe; + + // F[input_disable_46]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_mio_pad_attr_46_input_disable_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_input_disable_46_wd), + .d (hw2reg.mio_pad_attr[46].input_disable.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[7]), + .q (reg2hw.mio_pad_attr[46].input_disable.q), + .ds (), + .qs (mio_pad_attr_46_input_disable_46_qs) + ); + assign reg2hw.mio_pad_attr[46].input_disable.qe = mio_pad_attr_46_qe; + + // F[slew_rate_46]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_mio_pad_attr_46_slew_rate_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_slew_rate_46_wd), + .d (hw2reg.mio_pad_attr[46].slew_rate.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[8]), + .q (reg2hw.mio_pad_attr[46].slew_rate.q), + .ds (), + .qs (mio_pad_attr_46_slew_rate_46_qs) + ); + assign reg2hw.mio_pad_attr[46].slew_rate.qe = mio_pad_attr_46_qe; + + // F[drive_strength_46]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_mio_pad_attr_46_drive_strength_46 ( + .re (mio_pad_attr_46_re), + .we (mio_pad_attr_46_gated_we), + .wd (mio_pad_attr_46_drive_strength_46_wd), + .d (hw2reg.mio_pad_attr[46].drive_strength.d), + .qre (), + .qe (mio_pad_attr_46_flds_we[9]), + .q (reg2hw.mio_pad_attr[46].drive_strength.q), + .ds (), + .qs (mio_pad_attr_46_drive_strength_46_qs) + ); + assign reg2hw.mio_pad_attr[46].drive_strength.qe = mio_pad_attr_46_qe; + + + // Subregister 0 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_0_we), + .wd (dio_pad_attr_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_0_qs) + ); + + + // Subregister 1 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_1_we), + .wd (dio_pad_attr_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_1_qs) + ); + + + // Subregister 2 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_2_we), + .wd (dio_pad_attr_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_2_qs) + ); + + + // Subregister 3 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_3_we), + .wd (dio_pad_attr_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_3_qs) + ); + + + // Subregister 4 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_4_we), + .wd (dio_pad_attr_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_4_qs) + ); + + + // Subregister 5 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_5_we), + .wd (dio_pad_attr_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_5_qs) + ); + + + // Subregister 6 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_6_we), + .wd (dio_pad_attr_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_6_qs) + ); + + + // Subregister 7 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_7_we), + .wd (dio_pad_attr_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_7_qs) + ); + + + // Subregister 8 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_8_we), + .wd (dio_pad_attr_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_8_qs) + ); + + + // Subregister 9 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_9_we), + .wd (dio_pad_attr_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_9_qs) + ); + + + // Subregister 10 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_10]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_10_we), + .wd (dio_pad_attr_regwen_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_10_qs) + ); + + + // Subregister 11 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_11]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_11_we), + .wd (dio_pad_attr_regwen_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_11_qs) + ); + + + // Subregister 12 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_12]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_12_we), + .wd (dio_pad_attr_regwen_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_12_qs) + ); + + + // Subregister 13 of Multireg dio_pad_attr_regwen + // R[dio_pad_attr_regwen_13]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_attr_regwen_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_attr_regwen_13_we), + .wd (dio_pad_attr_regwen_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_attr_regwen_13_qs) + ); + + + // Subregister 0 of Multireg dio_pad_attr + // R[dio_pad_attr_0]: V(True) + logic dio_pad_attr_0_qe; + logic [9:0] dio_pad_attr_0_flds_we; + assign dio_pad_attr_0_qe = &dio_pad_attr_0_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_0_gated_we; + assign dio_pad_attr_0_gated_we = dio_pad_attr_0_we & dio_pad_attr_regwen_0_qs; + // F[invert_0]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_invert_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_invert_0_wd), + .d (hw2reg.dio_pad_attr[0].invert.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[0]), + .q (reg2hw.dio_pad_attr[0].invert.q), + .ds (), + .qs (dio_pad_attr_0_invert_0_qs) + ); + assign reg2hw.dio_pad_attr[0].invert.qe = dio_pad_attr_0_qe; + + // F[virtual_od_en_0]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_virtual_od_en_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_virtual_od_en_0_wd), + .d (hw2reg.dio_pad_attr[0].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[1]), + .q (reg2hw.dio_pad_attr[0].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_0_virtual_od_en_0_qs) + ); + assign reg2hw.dio_pad_attr[0].virtual_od_en.qe = dio_pad_attr_0_qe; + + // F[pull_en_0]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_pull_en_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_pull_en_0_wd), + .d (hw2reg.dio_pad_attr[0].pull_en.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[2]), + .q (reg2hw.dio_pad_attr[0].pull_en.q), + .ds (), + .qs (dio_pad_attr_0_pull_en_0_qs) + ); + assign reg2hw.dio_pad_attr[0].pull_en.qe = dio_pad_attr_0_qe; + + // F[pull_select_0]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_pull_select_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_pull_select_0_wd), + .d (hw2reg.dio_pad_attr[0].pull_select.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[3]), + .q (reg2hw.dio_pad_attr[0].pull_select.q), + .ds (), + .qs (dio_pad_attr_0_pull_select_0_qs) + ); + assign reg2hw.dio_pad_attr[0].pull_select.qe = dio_pad_attr_0_qe; + + // F[keeper_en_0]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_keeper_en_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_keeper_en_0_wd), + .d (hw2reg.dio_pad_attr[0].keeper_en.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[4]), + .q (reg2hw.dio_pad_attr[0].keeper_en.q), + .ds (), + .qs (dio_pad_attr_0_keeper_en_0_qs) + ); + assign reg2hw.dio_pad_attr[0].keeper_en.qe = dio_pad_attr_0_qe; + + // F[schmitt_en_0]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_schmitt_en_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_schmitt_en_0_wd), + .d (hw2reg.dio_pad_attr[0].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[5]), + .q (reg2hw.dio_pad_attr[0].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_0_schmitt_en_0_qs) + ); + assign reg2hw.dio_pad_attr[0].schmitt_en.qe = dio_pad_attr_0_qe; + + // F[od_en_0]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_od_en_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_od_en_0_wd), + .d (hw2reg.dio_pad_attr[0].od_en.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[6]), + .q (reg2hw.dio_pad_attr[0].od_en.q), + .ds (), + .qs (dio_pad_attr_0_od_en_0_qs) + ); + assign reg2hw.dio_pad_attr[0].od_en.qe = dio_pad_attr_0_qe; + + // F[input_disable_0]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_0_input_disable_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_input_disable_0_wd), + .d (hw2reg.dio_pad_attr[0].input_disable.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[7]), + .q (reg2hw.dio_pad_attr[0].input_disable.q), + .ds (), + .qs (dio_pad_attr_0_input_disable_0_qs) + ); + assign reg2hw.dio_pad_attr[0].input_disable.qe = dio_pad_attr_0_qe; + + // F[slew_rate_0]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_0_slew_rate_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_slew_rate_0_wd), + .d (hw2reg.dio_pad_attr[0].slew_rate.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[8]), + .q (reg2hw.dio_pad_attr[0].slew_rate.q), + .ds (), + .qs (dio_pad_attr_0_slew_rate_0_qs) + ); + assign reg2hw.dio_pad_attr[0].slew_rate.qe = dio_pad_attr_0_qe; + + // F[drive_strength_0]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_0_drive_strength_0 ( + .re (dio_pad_attr_0_re), + .we (dio_pad_attr_0_gated_we), + .wd (dio_pad_attr_0_drive_strength_0_wd), + .d (hw2reg.dio_pad_attr[0].drive_strength.d), + .qre (), + .qe (dio_pad_attr_0_flds_we[9]), + .q (reg2hw.dio_pad_attr[0].drive_strength.q), + .ds (), + .qs (dio_pad_attr_0_drive_strength_0_qs) + ); + assign reg2hw.dio_pad_attr[0].drive_strength.qe = dio_pad_attr_0_qe; + + + // Subregister 1 of Multireg dio_pad_attr + // R[dio_pad_attr_1]: V(True) + logic dio_pad_attr_1_qe; + logic [9:0] dio_pad_attr_1_flds_we; + assign dio_pad_attr_1_qe = &dio_pad_attr_1_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_1_gated_we; + assign dio_pad_attr_1_gated_we = dio_pad_attr_1_we & dio_pad_attr_regwen_1_qs; + // F[invert_1]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_invert_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_invert_1_wd), + .d (hw2reg.dio_pad_attr[1].invert.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[0]), + .q (reg2hw.dio_pad_attr[1].invert.q), + .ds (), + .qs (dio_pad_attr_1_invert_1_qs) + ); + assign reg2hw.dio_pad_attr[1].invert.qe = dio_pad_attr_1_qe; + + // F[virtual_od_en_1]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_virtual_od_en_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_virtual_od_en_1_wd), + .d (hw2reg.dio_pad_attr[1].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[1]), + .q (reg2hw.dio_pad_attr[1].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_1_virtual_od_en_1_qs) + ); + assign reg2hw.dio_pad_attr[1].virtual_od_en.qe = dio_pad_attr_1_qe; + + // F[pull_en_1]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_pull_en_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_pull_en_1_wd), + .d (hw2reg.dio_pad_attr[1].pull_en.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[2]), + .q (reg2hw.dio_pad_attr[1].pull_en.q), + .ds (), + .qs (dio_pad_attr_1_pull_en_1_qs) + ); + assign reg2hw.dio_pad_attr[1].pull_en.qe = dio_pad_attr_1_qe; + + // F[pull_select_1]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_pull_select_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_pull_select_1_wd), + .d (hw2reg.dio_pad_attr[1].pull_select.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[3]), + .q (reg2hw.dio_pad_attr[1].pull_select.q), + .ds (), + .qs (dio_pad_attr_1_pull_select_1_qs) + ); + assign reg2hw.dio_pad_attr[1].pull_select.qe = dio_pad_attr_1_qe; + + // F[keeper_en_1]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_keeper_en_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_keeper_en_1_wd), + .d (hw2reg.dio_pad_attr[1].keeper_en.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[4]), + .q (reg2hw.dio_pad_attr[1].keeper_en.q), + .ds (), + .qs (dio_pad_attr_1_keeper_en_1_qs) + ); + assign reg2hw.dio_pad_attr[1].keeper_en.qe = dio_pad_attr_1_qe; + + // F[schmitt_en_1]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_schmitt_en_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_schmitt_en_1_wd), + .d (hw2reg.dio_pad_attr[1].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[5]), + .q (reg2hw.dio_pad_attr[1].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_1_schmitt_en_1_qs) + ); + assign reg2hw.dio_pad_attr[1].schmitt_en.qe = dio_pad_attr_1_qe; + + // F[od_en_1]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_od_en_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_od_en_1_wd), + .d (hw2reg.dio_pad_attr[1].od_en.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[6]), + .q (reg2hw.dio_pad_attr[1].od_en.q), + .ds (), + .qs (dio_pad_attr_1_od_en_1_qs) + ); + assign reg2hw.dio_pad_attr[1].od_en.qe = dio_pad_attr_1_qe; + + // F[input_disable_1]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_1_input_disable_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_input_disable_1_wd), + .d (hw2reg.dio_pad_attr[1].input_disable.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[7]), + .q (reg2hw.dio_pad_attr[1].input_disable.q), + .ds (), + .qs (dio_pad_attr_1_input_disable_1_qs) + ); + assign reg2hw.dio_pad_attr[1].input_disable.qe = dio_pad_attr_1_qe; + + // F[slew_rate_1]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_1_slew_rate_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_slew_rate_1_wd), + .d (hw2reg.dio_pad_attr[1].slew_rate.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[8]), + .q (reg2hw.dio_pad_attr[1].slew_rate.q), + .ds (), + .qs (dio_pad_attr_1_slew_rate_1_qs) + ); + assign reg2hw.dio_pad_attr[1].slew_rate.qe = dio_pad_attr_1_qe; + + // F[drive_strength_1]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_1_drive_strength_1 ( + .re (dio_pad_attr_1_re), + .we (dio_pad_attr_1_gated_we), + .wd (dio_pad_attr_1_drive_strength_1_wd), + .d (hw2reg.dio_pad_attr[1].drive_strength.d), + .qre (), + .qe (dio_pad_attr_1_flds_we[9]), + .q (reg2hw.dio_pad_attr[1].drive_strength.q), + .ds (), + .qs (dio_pad_attr_1_drive_strength_1_qs) + ); + assign reg2hw.dio_pad_attr[1].drive_strength.qe = dio_pad_attr_1_qe; + + + // Subregister 2 of Multireg dio_pad_attr + // R[dio_pad_attr_2]: V(True) + logic dio_pad_attr_2_qe; + logic [9:0] dio_pad_attr_2_flds_we; + assign dio_pad_attr_2_qe = &dio_pad_attr_2_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_2_gated_we; + assign dio_pad_attr_2_gated_we = dio_pad_attr_2_we & dio_pad_attr_regwen_2_qs; + // F[invert_2]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_invert_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_invert_2_wd), + .d (hw2reg.dio_pad_attr[2].invert.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[0]), + .q (reg2hw.dio_pad_attr[2].invert.q), + .ds (), + .qs (dio_pad_attr_2_invert_2_qs) + ); + assign reg2hw.dio_pad_attr[2].invert.qe = dio_pad_attr_2_qe; + + // F[virtual_od_en_2]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_virtual_od_en_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_virtual_od_en_2_wd), + .d (hw2reg.dio_pad_attr[2].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[1]), + .q (reg2hw.dio_pad_attr[2].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_2_virtual_od_en_2_qs) + ); + assign reg2hw.dio_pad_attr[2].virtual_od_en.qe = dio_pad_attr_2_qe; + + // F[pull_en_2]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_pull_en_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_pull_en_2_wd), + .d (hw2reg.dio_pad_attr[2].pull_en.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[2]), + .q (reg2hw.dio_pad_attr[2].pull_en.q), + .ds (), + .qs (dio_pad_attr_2_pull_en_2_qs) + ); + assign reg2hw.dio_pad_attr[2].pull_en.qe = dio_pad_attr_2_qe; + + // F[pull_select_2]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_pull_select_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_pull_select_2_wd), + .d (hw2reg.dio_pad_attr[2].pull_select.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[3]), + .q (reg2hw.dio_pad_attr[2].pull_select.q), + .ds (), + .qs (dio_pad_attr_2_pull_select_2_qs) + ); + assign reg2hw.dio_pad_attr[2].pull_select.qe = dio_pad_attr_2_qe; + + // F[keeper_en_2]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_keeper_en_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_keeper_en_2_wd), + .d (hw2reg.dio_pad_attr[2].keeper_en.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[4]), + .q (reg2hw.dio_pad_attr[2].keeper_en.q), + .ds (), + .qs (dio_pad_attr_2_keeper_en_2_qs) + ); + assign reg2hw.dio_pad_attr[2].keeper_en.qe = dio_pad_attr_2_qe; + + // F[schmitt_en_2]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_schmitt_en_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_schmitt_en_2_wd), + .d (hw2reg.dio_pad_attr[2].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[5]), + .q (reg2hw.dio_pad_attr[2].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_2_schmitt_en_2_qs) + ); + assign reg2hw.dio_pad_attr[2].schmitt_en.qe = dio_pad_attr_2_qe; + + // F[od_en_2]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_od_en_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_od_en_2_wd), + .d (hw2reg.dio_pad_attr[2].od_en.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[6]), + .q (reg2hw.dio_pad_attr[2].od_en.q), + .ds (), + .qs (dio_pad_attr_2_od_en_2_qs) + ); + assign reg2hw.dio_pad_attr[2].od_en.qe = dio_pad_attr_2_qe; + + // F[input_disable_2]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_2_input_disable_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_input_disable_2_wd), + .d (hw2reg.dio_pad_attr[2].input_disable.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[7]), + .q (reg2hw.dio_pad_attr[2].input_disable.q), + .ds (), + .qs (dio_pad_attr_2_input_disable_2_qs) + ); + assign reg2hw.dio_pad_attr[2].input_disable.qe = dio_pad_attr_2_qe; + + // F[slew_rate_2]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_2_slew_rate_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_slew_rate_2_wd), + .d (hw2reg.dio_pad_attr[2].slew_rate.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[8]), + .q (reg2hw.dio_pad_attr[2].slew_rate.q), + .ds (), + .qs (dio_pad_attr_2_slew_rate_2_qs) + ); + assign reg2hw.dio_pad_attr[2].slew_rate.qe = dio_pad_attr_2_qe; + + // F[drive_strength_2]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_2_drive_strength_2 ( + .re (dio_pad_attr_2_re), + .we (dio_pad_attr_2_gated_we), + .wd (dio_pad_attr_2_drive_strength_2_wd), + .d (hw2reg.dio_pad_attr[2].drive_strength.d), + .qre (), + .qe (dio_pad_attr_2_flds_we[9]), + .q (reg2hw.dio_pad_attr[2].drive_strength.q), + .ds (), + .qs (dio_pad_attr_2_drive_strength_2_qs) + ); + assign reg2hw.dio_pad_attr[2].drive_strength.qe = dio_pad_attr_2_qe; + + + // Subregister 3 of Multireg dio_pad_attr + // R[dio_pad_attr_3]: V(True) + logic dio_pad_attr_3_qe; + logic [9:0] dio_pad_attr_3_flds_we; + assign dio_pad_attr_3_qe = &dio_pad_attr_3_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_3_gated_we; + assign dio_pad_attr_3_gated_we = dio_pad_attr_3_we & dio_pad_attr_regwen_3_qs; + // F[invert_3]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_invert_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_invert_3_wd), + .d (hw2reg.dio_pad_attr[3].invert.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[0]), + .q (reg2hw.dio_pad_attr[3].invert.q), + .ds (), + .qs (dio_pad_attr_3_invert_3_qs) + ); + assign reg2hw.dio_pad_attr[3].invert.qe = dio_pad_attr_3_qe; + + // F[virtual_od_en_3]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_virtual_od_en_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_virtual_od_en_3_wd), + .d (hw2reg.dio_pad_attr[3].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[1]), + .q (reg2hw.dio_pad_attr[3].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_3_virtual_od_en_3_qs) + ); + assign reg2hw.dio_pad_attr[3].virtual_od_en.qe = dio_pad_attr_3_qe; + + // F[pull_en_3]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_pull_en_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_pull_en_3_wd), + .d (hw2reg.dio_pad_attr[3].pull_en.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[2]), + .q (reg2hw.dio_pad_attr[3].pull_en.q), + .ds (), + .qs (dio_pad_attr_3_pull_en_3_qs) + ); + assign reg2hw.dio_pad_attr[3].pull_en.qe = dio_pad_attr_3_qe; + + // F[pull_select_3]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_pull_select_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_pull_select_3_wd), + .d (hw2reg.dio_pad_attr[3].pull_select.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[3]), + .q (reg2hw.dio_pad_attr[3].pull_select.q), + .ds (), + .qs (dio_pad_attr_3_pull_select_3_qs) + ); + assign reg2hw.dio_pad_attr[3].pull_select.qe = dio_pad_attr_3_qe; + + // F[keeper_en_3]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_keeper_en_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_keeper_en_3_wd), + .d (hw2reg.dio_pad_attr[3].keeper_en.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[4]), + .q (reg2hw.dio_pad_attr[3].keeper_en.q), + .ds (), + .qs (dio_pad_attr_3_keeper_en_3_qs) + ); + assign reg2hw.dio_pad_attr[3].keeper_en.qe = dio_pad_attr_3_qe; + + // F[schmitt_en_3]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_schmitt_en_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_schmitt_en_3_wd), + .d (hw2reg.dio_pad_attr[3].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[5]), + .q (reg2hw.dio_pad_attr[3].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_3_schmitt_en_3_qs) + ); + assign reg2hw.dio_pad_attr[3].schmitt_en.qe = dio_pad_attr_3_qe; + + // F[od_en_3]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_od_en_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_od_en_3_wd), + .d (hw2reg.dio_pad_attr[3].od_en.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[6]), + .q (reg2hw.dio_pad_attr[3].od_en.q), + .ds (), + .qs (dio_pad_attr_3_od_en_3_qs) + ); + assign reg2hw.dio_pad_attr[3].od_en.qe = dio_pad_attr_3_qe; + + // F[input_disable_3]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_3_input_disable_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_input_disable_3_wd), + .d (hw2reg.dio_pad_attr[3].input_disable.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[7]), + .q (reg2hw.dio_pad_attr[3].input_disable.q), + .ds (), + .qs (dio_pad_attr_3_input_disable_3_qs) + ); + assign reg2hw.dio_pad_attr[3].input_disable.qe = dio_pad_attr_3_qe; + + // F[slew_rate_3]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_3_slew_rate_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_slew_rate_3_wd), + .d (hw2reg.dio_pad_attr[3].slew_rate.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[8]), + .q (reg2hw.dio_pad_attr[3].slew_rate.q), + .ds (), + .qs (dio_pad_attr_3_slew_rate_3_qs) + ); + assign reg2hw.dio_pad_attr[3].slew_rate.qe = dio_pad_attr_3_qe; + + // F[drive_strength_3]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_3_drive_strength_3 ( + .re (dio_pad_attr_3_re), + .we (dio_pad_attr_3_gated_we), + .wd (dio_pad_attr_3_drive_strength_3_wd), + .d (hw2reg.dio_pad_attr[3].drive_strength.d), + .qre (), + .qe (dio_pad_attr_3_flds_we[9]), + .q (reg2hw.dio_pad_attr[3].drive_strength.q), + .ds (), + .qs (dio_pad_attr_3_drive_strength_3_qs) + ); + assign reg2hw.dio_pad_attr[3].drive_strength.qe = dio_pad_attr_3_qe; + + + // Subregister 4 of Multireg dio_pad_attr + // R[dio_pad_attr_4]: V(True) + logic dio_pad_attr_4_qe; + logic [9:0] dio_pad_attr_4_flds_we; + assign dio_pad_attr_4_qe = &dio_pad_attr_4_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_4_gated_we; + assign dio_pad_attr_4_gated_we = dio_pad_attr_4_we & dio_pad_attr_regwen_4_qs; + // F[invert_4]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_invert_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_invert_4_wd), + .d (hw2reg.dio_pad_attr[4].invert.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[0]), + .q (reg2hw.dio_pad_attr[4].invert.q), + .ds (), + .qs (dio_pad_attr_4_invert_4_qs) + ); + assign reg2hw.dio_pad_attr[4].invert.qe = dio_pad_attr_4_qe; + + // F[virtual_od_en_4]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_virtual_od_en_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_virtual_od_en_4_wd), + .d (hw2reg.dio_pad_attr[4].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[1]), + .q (reg2hw.dio_pad_attr[4].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_4_virtual_od_en_4_qs) + ); + assign reg2hw.dio_pad_attr[4].virtual_od_en.qe = dio_pad_attr_4_qe; + + // F[pull_en_4]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_pull_en_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_pull_en_4_wd), + .d (hw2reg.dio_pad_attr[4].pull_en.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[2]), + .q (reg2hw.dio_pad_attr[4].pull_en.q), + .ds (), + .qs (dio_pad_attr_4_pull_en_4_qs) + ); + assign reg2hw.dio_pad_attr[4].pull_en.qe = dio_pad_attr_4_qe; + + // F[pull_select_4]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_pull_select_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_pull_select_4_wd), + .d (hw2reg.dio_pad_attr[4].pull_select.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[3]), + .q (reg2hw.dio_pad_attr[4].pull_select.q), + .ds (), + .qs (dio_pad_attr_4_pull_select_4_qs) + ); + assign reg2hw.dio_pad_attr[4].pull_select.qe = dio_pad_attr_4_qe; + + // F[keeper_en_4]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_keeper_en_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_keeper_en_4_wd), + .d (hw2reg.dio_pad_attr[4].keeper_en.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[4]), + .q (reg2hw.dio_pad_attr[4].keeper_en.q), + .ds (), + .qs (dio_pad_attr_4_keeper_en_4_qs) + ); + assign reg2hw.dio_pad_attr[4].keeper_en.qe = dio_pad_attr_4_qe; + + // F[schmitt_en_4]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_schmitt_en_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_schmitt_en_4_wd), + .d (hw2reg.dio_pad_attr[4].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[5]), + .q (reg2hw.dio_pad_attr[4].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_4_schmitt_en_4_qs) + ); + assign reg2hw.dio_pad_attr[4].schmitt_en.qe = dio_pad_attr_4_qe; + + // F[od_en_4]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_od_en_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_od_en_4_wd), + .d (hw2reg.dio_pad_attr[4].od_en.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[6]), + .q (reg2hw.dio_pad_attr[4].od_en.q), + .ds (), + .qs (dio_pad_attr_4_od_en_4_qs) + ); + assign reg2hw.dio_pad_attr[4].od_en.qe = dio_pad_attr_4_qe; + + // F[input_disable_4]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_4_input_disable_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_input_disable_4_wd), + .d (hw2reg.dio_pad_attr[4].input_disable.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[7]), + .q (reg2hw.dio_pad_attr[4].input_disable.q), + .ds (), + .qs (dio_pad_attr_4_input_disable_4_qs) + ); + assign reg2hw.dio_pad_attr[4].input_disable.qe = dio_pad_attr_4_qe; + + // F[slew_rate_4]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_4_slew_rate_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_slew_rate_4_wd), + .d (hw2reg.dio_pad_attr[4].slew_rate.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[8]), + .q (reg2hw.dio_pad_attr[4].slew_rate.q), + .ds (), + .qs (dio_pad_attr_4_slew_rate_4_qs) + ); + assign reg2hw.dio_pad_attr[4].slew_rate.qe = dio_pad_attr_4_qe; + + // F[drive_strength_4]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_4_drive_strength_4 ( + .re (dio_pad_attr_4_re), + .we (dio_pad_attr_4_gated_we), + .wd (dio_pad_attr_4_drive_strength_4_wd), + .d (hw2reg.dio_pad_attr[4].drive_strength.d), + .qre (), + .qe (dio_pad_attr_4_flds_we[9]), + .q (reg2hw.dio_pad_attr[4].drive_strength.q), + .ds (), + .qs (dio_pad_attr_4_drive_strength_4_qs) + ); + assign reg2hw.dio_pad_attr[4].drive_strength.qe = dio_pad_attr_4_qe; + + + // Subregister 5 of Multireg dio_pad_attr + // R[dio_pad_attr_5]: V(True) + logic dio_pad_attr_5_qe; + logic [9:0] dio_pad_attr_5_flds_we; + assign dio_pad_attr_5_qe = &dio_pad_attr_5_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_5_gated_we; + assign dio_pad_attr_5_gated_we = dio_pad_attr_5_we & dio_pad_attr_regwen_5_qs; + // F[invert_5]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_invert_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_invert_5_wd), + .d (hw2reg.dio_pad_attr[5].invert.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[0]), + .q (reg2hw.dio_pad_attr[5].invert.q), + .ds (), + .qs (dio_pad_attr_5_invert_5_qs) + ); + assign reg2hw.dio_pad_attr[5].invert.qe = dio_pad_attr_5_qe; + + // F[virtual_od_en_5]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_virtual_od_en_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_virtual_od_en_5_wd), + .d (hw2reg.dio_pad_attr[5].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[1]), + .q (reg2hw.dio_pad_attr[5].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_5_virtual_od_en_5_qs) + ); + assign reg2hw.dio_pad_attr[5].virtual_od_en.qe = dio_pad_attr_5_qe; + + // F[pull_en_5]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_pull_en_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_pull_en_5_wd), + .d (hw2reg.dio_pad_attr[5].pull_en.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[2]), + .q (reg2hw.dio_pad_attr[5].pull_en.q), + .ds (), + .qs (dio_pad_attr_5_pull_en_5_qs) + ); + assign reg2hw.dio_pad_attr[5].pull_en.qe = dio_pad_attr_5_qe; + + // F[pull_select_5]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_pull_select_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_pull_select_5_wd), + .d (hw2reg.dio_pad_attr[5].pull_select.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[3]), + .q (reg2hw.dio_pad_attr[5].pull_select.q), + .ds (), + .qs (dio_pad_attr_5_pull_select_5_qs) + ); + assign reg2hw.dio_pad_attr[5].pull_select.qe = dio_pad_attr_5_qe; + + // F[keeper_en_5]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_keeper_en_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_keeper_en_5_wd), + .d (hw2reg.dio_pad_attr[5].keeper_en.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[4]), + .q (reg2hw.dio_pad_attr[5].keeper_en.q), + .ds (), + .qs (dio_pad_attr_5_keeper_en_5_qs) + ); + assign reg2hw.dio_pad_attr[5].keeper_en.qe = dio_pad_attr_5_qe; + + // F[schmitt_en_5]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_schmitt_en_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_schmitt_en_5_wd), + .d (hw2reg.dio_pad_attr[5].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[5]), + .q (reg2hw.dio_pad_attr[5].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_5_schmitt_en_5_qs) + ); + assign reg2hw.dio_pad_attr[5].schmitt_en.qe = dio_pad_attr_5_qe; + + // F[od_en_5]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_od_en_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_od_en_5_wd), + .d (hw2reg.dio_pad_attr[5].od_en.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[6]), + .q (reg2hw.dio_pad_attr[5].od_en.q), + .ds (), + .qs (dio_pad_attr_5_od_en_5_qs) + ); + assign reg2hw.dio_pad_attr[5].od_en.qe = dio_pad_attr_5_qe; + + // F[input_disable_5]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_5_input_disable_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_input_disable_5_wd), + .d (hw2reg.dio_pad_attr[5].input_disable.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[7]), + .q (reg2hw.dio_pad_attr[5].input_disable.q), + .ds (), + .qs (dio_pad_attr_5_input_disable_5_qs) + ); + assign reg2hw.dio_pad_attr[5].input_disable.qe = dio_pad_attr_5_qe; + + // F[slew_rate_5]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_5_slew_rate_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_slew_rate_5_wd), + .d (hw2reg.dio_pad_attr[5].slew_rate.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[8]), + .q (reg2hw.dio_pad_attr[5].slew_rate.q), + .ds (), + .qs (dio_pad_attr_5_slew_rate_5_qs) + ); + assign reg2hw.dio_pad_attr[5].slew_rate.qe = dio_pad_attr_5_qe; + + // F[drive_strength_5]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_5_drive_strength_5 ( + .re (dio_pad_attr_5_re), + .we (dio_pad_attr_5_gated_we), + .wd (dio_pad_attr_5_drive_strength_5_wd), + .d (hw2reg.dio_pad_attr[5].drive_strength.d), + .qre (), + .qe (dio_pad_attr_5_flds_we[9]), + .q (reg2hw.dio_pad_attr[5].drive_strength.q), + .ds (), + .qs (dio_pad_attr_5_drive_strength_5_qs) + ); + assign reg2hw.dio_pad_attr[5].drive_strength.qe = dio_pad_attr_5_qe; + + + // Subregister 6 of Multireg dio_pad_attr + // R[dio_pad_attr_6]: V(True) + logic dio_pad_attr_6_qe; + logic [9:0] dio_pad_attr_6_flds_we; + assign dio_pad_attr_6_qe = &dio_pad_attr_6_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_6_gated_we; + assign dio_pad_attr_6_gated_we = dio_pad_attr_6_we & dio_pad_attr_regwen_6_qs; + // F[invert_6]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_invert_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_invert_6_wd), + .d (hw2reg.dio_pad_attr[6].invert.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[0]), + .q (reg2hw.dio_pad_attr[6].invert.q), + .ds (), + .qs (dio_pad_attr_6_invert_6_qs) + ); + assign reg2hw.dio_pad_attr[6].invert.qe = dio_pad_attr_6_qe; + + // F[virtual_od_en_6]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_virtual_od_en_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_virtual_od_en_6_wd), + .d (hw2reg.dio_pad_attr[6].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[1]), + .q (reg2hw.dio_pad_attr[6].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_6_virtual_od_en_6_qs) + ); + assign reg2hw.dio_pad_attr[6].virtual_od_en.qe = dio_pad_attr_6_qe; + + // F[pull_en_6]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_pull_en_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_pull_en_6_wd), + .d (hw2reg.dio_pad_attr[6].pull_en.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[2]), + .q (reg2hw.dio_pad_attr[6].pull_en.q), + .ds (), + .qs (dio_pad_attr_6_pull_en_6_qs) + ); + assign reg2hw.dio_pad_attr[6].pull_en.qe = dio_pad_attr_6_qe; + + // F[pull_select_6]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_pull_select_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_pull_select_6_wd), + .d (hw2reg.dio_pad_attr[6].pull_select.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[3]), + .q (reg2hw.dio_pad_attr[6].pull_select.q), + .ds (), + .qs (dio_pad_attr_6_pull_select_6_qs) + ); + assign reg2hw.dio_pad_attr[6].pull_select.qe = dio_pad_attr_6_qe; + + // F[keeper_en_6]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_keeper_en_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_keeper_en_6_wd), + .d (hw2reg.dio_pad_attr[6].keeper_en.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[4]), + .q (reg2hw.dio_pad_attr[6].keeper_en.q), + .ds (), + .qs (dio_pad_attr_6_keeper_en_6_qs) + ); + assign reg2hw.dio_pad_attr[6].keeper_en.qe = dio_pad_attr_6_qe; + + // F[schmitt_en_6]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_schmitt_en_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_schmitt_en_6_wd), + .d (hw2reg.dio_pad_attr[6].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[5]), + .q (reg2hw.dio_pad_attr[6].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_6_schmitt_en_6_qs) + ); + assign reg2hw.dio_pad_attr[6].schmitt_en.qe = dio_pad_attr_6_qe; + + // F[od_en_6]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_od_en_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_od_en_6_wd), + .d (hw2reg.dio_pad_attr[6].od_en.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[6]), + .q (reg2hw.dio_pad_attr[6].od_en.q), + .ds (), + .qs (dio_pad_attr_6_od_en_6_qs) + ); + assign reg2hw.dio_pad_attr[6].od_en.qe = dio_pad_attr_6_qe; + + // F[input_disable_6]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_6_input_disable_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_input_disable_6_wd), + .d (hw2reg.dio_pad_attr[6].input_disable.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[7]), + .q (reg2hw.dio_pad_attr[6].input_disable.q), + .ds (), + .qs (dio_pad_attr_6_input_disable_6_qs) + ); + assign reg2hw.dio_pad_attr[6].input_disable.qe = dio_pad_attr_6_qe; + + // F[slew_rate_6]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_6_slew_rate_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_slew_rate_6_wd), + .d (hw2reg.dio_pad_attr[6].slew_rate.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[8]), + .q (reg2hw.dio_pad_attr[6].slew_rate.q), + .ds (), + .qs (dio_pad_attr_6_slew_rate_6_qs) + ); + assign reg2hw.dio_pad_attr[6].slew_rate.qe = dio_pad_attr_6_qe; + + // F[drive_strength_6]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_6_drive_strength_6 ( + .re (dio_pad_attr_6_re), + .we (dio_pad_attr_6_gated_we), + .wd (dio_pad_attr_6_drive_strength_6_wd), + .d (hw2reg.dio_pad_attr[6].drive_strength.d), + .qre (), + .qe (dio_pad_attr_6_flds_we[9]), + .q (reg2hw.dio_pad_attr[6].drive_strength.q), + .ds (), + .qs (dio_pad_attr_6_drive_strength_6_qs) + ); + assign reg2hw.dio_pad_attr[6].drive_strength.qe = dio_pad_attr_6_qe; + + + // Subregister 7 of Multireg dio_pad_attr + // R[dio_pad_attr_7]: V(True) + logic dio_pad_attr_7_qe; + logic [9:0] dio_pad_attr_7_flds_we; + assign dio_pad_attr_7_qe = &dio_pad_attr_7_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_7_gated_we; + assign dio_pad_attr_7_gated_we = dio_pad_attr_7_we & dio_pad_attr_regwen_7_qs; + // F[invert_7]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_invert_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_invert_7_wd), + .d (hw2reg.dio_pad_attr[7].invert.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[0]), + .q (reg2hw.dio_pad_attr[7].invert.q), + .ds (), + .qs (dio_pad_attr_7_invert_7_qs) + ); + assign reg2hw.dio_pad_attr[7].invert.qe = dio_pad_attr_7_qe; + + // F[virtual_od_en_7]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_virtual_od_en_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_virtual_od_en_7_wd), + .d (hw2reg.dio_pad_attr[7].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[1]), + .q (reg2hw.dio_pad_attr[7].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_7_virtual_od_en_7_qs) + ); + assign reg2hw.dio_pad_attr[7].virtual_od_en.qe = dio_pad_attr_7_qe; + + // F[pull_en_7]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_pull_en_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_pull_en_7_wd), + .d (hw2reg.dio_pad_attr[7].pull_en.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[2]), + .q (reg2hw.dio_pad_attr[7].pull_en.q), + .ds (), + .qs (dio_pad_attr_7_pull_en_7_qs) + ); + assign reg2hw.dio_pad_attr[7].pull_en.qe = dio_pad_attr_7_qe; + + // F[pull_select_7]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_pull_select_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_pull_select_7_wd), + .d (hw2reg.dio_pad_attr[7].pull_select.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[3]), + .q (reg2hw.dio_pad_attr[7].pull_select.q), + .ds (), + .qs (dio_pad_attr_7_pull_select_7_qs) + ); + assign reg2hw.dio_pad_attr[7].pull_select.qe = dio_pad_attr_7_qe; + + // F[keeper_en_7]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_keeper_en_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_keeper_en_7_wd), + .d (hw2reg.dio_pad_attr[7].keeper_en.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[4]), + .q (reg2hw.dio_pad_attr[7].keeper_en.q), + .ds (), + .qs (dio_pad_attr_7_keeper_en_7_qs) + ); + assign reg2hw.dio_pad_attr[7].keeper_en.qe = dio_pad_attr_7_qe; + + // F[schmitt_en_7]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_schmitt_en_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_schmitt_en_7_wd), + .d (hw2reg.dio_pad_attr[7].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[5]), + .q (reg2hw.dio_pad_attr[7].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_7_schmitt_en_7_qs) + ); + assign reg2hw.dio_pad_attr[7].schmitt_en.qe = dio_pad_attr_7_qe; + + // F[od_en_7]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_od_en_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_od_en_7_wd), + .d (hw2reg.dio_pad_attr[7].od_en.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[6]), + .q (reg2hw.dio_pad_attr[7].od_en.q), + .ds (), + .qs (dio_pad_attr_7_od_en_7_qs) + ); + assign reg2hw.dio_pad_attr[7].od_en.qe = dio_pad_attr_7_qe; + + // F[input_disable_7]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_7_input_disable_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_input_disable_7_wd), + .d (hw2reg.dio_pad_attr[7].input_disable.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[7]), + .q (reg2hw.dio_pad_attr[7].input_disable.q), + .ds (), + .qs (dio_pad_attr_7_input_disable_7_qs) + ); + assign reg2hw.dio_pad_attr[7].input_disable.qe = dio_pad_attr_7_qe; + + // F[slew_rate_7]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_7_slew_rate_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_slew_rate_7_wd), + .d (hw2reg.dio_pad_attr[7].slew_rate.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[8]), + .q (reg2hw.dio_pad_attr[7].slew_rate.q), + .ds (), + .qs (dio_pad_attr_7_slew_rate_7_qs) + ); + assign reg2hw.dio_pad_attr[7].slew_rate.qe = dio_pad_attr_7_qe; + + // F[drive_strength_7]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_7_drive_strength_7 ( + .re (dio_pad_attr_7_re), + .we (dio_pad_attr_7_gated_we), + .wd (dio_pad_attr_7_drive_strength_7_wd), + .d (hw2reg.dio_pad_attr[7].drive_strength.d), + .qre (), + .qe (dio_pad_attr_7_flds_we[9]), + .q (reg2hw.dio_pad_attr[7].drive_strength.q), + .ds (), + .qs (dio_pad_attr_7_drive_strength_7_qs) + ); + assign reg2hw.dio_pad_attr[7].drive_strength.qe = dio_pad_attr_7_qe; + + + // Subregister 8 of Multireg dio_pad_attr + // R[dio_pad_attr_8]: V(True) + logic dio_pad_attr_8_qe; + logic [9:0] dio_pad_attr_8_flds_we; + assign dio_pad_attr_8_qe = &dio_pad_attr_8_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_8_gated_we; + assign dio_pad_attr_8_gated_we = dio_pad_attr_8_we & dio_pad_attr_regwen_8_qs; + // F[invert_8]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_invert_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_invert_8_wd), + .d (hw2reg.dio_pad_attr[8].invert.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[0]), + .q (reg2hw.dio_pad_attr[8].invert.q), + .ds (), + .qs (dio_pad_attr_8_invert_8_qs) + ); + assign reg2hw.dio_pad_attr[8].invert.qe = dio_pad_attr_8_qe; + + // F[virtual_od_en_8]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_virtual_od_en_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_virtual_od_en_8_wd), + .d (hw2reg.dio_pad_attr[8].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[1]), + .q (reg2hw.dio_pad_attr[8].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_8_virtual_od_en_8_qs) + ); + assign reg2hw.dio_pad_attr[8].virtual_od_en.qe = dio_pad_attr_8_qe; + + // F[pull_en_8]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_pull_en_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_pull_en_8_wd), + .d (hw2reg.dio_pad_attr[8].pull_en.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[2]), + .q (reg2hw.dio_pad_attr[8].pull_en.q), + .ds (), + .qs (dio_pad_attr_8_pull_en_8_qs) + ); + assign reg2hw.dio_pad_attr[8].pull_en.qe = dio_pad_attr_8_qe; + + // F[pull_select_8]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_pull_select_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_pull_select_8_wd), + .d (hw2reg.dio_pad_attr[8].pull_select.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[3]), + .q (reg2hw.dio_pad_attr[8].pull_select.q), + .ds (), + .qs (dio_pad_attr_8_pull_select_8_qs) + ); + assign reg2hw.dio_pad_attr[8].pull_select.qe = dio_pad_attr_8_qe; + + // F[keeper_en_8]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_keeper_en_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_keeper_en_8_wd), + .d (hw2reg.dio_pad_attr[8].keeper_en.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[4]), + .q (reg2hw.dio_pad_attr[8].keeper_en.q), + .ds (), + .qs (dio_pad_attr_8_keeper_en_8_qs) + ); + assign reg2hw.dio_pad_attr[8].keeper_en.qe = dio_pad_attr_8_qe; + + // F[schmitt_en_8]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_schmitt_en_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_schmitt_en_8_wd), + .d (hw2reg.dio_pad_attr[8].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[5]), + .q (reg2hw.dio_pad_attr[8].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_8_schmitt_en_8_qs) + ); + assign reg2hw.dio_pad_attr[8].schmitt_en.qe = dio_pad_attr_8_qe; + + // F[od_en_8]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_od_en_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_od_en_8_wd), + .d (hw2reg.dio_pad_attr[8].od_en.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[6]), + .q (reg2hw.dio_pad_attr[8].od_en.q), + .ds (), + .qs (dio_pad_attr_8_od_en_8_qs) + ); + assign reg2hw.dio_pad_attr[8].od_en.qe = dio_pad_attr_8_qe; + + // F[input_disable_8]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_8_input_disable_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_input_disable_8_wd), + .d (hw2reg.dio_pad_attr[8].input_disable.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[7]), + .q (reg2hw.dio_pad_attr[8].input_disable.q), + .ds (), + .qs (dio_pad_attr_8_input_disable_8_qs) + ); + assign reg2hw.dio_pad_attr[8].input_disable.qe = dio_pad_attr_8_qe; + + // F[slew_rate_8]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_8_slew_rate_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_slew_rate_8_wd), + .d (hw2reg.dio_pad_attr[8].slew_rate.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[8]), + .q (reg2hw.dio_pad_attr[8].slew_rate.q), + .ds (), + .qs (dio_pad_attr_8_slew_rate_8_qs) + ); + assign reg2hw.dio_pad_attr[8].slew_rate.qe = dio_pad_attr_8_qe; + + // F[drive_strength_8]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_8_drive_strength_8 ( + .re (dio_pad_attr_8_re), + .we (dio_pad_attr_8_gated_we), + .wd (dio_pad_attr_8_drive_strength_8_wd), + .d (hw2reg.dio_pad_attr[8].drive_strength.d), + .qre (), + .qe (dio_pad_attr_8_flds_we[9]), + .q (reg2hw.dio_pad_attr[8].drive_strength.q), + .ds (), + .qs (dio_pad_attr_8_drive_strength_8_qs) + ); + assign reg2hw.dio_pad_attr[8].drive_strength.qe = dio_pad_attr_8_qe; + + + // Subregister 9 of Multireg dio_pad_attr + // R[dio_pad_attr_9]: V(True) + logic dio_pad_attr_9_qe; + logic [9:0] dio_pad_attr_9_flds_we; + assign dio_pad_attr_9_qe = &dio_pad_attr_9_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_9_gated_we; + assign dio_pad_attr_9_gated_we = dio_pad_attr_9_we & dio_pad_attr_regwen_9_qs; + // F[invert_9]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_invert_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_invert_9_wd), + .d (hw2reg.dio_pad_attr[9].invert.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[0]), + .q (reg2hw.dio_pad_attr[9].invert.q), + .ds (), + .qs (dio_pad_attr_9_invert_9_qs) + ); + assign reg2hw.dio_pad_attr[9].invert.qe = dio_pad_attr_9_qe; + + // F[virtual_od_en_9]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_virtual_od_en_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_virtual_od_en_9_wd), + .d (hw2reg.dio_pad_attr[9].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[1]), + .q (reg2hw.dio_pad_attr[9].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_9_virtual_od_en_9_qs) + ); + assign reg2hw.dio_pad_attr[9].virtual_od_en.qe = dio_pad_attr_9_qe; + + // F[pull_en_9]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_pull_en_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_pull_en_9_wd), + .d (hw2reg.dio_pad_attr[9].pull_en.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[2]), + .q (reg2hw.dio_pad_attr[9].pull_en.q), + .ds (), + .qs (dio_pad_attr_9_pull_en_9_qs) + ); + assign reg2hw.dio_pad_attr[9].pull_en.qe = dio_pad_attr_9_qe; + + // F[pull_select_9]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_pull_select_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_pull_select_9_wd), + .d (hw2reg.dio_pad_attr[9].pull_select.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[3]), + .q (reg2hw.dio_pad_attr[9].pull_select.q), + .ds (), + .qs (dio_pad_attr_9_pull_select_9_qs) + ); + assign reg2hw.dio_pad_attr[9].pull_select.qe = dio_pad_attr_9_qe; + + // F[keeper_en_9]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_keeper_en_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_keeper_en_9_wd), + .d (hw2reg.dio_pad_attr[9].keeper_en.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[4]), + .q (reg2hw.dio_pad_attr[9].keeper_en.q), + .ds (), + .qs (dio_pad_attr_9_keeper_en_9_qs) + ); + assign reg2hw.dio_pad_attr[9].keeper_en.qe = dio_pad_attr_9_qe; + + // F[schmitt_en_9]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_schmitt_en_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_schmitt_en_9_wd), + .d (hw2reg.dio_pad_attr[9].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[5]), + .q (reg2hw.dio_pad_attr[9].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_9_schmitt_en_9_qs) + ); + assign reg2hw.dio_pad_attr[9].schmitt_en.qe = dio_pad_attr_9_qe; + + // F[od_en_9]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_od_en_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_od_en_9_wd), + .d (hw2reg.dio_pad_attr[9].od_en.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[6]), + .q (reg2hw.dio_pad_attr[9].od_en.q), + .ds (), + .qs (dio_pad_attr_9_od_en_9_qs) + ); + assign reg2hw.dio_pad_attr[9].od_en.qe = dio_pad_attr_9_qe; + + // F[input_disable_9]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_9_input_disable_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_input_disable_9_wd), + .d (hw2reg.dio_pad_attr[9].input_disable.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[7]), + .q (reg2hw.dio_pad_attr[9].input_disable.q), + .ds (), + .qs (dio_pad_attr_9_input_disable_9_qs) + ); + assign reg2hw.dio_pad_attr[9].input_disable.qe = dio_pad_attr_9_qe; + + // F[slew_rate_9]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_9_slew_rate_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_slew_rate_9_wd), + .d (hw2reg.dio_pad_attr[9].slew_rate.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[8]), + .q (reg2hw.dio_pad_attr[9].slew_rate.q), + .ds (), + .qs (dio_pad_attr_9_slew_rate_9_qs) + ); + assign reg2hw.dio_pad_attr[9].slew_rate.qe = dio_pad_attr_9_qe; + + // F[drive_strength_9]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_9_drive_strength_9 ( + .re (dio_pad_attr_9_re), + .we (dio_pad_attr_9_gated_we), + .wd (dio_pad_attr_9_drive_strength_9_wd), + .d (hw2reg.dio_pad_attr[9].drive_strength.d), + .qre (), + .qe (dio_pad_attr_9_flds_we[9]), + .q (reg2hw.dio_pad_attr[9].drive_strength.q), + .ds (), + .qs (dio_pad_attr_9_drive_strength_9_qs) + ); + assign reg2hw.dio_pad_attr[9].drive_strength.qe = dio_pad_attr_9_qe; + + + // Subregister 10 of Multireg dio_pad_attr + // R[dio_pad_attr_10]: V(True) + logic dio_pad_attr_10_qe; + logic [9:0] dio_pad_attr_10_flds_we; + assign dio_pad_attr_10_qe = &dio_pad_attr_10_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_10_gated_we; + assign dio_pad_attr_10_gated_we = dio_pad_attr_10_we & dio_pad_attr_regwen_10_qs; + // F[invert_10]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_invert_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_invert_10_wd), + .d (hw2reg.dio_pad_attr[10].invert.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[0]), + .q (reg2hw.dio_pad_attr[10].invert.q), + .ds (), + .qs (dio_pad_attr_10_invert_10_qs) + ); + assign reg2hw.dio_pad_attr[10].invert.qe = dio_pad_attr_10_qe; + + // F[virtual_od_en_10]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_virtual_od_en_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_virtual_od_en_10_wd), + .d (hw2reg.dio_pad_attr[10].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[1]), + .q (reg2hw.dio_pad_attr[10].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_10_virtual_od_en_10_qs) + ); + assign reg2hw.dio_pad_attr[10].virtual_od_en.qe = dio_pad_attr_10_qe; + + // F[pull_en_10]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_pull_en_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_pull_en_10_wd), + .d (hw2reg.dio_pad_attr[10].pull_en.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[2]), + .q (reg2hw.dio_pad_attr[10].pull_en.q), + .ds (), + .qs (dio_pad_attr_10_pull_en_10_qs) + ); + assign reg2hw.dio_pad_attr[10].pull_en.qe = dio_pad_attr_10_qe; + + // F[pull_select_10]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_pull_select_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_pull_select_10_wd), + .d (hw2reg.dio_pad_attr[10].pull_select.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[3]), + .q (reg2hw.dio_pad_attr[10].pull_select.q), + .ds (), + .qs (dio_pad_attr_10_pull_select_10_qs) + ); + assign reg2hw.dio_pad_attr[10].pull_select.qe = dio_pad_attr_10_qe; + + // F[keeper_en_10]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_keeper_en_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_keeper_en_10_wd), + .d (hw2reg.dio_pad_attr[10].keeper_en.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[4]), + .q (reg2hw.dio_pad_attr[10].keeper_en.q), + .ds (), + .qs (dio_pad_attr_10_keeper_en_10_qs) + ); + assign reg2hw.dio_pad_attr[10].keeper_en.qe = dio_pad_attr_10_qe; + + // F[schmitt_en_10]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_schmitt_en_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_schmitt_en_10_wd), + .d (hw2reg.dio_pad_attr[10].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[5]), + .q (reg2hw.dio_pad_attr[10].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_10_schmitt_en_10_qs) + ); + assign reg2hw.dio_pad_attr[10].schmitt_en.qe = dio_pad_attr_10_qe; + + // F[od_en_10]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_od_en_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_od_en_10_wd), + .d (hw2reg.dio_pad_attr[10].od_en.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[6]), + .q (reg2hw.dio_pad_attr[10].od_en.q), + .ds (), + .qs (dio_pad_attr_10_od_en_10_qs) + ); + assign reg2hw.dio_pad_attr[10].od_en.qe = dio_pad_attr_10_qe; + + // F[input_disable_10]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_10_input_disable_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_input_disable_10_wd), + .d (hw2reg.dio_pad_attr[10].input_disable.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[7]), + .q (reg2hw.dio_pad_attr[10].input_disable.q), + .ds (), + .qs (dio_pad_attr_10_input_disable_10_qs) + ); + assign reg2hw.dio_pad_attr[10].input_disable.qe = dio_pad_attr_10_qe; + + // F[slew_rate_10]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_10_slew_rate_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_slew_rate_10_wd), + .d (hw2reg.dio_pad_attr[10].slew_rate.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[8]), + .q (reg2hw.dio_pad_attr[10].slew_rate.q), + .ds (), + .qs (dio_pad_attr_10_slew_rate_10_qs) + ); + assign reg2hw.dio_pad_attr[10].slew_rate.qe = dio_pad_attr_10_qe; + + // F[drive_strength_10]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_10_drive_strength_10 ( + .re (dio_pad_attr_10_re), + .we (dio_pad_attr_10_gated_we), + .wd (dio_pad_attr_10_drive_strength_10_wd), + .d (hw2reg.dio_pad_attr[10].drive_strength.d), + .qre (), + .qe (dio_pad_attr_10_flds_we[9]), + .q (reg2hw.dio_pad_attr[10].drive_strength.q), + .ds (), + .qs (dio_pad_attr_10_drive_strength_10_qs) + ); + assign reg2hw.dio_pad_attr[10].drive_strength.qe = dio_pad_attr_10_qe; + + + // Subregister 11 of Multireg dio_pad_attr + // R[dio_pad_attr_11]: V(True) + logic dio_pad_attr_11_qe; + logic [9:0] dio_pad_attr_11_flds_we; + assign dio_pad_attr_11_qe = &dio_pad_attr_11_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_11_gated_we; + assign dio_pad_attr_11_gated_we = dio_pad_attr_11_we & dio_pad_attr_regwen_11_qs; + // F[invert_11]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_invert_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_invert_11_wd), + .d (hw2reg.dio_pad_attr[11].invert.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[0]), + .q (reg2hw.dio_pad_attr[11].invert.q), + .ds (), + .qs (dio_pad_attr_11_invert_11_qs) + ); + assign reg2hw.dio_pad_attr[11].invert.qe = dio_pad_attr_11_qe; + + // F[virtual_od_en_11]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_virtual_od_en_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_virtual_od_en_11_wd), + .d (hw2reg.dio_pad_attr[11].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[1]), + .q (reg2hw.dio_pad_attr[11].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_11_virtual_od_en_11_qs) + ); + assign reg2hw.dio_pad_attr[11].virtual_od_en.qe = dio_pad_attr_11_qe; + + // F[pull_en_11]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_pull_en_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_pull_en_11_wd), + .d (hw2reg.dio_pad_attr[11].pull_en.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[2]), + .q (reg2hw.dio_pad_attr[11].pull_en.q), + .ds (), + .qs (dio_pad_attr_11_pull_en_11_qs) + ); + assign reg2hw.dio_pad_attr[11].pull_en.qe = dio_pad_attr_11_qe; + + // F[pull_select_11]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_pull_select_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_pull_select_11_wd), + .d (hw2reg.dio_pad_attr[11].pull_select.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[3]), + .q (reg2hw.dio_pad_attr[11].pull_select.q), + .ds (), + .qs (dio_pad_attr_11_pull_select_11_qs) + ); + assign reg2hw.dio_pad_attr[11].pull_select.qe = dio_pad_attr_11_qe; + + // F[keeper_en_11]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_keeper_en_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_keeper_en_11_wd), + .d (hw2reg.dio_pad_attr[11].keeper_en.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[4]), + .q (reg2hw.dio_pad_attr[11].keeper_en.q), + .ds (), + .qs (dio_pad_attr_11_keeper_en_11_qs) + ); + assign reg2hw.dio_pad_attr[11].keeper_en.qe = dio_pad_attr_11_qe; + + // F[schmitt_en_11]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_schmitt_en_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_schmitt_en_11_wd), + .d (hw2reg.dio_pad_attr[11].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[5]), + .q (reg2hw.dio_pad_attr[11].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_11_schmitt_en_11_qs) + ); + assign reg2hw.dio_pad_attr[11].schmitt_en.qe = dio_pad_attr_11_qe; + + // F[od_en_11]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_od_en_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_od_en_11_wd), + .d (hw2reg.dio_pad_attr[11].od_en.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[6]), + .q (reg2hw.dio_pad_attr[11].od_en.q), + .ds (), + .qs (dio_pad_attr_11_od_en_11_qs) + ); + assign reg2hw.dio_pad_attr[11].od_en.qe = dio_pad_attr_11_qe; + + // F[input_disable_11]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_11_input_disable_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_input_disable_11_wd), + .d (hw2reg.dio_pad_attr[11].input_disable.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[7]), + .q (reg2hw.dio_pad_attr[11].input_disable.q), + .ds (), + .qs (dio_pad_attr_11_input_disable_11_qs) + ); + assign reg2hw.dio_pad_attr[11].input_disable.qe = dio_pad_attr_11_qe; + + // F[slew_rate_11]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_11_slew_rate_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_slew_rate_11_wd), + .d (hw2reg.dio_pad_attr[11].slew_rate.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[8]), + .q (reg2hw.dio_pad_attr[11].slew_rate.q), + .ds (), + .qs (dio_pad_attr_11_slew_rate_11_qs) + ); + assign reg2hw.dio_pad_attr[11].slew_rate.qe = dio_pad_attr_11_qe; + + // F[drive_strength_11]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_11_drive_strength_11 ( + .re (dio_pad_attr_11_re), + .we (dio_pad_attr_11_gated_we), + .wd (dio_pad_attr_11_drive_strength_11_wd), + .d (hw2reg.dio_pad_attr[11].drive_strength.d), + .qre (), + .qe (dio_pad_attr_11_flds_we[9]), + .q (reg2hw.dio_pad_attr[11].drive_strength.q), + .ds (), + .qs (dio_pad_attr_11_drive_strength_11_qs) + ); + assign reg2hw.dio_pad_attr[11].drive_strength.qe = dio_pad_attr_11_qe; + + + // Subregister 12 of Multireg dio_pad_attr + // R[dio_pad_attr_12]: V(True) + logic dio_pad_attr_12_qe; + logic [9:0] dio_pad_attr_12_flds_we; + assign dio_pad_attr_12_qe = &dio_pad_attr_12_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_12_gated_we; + assign dio_pad_attr_12_gated_we = dio_pad_attr_12_we & dio_pad_attr_regwen_12_qs; + // F[invert_12]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_invert_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_invert_12_wd), + .d (hw2reg.dio_pad_attr[12].invert.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[0]), + .q (reg2hw.dio_pad_attr[12].invert.q), + .ds (), + .qs (dio_pad_attr_12_invert_12_qs) + ); + assign reg2hw.dio_pad_attr[12].invert.qe = dio_pad_attr_12_qe; + + // F[virtual_od_en_12]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_virtual_od_en_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_virtual_od_en_12_wd), + .d (hw2reg.dio_pad_attr[12].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[1]), + .q (reg2hw.dio_pad_attr[12].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_12_virtual_od_en_12_qs) + ); + assign reg2hw.dio_pad_attr[12].virtual_od_en.qe = dio_pad_attr_12_qe; + + // F[pull_en_12]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_pull_en_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_pull_en_12_wd), + .d (hw2reg.dio_pad_attr[12].pull_en.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[2]), + .q (reg2hw.dio_pad_attr[12].pull_en.q), + .ds (), + .qs (dio_pad_attr_12_pull_en_12_qs) + ); + assign reg2hw.dio_pad_attr[12].pull_en.qe = dio_pad_attr_12_qe; + + // F[pull_select_12]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_pull_select_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_pull_select_12_wd), + .d (hw2reg.dio_pad_attr[12].pull_select.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[3]), + .q (reg2hw.dio_pad_attr[12].pull_select.q), + .ds (), + .qs (dio_pad_attr_12_pull_select_12_qs) + ); + assign reg2hw.dio_pad_attr[12].pull_select.qe = dio_pad_attr_12_qe; + + // F[keeper_en_12]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_keeper_en_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_keeper_en_12_wd), + .d (hw2reg.dio_pad_attr[12].keeper_en.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[4]), + .q (reg2hw.dio_pad_attr[12].keeper_en.q), + .ds (), + .qs (dio_pad_attr_12_keeper_en_12_qs) + ); + assign reg2hw.dio_pad_attr[12].keeper_en.qe = dio_pad_attr_12_qe; + + // F[schmitt_en_12]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_schmitt_en_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_schmitt_en_12_wd), + .d (hw2reg.dio_pad_attr[12].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[5]), + .q (reg2hw.dio_pad_attr[12].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_12_schmitt_en_12_qs) + ); + assign reg2hw.dio_pad_attr[12].schmitt_en.qe = dio_pad_attr_12_qe; + + // F[od_en_12]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_od_en_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_od_en_12_wd), + .d (hw2reg.dio_pad_attr[12].od_en.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[6]), + .q (reg2hw.dio_pad_attr[12].od_en.q), + .ds (), + .qs (dio_pad_attr_12_od_en_12_qs) + ); + assign reg2hw.dio_pad_attr[12].od_en.qe = dio_pad_attr_12_qe; + + // F[input_disable_12]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_12_input_disable_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_input_disable_12_wd), + .d (hw2reg.dio_pad_attr[12].input_disable.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[7]), + .q (reg2hw.dio_pad_attr[12].input_disable.q), + .ds (), + .qs (dio_pad_attr_12_input_disable_12_qs) + ); + assign reg2hw.dio_pad_attr[12].input_disable.qe = dio_pad_attr_12_qe; + + // F[slew_rate_12]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_12_slew_rate_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_slew_rate_12_wd), + .d (hw2reg.dio_pad_attr[12].slew_rate.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[8]), + .q (reg2hw.dio_pad_attr[12].slew_rate.q), + .ds (), + .qs (dio_pad_attr_12_slew_rate_12_qs) + ); + assign reg2hw.dio_pad_attr[12].slew_rate.qe = dio_pad_attr_12_qe; + + // F[drive_strength_12]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_12_drive_strength_12 ( + .re (dio_pad_attr_12_re), + .we (dio_pad_attr_12_gated_we), + .wd (dio_pad_attr_12_drive_strength_12_wd), + .d (hw2reg.dio_pad_attr[12].drive_strength.d), + .qre (), + .qe (dio_pad_attr_12_flds_we[9]), + .q (reg2hw.dio_pad_attr[12].drive_strength.q), + .ds (), + .qs (dio_pad_attr_12_drive_strength_12_qs) + ); + assign reg2hw.dio_pad_attr[12].drive_strength.qe = dio_pad_attr_12_qe; + + + // Subregister 13 of Multireg dio_pad_attr + // R[dio_pad_attr_13]: V(True) + logic dio_pad_attr_13_qe; + logic [9:0] dio_pad_attr_13_flds_we; + assign dio_pad_attr_13_qe = &dio_pad_attr_13_flds_we; + // Create REGWEN-gated WE signal + logic dio_pad_attr_13_gated_we; + assign dio_pad_attr_13_gated_we = dio_pad_attr_13_we & dio_pad_attr_regwen_13_qs; + // F[invert_13]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_invert_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_invert_13_wd), + .d (hw2reg.dio_pad_attr[13].invert.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[0]), + .q (reg2hw.dio_pad_attr[13].invert.q), + .ds (), + .qs (dio_pad_attr_13_invert_13_qs) + ); + assign reg2hw.dio_pad_attr[13].invert.qe = dio_pad_attr_13_qe; + + // F[virtual_od_en_13]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_virtual_od_en_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_virtual_od_en_13_wd), + .d (hw2reg.dio_pad_attr[13].virtual_od_en.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[1]), + .q (reg2hw.dio_pad_attr[13].virtual_od_en.q), + .ds (), + .qs (dio_pad_attr_13_virtual_od_en_13_qs) + ); + assign reg2hw.dio_pad_attr[13].virtual_od_en.qe = dio_pad_attr_13_qe; + + // F[pull_en_13]: 2:2 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_pull_en_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_pull_en_13_wd), + .d (hw2reg.dio_pad_attr[13].pull_en.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[2]), + .q (reg2hw.dio_pad_attr[13].pull_en.q), + .ds (), + .qs (dio_pad_attr_13_pull_en_13_qs) + ); + assign reg2hw.dio_pad_attr[13].pull_en.qe = dio_pad_attr_13_qe; + + // F[pull_select_13]: 3:3 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_pull_select_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_pull_select_13_wd), + .d (hw2reg.dio_pad_attr[13].pull_select.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[3]), + .q (reg2hw.dio_pad_attr[13].pull_select.q), + .ds (), + .qs (dio_pad_attr_13_pull_select_13_qs) + ); + assign reg2hw.dio_pad_attr[13].pull_select.qe = dio_pad_attr_13_qe; + + // F[keeper_en_13]: 4:4 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_keeper_en_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_keeper_en_13_wd), + .d (hw2reg.dio_pad_attr[13].keeper_en.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[4]), + .q (reg2hw.dio_pad_attr[13].keeper_en.q), + .ds (), + .qs (dio_pad_attr_13_keeper_en_13_qs) + ); + assign reg2hw.dio_pad_attr[13].keeper_en.qe = dio_pad_attr_13_qe; + + // F[schmitt_en_13]: 5:5 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_schmitt_en_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_schmitt_en_13_wd), + .d (hw2reg.dio_pad_attr[13].schmitt_en.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[5]), + .q (reg2hw.dio_pad_attr[13].schmitt_en.q), + .ds (), + .qs (dio_pad_attr_13_schmitt_en_13_qs) + ); + assign reg2hw.dio_pad_attr[13].schmitt_en.qe = dio_pad_attr_13_qe; + + // F[od_en_13]: 6:6 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_od_en_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_od_en_13_wd), + .d (hw2reg.dio_pad_attr[13].od_en.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[6]), + .q (reg2hw.dio_pad_attr[13].od_en.q), + .ds (), + .qs (dio_pad_attr_13_od_en_13_qs) + ); + assign reg2hw.dio_pad_attr[13].od_en.qe = dio_pad_attr_13_qe; + + // F[input_disable_13]: 7:7 + prim_subreg_ext #( + .DW (1) + ) u_dio_pad_attr_13_input_disable_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_input_disable_13_wd), + .d (hw2reg.dio_pad_attr[13].input_disable.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[7]), + .q (reg2hw.dio_pad_attr[13].input_disable.q), + .ds (), + .qs (dio_pad_attr_13_input_disable_13_qs) + ); + assign reg2hw.dio_pad_attr[13].input_disable.qe = dio_pad_attr_13_qe; + + // F[slew_rate_13]: 17:16 + prim_subreg_ext #( + .DW (2) + ) u_dio_pad_attr_13_slew_rate_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_slew_rate_13_wd), + .d (hw2reg.dio_pad_attr[13].slew_rate.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[8]), + .q (reg2hw.dio_pad_attr[13].slew_rate.q), + .ds (), + .qs (dio_pad_attr_13_slew_rate_13_qs) + ); + assign reg2hw.dio_pad_attr[13].slew_rate.qe = dio_pad_attr_13_qe; + + // F[drive_strength_13]: 23:20 + prim_subreg_ext #( + .DW (4) + ) u_dio_pad_attr_13_drive_strength_13 ( + .re (dio_pad_attr_13_re), + .we (dio_pad_attr_13_gated_we), + .wd (dio_pad_attr_13_drive_strength_13_wd), + .d (hw2reg.dio_pad_attr[13].drive_strength.d), + .qre (), + .qe (dio_pad_attr_13_flds_we[9]), + .q (reg2hw.dio_pad_attr[13].drive_strength.q), + .ds (), + .qs (dio_pad_attr_13_drive_strength_13_qs) + ); + assign reg2hw.dio_pad_attr[13].drive_strength.qe = dio_pad_attr_13_qe; + + + // Subregister 0 of Multireg mio_pad_sleep_status + // R[mio_pad_sleep_status_0]: V(False) + // F[en_0]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_0_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[0].de), + .d (hw2reg.mio_pad_sleep_status[0].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[0].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_0_qs) + ); + + // F[en_1]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_1_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[1].de), + .d (hw2reg.mio_pad_sleep_status[1].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[1].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_1_qs) + ); + + // F[en_2]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_2_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[2].de), + .d (hw2reg.mio_pad_sleep_status[2].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[2].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_2_qs) + ); + + // F[en_3]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_3_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[3].de), + .d (hw2reg.mio_pad_sleep_status[3].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[3].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_3_qs) + ); + + // F[en_4]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_4_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[4].de), + .d (hw2reg.mio_pad_sleep_status[4].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[4].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_4_qs) + ); + + // F[en_5]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_5_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[5].de), + .d (hw2reg.mio_pad_sleep_status[5].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[5].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_5_qs) + ); + + // F[en_6]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_6_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[6].de), + .d (hw2reg.mio_pad_sleep_status[6].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[6].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_6_qs) + ); + + // F[en_7]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_7_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[7].de), + .d (hw2reg.mio_pad_sleep_status[7].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[7].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_7_qs) + ); + + // F[en_8]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_8_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[8].de), + .d (hw2reg.mio_pad_sleep_status[8].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[8].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_8_qs) + ); + + // F[en_9]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_9_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[9].de), + .d (hw2reg.mio_pad_sleep_status[9].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[9].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_9_qs) + ); + + // F[en_10]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_10_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[10].de), + .d (hw2reg.mio_pad_sleep_status[10].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[10].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_10_qs) + ); + + // F[en_11]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_11_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[11].de), + .d (hw2reg.mio_pad_sleep_status[11].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[11].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_11_qs) + ); + + // F[en_12]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_12_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[12].de), + .d (hw2reg.mio_pad_sleep_status[12].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[12].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_12_qs) + ); + + // F[en_13]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_13_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[13].de), + .d (hw2reg.mio_pad_sleep_status[13].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[13].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_13_qs) + ); + + // F[en_14]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_14_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[14].de), + .d (hw2reg.mio_pad_sleep_status[14].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[14].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_14_qs) + ); + + // F[en_15]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_15_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[15].de), + .d (hw2reg.mio_pad_sleep_status[15].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[15].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_15_qs) + ); + + // F[en_16]: 16:16 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_16_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[16].de), + .d (hw2reg.mio_pad_sleep_status[16].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[16].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_16_qs) + ); + + // F[en_17]: 17:17 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_17_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[17].de), + .d (hw2reg.mio_pad_sleep_status[17].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[17].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_17_qs) + ); + + // F[en_18]: 18:18 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_18_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[18].de), + .d (hw2reg.mio_pad_sleep_status[18].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[18].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_18_qs) + ); + + // F[en_19]: 19:19 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_19_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[19].de), + .d (hw2reg.mio_pad_sleep_status[19].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[19].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_19_qs) + ); + + // F[en_20]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_20_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[20].de), + .d (hw2reg.mio_pad_sleep_status[20].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[20].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_20_qs) + ); + + // F[en_21]: 21:21 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_21_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[21].de), + .d (hw2reg.mio_pad_sleep_status[21].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[21].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_21_qs) + ); + + // F[en_22]: 22:22 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_22_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[22].de), + .d (hw2reg.mio_pad_sleep_status[22].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[22].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_22_qs) + ); + + // F[en_23]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_23_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[23].de), + .d (hw2reg.mio_pad_sleep_status[23].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[23].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_23_qs) + ); + + // F[en_24]: 24:24 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_24_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[24].de), + .d (hw2reg.mio_pad_sleep_status[24].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[24].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_24_qs) + ); + + // F[en_25]: 25:25 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_25_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[25].de), + .d (hw2reg.mio_pad_sleep_status[25].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[25].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_25_qs) + ); + + // F[en_26]: 26:26 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_26_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[26].de), + .d (hw2reg.mio_pad_sleep_status[26].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[26].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_26_qs) + ); + + // F[en_27]: 27:27 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_27_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[27].de), + .d (hw2reg.mio_pad_sleep_status[27].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[27].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_27_qs) + ); + + // F[en_28]: 28:28 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_28_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[28].de), + .d (hw2reg.mio_pad_sleep_status[28].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[28].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_28_qs) + ); + + // F[en_29]: 29:29 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_29_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[29].de), + .d (hw2reg.mio_pad_sleep_status[29].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[29].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_29_qs) + ); + + // F[en_30]: 30:30 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_30_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[30].de), + .d (hw2reg.mio_pad_sleep_status[30].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[30].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_30_qs) + ); + + // F[en_31]: 31:31 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_0_en_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_0_we), + .wd (mio_pad_sleep_status_0_en_31_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[31].de), + .d (hw2reg.mio_pad_sleep_status[31].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[31].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_0_en_31_qs) + ); + + + // Subregister 1 of Multireg mio_pad_sleep_status + // R[mio_pad_sleep_status_1]: V(False) + // F[en_32]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_32_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[32].de), + .d (hw2reg.mio_pad_sleep_status[32].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[32].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_32_qs) + ); + + // F[en_33]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_33_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[33].de), + .d (hw2reg.mio_pad_sleep_status[33].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[33].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_33_qs) + ); + + // F[en_34]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_34_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[34].de), + .d (hw2reg.mio_pad_sleep_status[34].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[34].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_34_qs) + ); + + // F[en_35]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_35_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[35].de), + .d (hw2reg.mio_pad_sleep_status[35].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[35].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_35_qs) + ); + + // F[en_36]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_36_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[36].de), + .d (hw2reg.mio_pad_sleep_status[36].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[36].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_36_qs) + ); + + // F[en_37]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_37_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[37].de), + .d (hw2reg.mio_pad_sleep_status[37].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[37].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_37_qs) + ); + + // F[en_38]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_38_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[38].de), + .d (hw2reg.mio_pad_sleep_status[38].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[38].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_38_qs) + ); + + // F[en_39]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_39_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[39].de), + .d (hw2reg.mio_pad_sleep_status[39].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[39].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_39_qs) + ); + + // F[en_40]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_40_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[40].de), + .d (hw2reg.mio_pad_sleep_status[40].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[40].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_40_qs) + ); + + // F[en_41]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_41_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[41].de), + .d (hw2reg.mio_pad_sleep_status[41].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[41].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_41_qs) + ); + + // F[en_42]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_42_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[42].de), + .d (hw2reg.mio_pad_sleep_status[42].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[42].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_42_qs) + ); + + // F[en_43]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_43_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[43].de), + .d (hw2reg.mio_pad_sleep_status[43].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[43].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_43_qs) + ); + + // F[en_44]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_44_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[44].de), + .d (hw2reg.mio_pad_sleep_status[44].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[44].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_44_qs) + ); + + // F[en_45]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_45_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[45].de), + .d (hw2reg.mio_pad_sleep_status[45].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[45].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_45_qs) + ); + + // F[en_46]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_status_1_en_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_status_1_we), + .wd (mio_pad_sleep_status_1_en_46_wd), + + // from internal hardware + .de (hw2reg.mio_pad_sleep_status[46].de), + .d (hw2reg.mio_pad_sleep_status[46].d), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_status[46].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_status_1_en_46_qs) + ); + + + // Subregister 0 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_0_we), + .wd (mio_pad_sleep_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_0_qs) + ); + + + // Subregister 1 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_1_we), + .wd (mio_pad_sleep_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_1_qs) + ); + + + // Subregister 2 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_2_we), + .wd (mio_pad_sleep_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_2_qs) + ); + + + // Subregister 3 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_3_we), + .wd (mio_pad_sleep_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_3_qs) + ); + + + // Subregister 4 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_4_we), + .wd (mio_pad_sleep_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_4_qs) + ); + + + // Subregister 5 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_5_we), + .wd (mio_pad_sleep_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_5_qs) + ); + + + // Subregister 6 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_6_we), + .wd (mio_pad_sleep_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_6_qs) + ); + + + // Subregister 7 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_7_we), + .wd (mio_pad_sleep_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_7_qs) + ); + + + // Subregister 8 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_8_we), + .wd (mio_pad_sleep_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_8_qs) + ); + + + // Subregister 9 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_9_we), + .wd (mio_pad_sleep_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_9_qs) + ); + + + // Subregister 10 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_10]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_10_we), + .wd (mio_pad_sleep_regwen_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_10_qs) + ); + + + // Subregister 11 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_11]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_11_we), + .wd (mio_pad_sleep_regwen_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_11_qs) + ); + + + // Subregister 12 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_12]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_12_we), + .wd (mio_pad_sleep_regwen_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_12_qs) + ); + + + // Subregister 13 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_13]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_13_we), + .wd (mio_pad_sleep_regwen_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_13_qs) + ); + + + // Subregister 14 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_14]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_14_we), + .wd (mio_pad_sleep_regwen_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_14_qs) + ); + + + // Subregister 15 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_15]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_15_we), + .wd (mio_pad_sleep_regwen_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_15_qs) + ); + + + // Subregister 16 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_16]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_16_we), + .wd (mio_pad_sleep_regwen_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_16_qs) + ); + + + // Subregister 17 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_17]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_17_we), + .wd (mio_pad_sleep_regwen_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_17_qs) + ); + + + // Subregister 18 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_18]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_18_we), + .wd (mio_pad_sleep_regwen_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_18_qs) + ); + + + // Subregister 19 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_19]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_19_we), + .wd (mio_pad_sleep_regwen_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_19_qs) + ); + + + // Subregister 20 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_20]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_20_we), + .wd (mio_pad_sleep_regwen_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_20_qs) + ); + + + // Subregister 21 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_21]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_21_we), + .wd (mio_pad_sleep_regwen_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_21_qs) + ); + + + // Subregister 22 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_22]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_22_we), + .wd (mio_pad_sleep_regwen_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_22_qs) + ); + + + // Subregister 23 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_23]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_23_we), + .wd (mio_pad_sleep_regwen_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_23_qs) + ); + + + // Subregister 24 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_24]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_24_we), + .wd (mio_pad_sleep_regwen_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_24_qs) + ); + + + // Subregister 25 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_25]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_25_we), + .wd (mio_pad_sleep_regwen_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_25_qs) + ); + + + // Subregister 26 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_26]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_26_we), + .wd (mio_pad_sleep_regwen_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_26_qs) + ); + + + // Subregister 27 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_27]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_27_we), + .wd (mio_pad_sleep_regwen_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_27_qs) + ); + + + // Subregister 28 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_28]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_28_we), + .wd (mio_pad_sleep_regwen_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_28_qs) + ); + + + // Subregister 29 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_29]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_29_we), + .wd (mio_pad_sleep_regwen_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_29_qs) + ); + + + // Subregister 30 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_30]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_30_we), + .wd (mio_pad_sleep_regwen_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_30_qs) + ); + + + // Subregister 31 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_31]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_31_we), + .wd (mio_pad_sleep_regwen_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_31_qs) + ); + + + // Subregister 32 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_32]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_32_we), + .wd (mio_pad_sleep_regwen_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_32_qs) + ); + + + // Subregister 33 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_33]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_33_we), + .wd (mio_pad_sleep_regwen_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_33_qs) + ); + + + // Subregister 34 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_34]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_34_we), + .wd (mio_pad_sleep_regwen_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_34_qs) + ); + + + // Subregister 35 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_35]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_35_we), + .wd (mio_pad_sleep_regwen_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_35_qs) + ); + + + // Subregister 36 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_36]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_36_we), + .wd (mio_pad_sleep_regwen_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_36_qs) + ); + + + // Subregister 37 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_37]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_37_we), + .wd (mio_pad_sleep_regwen_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_37_qs) + ); + + + // Subregister 38 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_38]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_38_we), + .wd (mio_pad_sleep_regwen_38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_38_qs) + ); + + + // Subregister 39 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_39]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_39_we), + .wd (mio_pad_sleep_regwen_39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_39_qs) + ); + + + // Subregister 40 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_40]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_40_we), + .wd (mio_pad_sleep_regwen_40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_40_qs) + ); + + + // Subregister 41 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_41]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_41_we), + .wd (mio_pad_sleep_regwen_41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_41_qs) + ); + + + // Subregister 42 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_42]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_42_we), + .wd (mio_pad_sleep_regwen_42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_42_qs) + ); + + + // Subregister 43 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_43]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_43_we), + .wd (mio_pad_sleep_regwen_43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_43_qs) + ); + + + // Subregister 44 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_44]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_44_we), + .wd (mio_pad_sleep_regwen_44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_44_qs) + ); + + + // Subregister 45 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_45]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_45_we), + .wd (mio_pad_sleep_regwen_45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_45_qs) + ); + + + // Subregister 46 of Multireg mio_pad_sleep_regwen + // R[mio_pad_sleep_regwen_46]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_mio_pad_sleep_regwen_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_regwen_46_we), + .wd (mio_pad_sleep_regwen_46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_regwen_46_qs) + ); + + + // Subregister 0 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_0]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_0_gated_we; + assign mio_pad_sleep_en_0_gated_we = mio_pad_sleep_en_0_we & mio_pad_sleep_regwen_0_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_0_gated_we), + .wd (mio_pad_sleep_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[0].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_0_qs) + ); + + + // Subregister 1 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_1]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_1_gated_we; + assign mio_pad_sleep_en_1_gated_we = mio_pad_sleep_en_1_we & mio_pad_sleep_regwen_1_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_1_gated_we), + .wd (mio_pad_sleep_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[1].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_1_qs) + ); + + + // Subregister 2 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_2]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_2_gated_we; + assign mio_pad_sleep_en_2_gated_we = mio_pad_sleep_en_2_we & mio_pad_sleep_regwen_2_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_2_gated_we), + .wd (mio_pad_sleep_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[2].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_2_qs) + ); + + + // Subregister 3 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_3]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_3_gated_we; + assign mio_pad_sleep_en_3_gated_we = mio_pad_sleep_en_3_we & mio_pad_sleep_regwen_3_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_3_gated_we), + .wd (mio_pad_sleep_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[3].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_3_qs) + ); + + + // Subregister 4 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_4]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_4_gated_we; + assign mio_pad_sleep_en_4_gated_we = mio_pad_sleep_en_4_we & mio_pad_sleep_regwen_4_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_4_gated_we), + .wd (mio_pad_sleep_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[4].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_4_qs) + ); + + + // Subregister 5 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_5]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_5_gated_we; + assign mio_pad_sleep_en_5_gated_we = mio_pad_sleep_en_5_we & mio_pad_sleep_regwen_5_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_5_gated_we), + .wd (mio_pad_sleep_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[5].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_5_qs) + ); + + + // Subregister 6 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_6]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_6_gated_we; + assign mio_pad_sleep_en_6_gated_we = mio_pad_sleep_en_6_we & mio_pad_sleep_regwen_6_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_6_gated_we), + .wd (mio_pad_sleep_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[6].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_6_qs) + ); + + + // Subregister 7 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_7]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_7_gated_we; + assign mio_pad_sleep_en_7_gated_we = mio_pad_sleep_en_7_we & mio_pad_sleep_regwen_7_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_7_gated_we), + .wd (mio_pad_sleep_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[7].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_7_qs) + ); + + + // Subregister 8 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_8]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_8_gated_we; + assign mio_pad_sleep_en_8_gated_we = mio_pad_sleep_en_8_we & mio_pad_sleep_regwen_8_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_8_gated_we), + .wd (mio_pad_sleep_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[8].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_8_qs) + ); + + + // Subregister 9 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_9]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_9_gated_we; + assign mio_pad_sleep_en_9_gated_we = mio_pad_sleep_en_9_we & mio_pad_sleep_regwen_9_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_9_gated_we), + .wd (mio_pad_sleep_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[9].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_9_qs) + ); + + + // Subregister 10 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_10]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_10_gated_we; + assign mio_pad_sleep_en_10_gated_we = mio_pad_sleep_en_10_we & mio_pad_sleep_regwen_10_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_10_gated_we), + .wd (mio_pad_sleep_en_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[10].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_10_qs) + ); + + + // Subregister 11 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_11]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_11_gated_we; + assign mio_pad_sleep_en_11_gated_we = mio_pad_sleep_en_11_we & mio_pad_sleep_regwen_11_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_11_gated_we), + .wd (mio_pad_sleep_en_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[11].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_11_qs) + ); + + + // Subregister 12 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_12]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_12_gated_we; + assign mio_pad_sleep_en_12_gated_we = mio_pad_sleep_en_12_we & mio_pad_sleep_regwen_12_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_12_gated_we), + .wd (mio_pad_sleep_en_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[12].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_12_qs) + ); + + + // Subregister 13 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_13]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_13_gated_we; + assign mio_pad_sleep_en_13_gated_we = mio_pad_sleep_en_13_we & mio_pad_sleep_regwen_13_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_13_gated_we), + .wd (mio_pad_sleep_en_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[13].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_13_qs) + ); + + + // Subregister 14 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_14]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_14_gated_we; + assign mio_pad_sleep_en_14_gated_we = mio_pad_sleep_en_14_we & mio_pad_sleep_regwen_14_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_14_gated_we), + .wd (mio_pad_sleep_en_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[14].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_14_qs) + ); + + + // Subregister 15 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_15]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_15_gated_we; + assign mio_pad_sleep_en_15_gated_we = mio_pad_sleep_en_15_we & mio_pad_sleep_regwen_15_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_15_gated_we), + .wd (mio_pad_sleep_en_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[15].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_15_qs) + ); + + + // Subregister 16 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_16]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_16_gated_we; + assign mio_pad_sleep_en_16_gated_we = mio_pad_sleep_en_16_we & mio_pad_sleep_regwen_16_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_16_gated_we), + .wd (mio_pad_sleep_en_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[16].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_16_qs) + ); + + + // Subregister 17 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_17]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_17_gated_we; + assign mio_pad_sleep_en_17_gated_we = mio_pad_sleep_en_17_we & mio_pad_sleep_regwen_17_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_17_gated_we), + .wd (mio_pad_sleep_en_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[17].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_17_qs) + ); + + + // Subregister 18 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_18]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_18_gated_we; + assign mio_pad_sleep_en_18_gated_we = mio_pad_sleep_en_18_we & mio_pad_sleep_regwen_18_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_18_gated_we), + .wd (mio_pad_sleep_en_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[18].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_18_qs) + ); + + + // Subregister 19 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_19]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_19_gated_we; + assign mio_pad_sleep_en_19_gated_we = mio_pad_sleep_en_19_we & mio_pad_sleep_regwen_19_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_19_gated_we), + .wd (mio_pad_sleep_en_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[19].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_19_qs) + ); + + + // Subregister 20 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_20]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_20_gated_we; + assign mio_pad_sleep_en_20_gated_we = mio_pad_sleep_en_20_we & mio_pad_sleep_regwen_20_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_20_gated_we), + .wd (mio_pad_sleep_en_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[20].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_20_qs) + ); + + + // Subregister 21 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_21]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_21_gated_we; + assign mio_pad_sleep_en_21_gated_we = mio_pad_sleep_en_21_we & mio_pad_sleep_regwen_21_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_21_gated_we), + .wd (mio_pad_sleep_en_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[21].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_21_qs) + ); + + + // Subregister 22 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_22]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_22_gated_we; + assign mio_pad_sleep_en_22_gated_we = mio_pad_sleep_en_22_we & mio_pad_sleep_regwen_22_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_22_gated_we), + .wd (mio_pad_sleep_en_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[22].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_22_qs) + ); + + + // Subregister 23 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_23]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_23_gated_we; + assign mio_pad_sleep_en_23_gated_we = mio_pad_sleep_en_23_we & mio_pad_sleep_regwen_23_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_23_gated_we), + .wd (mio_pad_sleep_en_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[23].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_23_qs) + ); + + + // Subregister 24 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_24]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_24_gated_we; + assign mio_pad_sleep_en_24_gated_we = mio_pad_sleep_en_24_we & mio_pad_sleep_regwen_24_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_24_gated_we), + .wd (mio_pad_sleep_en_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[24].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_24_qs) + ); + + + // Subregister 25 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_25]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_25_gated_we; + assign mio_pad_sleep_en_25_gated_we = mio_pad_sleep_en_25_we & mio_pad_sleep_regwen_25_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_25_gated_we), + .wd (mio_pad_sleep_en_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[25].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_25_qs) + ); + + + // Subregister 26 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_26]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_26_gated_we; + assign mio_pad_sleep_en_26_gated_we = mio_pad_sleep_en_26_we & mio_pad_sleep_regwen_26_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_26_gated_we), + .wd (mio_pad_sleep_en_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[26].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_26_qs) + ); + + + // Subregister 27 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_27]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_27_gated_we; + assign mio_pad_sleep_en_27_gated_we = mio_pad_sleep_en_27_we & mio_pad_sleep_regwen_27_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_27_gated_we), + .wd (mio_pad_sleep_en_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[27].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_27_qs) + ); + + + // Subregister 28 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_28]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_28_gated_we; + assign mio_pad_sleep_en_28_gated_we = mio_pad_sleep_en_28_we & mio_pad_sleep_regwen_28_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_28_gated_we), + .wd (mio_pad_sleep_en_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[28].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_28_qs) + ); + + + // Subregister 29 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_29]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_29_gated_we; + assign mio_pad_sleep_en_29_gated_we = mio_pad_sleep_en_29_we & mio_pad_sleep_regwen_29_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_29_gated_we), + .wd (mio_pad_sleep_en_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[29].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_29_qs) + ); + + + // Subregister 30 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_30]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_30_gated_we; + assign mio_pad_sleep_en_30_gated_we = mio_pad_sleep_en_30_we & mio_pad_sleep_regwen_30_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_30_gated_we), + .wd (mio_pad_sleep_en_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[30].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_30_qs) + ); + + + // Subregister 31 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_31]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_31_gated_we; + assign mio_pad_sleep_en_31_gated_we = mio_pad_sleep_en_31_we & mio_pad_sleep_regwen_31_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_31_gated_we), + .wd (mio_pad_sleep_en_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[31].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_31_qs) + ); + + + // Subregister 32 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_32]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_32_gated_we; + assign mio_pad_sleep_en_32_gated_we = mio_pad_sleep_en_32_we & mio_pad_sleep_regwen_32_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_32_gated_we), + .wd (mio_pad_sleep_en_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[32].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_32_qs) + ); + + + // Subregister 33 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_33]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_33_gated_we; + assign mio_pad_sleep_en_33_gated_we = mio_pad_sleep_en_33_we & mio_pad_sleep_regwen_33_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_33_gated_we), + .wd (mio_pad_sleep_en_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[33].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_33_qs) + ); + + + // Subregister 34 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_34]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_34_gated_we; + assign mio_pad_sleep_en_34_gated_we = mio_pad_sleep_en_34_we & mio_pad_sleep_regwen_34_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_34_gated_we), + .wd (mio_pad_sleep_en_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[34].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_34_qs) + ); + + + // Subregister 35 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_35]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_35_gated_we; + assign mio_pad_sleep_en_35_gated_we = mio_pad_sleep_en_35_we & mio_pad_sleep_regwen_35_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_35_gated_we), + .wd (mio_pad_sleep_en_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[35].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_35_qs) + ); + + + // Subregister 36 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_36]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_36_gated_we; + assign mio_pad_sleep_en_36_gated_we = mio_pad_sleep_en_36_we & mio_pad_sleep_regwen_36_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_36_gated_we), + .wd (mio_pad_sleep_en_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[36].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_36_qs) + ); + + + // Subregister 37 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_37]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_37_gated_we; + assign mio_pad_sleep_en_37_gated_we = mio_pad_sleep_en_37_we & mio_pad_sleep_regwen_37_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_37_gated_we), + .wd (mio_pad_sleep_en_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[37].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_37_qs) + ); + + + // Subregister 38 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_38]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_38_gated_we; + assign mio_pad_sleep_en_38_gated_we = mio_pad_sleep_en_38_we & mio_pad_sleep_regwen_38_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_38_gated_we), + .wd (mio_pad_sleep_en_38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[38].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_38_qs) + ); + + + // Subregister 39 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_39]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_39_gated_we; + assign mio_pad_sleep_en_39_gated_we = mio_pad_sleep_en_39_we & mio_pad_sleep_regwen_39_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_39_gated_we), + .wd (mio_pad_sleep_en_39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[39].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_39_qs) + ); + + + // Subregister 40 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_40]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_40_gated_we; + assign mio_pad_sleep_en_40_gated_we = mio_pad_sleep_en_40_we & mio_pad_sleep_regwen_40_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_40_gated_we), + .wd (mio_pad_sleep_en_40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[40].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_40_qs) + ); + + + // Subregister 41 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_41]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_41_gated_we; + assign mio_pad_sleep_en_41_gated_we = mio_pad_sleep_en_41_we & mio_pad_sleep_regwen_41_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_41_gated_we), + .wd (mio_pad_sleep_en_41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[41].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_41_qs) + ); + + + // Subregister 42 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_42]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_42_gated_we; + assign mio_pad_sleep_en_42_gated_we = mio_pad_sleep_en_42_we & mio_pad_sleep_regwen_42_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_42_gated_we), + .wd (mio_pad_sleep_en_42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[42].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_42_qs) + ); + + + // Subregister 43 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_43]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_43_gated_we; + assign mio_pad_sleep_en_43_gated_we = mio_pad_sleep_en_43_we & mio_pad_sleep_regwen_43_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_43_gated_we), + .wd (mio_pad_sleep_en_43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[43].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_43_qs) + ); + + + // Subregister 44 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_44]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_44_gated_we; + assign mio_pad_sleep_en_44_gated_we = mio_pad_sleep_en_44_we & mio_pad_sleep_regwen_44_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_44_gated_we), + .wd (mio_pad_sleep_en_44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[44].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_44_qs) + ); + + + // Subregister 45 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_45]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_45_gated_we; + assign mio_pad_sleep_en_45_gated_we = mio_pad_sleep_en_45_we & mio_pad_sleep_regwen_45_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_45_gated_we), + .wd (mio_pad_sleep_en_45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[45].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_45_qs) + ); + + + // Subregister 46 of Multireg mio_pad_sleep_en + // R[mio_pad_sleep_en_46]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_en_46_gated_we; + assign mio_pad_sleep_en_46_gated_we = mio_pad_sleep_en_46_we & mio_pad_sleep_regwen_46_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_mio_pad_sleep_en_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_en_46_gated_we), + .wd (mio_pad_sleep_en_46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_en[46].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_en_46_qs) + ); + + + // Subregister 0 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_0]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_0_gated_we; + assign mio_pad_sleep_mode_0_gated_we = mio_pad_sleep_mode_0_we & mio_pad_sleep_regwen_0_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_0_gated_we), + .wd (mio_pad_sleep_mode_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[0].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_0_qs) + ); + + + // Subregister 1 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_1]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_1_gated_we; + assign mio_pad_sleep_mode_1_gated_we = mio_pad_sleep_mode_1_we & mio_pad_sleep_regwen_1_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_1_gated_we), + .wd (mio_pad_sleep_mode_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[1].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_1_qs) + ); + + + // Subregister 2 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_2]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_2_gated_we; + assign mio_pad_sleep_mode_2_gated_we = mio_pad_sleep_mode_2_we & mio_pad_sleep_regwen_2_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_2_gated_we), + .wd (mio_pad_sleep_mode_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[2].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_2_qs) + ); + + + // Subregister 3 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_3]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_3_gated_we; + assign mio_pad_sleep_mode_3_gated_we = mio_pad_sleep_mode_3_we & mio_pad_sleep_regwen_3_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_3_gated_we), + .wd (mio_pad_sleep_mode_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[3].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_3_qs) + ); + + + // Subregister 4 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_4]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_4_gated_we; + assign mio_pad_sleep_mode_4_gated_we = mio_pad_sleep_mode_4_we & mio_pad_sleep_regwen_4_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_4_gated_we), + .wd (mio_pad_sleep_mode_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[4].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_4_qs) + ); + + + // Subregister 5 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_5]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_5_gated_we; + assign mio_pad_sleep_mode_5_gated_we = mio_pad_sleep_mode_5_we & mio_pad_sleep_regwen_5_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_5_gated_we), + .wd (mio_pad_sleep_mode_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[5].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_5_qs) + ); + + + // Subregister 6 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_6]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_6_gated_we; + assign mio_pad_sleep_mode_6_gated_we = mio_pad_sleep_mode_6_we & mio_pad_sleep_regwen_6_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_6_gated_we), + .wd (mio_pad_sleep_mode_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[6].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_6_qs) + ); + + + // Subregister 7 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_7]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_7_gated_we; + assign mio_pad_sleep_mode_7_gated_we = mio_pad_sleep_mode_7_we & mio_pad_sleep_regwen_7_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_7_gated_we), + .wd (mio_pad_sleep_mode_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[7].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_7_qs) + ); + + + // Subregister 8 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_8]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_8_gated_we; + assign mio_pad_sleep_mode_8_gated_we = mio_pad_sleep_mode_8_we & mio_pad_sleep_regwen_8_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_8_gated_we), + .wd (mio_pad_sleep_mode_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[8].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_8_qs) + ); + + + // Subregister 9 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_9]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_9_gated_we; + assign mio_pad_sleep_mode_9_gated_we = mio_pad_sleep_mode_9_we & mio_pad_sleep_regwen_9_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_9_gated_we), + .wd (mio_pad_sleep_mode_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[9].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_9_qs) + ); + + + // Subregister 10 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_10]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_10_gated_we; + assign mio_pad_sleep_mode_10_gated_we = mio_pad_sleep_mode_10_we & mio_pad_sleep_regwen_10_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_10_gated_we), + .wd (mio_pad_sleep_mode_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[10].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_10_qs) + ); + + + // Subregister 11 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_11]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_11_gated_we; + assign mio_pad_sleep_mode_11_gated_we = mio_pad_sleep_mode_11_we & mio_pad_sleep_regwen_11_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_11_gated_we), + .wd (mio_pad_sleep_mode_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[11].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_11_qs) + ); + + + // Subregister 12 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_12]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_12_gated_we; + assign mio_pad_sleep_mode_12_gated_we = mio_pad_sleep_mode_12_we & mio_pad_sleep_regwen_12_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_12_gated_we), + .wd (mio_pad_sleep_mode_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[12].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_12_qs) + ); + + + // Subregister 13 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_13]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_13_gated_we; + assign mio_pad_sleep_mode_13_gated_we = mio_pad_sleep_mode_13_we & mio_pad_sleep_regwen_13_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_13_gated_we), + .wd (mio_pad_sleep_mode_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[13].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_13_qs) + ); + + + // Subregister 14 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_14]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_14_gated_we; + assign mio_pad_sleep_mode_14_gated_we = mio_pad_sleep_mode_14_we & mio_pad_sleep_regwen_14_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_14_gated_we), + .wd (mio_pad_sleep_mode_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[14].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_14_qs) + ); + + + // Subregister 15 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_15]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_15_gated_we; + assign mio_pad_sleep_mode_15_gated_we = mio_pad_sleep_mode_15_we & mio_pad_sleep_regwen_15_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_15_gated_we), + .wd (mio_pad_sleep_mode_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[15].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_15_qs) + ); + + + // Subregister 16 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_16]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_16_gated_we; + assign mio_pad_sleep_mode_16_gated_we = mio_pad_sleep_mode_16_we & mio_pad_sleep_regwen_16_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_16_gated_we), + .wd (mio_pad_sleep_mode_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[16].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_16_qs) + ); + + + // Subregister 17 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_17]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_17_gated_we; + assign mio_pad_sleep_mode_17_gated_we = mio_pad_sleep_mode_17_we & mio_pad_sleep_regwen_17_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_17_gated_we), + .wd (mio_pad_sleep_mode_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[17].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_17_qs) + ); + + + // Subregister 18 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_18]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_18_gated_we; + assign mio_pad_sleep_mode_18_gated_we = mio_pad_sleep_mode_18_we & mio_pad_sleep_regwen_18_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_18_gated_we), + .wd (mio_pad_sleep_mode_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[18].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_18_qs) + ); + + + // Subregister 19 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_19]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_19_gated_we; + assign mio_pad_sleep_mode_19_gated_we = mio_pad_sleep_mode_19_we & mio_pad_sleep_regwen_19_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_19_gated_we), + .wd (mio_pad_sleep_mode_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[19].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_19_qs) + ); + + + // Subregister 20 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_20]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_20_gated_we; + assign mio_pad_sleep_mode_20_gated_we = mio_pad_sleep_mode_20_we & mio_pad_sleep_regwen_20_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_20_gated_we), + .wd (mio_pad_sleep_mode_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[20].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_20_qs) + ); + + + // Subregister 21 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_21]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_21_gated_we; + assign mio_pad_sleep_mode_21_gated_we = mio_pad_sleep_mode_21_we & mio_pad_sleep_regwen_21_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_21_gated_we), + .wd (mio_pad_sleep_mode_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[21].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_21_qs) + ); + + + // Subregister 22 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_22]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_22_gated_we; + assign mio_pad_sleep_mode_22_gated_we = mio_pad_sleep_mode_22_we & mio_pad_sleep_regwen_22_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_22_gated_we), + .wd (mio_pad_sleep_mode_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[22].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_22_qs) + ); + + + // Subregister 23 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_23]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_23_gated_we; + assign mio_pad_sleep_mode_23_gated_we = mio_pad_sleep_mode_23_we & mio_pad_sleep_regwen_23_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_23_gated_we), + .wd (mio_pad_sleep_mode_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[23].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_23_qs) + ); + + + // Subregister 24 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_24]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_24_gated_we; + assign mio_pad_sleep_mode_24_gated_we = mio_pad_sleep_mode_24_we & mio_pad_sleep_regwen_24_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_24_gated_we), + .wd (mio_pad_sleep_mode_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[24].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_24_qs) + ); + + + // Subregister 25 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_25]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_25_gated_we; + assign mio_pad_sleep_mode_25_gated_we = mio_pad_sleep_mode_25_we & mio_pad_sleep_regwen_25_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_25_gated_we), + .wd (mio_pad_sleep_mode_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[25].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_25_qs) + ); + + + // Subregister 26 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_26]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_26_gated_we; + assign mio_pad_sleep_mode_26_gated_we = mio_pad_sleep_mode_26_we & mio_pad_sleep_regwen_26_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_26_gated_we), + .wd (mio_pad_sleep_mode_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[26].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_26_qs) + ); + + + // Subregister 27 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_27]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_27_gated_we; + assign mio_pad_sleep_mode_27_gated_we = mio_pad_sleep_mode_27_we & mio_pad_sleep_regwen_27_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_27_gated_we), + .wd (mio_pad_sleep_mode_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[27].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_27_qs) + ); + + + // Subregister 28 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_28]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_28_gated_we; + assign mio_pad_sleep_mode_28_gated_we = mio_pad_sleep_mode_28_we & mio_pad_sleep_regwen_28_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_28_gated_we), + .wd (mio_pad_sleep_mode_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[28].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_28_qs) + ); + + + // Subregister 29 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_29]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_29_gated_we; + assign mio_pad_sleep_mode_29_gated_we = mio_pad_sleep_mode_29_we & mio_pad_sleep_regwen_29_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_29_gated_we), + .wd (mio_pad_sleep_mode_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[29].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_29_qs) + ); + + + // Subregister 30 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_30]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_30_gated_we; + assign mio_pad_sleep_mode_30_gated_we = mio_pad_sleep_mode_30_we & mio_pad_sleep_regwen_30_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_30_gated_we), + .wd (mio_pad_sleep_mode_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[30].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_30_qs) + ); + + + // Subregister 31 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_31]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_31_gated_we; + assign mio_pad_sleep_mode_31_gated_we = mio_pad_sleep_mode_31_we & mio_pad_sleep_regwen_31_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_31_gated_we), + .wd (mio_pad_sleep_mode_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[31].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_31_qs) + ); + + + // Subregister 32 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_32]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_32_gated_we; + assign mio_pad_sleep_mode_32_gated_we = mio_pad_sleep_mode_32_we & mio_pad_sleep_regwen_32_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_32_gated_we), + .wd (mio_pad_sleep_mode_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[32].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_32_qs) + ); + + + // Subregister 33 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_33]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_33_gated_we; + assign mio_pad_sleep_mode_33_gated_we = mio_pad_sleep_mode_33_we & mio_pad_sleep_regwen_33_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_33_gated_we), + .wd (mio_pad_sleep_mode_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[33].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_33_qs) + ); + + + // Subregister 34 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_34]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_34_gated_we; + assign mio_pad_sleep_mode_34_gated_we = mio_pad_sleep_mode_34_we & mio_pad_sleep_regwen_34_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_34_gated_we), + .wd (mio_pad_sleep_mode_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[34].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_34_qs) + ); + + + // Subregister 35 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_35]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_35_gated_we; + assign mio_pad_sleep_mode_35_gated_we = mio_pad_sleep_mode_35_we & mio_pad_sleep_regwen_35_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_35_gated_we), + .wd (mio_pad_sleep_mode_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[35].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_35_qs) + ); + + + // Subregister 36 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_36]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_36_gated_we; + assign mio_pad_sleep_mode_36_gated_we = mio_pad_sleep_mode_36_we & mio_pad_sleep_regwen_36_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_36_gated_we), + .wd (mio_pad_sleep_mode_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[36].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_36_qs) + ); + + + // Subregister 37 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_37]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_37_gated_we; + assign mio_pad_sleep_mode_37_gated_we = mio_pad_sleep_mode_37_we & mio_pad_sleep_regwen_37_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_37_gated_we), + .wd (mio_pad_sleep_mode_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[37].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_37_qs) + ); + + + // Subregister 38 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_38]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_38_gated_we; + assign mio_pad_sleep_mode_38_gated_we = mio_pad_sleep_mode_38_we & mio_pad_sleep_regwen_38_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_38_gated_we), + .wd (mio_pad_sleep_mode_38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[38].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_38_qs) + ); + + + // Subregister 39 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_39]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_39_gated_we; + assign mio_pad_sleep_mode_39_gated_we = mio_pad_sleep_mode_39_we & mio_pad_sleep_regwen_39_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_39_gated_we), + .wd (mio_pad_sleep_mode_39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[39].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_39_qs) + ); + + + // Subregister 40 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_40]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_40_gated_we; + assign mio_pad_sleep_mode_40_gated_we = mio_pad_sleep_mode_40_we & mio_pad_sleep_regwen_40_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_40_gated_we), + .wd (mio_pad_sleep_mode_40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[40].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_40_qs) + ); + + + // Subregister 41 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_41]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_41_gated_we; + assign mio_pad_sleep_mode_41_gated_we = mio_pad_sleep_mode_41_we & mio_pad_sleep_regwen_41_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_41_gated_we), + .wd (mio_pad_sleep_mode_41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[41].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_41_qs) + ); + + + // Subregister 42 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_42]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_42_gated_we; + assign mio_pad_sleep_mode_42_gated_we = mio_pad_sleep_mode_42_we & mio_pad_sleep_regwen_42_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_42_gated_we), + .wd (mio_pad_sleep_mode_42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[42].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_42_qs) + ); + + + // Subregister 43 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_43]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_43_gated_we; + assign mio_pad_sleep_mode_43_gated_we = mio_pad_sleep_mode_43_we & mio_pad_sleep_regwen_43_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_43_gated_we), + .wd (mio_pad_sleep_mode_43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[43].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_43_qs) + ); + + + // Subregister 44 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_44]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_44_gated_we; + assign mio_pad_sleep_mode_44_gated_we = mio_pad_sleep_mode_44_we & mio_pad_sleep_regwen_44_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_44_gated_we), + .wd (mio_pad_sleep_mode_44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[44].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_44_qs) + ); + + + // Subregister 45 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_45]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_45_gated_we; + assign mio_pad_sleep_mode_45_gated_we = mio_pad_sleep_mode_45_we & mio_pad_sleep_regwen_45_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_45_gated_we), + .wd (mio_pad_sleep_mode_45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[45].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_45_qs) + ); + + + // Subregister 46 of Multireg mio_pad_sleep_mode + // R[mio_pad_sleep_mode_46]: V(False) + // Create REGWEN-gated WE signal + logic mio_pad_sleep_mode_46_gated_we; + assign mio_pad_sleep_mode_46_gated_we = mio_pad_sleep_mode_46_we & mio_pad_sleep_regwen_46_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_mio_pad_sleep_mode_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (mio_pad_sleep_mode_46_gated_we), + .wd (mio_pad_sleep_mode_46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.mio_pad_sleep_mode[46].q), + .ds (), + + // to register interface (read) + .qs (mio_pad_sleep_mode_46_qs) + ); + + + // Subregister 0 of Multireg dio_pad_sleep_status + // R[dio_pad_sleep_status]: V(False) + // F[en_0]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_0_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[0].de), + .d (hw2reg.dio_pad_sleep_status[0].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[0].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_0_qs) + ); + + // F[en_1]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_1_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[1].de), + .d (hw2reg.dio_pad_sleep_status[1].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[1].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_1_qs) + ); + + // F[en_2]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_2_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[2].de), + .d (hw2reg.dio_pad_sleep_status[2].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[2].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_2_qs) + ); + + // F[en_3]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_3_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[3].de), + .d (hw2reg.dio_pad_sleep_status[3].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[3].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_3_qs) + ); + + // F[en_4]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_4_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[4].de), + .d (hw2reg.dio_pad_sleep_status[4].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[4].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_4_qs) + ); + + // F[en_5]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_5_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[5].de), + .d (hw2reg.dio_pad_sleep_status[5].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[5].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_5_qs) + ); + + // F[en_6]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_6_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[6].de), + .d (hw2reg.dio_pad_sleep_status[6].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[6].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_6_qs) + ); + + // F[en_7]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_7_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[7].de), + .d (hw2reg.dio_pad_sleep_status[7].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[7].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_7_qs) + ); + + // F[en_8]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_8_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[8].de), + .d (hw2reg.dio_pad_sleep_status[8].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[8].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_8_qs) + ); + + // F[en_9]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_9_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[9].de), + .d (hw2reg.dio_pad_sleep_status[9].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[9].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_9_qs) + ); + + // F[en_10]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_10_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[10].de), + .d (hw2reg.dio_pad_sleep_status[10].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[10].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_10_qs) + ); + + // F[en_11]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_11_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[11].de), + .d (hw2reg.dio_pad_sleep_status[11].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[11].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_11_qs) + ); + + // F[en_12]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_12_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[12].de), + .d (hw2reg.dio_pad_sleep_status[12].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[12].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_12_qs) + ); + + // F[en_13]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_status_en_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_status_we), + .wd (dio_pad_sleep_status_en_13_wd), + + // from internal hardware + .de (hw2reg.dio_pad_sleep_status[13].de), + .d (hw2reg.dio_pad_sleep_status[13].d), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_status[13].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_status_en_13_qs) + ); + + + // Subregister 0 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_0_we), + .wd (dio_pad_sleep_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_0_qs) + ); + + + // Subregister 1 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_1_we), + .wd (dio_pad_sleep_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_1_qs) + ); + + + // Subregister 2 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_2_we), + .wd (dio_pad_sleep_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_2_qs) + ); + + + // Subregister 3 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_3_we), + .wd (dio_pad_sleep_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_3_qs) + ); + + + // Subregister 4 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_4_we), + .wd (dio_pad_sleep_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_4_qs) + ); + + + // Subregister 5 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_5_we), + .wd (dio_pad_sleep_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_5_qs) + ); + + + // Subregister 6 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_6_we), + .wd (dio_pad_sleep_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_6_qs) + ); + + + // Subregister 7 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_7_we), + .wd (dio_pad_sleep_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_7_qs) + ); + + + // Subregister 8 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_8]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_8_we), + .wd (dio_pad_sleep_regwen_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_8_qs) + ); + + + // Subregister 9 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_9]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_9_we), + .wd (dio_pad_sleep_regwen_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_9_qs) + ); + + + // Subregister 10 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_10]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_10_we), + .wd (dio_pad_sleep_regwen_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_10_qs) + ); + + + // Subregister 11 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_11]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_11_we), + .wd (dio_pad_sleep_regwen_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_11_qs) + ); + + + // Subregister 12 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_12]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_12_we), + .wd (dio_pad_sleep_regwen_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_12_qs) + ); + + + // Subregister 13 of Multireg dio_pad_sleep_regwen + // R[dio_pad_sleep_regwen_13]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_dio_pad_sleep_regwen_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_regwen_13_we), + .wd (dio_pad_sleep_regwen_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_regwen_13_qs) + ); + + + // Subregister 0 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_0]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_0_gated_we; + assign dio_pad_sleep_en_0_gated_we = dio_pad_sleep_en_0_we & dio_pad_sleep_regwen_0_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_0_gated_we), + .wd (dio_pad_sleep_en_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[0].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_0_qs) + ); + + + // Subregister 1 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_1]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_1_gated_we; + assign dio_pad_sleep_en_1_gated_we = dio_pad_sleep_en_1_we & dio_pad_sleep_regwen_1_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_1_gated_we), + .wd (dio_pad_sleep_en_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[1].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_1_qs) + ); + + + // Subregister 2 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_2]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_2_gated_we; + assign dio_pad_sleep_en_2_gated_we = dio_pad_sleep_en_2_we & dio_pad_sleep_regwen_2_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_2_gated_we), + .wd (dio_pad_sleep_en_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[2].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_2_qs) + ); + + + // Subregister 3 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_3]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_3_gated_we; + assign dio_pad_sleep_en_3_gated_we = dio_pad_sleep_en_3_we & dio_pad_sleep_regwen_3_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_3_gated_we), + .wd (dio_pad_sleep_en_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[3].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_3_qs) + ); + + + // Subregister 4 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_4]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_4_gated_we; + assign dio_pad_sleep_en_4_gated_we = dio_pad_sleep_en_4_we & dio_pad_sleep_regwen_4_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_4_gated_we), + .wd (dio_pad_sleep_en_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[4].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_4_qs) + ); + + + // Subregister 5 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_5]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_5_gated_we; + assign dio_pad_sleep_en_5_gated_we = dio_pad_sleep_en_5_we & dio_pad_sleep_regwen_5_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_5_gated_we), + .wd (dio_pad_sleep_en_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[5].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_5_qs) + ); + + + // Subregister 6 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_6]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_6_gated_we; + assign dio_pad_sleep_en_6_gated_we = dio_pad_sleep_en_6_we & dio_pad_sleep_regwen_6_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_6_gated_we), + .wd (dio_pad_sleep_en_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[6].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_6_qs) + ); + + + // Subregister 7 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_7]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_7_gated_we; + assign dio_pad_sleep_en_7_gated_we = dio_pad_sleep_en_7_we & dio_pad_sleep_regwen_7_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_7_gated_we), + .wd (dio_pad_sleep_en_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[7].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_7_qs) + ); + + + // Subregister 8 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_8]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_8_gated_we; + assign dio_pad_sleep_en_8_gated_we = dio_pad_sleep_en_8_we & dio_pad_sleep_regwen_8_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_8_gated_we), + .wd (dio_pad_sleep_en_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[8].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_8_qs) + ); + + + // Subregister 9 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_9]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_9_gated_we; + assign dio_pad_sleep_en_9_gated_we = dio_pad_sleep_en_9_we & dio_pad_sleep_regwen_9_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_9_gated_we), + .wd (dio_pad_sleep_en_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[9].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_9_qs) + ); + + + // Subregister 10 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_10]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_10_gated_we; + assign dio_pad_sleep_en_10_gated_we = dio_pad_sleep_en_10_we & dio_pad_sleep_regwen_10_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_10_gated_we), + .wd (dio_pad_sleep_en_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[10].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_10_qs) + ); + + + // Subregister 11 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_11]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_11_gated_we; + assign dio_pad_sleep_en_11_gated_we = dio_pad_sleep_en_11_we & dio_pad_sleep_regwen_11_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_11_gated_we), + .wd (dio_pad_sleep_en_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[11].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_11_qs) + ); + + + // Subregister 12 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_12]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_12_gated_we; + assign dio_pad_sleep_en_12_gated_we = dio_pad_sleep_en_12_we & dio_pad_sleep_regwen_12_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_12_gated_we), + .wd (dio_pad_sleep_en_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[12].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_12_qs) + ); + + + // Subregister 13 of Multireg dio_pad_sleep_en + // R[dio_pad_sleep_en_13]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_en_13_gated_we; + assign dio_pad_sleep_en_13_gated_we = dio_pad_sleep_en_13_we & dio_pad_sleep_regwen_13_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_dio_pad_sleep_en_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_en_13_gated_we), + .wd (dio_pad_sleep_en_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_en[13].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_en_13_qs) + ); + + + // Subregister 0 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_0]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_0_gated_we; + assign dio_pad_sleep_mode_0_gated_we = dio_pad_sleep_mode_0_we & dio_pad_sleep_regwen_0_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_0_gated_we), + .wd (dio_pad_sleep_mode_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[0].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_0_qs) + ); + + + // Subregister 1 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_1]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_1_gated_we; + assign dio_pad_sleep_mode_1_gated_we = dio_pad_sleep_mode_1_we & dio_pad_sleep_regwen_1_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_1_gated_we), + .wd (dio_pad_sleep_mode_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[1].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_1_qs) + ); + + + // Subregister 2 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_2]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_2_gated_we; + assign dio_pad_sleep_mode_2_gated_we = dio_pad_sleep_mode_2_we & dio_pad_sleep_regwen_2_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_2_gated_we), + .wd (dio_pad_sleep_mode_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[2].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_2_qs) + ); + + + // Subregister 3 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_3]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_3_gated_we; + assign dio_pad_sleep_mode_3_gated_we = dio_pad_sleep_mode_3_we & dio_pad_sleep_regwen_3_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_3_gated_we), + .wd (dio_pad_sleep_mode_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[3].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_3_qs) + ); + + + // Subregister 4 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_4]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_4_gated_we; + assign dio_pad_sleep_mode_4_gated_we = dio_pad_sleep_mode_4_we & dio_pad_sleep_regwen_4_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_4_gated_we), + .wd (dio_pad_sleep_mode_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[4].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_4_qs) + ); + + + // Subregister 5 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_5]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_5_gated_we; + assign dio_pad_sleep_mode_5_gated_we = dio_pad_sleep_mode_5_we & dio_pad_sleep_regwen_5_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_5_gated_we), + .wd (dio_pad_sleep_mode_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[5].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_5_qs) + ); + + + // Subregister 6 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_6]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_6_gated_we; + assign dio_pad_sleep_mode_6_gated_we = dio_pad_sleep_mode_6_we & dio_pad_sleep_regwen_6_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_6_gated_we), + .wd (dio_pad_sleep_mode_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[6].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_6_qs) + ); + + + // Subregister 7 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_7]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_7_gated_we; + assign dio_pad_sleep_mode_7_gated_we = dio_pad_sleep_mode_7_we & dio_pad_sleep_regwen_7_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_7_gated_we), + .wd (dio_pad_sleep_mode_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[7].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_7_qs) + ); + + + // Subregister 8 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_8]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_8_gated_we; + assign dio_pad_sleep_mode_8_gated_we = dio_pad_sleep_mode_8_we & dio_pad_sleep_regwen_8_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_8_gated_we), + .wd (dio_pad_sleep_mode_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[8].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_8_qs) + ); + + + // Subregister 9 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_9]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_9_gated_we; + assign dio_pad_sleep_mode_9_gated_we = dio_pad_sleep_mode_9_we & dio_pad_sleep_regwen_9_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_9_gated_we), + .wd (dio_pad_sleep_mode_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[9].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_9_qs) + ); + + + // Subregister 10 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_10]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_10_gated_we; + assign dio_pad_sleep_mode_10_gated_we = dio_pad_sleep_mode_10_we & dio_pad_sleep_regwen_10_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_10_gated_we), + .wd (dio_pad_sleep_mode_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[10].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_10_qs) + ); + + + // Subregister 11 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_11]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_11_gated_we; + assign dio_pad_sleep_mode_11_gated_we = dio_pad_sleep_mode_11_we & dio_pad_sleep_regwen_11_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_11_gated_we), + .wd (dio_pad_sleep_mode_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[11].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_11_qs) + ); + + + // Subregister 12 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_12]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_12_gated_we; + assign dio_pad_sleep_mode_12_gated_we = dio_pad_sleep_mode_12_we & dio_pad_sleep_regwen_12_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_12_gated_we), + .wd (dio_pad_sleep_mode_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[12].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_12_qs) + ); + + + // Subregister 13 of Multireg dio_pad_sleep_mode + // R[dio_pad_sleep_mode_13]: V(False) + // Create REGWEN-gated WE signal + logic dio_pad_sleep_mode_13_gated_we; + assign dio_pad_sleep_mode_13_gated_we = dio_pad_sleep_mode_13_we & dio_pad_sleep_regwen_13_qs; + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h2), + .Mubi (1'b0) + ) u_dio_pad_sleep_mode_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (dio_pad_sleep_mode_13_gated_we), + .wd (dio_pad_sleep_mode_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.dio_pad_sleep_mode[13].q), + .ds (), + + // to register interface (read) + .qs (dio_pad_sleep_mode_13_qs) + ); + + + // Subregister 0 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_0_we), + .wd (wkup_detector_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_0_qs) + ); + + + // Subregister 1 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_1_we), + .wd (wkup_detector_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_1_qs) + ); + + + // Subregister 2 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_2_we), + .wd (wkup_detector_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_2_qs) + ); + + + // Subregister 3 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_3]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_3_we), + .wd (wkup_detector_regwen_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_3_qs) + ); + + + // Subregister 4 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_4]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_4_we), + .wd (wkup_detector_regwen_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_4_qs) + ); + + + // Subregister 5 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_5]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_5_we), + .wd (wkup_detector_regwen_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_5_qs) + ); + + + // Subregister 6 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_6]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_6_we), + .wd (wkup_detector_regwen_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_6_qs) + ); + + + // Subregister 7 of Multireg wkup_detector_regwen + // R[wkup_detector_regwen_7]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_wkup_detector_regwen_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_regwen_7_we), + .wd (wkup_detector_regwen_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (wkup_detector_regwen_7_qs) + ); + + + // Subregister 0 of Multireg wkup_detector_en + // R[wkup_detector_en_0]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_0_gated_we; + assign aon_wkup_detector_en_0_gated_we = + aon_wkup_detector_en_0_we & aon_wkup_detector_en_0_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_0 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_0_gated_we), + .wd (aon_wkup_detector_en_0_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[0].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_0_qs_int) + ); + + + // Subregister 1 of Multireg wkup_detector_en + // R[wkup_detector_en_1]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_1_gated_we; + assign aon_wkup_detector_en_1_gated_we = + aon_wkup_detector_en_1_we & aon_wkup_detector_en_1_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_1 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_1_gated_we), + .wd (aon_wkup_detector_en_1_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[1].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_1_qs_int) + ); + + + // Subregister 2 of Multireg wkup_detector_en + // R[wkup_detector_en_2]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_2_gated_we; + assign aon_wkup_detector_en_2_gated_we = + aon_wkup_detector_en_2_we & aon_wkup_detector_en_2_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_2 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_2_gated_we), + .wd (aon_wkup_detector_en_2_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[2].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_2_qs_int) + ); + + + // Subregister 3 of Multireg wkup_detector_en + // R[wkup_detector_en_3]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_3_gated_we; + assign aon_wkup_detector_en_3_gated_we = + aon_wkup_detector_en_3_we & aon_wkup_detector_en_3_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_3 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_3_gated_we), + .wd (aon_wkup_detector_en_3_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[3].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_3_qs_int) + ); + + + // Subregister 4 of Multireg wkup_detector_en + // R[wkup_detector_en_4]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_4_gated_we; + assign aon_wkup_detector_en_4_gated_we = + aon_wkup_detector_en_4_we & aon_wkup_detector_en_4_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_4 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_4_gated_we), + .wd (aon_wkup_detector_en_4_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[4].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_4_qs_int) + ); + + + // Subregister 5 of Multireg wkup_detector_en + // R[wkup_detector_en_5]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_5_gated_we; + assign aon_wkup_detector_en_5_gated_we = + aon_wkup_detector_en_5_we & aon_wkup_detector_en_5_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_5 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_5_gated_we), + .wd (aon_wkup_detector_en_5_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[5].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_5_qs_int) + ); + + + // Subregister 6 of Multireg wkup_detector_en + // R[wkup_detector_en_6]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_6_gated_we; + assign aon_wkup_detector_en_6_gated_we = + aon_wkup_detector_en_6_we & aon_wkup_detector_en_6_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_6 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_6_gated_we), + .wd (aon_wkup_detector_en_6_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[6].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_6_qs_int) + ); + + + // Subregister 7 of Multireg wkup_detector_en + // R[wkup_detector_en_7]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_en_7_gated_we; + assign aon_wkup_detector_en_7_gated_we = + aon_wkup_detector_en_7_we & aon_wkup_detector_en_7_regwen; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_en_7 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_en_7_gated_we), + .wd (aon_wkup_detector_en_7_wdata[0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_en[7].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_en_7_qs_int) + ); + + + // Subregister 0 of Multireg wkup_detector + // R[wkup_detector_0]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_0_gated_we; + assign aon_wkup_detector_0_gated_we = aon_wkup_detector_0_we & aon_wkup_detector_0_regwen; + // F[mode_0]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_0_mode_0 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_0_gated_we), + .wd (aon_wkup_detector_0_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[0].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_0_mode_0_qs_int) + ); + + // F[filter_0]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_0_filter_0 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_0_gated_we), + .wd (aon_wkup_detector_0_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[0].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_0_filter_0_qs_int) + ); + + // F[miodio_0]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_0_miodio_0 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_0_gated_we), + .wd (aon_wkup_detector_0_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[0].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_0_miodio_0_qs_int) + ); + + + // Subregister 1 of Multireg wkup_detector + // R[wkup_detector_1]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_1_gated_we; + assign aon_wkup_detector_1_gated_we = aon_wkup_detector_1_we & aon_wkup_detector_1_regwen; + // F[mode_1]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_1_mode_1 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_1_gated_we), + .wd (aon_wkup_detector_1_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[1].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_1_mode_1_qs_int) + ); + + // F[filter_1]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_1_filter_1 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_1_gated_we), + .wd (aon_wkup_detector_1_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[1].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_1_filter_1_qs_int) + ); + + // F[miodio_1]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_1_miodio_1 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_1_gated_we), + .wd (aon_wkup_detector_1_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[1].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_1_miodio_1_qs_int) + ); + + + // Subregister 2 of Multireg wkup_detector + // R[wkup_detector_2]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_2_gated_we; + assign aon_wkup_detector_2_gated_we = aon_wkup_detector_2_we & aon_wkup_detector_2_regwen; + // F[mode_2]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_2_mode_2 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_2_gated_we), + .wd (aon_wkup_detector_2_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[2].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_2_mode_2_qs_int) + ); + + // F[filter_2]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_2_filter_2 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_2_gated_we), + .wd (aon_wkup_detector_2_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[2].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_2_filter_2_qs_int) + ); + + // F[miodio_2]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_2_miodio_2 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_2_gated_we), + .wd (aon_wkup_detector_2_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[2].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_2_miodio_2_qs_int) + ); + + + // Subregister 3 of Multireg wkup_detector + // R[wkup_detector_3]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_3_gated_we; + assign aon_wkup_detector_3_gated_we = aon_wkup_detector_3_we & aon_wkup_detector_3_regwen; + // F[mode_3]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_3_mode_3 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_3_gated_we), + .wd (aon_wkup_detector_3_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[3].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_3_mode_3_qs_int) + ); + + // F[filter_3]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_3_filter_3 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_3_gated_we), + .wd (aon_wkup_detector_3_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[3].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_3_filter_3_qs_int) + ); + + // F[miodio_3]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_3_miodio_3 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_3_gated_we), + .wd (aon_wkup_detector_3_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[3].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_3_miodio_3_qs_int) + ); + + + // Subregister 4 of Multireg wkup_detector + // R[wkup_detector_4]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_4_gated_we; + assign aon_wkup_detector_4_gated_we = aon_wkup_detector_4_we & aon_wkup_detector_4_regwen; + // F[mode_4]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_4_mode_4 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_4_gated_we), + .wd (aon_wkup_detector_4_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[4].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_4_mode_4_qs_int) + ); + + // F[filter_4]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_4_filter_4 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_4_gated_we), + .wd (aon_wkup_detector_4_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[4].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_4_filter_4_qs_int) + ); + + // F[miodio_4]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_4_miodio_4 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_4_gated_we), + .wd (aon_wkup_detector_4_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[4].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_4_miodio_4_qs_int) + ); + + + // Subregister 5 of Multireg wkup_detector + // R[wkup_detector_5]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_5_gated_we; + assign aon_wkup_detector_5_gated_we = aon_wkup_detector_5_we & aon_wkup_detector_5_regwen; + // F[mode_5]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_5_mode_5 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_5_gated_we), + .wd (aon_wkup_detector_5_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[5].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_5_mode_5_qs_int) + ); + + // F[filter_5]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_5_filter_5 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_5_gated_we), + .wd (aon_wkup_detector_5_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[5].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_5_filter_5_qs_int) + ); + + // F[miodio_5]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_5_miodio_5 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_5_gated_we), + .wd (aon_wkup_detector_5_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[5].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_5_miodio_5_qs_int) + ); + + + // Subregister 6 of Multireg wkup_detector + // R[wkup_detector_6]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_6_gated_we; + assign aon_wkup_detector_6_gated_we = aon_wkup_detector_6_we & aon_wkup_detector_6_regwen; + // F[mode_6]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_6_mode_6 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_6_gated_we), + .wd (aon_wkup_detector_6_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[6].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_6_mode_6_qs_int) + ); + + // F[filter_6]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_6_filter_6 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_6_gated_we), + .wd (aon_wkup_detector_6_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[6].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_6_filter_6_qs_int) + ); + + // F[miodio_6]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_6_miodio_6 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_6_gated_we), + .wd (aon_wkup_detector_6_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[6].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_6_miodio_6_qs_int) + ); + + + // Subregister 7 of Multireg wkup_detector + // R[wkup_detector_7]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_7_gated_we; + assign aon_wkup_detector_7_gated_we = aon_wkup_detector_7_we & aon_wkup_detector_7_regwen; + // F[mode_7]: 2:0 + prim_subreg #( + .DW (3), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (3'h0), + .Mubi (1'b0) + ) u_wkup_detector_7_mode_7 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_7_gated_we), + .wd (aon_wkup_detector_7_wdata[2:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[7].mode.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_7_mode_7_qs_int) + ); + + // F[filter_7]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_7_filter_7 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_7_gated_we), + .wd (aon_wkup_detector_7_wdata[3]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[7].filter.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_7_filter_7_qs_int) + ); + + // F[miodio_7]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_detector_7_miodio_7 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_7_gated_we), + .wd (aon_wkup_detector_7_wdata[4]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector[7].miodio.q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_7_miodio_7_qs_int) + ); + + + // Subregister 0 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_0]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_0_gated_we; + assign aon_wkup_detector_cnt_th_0_gated_we = + aon_wkup_detector_cnt_th_0_we & aon_wkup_detector_cnt_th_0_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_0 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_0_gated_we), + .wd (aon_wkup_detector_cnt_th_0_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[0].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_0_qs_int) + ); + + + // Subregister 1 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_1]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_1_gated_we; + assign aon_wkup_detector_cnt_th_1_gated_we = + aon_wkup_detector_cnt_th_1_we & aon_wkup_detector_cnt_th_1_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_1 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_1_gated_we), + .wd (aon_wkup_detector_cnt_th_1_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[1].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_1_qs_int) + ); + + + // Subregister 2 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_2]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_2_gated_we; + assign aon_wkup_detector_cnt_th_2_gated_we = + aon_wkup_detector_cnt_th_2_we & aon_wkup_detector_cnt_th_2_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_2 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_2_gated_we), + .wd (aon_wkup_detector_cnt_th_2_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[2].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_2_qs_int) + ); + + + // Subregister 3 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_3]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_3_gated_we; + assign aon_wkup_detector_cnt_th_3_gated_we = + aon_wkup_detector_cnt_th_3_we & aon_wkup_detector_cnt_th_3_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_3 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_3_gated_we), + .wd (aon_wkup_detector_cnt_th_3_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[3].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_3_qs_int) + ); + + + // Subregister 4 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_4]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_4_gated_we; + assign aon_wkup_detector_cnt_th_4_gated_we = + aon_wkup_detector_cnt_th_4_we & aon_wkup_detector_cnt_th_4_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_4 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_4_gated_we), + .wd (aon_wkup_detector_cnt_th_4_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[4].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_4_qs_int) + ); + + + // Subregister 5 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_5]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_5_gated_we; + assign aon_wkup_detector_cnt_th_5_gated_we = + aon_wkup_detector_cnt_th_5_we & aon_wkup_detector_cnt_th_5_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_5 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_5_gated_we), + .wd (aon_wkup_detector_cnt_th_5_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[5].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_5_qs_int) + ); + + + // Subregister 6 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_6]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_6_gated_we; + assign aon_wkup_detector_cnt_th_6_gated_we = + aon_wkup_detector_cnt_th_6_we & aon_wkup_detector_cnt_th_6_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_6 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_6_gated_we), + .wd (aon_wkup_detector_cnt_th_6_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[6].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_6_qs_int) + ); + + + // Subregister 7 of Multireg wkup_detector_cnt_th + // R[wkup_detector_cnt_th_7]: V(False) + // Create REGWEN-gated WE signal + logic aon_wkup_detector_cnt_th_7_gated_we; + assign aon_wkup_detector_cnt_th_7_gated_we = + aon_wkup_detector_cnt_th_7_we & aon_wkup_detector_cnt_th_7_regwen; + prim_subreg #( + .DW (8), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (8'h0), + .Mubi (1'b0) + ) u_wkup_detector_cnt_th_7 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_detector_cnt_th_7_gated_we), + .wd (aon_wkup_detector_cnt_th_7_wdata[7:0]), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_cnt_th[7].q), + .ds (), + + // to register interface (read) + .qs (aon_wkup_detector_cnt_th_7_qs_int) + ); + + + // Subregister 0 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_0]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_0_gated_we; + assign wkup_detector_padsel_0_gated_we = wkup_detector_padsel_0_we & wkup_detector_regwen_0_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_0_gated_we), + .wd (wkup_detector_padsel_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[0].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_0_qs) + ); + + + // Subregister 1 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_1]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_1_gated_we; + assign wkup_detector_padsel_1_gated_we = wkup_detector_padsel_1_we & wkup_detector_regwen_1_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_1_gated_we), + .wd (wkup_detector_padsel_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[1].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_1_qs) + ); + + + // Subregister 2 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_2]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_2_gated_we; + assign wkup_detector_padsel_2_gated_we = wkup_detector_padsel_2_we & wkup_detector_regwen_2_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_2_gated_we), + .wd (wkup_detector_padsel_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[2].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_2_qs) + ); + + + // Subregister 3 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_3]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_3_gated_we; + assign wkup_detector_padsel_3_gated_we = wkup_detector_padsel_3_we & wkup_detector_regwen_3_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_3_gated_we), + .wd (wkup_detector_padsel_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[3].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_3_qs) + ); + + + // Subregister 4 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_4]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_4_gated_we; + assign wkup_detector_padsel_4_gated_we = wkup_detector_padsel_4_we & wkup_detector_regwen_4_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_4_gated_we), + .wd (wkup_detector_padsel_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[4].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_4_qs) + ); + + + // Subregister 5 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_5]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_5_gated_we; + assign wkup_detector_padsel_5_gated_we = wkup_detector_padsel_5_we & wkup_detector_regwen_5_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_5_gated_we), + .wd (wkup_detector_padsel_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[5].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_5_qs) + ); + + + // Subregister 6 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_6]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_6_gated_we; + assign wkup_detector_padsel_6_gated_we = wkup_detector_padsel_6_we & wkup_detector_regwen_6_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_6_gated_we), + .wd (wkup_detector_padsel_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[6].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_6_qs) + ); + + + // Subregister 7 of Multireg wkup_detector_padsel + // R[wkup_detector_padsel_7]: V(False) + // Create REGWEN-gated WE signal + logic wkup_detector_padsel_7_gated_we; + assign wkup_detector_padsel_7_gated_we = wkup_detector_padsel_7_we & wkup_detector_regwen_7_qs; + prim_subreg #( + .DW (6), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (6'h0), + .Mubi (1'b0) + ) u_wkup_detector_padsel_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (wkup_detector_padsel_7_gated_we), + .wd (wkup_detector_padsel_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.wkup_detector_padsel[7].q), + .ds (), + + // to register interface (read) + .qs (wkup_detector_padsel_7_qs) + ); + + + // Subregister 0 of Multireg wkup_cause + // R[wkup_cause]: V(False) + logic [7:0] wkup_cause_flds_we; + assign aon_wkup_cause_qe = |wkup_cause_flds_we; + // F[cause_0]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_0 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[0]), + + // from internal hardware + .de (hw2reg.wkup_cause[0].de), + .d (hw2reg.wkup_cause[0].d), + + // to internal hardware + .qe (wkup_cause_flds_we[0]), + .q (reg2hw.wkup_cause[0].q), + .ds (aon_wkup_cause_cause_0_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_0_qs_int) + ); + + // F[cause_1]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_1 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[1]), + + // from internal hardware + .de (hw2reg.wkup_cause[1].de), + .d (hw2reg.wkup_cause[1].d), + + // to internal hardware + .qe (wkup_cause_flds_we[1]), + .q (reg2hw.wkup_cause[1].q), + .ds (aon_wkup_cause_cause_1_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_1_qs_int) + ); + + // F[cause_2]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_2 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[2]), + + // from internal hardware + .de (hw2reg.wkup_cause[2].de), + .d (hw2reg.wkup_cause[2].d), + + // to internal hardware + .qe (wkup_cause_flds_we[2]), + .q (reg2hw.wkup_cause[2].q), + .ds (aon_wkup_cause_cause_2_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_2_qs_int) + ); + + // F[cause_3]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_3 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[3]), + + // from internal hardware + .de (hw2reg.wkup_cause[3].de), + .d (hw2reg.wkup_cause[3].d), + + // to internal hardware + .qe (wkup_cause_flds_we[3]), + .q (reg2hw.wkup_cause[3].q), + .ds (aon_wkup_cause_cause_3_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_3_qs_int) + ); + + // F[cause_4]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_4 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[4]), + + // from internal hardware + .de (hw2reg.wkup_cause[4].de), + .d (hw2reg.wkup_cause[4].d), + + // to internal hardware + .qe (wkup_cause_flds_we[4]), + .q (reg2hw.wkup_cause[4].q), + .ds (aon_wkup_cause_cause_4_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_4_qs_int) + ); + + // F[cause_5]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_5 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[5]), + + // from internal hardware + .de (hw2reg.wkup_cause[5].de), + .d (hw2reg.wkup_cause[5].d), + + // to internal hardware + .qe (wkup_cause_flds_we[5]), + .q (reg2hw.wkup_cause[5].q), + .ds (aon_wkup_cause_cause_5_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_5_qs_int) + ); + + // F[cause_6]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_6 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[6]), + + // from internal hardware + .de (hw2reg.wkup_cause[6].de), + .d (hw2reg.wkup_cause[6].d), + + // to internal hardware + .qe (wkup_cause_flds_we[6]), + .q (reg2hw.wkup_cause[6].q), + .ds (aon_wkup_cause_cause_6_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_6_qs_int) + ); + + // F[cause_7]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_wkup_cause_cause_7 ( + .clk_i (clk_aon_i), + .rst_ni (rst_aon_ni), + + // from register interface + .we (aon_wkup_cause_we), + .wd (aon_wkup_cause_wdata[7]), + + // from internal hardware + .de (hw2reg.wkup_cause[7].de), + .d (hw2reg.wkup_cause[7].d), + + // to internal hardware + .qe (wkup_cause_flds_we[7]), + .q (reg2hw.wkup_cause[7].q), + .ds (aon_wkup_cause_cause_7_ds_int), + + // to register interface (read) + .qs (aon_wkup_cause_cause_7_qs_int) + ); + + + + logic [519:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == PINMUX_ALERT_TEST_OFFSET); + addr_hit[ 1] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_0_OFFSET); + addr_hit[ 2] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_1_OFFSET); + addr_hit[ 3] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_2_OFFSET); + addr_hit[ 4] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_3_OFFSET); + addr_hit[ 5] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_4_OFFSET); + addr_hit[ 6] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_5_OFFSET); + addr_hit[ 7] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_6_OFFSET); + addr_hit[ 8] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_7_OFFSET); + addr_hit[ 9] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_8_OFFSET); + addr_hit[ 10] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_9_OFFSET); + addr_hit[ 11] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_10_OFFSET); + addr_hit[ 12] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_11_OFFSET); + addr_hit[ 13] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_12_OFFSET); + addr_hit[ 14] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_13_OFFSET); + addr_hit[ 15] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_14_OFFSET); + addr_hit[ 16] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_15_OFFSET); + addr_hit[ 17] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_16_OFFSET); + addr_hit[ 18] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_17_OFFSET); + addr_hit[ 19] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_18_OFFSET); + addr_hit[ 20] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_19_OFFSET); + addr_hit[ 21] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_20_OFFSET); + addr_hit[ 22] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_21_OFFSET); + addr_hit[ 23] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_22_OFFSET); + addr_hit[ 24] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_23_OFFSET); + addr_hit[ 25] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_24_OFFSET); + addr_hit[ 26] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_25_OFFSET); + addr_hit[ 27] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_26_OFFSET); + addr_hit[ 28] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_27_OFFSET); + addr_hit[ 29] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_28_OFFSET); + addr_hit[ 30] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_29_OFFSET); + addr_hit[ 31] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_30_OFFSET); + addr_hit[ 32] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_31_OFFSET); + addr_hit[ 33] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_32_OFFSET); + addr_hit[ 34] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_33_OFFSET); + addr_hit[ 35] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_34_OFFSET); + addr_hit[ 36] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_35_OFFSET); + addr_hit[ 37] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_36_OFFSET); + addr_hit[ 38] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_REGWEN_37_OFFSET); + addr_hit[ 39] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_0_OFFSET); + addr_hit[ 40] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_1_OFFSET); + addr_hit[ 41] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_2_OFFSET); + addr_hit[ 42] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_3_OFFSET); + addr_hit[ 43] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_4_OFFSET); + addr_hit[ 44] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_5_OFFSET); + addr_hit[ 45] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_6_OFFSET); + addr_hit[ 46] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_7_OFFSET); + addr_hit[ 47] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_8_OFFSET); + addr_hit[ 48] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_9_OFFSET); + addr_hit[ 49] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_10_OFFSET); + addr_hit[ 50] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_11_OFFSET); + addr_hit[ 51] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_12_OFFSET); + addr_hit[ 52] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_13_OFFSET); + addr_hit[ 53] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_14_OFFSET); + addr_hit[ 54] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_15_OFFSET); + addr_hit[ 55] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_16_OFFSET); + addr_hit[ 56] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_17_OFFSET); + addr_hit[ 57] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_18_OFFSET); + addr_hit[ 58] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_19_OFFSET); + addr_hit[ 59] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_20_OFFSET); + addr_hit[ 60] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_21_OFFSET); + addr_hit[ 61] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_22_OFFSET); + addr_hit[ 62] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_23_OFFSET); + addr_hit[ 63] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_24_OFFSET); + addr_hit[ 64] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_25_OFFSET); + addr_hit[ 65] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_26_OFFSET); + addr_hit[ 66] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_27_OFFSET); + addr_hit[ 67] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_28_OFFSET); + addr_hit[ 68] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_29_OFFSET); + addr_hit[ 69] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_30_OFFSET); + addr_hit[ 70] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_31_OFFSET); + addr_hit[ 71] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_32_OFFSET); + addr_hit[ 72] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_33_OFFSET); + addr_hit[ 73] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_34_OFFSET); + addr_hit[ 74] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_35_OFFSET); + addr_hit[ 75] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_36_OFFSET); + addr_hit[ 76] = (reg_addr == PINMUX_MIO_PERIPH_INSEL_37_OFFSET); + addr_hit[ 77] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_0_OFFSET); + addr_hit[ 78] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_1_OFFSET); + addr_hit[ 79] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_2_OFFSET); + addr_hit[ 80] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_3_OFFSET); + addr_hit[ 81] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_4_OFFSET); + addr_hit[ 82] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_5_OFFSET); + addr_hit[ 83] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_6_OFFSET); + addr_hit[ 84] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_7_OFFSET); + addr_hit[ 85] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_8_OFFSET); + addr_hit[ 86] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_9_OFFSET); + addr_hit[ 87] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_10_OFFSET); + addr_hit[ 88] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_11_OFFSET); + addr_hit[ 89] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_12_OFFSET); + addr_hit[ 90] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_13_OFFSET); + addr_hit[ 91] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_14_OFFSET); + addr_hit[ 92] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_15_OFFSET); + addr_hit[ 93] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_16_OFFSET); + addr_hit[ 94] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_17_OFFSET); + addr_hit[ 95] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_18_OFFSET); + addr_hit[ 96] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_19_OFFSET); + addr_hit[ 97] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_20_OFFSET); + addr_hit[ 98] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_21_OFFSET); + addr_hit[ 99] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_22_OFFSET); + addr_hit[100] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_23_OFFSET); + addr_hit[101] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_24_OFFSET); + addr_hit[102] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_25_OFFSET); + addr_hit[103] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_26_OFFSET); + addr_hit[104] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_27_OFFSET); + addr_hit[105] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_28_OFFSET); + addr_hit[106] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_29_OFFSET); + addr_hit[107] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_30_OFFSET); + addr_hit[108] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_31_OFFSET); + addr_hit[109] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_32_OFFSET); + addr_hit[110] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_33_OFFSET); + addr_hit[111] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_34_OFFSET); + addr_hit[112] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_35_OFFSET); + addr_hit[113] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_36_OFFSET); + addr_hit[114] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_37_OFFSET); + addr_hit[115] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_38_OFFSET); + addr_hit[116] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_39_OFFSET); + addr_hit[117] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_40_OFFSET); + addr_hit[118] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_41_OFFSET); + addr_hit[119] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_42_OFFSET); + addr_hit[120] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_43_OFFSET); + addr_hit[121] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_44_OFFSET); + addr_hit[122] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_45_OFFSET); + addr_hit[123] = (reg_addr == PINMUX_MIO_OUTSEL_REGWEN_46_OFFSET); + addr_hit[124] = (reg_addr == PINMUX_MIO_OUTSEL_0_OFFSET); + addr_hit[125] = (reg_addr == PINMUX_MIO_OUTSEL_1_OFFSET); + addr_hit[126] = (reg_addr == PINMUX_MIO_OUTSEL_2_OFFSET); + addr_hit[127] = (reg_addr == PINMUX_MIO_OUTSEL_3_OFFSET); + addr_hit[128] = (reg_addr == PINMUX_MIO_OUTSEL_4_OFFSET); + addr_hit[129] = (reg_addr == PINMUX_MIO_OUTSEL_5_OFFSET); + addr_hit[130] = (reg_addr == PINMUX_MIO_OUTSEL_6_OFFSET); + addr_hit[131] = (reg_addr == PINMUX_MIO_OUTSEL_7_OFFSET); + addr_hit[132] = (reg_addr == PINMUX_MIO_OUTSEL_8_OFFSET); + addr_hit[133] = (reg_addr == PINMUX_MIO_OUTSEL_9_OFFSET); + addr_hit[134] = (reg_addr == PINMUX_MIO_OUTSEL_10_OFFSET); + addr_hit[135] = (reg_addr == PINMUX_MIO_OUTSEL_11_OFFSET); + addr_hit[136] = (reg_addr == PINMUX_MIO_OUTSEL_12_OFFSET); + addr_hit[137] = (reg_addr == PINMUX_MIO_OUTSEL_13_OFFSET); + addr_hit[138] = (reg_addr == PINMUX_MIO_OUTSEL_14_OFFSET); + addr_hit[139] = (reg_addr == PINMUX_MIO_OUTSEL_15_OFFSET); + addr_hit[140] = (reg_addr == PINMUX_MIO_OUTSEL_16_OFFSET); + addr_hit[141] = (reg_addr == PINMUX_MIO_OUTSEL_17_OFFSET); + addr_hit[142] = (reg_addr == PINMUX_MIO_OUTSEL_18_OFFSET); + addr_hit[143] = (reg_addr == PINMUX_MIO_OUTSEL_19_OFFSET); + addr_hit[144] = (reg_addr == PINMUX_MIO_OUTSEL_20_OFFSET); + addr_hit[145] = (reg_addr == PINMUX_MIO_OUTSEL_21_OFFSET); + addr_hit[146] = (reg_addr == PINMUX_MIO_OUTSEL_22_OFFSET); + addr_hit[147] = (reg_addr == PINMUX_MIO_OUTSEL_23_OFFSET); + addr_hit[148] = (reg_addr == PINMUX_MIO_OUTSEL_24_OFFSET); + addr_hit[149] = (reg_addr == PINMUX_MIO_OUTSEL_25_OFFSET); + addr_hit[150] = (reg_addr == PINMUX_MIO_OUTSEL_26_OFFSET); + addr_hit[151] = (reg_addr == PINMUX_MIO_OUTSEL_27_OFFSET); + addr_hit[152] = (reg_addr == PINMUX_MIO_OUTSEL_28_OFFSET); + addr_hit[153] = (reg_addr == PINMUX_MIO_OUTSEL_29_OFFSET); + addr_hit[154] = (reg_addr == PINMUX_MIO_OUTSEL_30_OFFSET); + addr_hit[155] = (reg_addr == PINMUX_MIO_OUTSEL_31_OFFSET); + addr_hit[156] = (reg_addr == PINMUX_MIO_OUTSEL_32_OFFSET); + addr_hit[157] = (reg_addr == PINMUX_MIO_OUTSEL_33_OFFSET); + addr_hit[158] = (reg_addr == PINMUX_MIO_OUTSEL_34_OFFSET); + addr_hit[159] = (reg_addr == PINMUX_MIO_OUTSEL_35_OFFSET); + addr_hit[160] = (reg_addr == PINMUX_MIO_OUTSEL_36_OFFSET); + addr_hit[161] = (reg_addr == PINMUX_MIO_OUTSEL_37_OFFSET); + addr_hit[162] = (reg_addr == PINMUX_MIO_OUTSEL_38_OFFSET); + addr_hit[163] = (reg_addr == PINMUX_MIO_OUTSEL_39_OFFSET); + addr_hit[164] = (reg_addr == PINMUX_MIO_OUTSEL_40_OFFSET); + addr_hit[165] = (reg_addr == PINMUX_MIO_OUTSEL_41_OFFSET); + addr_hit[166] = (reg_addr == PINMUX_MIO_OUTSEL_42_OFFSET); + addr_hit[167] = (reg_addr == PINMUX_MIO_OUTSEL_43_OFFSET); + addr_hit[168] = (reg_addr == PINMUX_MIO_OUTSEL_44_OFFSET); + addr_hit[169] = (reg_addr == PINMUX_MIO_OUTSEL_45_OFFSET); + addr_hit[170] = (reg_addr == PINMUX_MIO_OUTSEL_46_OFFSET); + addr_hit[171] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_0_OFFSET); + addr_hit[172] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_1_OFFSET); + addr_hit[173] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_2_OFFSET); + addr_hit[174] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_3_OFFSET); + addr_hit[175] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_4_OFFSET); + addr_hit[176] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_5_OFFSET); + addr_hit[177] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_6_OFFSET); + addr_hit[178] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_7_OFFSET); + addr_hit[179] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_8_OFFSET); + addr_hit[180] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_9_OFFSET); + addr_hit[181] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_10_OFFSET); + addr_hit[182] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_11_OFFSET); + addr_hit[183] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_12_OFFSET); + addr_hit[184] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_13_OFFSET); + addr_hit[185] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_14_OFFSET); + addr_hit[186] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_15_OFFSET); + addr_hit[187] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_16_OFFSET); + addr_hit[188] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_17_OFFSET); + addr_hit[189] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_18_OFFSET); + addr_hit[190] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_19_OFFSET); + addr_hit[191] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_20_OFFSET); + addr_hit[192] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_21_OFFSET); + addr_hit[193] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_22_OFFSET); + addr_hit[194] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_23_OFFSET); + addr_hit[195] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_24_OFFSET); + addr_hit[196] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_25_OFFSET); + addr_hit[197] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_26_OFFSET); + addr_hit[198] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_27_OFFSET); + addr_hit[199] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_28_OFFSET); + addr_hit[200] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_29_OFFSET); + addr_hit[201] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_30_OFFSET); + addr_hit[202] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_31_OFFSET); + addr_hit[203] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_32_OFFSET); + addr_hit[204] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_33_OFFSET); + addr_hit[205] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_34_OFFSET); + addr_hit[206] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_35_OFFSET); + addr_hit[207] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_36_OFFSET); + addr_hit[208] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_37_OFFSET); + addr_hit[209] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_38_OFFSET); + addr_hit[210] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_39_OFFSET); + addr_hit[211] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_40_OFFSET); + addr_hit[212] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_41_OFFSET); + addr_hit[213] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_42_OFFSET); + addr_hit[214] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_43_OFFSET); + addr_hit[215] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_44_OFFSET); + addr_hit[216] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_45_OFFSET); + addr_hit[217] = (reg_addr == PINMUX_MIO_PAD_ATTR_REGWEN_46_OFFSET); + addr_hit[218] = (reg_addr == PINMUX_MIO_PAD_ATTR_0_OFFSET); + addr_hit[219] = (reg_addr == PINMUX_MIO_PAD_ATTR_1_OFFSET); + addr_hit[220] = (reg_addr == PINMUX_MIO_PAD_ATTR_2_OFFSET); + addr_hit[221] = (reg_addr == PINMUX_MIO_PAD_ATTR_3_OFFSET); + addr_hit[222] = (reg_addr == PINMUX_MIO_PAD_ATTR_4_OFFSET); + addr_hit[223] = (reg_addr == PINMUX_MIO_PAD_ATTR_5_OFFSET); + addr_hit[224] = (reg_addr == PINMUX_MIO_PAD_ATTR_6_OFFSET); + addr_hit[225] = (reg_addr == PINMUX_MIO_PAD_ATTR_7_OFFSET); + addr_hit[226] = (reg_addr == PINMUX_MIO_PAD_ATTR_8_OFFSET); + addr_hit[227] = (reg_addr == PINMUX_MIO_PAD_ATTR_9_OFFSET); + addr_hit[228] = (reg_addr == PINMUX_MIO_PAD_ATTR_10_OFFSET); + addr_hit[229] = (reg_addr == PINMUX_MIO_PAD_ATTR_11_OFFSET); + addr_hit[230] = (reg_addr == PINMUX_MIO_PAD_ATTR_12_OFFSET); + addr_hit[231] = (reg_addr == PINMUX_MIO_PAD_ATTR_13_OFFSET); + addr_hit[232] = (reg_addr == PINMUX_MIO_PAD_ATTR_14_OFFSET); + addr_hit[233] = (reg_addr == PINMUX_MIO_PAD_ATTR_15_OFFSET); + addr_hit[234] = (reg_addr == PINMUX_MIO_PAD_ATTR_16_OFFSET); + addr_hit[235] = (reg_addr == PINMUX_MIO_PAD_ATTR_17_OFFSET); + addr_hit[236] = (reg_addr == PINMUX_MIO_PAD_ATTR_18_OFFSET); + addr_hit[237] = (reg_addr == PINMUX_MIO_PAD_ATTR_19_OFFSET); + addr_hit[238] = (reg_addr == PINMUX_MIO_PAD_ATTR_20_OFFSET); + addr_hit[239] = (reg_addr == PINMUX_MIO_PAD_ATTR_21_OFFSET); + addr_hit[240] = (reg_addr == PINMUX_MIO_PAD_ATTR_22_OFFSET); + addr_hit[241] = (reg_addr == PINMUX_MIO_PAD_ATTR_23_OFFSET); + addr_hit[242] = (reg_addr == PINMUX_MIO_PAD_ATTR_24_OFFSET); + addr_hit[243] = (reg_addr == PINMUX_MIO_PAD_ATTR_25_OFFSET); + addr_hit[244] = (reg_addr == PINMUX_MIO_PAD_ATTR_26_OFFSET); + addr_hit[245] = (reg_addr == PINMUX_MIO_PAD_ATTR_27_OFFSET); + addr_hit[246] = (reg_addr == PINMUX_MIO_PAD_ATTR_28_OFFSET); + addr_hit[247] = (reg_addr == PINMUX_MIO_PAD_ATTR_29_OFFSET); + addr_hit[248] = (reg_addr == PINMUX_MIO_PAD_ATTR_30_OFFSET); + addr_hit[249] = (reg_addr == PINMUX_MIO_PAD_ATTR_31_OFFSET); + addr_hit[250] = (reg_addr == PINMUX_MIO_PAD_ATTR_32_OFFSET); + addr_hit[251] = (reg_addr == PINMUX_MIO_PAD_ATTR_33_OFFSET); + addr_hit[252] = (reg_addr == PINMUX_MIO_PAD_ATTR_34_OFFSET); + addr_hit[253] = (reg_addr == PINMUX_MIO_PAD_ATTR_35_OFFSET); + addr_hit[254] = (reg_addr == PINMUX_MIO_PAD_ATTR_36_OFFSET); + addr_hit[255] = (reg_addr == PINMUX_MIO_PAD_ATTR_37_OFFSET); + addr_hit[256] = (reg_addr == PINMUX_MIO_PAD_ATTR_38_OFFSET); + addr_hit[257] = (reg_addr == PINMUX_MIO_PAD_ATTR_39_OFFSET); + addr_hit[258] = (reg_addr == PINMUX_MIO_PAD_ATTR_40_OFFSET); + addr_hit[259] = (reg_addr == PINMUX_MIO_PAD_ATTR_41_OFFSET); + addr_hit[260] = (reg_addr == PINMUX_MIO_PAD_ATTR_42_OFFSET); + addr_hit[261] = (reg_addr == PINMUX_MIO_PAD_ATTR_43_OFFSET); + addr_hit[262] = (reg_addr == PINMUX_MIO_PAD_ATTR_44_OFFSET); + addr_hit[263] = (reg_addr == PINMUX_MIO_PAD_ATTR_45_OFFSET); + addr_hit[264] = (reg_addr == PINMUX_MIO_PAD_ATTR_46_OFFSET); + addr_hit[265] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_0_OFFSET); + addr_hit[266] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_1_OFFSET); + addr_hit[267] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_2_OFFSET); + addr_hit[268] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_3_OFFSET); + addr_hit[269] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_4_OFFSET); + addr_hit[270] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_5_OFFSET); + addr_hit[271] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_6_OFFSET); + addr_hit[272] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_7_OFFSET); + addr_hit[273] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_8_OFFSET); + addr_hit[274] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_9_OFFSET); + addr_hit[275] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_10_OFFSET); + addr_hit[276] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_11_OFFSET); + addr_hit[277] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_12_OFFSET); + addr_hit[278] = (reg_addr == PINMUX_DIO_PAD_ATTR_REGWEN_13_OFFSET); + addr_hit[279] = (reg_addr == PINMUX_DIO_PAD_ATTR_0_OFFSET); + addr_hit[280] = (reg_addr == PINMUX_DIO_PAD_ATTR_1_OFFSET); + addr_hit[281] = (reg_addr == PINMUX_DIO_PAD_ATTR_2_OFFSET); + addr_hit[282] = (reg_addr == PINMUX_DIO_PAD_ATTR_3_OFFSET); + addr_hit[283] = (reg_addr == PINMUX_DIO_PAD_ATTR_4_OFFSET); + addr_hit[284] = (reg_addr == PINMUX_DIO_PAD_ATTR_5_OFFSET); + addr_hit[285] = (reg_addr == PINMUX_DIO_PAD_ATTR_6_OFFSET); + addr_hit[286] = (reg_addr == PINMUX_DIO_PAD_ATTR_7_OFFSET); + addr_hit[287] = (reg_addr == PINMUX_DIO_PAD_ATTR_8_OFFSET); + addr_hit[288] = (reg_addr == PINMUX_DIO_PAD_ATTR_9_OFFSET); + addr_hit[289] = (reg_addr == PINMUX_DIO_PAD_ATTR_10_OFFSET); + addr_hit[290] = (reg_addr == PINMUX_DIO_PAD_ATTR_11_OFFSET); + addr_hit[291] = (reg_addr == PINMUX_DIO_PAD_ATTR_12_OFFSET); + addr_hit[292] = (reg_addr == PINMUX_DIO_PAD_ATTR_13_OFFSET); + addr_hit[293] = (reg_addr == PINMUX_MIO_PAD_SLEEP_STATUS_0_OFFSET); + addr_hit[294] = (reg_addr == PINMUX_MIO_PAD_SLEEP_STATUS_1_OFFSET); + addr_hit[295] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_0_OFFSET); + addr_hit[296] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_1_OFFSET); + addr_hit[297] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_2_OFFSET); + addr_hit[298] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_3_OFFSET); + addr_hit[299] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_4_OFFSET); + addr_hit[300] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_5_OFFSET); + addr_hit[301] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_6_OFFSET); + addr_hit[302] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_7_OFFSET); + addr_hit[303] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_8_OFFSET); + addr_hit[304] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_9_OFFSET); + addr_hit[305] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_10_OFFSET); + addr_hit[306] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_11_OFFSET); + addr_hit[307] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_12_OFFSET); + addr_hit[308] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_13_OFFSET); + addr_hit[309] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_14_OFFSET); + addr_hit[310] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_15_OFFSET); + addr_hit[311] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_16_OFFSET); + addr_hit[312] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_17_OFFSET); + addr_hit[313] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_18_OFFSET); + addr_hit[314] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_19_OFFSET); + addr_hit[315] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_20_OFFSET); + addr_hit[316] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_21_OFFSET); + addr_hit[317] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_22_OFFSET); + addr_hit[318] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_23_OFFSET); + addr_hit[319] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_24_OFFSET); + addr_hit[320] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_25_OFFSET); + addr_hit[321] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_26_OFFSET); + addr_hit[322] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_27_OFFSET); + addr_hit[323] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_28_OFFSET); + addr_hit[324] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_29_OFFSET); + addr_hit[325] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_30_OFFSET); + addr_hit[326] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_31_OFFSET); + addr_hit[327] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_32_OFFSET); + addr_hit[328] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_33_OFFSET); + addr_hit[329] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_34_OFFSET); + addr_hit[330] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_35_OFFSET); + addr_hit[331] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_36_OFFSET); + addr_hit[332] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_37_OFFSET); + addr_hit[333] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_38_OFFSET); + addr_hit[334] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_39_OFFSET); + addr_hit[335] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_40_OFFSET); + addr_hit[336] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_41_OFFSET); + addr_hit[337] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_42_OFFSET); + addr_hit[338] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_43_OFFSET); + addr_hit[339] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_44_OFFSET); + addr_hit[340] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_45_OFFSET); + addr_hit[341] = (reg_addr == PINMUX_MIO_PAD_SLEEP_REGWEN_46_OFFSET); + addr_hit[342] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_0_OFFSET); + addr_hit[343] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_1_OFFSET); + addr_hit[344] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_2_OFFSET); + addr_hit[345] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_3_OFFSET); + addr_hit[346] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_4_OFFSET); + addr_hit[347] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_5_OFFSET); + addr_hit[348] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_6_OFFSET); + addr_hit[349] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_7_OFFSET); + addr_hit[350] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_8_OFFSET); + addr_hit[351] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_9_OFFSET); + addr_hit[352] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_10_OFFSET); + addr_hit[353] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_11_OFFSET); + addr_hit[354] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_12_OFFSET); + addr_hit[355] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_13_OFFSET); + addr_hit[356] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_14_OFFSET); + addr_hit[357] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_15_OFFSET); + addr_hit[358] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_16_OFFSET); + addr_hit[359] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_17_OFFSET); + addr_hit[360] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_18_OFFSET); + addr_hit[361] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_19_OFFSET); + addr_hit[362] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_20_OFFSET); + addr_hit[363] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_21_OFFSET); + addr_hit[364] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_22_OFFSET); + addr_hit[365] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_23_OFFSET); + addr_hit[366] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_24_OFFSET); + addr_hit[367] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_25_OFFSET); + addr_hit[368] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_26_OFFSET); + addr_hit[369] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_27_OFFSET); + addr_hit[370] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_28_OFFSET); + addr_hit[371] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_29_OFFSET); + addr_hit[372] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_30_OFFSET); + addr_hit[373] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_31_OFFSET); + addr_hit[374] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_32_OFFSET); + addr_hit[375] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_33_OFFSET); + addr_hit[376] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_34_OFFSET); + addr_hit[377] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_35_OFFSET); + addr_hit[378] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_36_OFFSET); + addr_hit[379] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_37_OFFSET); + addr_hit[380] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_38_OFFSET); + addr_hit[381] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_39_OFFSET); + addr_hit[382] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_40_OFFSET); + addr_hit[383] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_41_OFFSET); + addr_hit[384] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_42_OFFSET); + addr_hit[385] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_43_OFFSET); + addr_hit[386] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_44_OFFSET); + addr_hit[387] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_45_OFFSET); + addr_hit[388] = (reg_addr == PINMUX_MIO_PAD_SLEEP_EN_46_OFFSET); + addr_hit[389] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_0_OFFSET); + addr_hit[390] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_1_OFFSET); + addr_hit[391] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_2_OFFSET); + addr_hit[392] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_3_OFFSET); + addr_hit[393] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_4_OFFSET); + addr_hit[394] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_5_OFFSET); + addr_hit[395] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_6_OFFSET); + addr_hit[396] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_7_OFFSET); + addr_hit[397] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_8_OFFSET); + addr_hit[398] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_9_OFFSET); + addr_hit[399] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_10_OFFSET); + addr_hit[400] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_11_OFFSET); + addr_hit[401] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_12_OFFSET); + addr_hit[402] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_13_OFFSET); + addr_hit[403] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_14_OFFSET); + addr_hit[404] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_15_OFFSET); + addr_hit[405] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_16_OFFSET); + addr_hit[406] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_17_OFFSET); + addr_hit[407] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_18_OFFSET); + addr_hit[408] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_19_OFFSET); + addr_hit[409] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_20_OFFSET); + addr_hit[410] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_21_OFFSET); + addr_hit[411] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_22_OFFSET); + addr_hit[412] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_23_OFFSET); + addr_hit[413] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_24_OFFSET); + addr_hit[414] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_25_OFFSET); + addr_hit[415] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_26_OFFSET); + addr_hit[416] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_27_OFFSET); + addr_hit[417] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_28_OFFSET); + addr_hit[418] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_29_OFFSET); + addr_hit[419] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_30_OFFSET); + addr_hit[420] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_31_OFFSET); + addr_hit[421] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_32_OFFSET); + addr_hit[422] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_33_OFFSET); + addr_hit[423] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_34_OFFSET); + addr_hit[424] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_35_OFFSET); + addr_hit[425] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_36_OFFSET); + addr_hit[426] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_37_OFFSET); + addr_hit[427] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_38_OFFSET); + addr_hit[428] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_39_OFFSET); + addr_hit[429] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_40_OFFSET); + addr_hit[430] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_41_OFFSET); + addr_hit[431] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_42_OFFSET); + addr_hit[432] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_43_OFFSET); + addr_hit[433] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_44_OFFSET); + addr_hit[434] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_45_OFFSET); + addr_hit[435] = (reg_addr == PINMUX_MIO_PAD_SLEEP_MODE_46_OFFSET); + addr_hit[436] = (reg_addr == PINMUX_DIO_PAD_SLEEP_STATUS_OFFSET); + addr_hit[437] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_0_OFFSET); + addr_hit[438] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_1_OFFSET); + addr_hit[439] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_2_OFFSET); + addr_hit[440] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_3_OFFSET); + addr_hit[441] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_4_OFFSET); + addr_hit[442] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_5_OFFSET); + addr_hit[443] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_6_OFFSET); + addr_hit[444] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_7_OFFSET); + addr_hit[445] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_8_OFFSET); + addr_hit[446] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_9_OFFSET); + addr_hit[447] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_10_OFFSET); + addr_hit[448] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_11_OFFSET); + addr_hit[449] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_12_OFFSET); + addr_hit[450] = (reg_addr == PINMUX_DIO_PAD_SLEEP_REGWEN_13_OFFSET); + addr_hit[451] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_0_OFFSET); + addr_hit[452] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_1_OFFSET); + addr_hit[453] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_2_OFFSET); + addr_hit[454] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_3_OFFSET); + addr_hit[455] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_4_OFFSET); + addr_hit[456] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_5_OFFSET); + addr_hit[457] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_6_OFFSET); + addr_hit[458] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_7_OFFSET); + addr_hit[459] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_8_OFFSET); + addr_hit[460] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_9_OFFSET); + addr_hit[461] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_10_OFFSET); + addr_hit[462] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_11_OFFSET); + addr_hit[463] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_12_OFFSET); + addr_hit[464] = (reg_addr == PINMUX_DIO_PAD_SLEEP_EN_13_OFFSET); + addr_hit[465] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_0_OFFSET); + addr_hit[466] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_1_OFFSET); + addr_hit[467] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_2_OFFSET); + addr_hit[468] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_3_OFFSET); + addr_hit[469] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_4_OFFSET); + addr_hit[470] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_5_OFFSET); + addr_hit[471] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_6_OFFSET); + addr_hit[472] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_7_OFFSET); + addr_hit[473] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_8_OFFSET); + addr_hit[474] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_9_OFFSET); + addr_hit[475] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_10_OFFSET); + addr_hit[476] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_11_OFFSET); + addr_hit[477] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_12_OFFSET); + addr_hit[478] = (reg_addr == PINMUX_DIO_PAD_SLEEP_MODE_13_OFFSET); + addr_hit[479] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_0_OFFSET); + addr_hit[480] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_1_OFFSET); + addr_hit[481] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_2_OFFSET); + addr_hit[482] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_3_OFFSET); + addr_hit[483] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_4_OFFSET); + addr_hit[484] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_5_OFFSET); + addr_hit[485] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_6_OFFSET); + addr_hit[486] = (reg_addr == PINMUX_WKUP_DETECTOR_REGWEN_7_OFFSET); + addr_hit[487] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_0_OFFSET); + addr_hit[488] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_1_OFFSET); + addr_hit[489] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_2_OFFSET); + addr_hit[490] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_3_OFFSET); + addr_hit[491] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_4_OFFSET); + addr_hit[492] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_5_OFFSET); + addr_hit[493] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_6_OFFSET); + addr_hit[494] = (reg_addr == PINMUX_WKUP_DETECTOR_EN_7_OFFSET); + addr_hit[495] = (reg_addr == PINMUX_WKUP_DETECTOR_0_OFFSET); + addr_hit[496] = (reg_addr == PINMUX_WKUP_DETECTOR_1_OFFSET); + addr_hit[497] = (reg_addr == PINMUX_WKUP_DETECTOR_2_OFFSET); + addr_hit[498] = (reg_addr == PINMUX_WKUP_DETECTOR_3_OFFSET); + addr_hit[499] = (reg_addr == PINMUX_WKUP_DETECTOR_4_OFFSET); + addr_hit[500] = (reg_addr == PINMUX_WKUP_DETECTOR_5_OFFSET); + addr_hit[501] = (reg_addr == PINMUX_WKUP_DETECTOR_6_OFFSET); + addr_hit[502] = (reg_addr == PINMUX_WKUP_DETECTOR_7_OFFSET); + addr_hit[503] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_0_OFFSET); + addr_hit[504] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_1_OFFSET); + addr_hit[505] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_2_OFFSET); + addr_hit[506] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_3_OFFSET); + addr_hit[507] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_4_OFFSET); + addr_hit[508] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_5_OFFSET); + addr_hit[509] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_6_OFFSET); + addr_hit[510] = (reg_addr == PINMUX_WKUP_DETECTOR_CNT_TH_7_OFFSET); + addr_hit[511] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_0_OFFSET); + addr_hit[512] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_1_OFFSET); + addr_hit[513] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_2_OFFSET); + addr_hit[514] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_3_OFFSET); + addr_hit[515] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_4_OFFSET); + addr_hit[516] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_5_OFFSET); + addr_hit[517] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_6_OFFSET); + addr_hit[518] = (reg_addr == PINMUX_WKUP_DETECTOR_PADSEL_7_OFFSET); + addr_hit[519] = (reg_addr == PINMUX_WKUP_CAUSE_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] & (|(PINMUX_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(PINMUX_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(PINMUX_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(PINMUX_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(PINMUX_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(PINMUX_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(PINMUX_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(PINMUX_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(PINMUX_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(PINMUX_PERMIT[ 9] & ~reg_be))) | + (addr_hit[ 10] & (|(PINMUX_PERMIT[ 10] & ~reg_be))) | + (addr_hit[ 11] & (|(PINMUX_PERMIT[ 11] & ~reg_be))) | + (addr_hit[ 12] & (|(PINMUX_PERMIT[ 12] & ~reg_be))) | + (addr_hit[ 13] & (|(PINMUX_PERMIT[ 13] & ~reg_be))) | + (addr_hit[ 14] & (|(PINMUX_PERMIT[ 14] & ~reg_be))) | + (addr_hit[ 15] & (|(PINMUX_PERMIT[ 15] & ~reg_be))) | + (addr_hit[ 16] & (|(PINMUX_PERMIT[ 16] & ~reg_be))) | + (addr_hit[ 17] & (|(PINMUX_PERMIT[ 17] & ~reg_be))) | + (addr_hit[ 18] & (|(PINMUX_PERMIT[ 18] & ~reg_be))) | + (addr_hit[ 19] & (|(PINMUX_PERMIT[ 19] & ~reg_be))) | + (addr_hit[ 20] & (|(PINMUX_PERMIT[ 20] & ~reg_be))) | + (addr_hit[ 21] & (|(PINMUX_PERMIT[ 21] & ~reg_be))) | + (addr_hit[ 22] & (|(PINMUX_PERMIT[ 22] & ~reg_be))) | + (addr_hit[ 23] & (|(PINMUX_PERMIT[ 23] & ~reg_be))) | + (addr_hit[ 24] & (|(PINMUX_PERMIT[ 24] & ~reg_be))) | + (addr_hit[ 25] & (|(PINMUX_PERMIT[ 25] & ~reg_be))) | + (addr_hit[ 26] & (|(PINMUX_PERMIT[ 26] & ~reg_be))) | + (addr_hit[ 27] & (|(PINMUX_PERMIT[ 27] & ~reg_be))) | + (addr_hit[ 28] & (|(PINMUX_PERMIT[ 28] & ~reg_be))) | + (addr_hit[ 29] & (|(PINMUX_PERMIT[ 29] & ~reg_be))) | + (addr_hit[ 30] & (|(PINMUX_PERMIT[ 30] & ~reg_be))) | + (addr_hit[ 31] & (|(PINMUX_PERMIT[ 31] & ~reg_be))) | + (addr_hit[ 32] & (|(PINMUX_PERMIT[ 32] & ~reg_be))) | + (addr_hit[ 33] & (|(PINMUX_PERMIT[ 33] & ~reg_be))) | + (addr_hit[ 34] & (|(PINMUX_PERMIT[ 34] & ~reg_be))) | + (addr_hit[ 35] & (|(PINMUX_PERMIT[ 35] & ~reg_be))) | + (addr_hit[ 36] & (|(PINMUX_PERMIT[ 36] & ~reg_be))) | + (addr_hit[ 37] & (|(PINMUX_PERMIT[ 37] & ~reg_be))) | + (addr_hit[ 38] & (|(PINMUX_PERMIT[ 38] & ~reg_be))) | + (addr_hit[ 39] & (|(PINMUX_PERMIT[ 39] & ~reg_be))) | + (addr_hit[ 40] & (|(PINMUX_PERMIT[ 40] & ~reg_be))) | + (addr_hit[ 41] & (|(PINMUX_PERMIT[ 41] & ~reg_be))) | + (addr_hit[ 42] & (|(PINMUX_PERMIT[ 42] & ~reg_be))) | + (addr_hit[ 43] & (|(PINMUX_PERMIT[ 43] & ~reg_be))) | + (addr_hit[ 44] & (|(PINMUX_PERMIT[ 44] & ~reg_be))) | + (addr_hit[ 45] & (|(PINMUX_PERMIT[ 45] & ~reg_be))) | + (addr_hit[ 46] & (|(PINMUX_PERMIT[ 46] & ~reg_be))) | + (addr_hit[ 47] & (|(PINMUX_PERMIT[ 47] & ~reg_be))) | + (addr_hit[ 48] & (|(PINMUX_PERMIT[ 48] & ~reg_be))) | + (addr_hit[ 49] & (|(PINMUX_PERMIT[ 49] & ~reg_be))) | + (addr_hit[ 50] & (|(PINMUX_PERMIT[ 50] & ~reg_be))) | + (addr_hit[ 51] & (|(PINMUX_PERMIT[ 51] & ~reg_be))) | + (addr_hit[ 52] & (|(PINMUX_PERMIT[ 52] & ~reg_be))) | + (addr_hit[ 53] & (|(PINMUX_PERMIT[ 53] & ~reg_be))) | + (addr_hit[ 54] & (|(PINMUX_PERMIT[ 54] & ~reg_be))) | + (addr_hit[ 55] & (|(PINMUX_PERMIT[ 55] & ~reg_be))) | + (addr_hit[ 56] & (|(PINMUX_PERMIT[ 56] & ~reg_be))) | + (addr_hit[ 57] & (|(PINMUX_PERMIT[ 57] & ~reg_be))) | + (addr_hit[ 58] & (|(PINMUX_PERMIT[ 58] & ~reg_be))) | + (addr_hit[ 59] & (|(PINMUX_PERMIT[ 59] & ~reg_be))) | + (addr_hit[ 60] & (|(PINMUX_PERMIT[ 60] & ~reg_be))) | + (addr_hit[ 61] & (|(PINMUX_PERMIT[ 61] & ~reg_be))) | + (addr_hit[ 62] & (|(PINMUX_PERMIT[ 62] & ~reg_be))) | + (addr_hit[ 63] & (|(PINMUX_PERMIT[ 63] & ~reg_be))) | + (addr_hit[ 64] & (|(PINMUX_PERMIT[ 64] & ~reg_be))) | + (addr_hit[ 65] & (|(PINMUX_PERMIT[ 65] & ~reg_be))) | + (addr_hit[ 66] & (|(PINMUX_PERMIT[ 66] & ~reg_be))) | + (addr_hit[ 67] & (|(PINMUX_PERMIT[ 67] & ~reg_be))) | + (addr_hit[ 68] & (|(PINMUX_PERMIT[ 68] & ~reg_be))) | + (addr_hit[ 69] & (|(PINMUX_PERMIT[ 69] & ~reg_be))) | + (addr_hit[ 70] & (|(PINMUX_PERMIT[ 70] & ~reg_be))) | + (addr_hit[ 71] & (|(PINMUX_PERMIT[ 71] & ~reg_be))) | + (addr_hit[ 72] & (|(PINMUX_PERMIT[ 72] & ~reg_be))) | + (addr_hit[ 73] & (|(PINMUX_PERMIT[ 73] & ~reg_be))) | + (addr_hit[ 74] & (|(PINMUX_PERMIT[ 74] & ~reg_be))) | + (addr_hit[ 75] & (|(PINMUX_PERMIT[ 75] & ~reg_be))) | + (addr_hit[ 76] & (|(PINMUX_PERMIT[ 76] & ~reg_be))) | + (addr_hit[ 77] & (|(PINMUX_PERMIT[ 77] & ~reg_be))) | + (addr_hit[ 78] & (|(PINMUX_PERMIT[ 78] & ~reg_be))) | + (addr_hit[ 79] & (|(PINMUX_PERMIT[ 79] & ~reg_be))) | + (addr_hit[ 80] & (|(PINMUX_PERMIT[ 80] & ~reg_be))) | + (addr_hit[ 81] & (|(PINMUX_PERMIT[ 81] & ~reg_be))) | + (addr_hit[ 82] & (|(PINMUX_PERMIT[ 82] & ~reg_be))) | + (addr_hit[ 83] & (|(PINMUX_PERMIT[ 83] & ~reg_be))) | + (addr_hit[ 84] & (|(PINMUX_PERMIT[ 84] & ~reg_be))) | + (addr_hit[ 85] & (|(PINMUX_PERMIT[ 85] & ~reg_be))) | + (addr_hit[ 86] & (|(PINMUX_PERMIT[ 86] & ~reg_be))) | + (addr_hit[ 87] & (|(PINMUX_PERMIT[ 87] & ~reg_be))) | + (addr_hit[ 88] & (|(PINMUX_PERMIT[ 88] & ~reg_be))) | + (addr_hit[ 89] & (|(PINMUX_PERMIT[ 89] & ~reg_be))) | + (addr_hit[ 90] & (|(PINMUX_PERMIT[ 90] & ~reg_be))) | + (addr_hit[ 91] & (|(PINMUX_PERMIT[ 91] & ~reg_be))) | + (addr_hit[ 92] & (|(PINMUX_PERMIT[ 92] & ~reg_be))) | + (addr_hit[ 93] & (|(PINMUX_PERMIT[ 93] & ~reg_be))) | + (addr_hit[ 94] & (|(PINMUX_PERMIT[ 94] & ~reg_be))) | + (addr_hit[ 95] & (|(PINMUX_PERMIT[ 95] & ~reg_be))) | + (addr_hit[ 96] & (|(PINMUX_PERMIT[ 96] & ~reg_be))) | + (addr_hit[ 97] & (|(PINMUX_PERMIT[ 97] & ~reg_be))) | + (addr_hit[ 98] & (|(PINMUX_PERMIT[ 98] & ~reg_be))) | + (addr_hit[ 99] & (|(PINMUX_PERMIT[ 99] & ~reg_be))) | + (addr_hit[100] & (|(PINMUX_PERMIT[100] & ~reg_be))) | + (addr_hit[101] & (|(PINMUX_PERMIT[101] & ~reg_be))) | + (addr_hit[102] & (|(PINMUX_PERMIT[102] & ~reg_be))) | + (addr_hit[103] & (|(PINMUX_PERMIT[103] & ~reg_be))) | + (addr_hit[104] & (|(PINMUX_PERMIT[104] & ~reg_be))) | + (addr_hit[105] & (|(PINMUX_PERMIT[105] & ~reg_be))) | + (addr_hit[106] & (|(PINMUX_PERMIT[106] & ~reg_be))) | + (addr_hit[107] & (|(PINMUX_PERMIT[107] & ~reg_be))) | + (addr_hit[108] & (|(PINMUX_PERMIT[108] & ~reg_be))) | + (addr_hit[109] & (|(PINMUX_PERMIT[109] & ~reg_be))) | + (addr_hit[110] & (|(PINMUX_PERMIT[110] & ~reg_be))) | + (addr_hit[111] & (|(PINMUX_PERMIT[111] & ~reg_be))) | + (addr_hit[112] & (|(PINMUX_PERMIT[112] & ~reg_be))) | + (addr_hit[113] & (|(PINMUX_PERMIT[113] & ~reg_be))) | + (addr_hit[114] & (|(PINMUX_PERMIT[114] & ~reg_be))) | + (addr_hit[115] & (|(PINMUX_PERMIT[115] & ~reg_be))) | + (addr_hit[116] & (|(PINMUX_PERMIT[116] & ~reg_be))) | + (addr_hit[117] & (|(PINMUX_PERMIT[117] & ~reg_be))) | + (addr_hit[118] & (|(PINMUX_PERMIT[118] & ~reg_be))) | + (addr_hit[119] & (|(PINMUX_PERMIT[119] & ~reg_be))) | + (addr_hit[120] & (|(PINMUX_PERMIT[120] & ~reg_be))) | + (addr_hit[121] & (|(PINMUX_PERMIT[121] & ~reg_be))) | + (addr_hit[122] & (|(PINMUX_PERMIT[122] & ~reg_be))) | + (addr_hit[123] & (|(PINMUX_PERMIT[123] & ~reg_be))) | + (addr_hit[124] & (|(PINMUX_PERMIT[124] & ~reg_be))) | + (addr_hit[125] & (|(PINMUX_PERMIT[125] & ~reg_be))) | + (addr_hit[126] & (|(PINMUX_PERMIT[126] & ~reg_be))) | + (addr_hit[127] & (|(PINMUX_PERMIT[127] & ~reg_be))) | + (addr_hit[128] & (|(PINMUX_PERMIT[128] & ~reg_be))) | + (addr_hit[129] & (|(PINMUX_PERMIT[129] & ~reg_be))) | + (addr_hit[130] & (|(PINMUX_PERMIT[130] & ~reg_be))) | + (addr_hit[131] & (|(PINMUX_PERMIT[131] & ~reg_be))) | + (addr_hit[132] & (|(PINMUX_PERMIT[132] & ~reg_be))) | + (addr_hit[133] & (|(PINMUX_PERMIT[133] & ~reg_be))) | + (addr_hit[134] & (|(PINMUX_PERMIT[134] & ~reg_be))) | + (addr_hit[135] & (|(PINMUX_PERMIT[135] & ~reg_be))) | + (addr_hit[136] & (|(PINMUX_PERMIT[136] & ~reg_be))) | + (addr_hit[137] & (|(PINMUX_PERMIT[137] & ~reg_be))) | + (addr_hit[138] & (|(PINMUX_PERMIT[138] & ~reg_be))) | + (addr_hit[139] & (|(PINMUX_PERMIT[139] & ~reg_be))) | + (addr_hit[140] & (|(PINMUX_PERMIT[140] & ~reg_be))) | + (addr_hit[141] & (|(PINMUX_PERMIT[141] & ~reg_be))) | + (addr_hit[142] & (|(PINMUX_PERMIT[142] & ~reg_be))) | + (addr_hit[143] & (|(PINMUX_PERMIT[143] & ~reg_be))) | + (addr_hit[144] & (|(PINMUX_PERMIT[144] & ~reg_be))) | + (addr_hit[145] & (|(PINMUX_PERMIT[145] & ~reg_be))) | + (addr_hit[146] & (|(PINMUX_PERMIT[146] & ~reg_be))) | + (addr_hit[147] & (|(PINMUX_PERMIT[147] & ~reg_be))) | + (addr_hit[148] & (|(PINMUX_PERMIT[148] & ~reg_be))) | + (addr_hit[149] & (|(PINMUX_PERMIT[149] & ~reg_be))) | + (addr_hit[150] & (|(PINMUX_PERMIT[150] & ~reg_be))) | + (addr_hit[151] & (|(PINMUX_PERMIT[151] & ~reg_be))) | + (addr_hit[152] & (|(PINMUX_PERMIT[152] & ~reg_be))) | + (addr_hit[153] & (|(PINMUX_PERMIT[153] & ~reg_be))) | + (addr_hit[154] & (|(PINMUX_PERMIT[154] & ~reg_be))) | + (addr_hit[155] & (|(PINMUX_PERMIT[155] & ~reg_be))) | + (addr_hit[156] & (|(PINMUX_PERMIT[156] & ~reg_be))) | + (addr_hit[157] & (|(PINMUX_PERMIT[157] & ~reg_be))) | + (addr_hit[158] & (|(PINMUX_PERMIT[158] & ~reg_be))) | + (addr_hit[159] & (|(PINMUX_PERMIT[159] & ~reg_be))) | + (addr_hit[160] & (|(PINMUX_PERMIT[160] & ~reg_be))) | + (addr_hit[161] & (|(PINMUX_PERMIT[161] & ~reg_be))) | + (addr_hit[162] & (|(PINMUX_PERMIT[162] & ~reg_be))) | + (addr_hit[163] & (|(PINMUX_PERMIT[163] & ~reg_be))) | + (addr_hit[164] & (|(PINMUX_PERMIT[164] & ~reg_be))) | + (addr_hit[165] & (|(PINMUX_PERMIT[165] & ~reg_be))) | + (addr_hit[166] & (|(PINMUX_PERMIT[166] & ~reg_be))) | + (addr_hit[167] & (|(PINMUX_PERMIT[167] & ~reg_be))) | + (addr_hit[168] & (|(PINMUX_PERMIT[168] & ~reg_be))) | + (addr_hit[169] & (|(PINMUX_PERMIT[169] & ~reg_be))) | + (addr_hit[170] & (|(PINMUX_PERMIT[170] & ~reg_be))) | + (addr_hit[171] & (|(PINMUX_PERMIT[171] & ~reg_be))) | + (addr_hit[172] & (|(PINMUX_PERMIT[172] & ~reg_be))) | + (addr_hit[173] & (|(PINMUX_PERMIT[173] & ~reg_be))) | + (addr_hit[174] & (|(PINMUX_PERMIT[174] & ~reg_be))) | + (addr_hit[175] & (|(PINMUX_PERMIT[175] & ~reg_be))) | + (addr_hit[176] & (|(PINMUX_PERMIT[176] & ~reg_be))) | + (addr_hit[177] & (|(PINMUX_PERMIT[177] & ~reg_be))) | + (addr_hit[178] & (|(PINMUX_PERMIT[178] & ~reg_be))) | + (addr_hit[179] & (|(PINMUX_PERMIT[179] & ~reg_be))) | + (addr_hit[180] & (|(PINMUX_PERMIT[180] & ~reg_be))) | + (addr_hit[181] & (|(PINMUX_PERMIT[181] & ~reg_be))) | + (addr_hit[182] & (|(PINMUX_PERMIT[182] & ~reg_be))) | + (addr_hit[183] & (|(PINMUX_PERMIT[183] & ~reg_be))) | + (addr_hit[184] & (|(PINMUX_PERMIT[184] & ~reg_be))) | + (addr_hit[185] & (|(PINMUX_PERMIT[185] & ~reg_be))) | + (addr_hit[186] & (|(PINMUX_PERMIT[186] & ~reg_be))) | + (addr_hit[187] & (|(PINMUX_PERMIT[187] & ~reg_be))) | + (addr_hit[188] & (|(PINMUX_PERMIT[188] & ~reg_be))) | + (addr_hit[189] & (|(PINMUX_PERMIT[189] & ~reg_be))) | + (addr_hit[190] & (|(PINMUX_PERMIT[190] & ~reg_be))) | + (addr_hit[191] & (|(PINMUX_PERMIT[191] & ~reg_be))) | + (addr_hit[192] & (|(PINMUX_PERMIT[192] & ~reg_be))) | + (addr_hit[193] & (|(PINMUX_PERMIT[193] & ~reg_be))) | + (addr_hit[194] & (|(PINMUX_PERMIT[194] & ~reg_be))) | + (addr_hit[195] & (|(PINMUX_PERMIT[195] & ~reg_be))) | + (addr_hit[196] & (|(PINMUX_PERMIT[196] & ~reg_be))) | + (addr_hit[197] & (|(PINMUX_PERMIT[197] & ~reg_be))) | + (addr_hit[198] & (|(PINMUX_PERMIT[198] & ~reg_be))) | + (addr_hit[199] & (|(PINMUX_PERMIT[199] & ~reg_be))) | + (addr_hit[200] & (|(PINMUX_PERMIT[200] & ~reg_be))) | + (addr_hit[201] & (|(PINMUX_PERMIT[201] & ~reg_be))) | + (addr_hit[202] & (|(PINMUX_PERMIT[202] & ~reg_be))) | + (addr_hit[203] & (|(PINMUX_PERMIT[203] & ~reg_be))) | + (addr_hit[204] & (|(PINMUX_PERMIT[204] & ~reg_be))) | + (addr_hit[205] & (|(PINMUX_PERMIT[205] & ~reg_be))) | + (addr_hit[206] & (|(PINMUX_PERMIT[206] & ~reg_be))) | + (addr_hit[207] & (|(PINMUX_PERMIT[207] & ~reg_be))) | + (addr_hit[208] & (|(PINMUX_PERMIT[208] & ~reg_be))) | + (addr_hit[209] & (|(PINMUX_PERMIT[209] & ~reg_be))) | + (addr_hit[210] & (|(PINMUX_PERMIT[210] & ~reg_be))) | + (addr_hit[211] & (|(PINMUX_PERMIT[211] & ~reg_be))) | + (addr_hit[212] & (|(PINMUX_PERMIT[212] & ~reg_be))) | + (addr_hit[213] & (|(PINMUX_PERMIT[213] & ~reg_be))) | + (addr_hit[214] & (|(PINMUX_PERMIT[214] & ~reg_be))) | + (addr_hit[215] & (|(PINMUX_PERMIT[215] & ~reg_be))) | + (addr_hit[216] & (|(PINMUX_PERMIT[216] & ~reg_be))) | + (addr_hit[217] & (|(PINMUX_PERMIT[217] & ~reg_be))) | + (addr_hit[218] & (|(PINMUX_PERMIT[218] & ~reg_be))) | + (addr_hit[219] & (|(PINMUX_PERMIT[219] & ~reg_be))) | + (addr_hit[220] & (|(PINMUX_PERMIT[220] & ~reg_be))) | + (addr_hit[221] & (|(PINMUX_PERMIT[221] & ~reg_be))) | + (addr_hit[222] & (|(PINMUX_PERMIT[222] & ~reg_be))) | + (addr_hit[223] & (|(PINMUX_PERMIT[223] & ~reg_be))) | + (addr_hit[224] & (|(PINMUX_PERMIT[224] & ~reg_be))) | + (addr_hit[225] & (|(PINMUX_PERMIT[225] & ~reg_be))) | + (addr_hit[226] & (|(PINMUX_PERMIT[226] & ~reg_be))) | + (addr_hit[227] & (|(PINMUX_PERMIT[227] & ~reg_be))) | + (addr_hit[228] & (|(PINMUX_PERMIT[228] & ~reg_be))) | + (addr_hit[229] & (|(PINMUX_PERMIT[229] & ~reg_be))) | + (addr_hit[230] & (|(PINMUX_PERMIT[230] & ~reg_be))) | + (addr_hit[231] & (|(PINMUX_PERMIT[231] & ~reg_be))) | + (addr_hit[232] & (|(PINMUX_PERMIT[232] & ~reg_be))) | + (addr_hit[233] & (|(PINMUX_PERMIT[233] & ~reg_be))) | + (addr_hit[234] & (|(PINMUX_PERMIT[234] & ~reg_be))) | + (addr_hit[235] & (|(PINMUX_PERMIT[235] & ~reg_be))) | + (addr_hit[236] & (|(PINMUX_PERMIT[236] & ~reg_be))) | + (addr_hit[237] & (|(PINMUX_PERMIT[237] & ~reg_be))) | + (addr_hit[238] & (|(PINMUX_PERMIT[238] & ~reg_be))) | + (addr_hit[239] & (|(PINMUX_PERMIT[239] & ~reg_be))) | + (addr_hit[240] & (|(PINMUX_PERMIT[240] & ~reg_be))) | + (addr_hit[241] & (|(PINMUX_PERMIT[241] & ~reg_be))) | + (addr_hit[242] & (|(PINMUX_PERMIT[242] & ~reg_be))) | + (addr_hit[243] & (|(PINMUX_PERMIT[243] & ~reg_be))) | + (addr_hit[244] & (|(PINMUX_PERMIT[244] & ~reg_be))) | + (addr_hit[245] & (|(PINMUX_PERMIT[245] & ~reg_be))) | + (addr_hit[246] & (|(PINMUX_PERMIT[246] & ~reg_be))) | + (addr_hit[247] & (|(PINMUX_PERMIT[247] & ~reg_be))) | + (addr_hit[248] & (|(PINMUX_PERMIT[248] & ~reg_be))) | + (addr_hit[249] & (|(PINMUX_PERMIT[249] & ~reg_be))) | + (addr_hit[250] & (|(PINMUX_PERMIT[250] & ~reg_be))) | + (addr_hit[251] & (|(PINMUX_PERMIT[251] & ~reg_be))) | + (addr_hit[252] & (|(PINMUX_PERMIT[252] & ~reg_be))) | + (addr_hit[253] & (|(PINMUX_PERMIT[253] & ~reg_be))) | + (addr_hit[254] & (|(PINMUX_PERMIT[254] & ~reg_be))) | + (addr_hit[255] & (|(PINMUX_PERMIT[255] & ~reg_be))) | + (addr_hit[256] & (|(PINMUX_PERMIT[256] & ~reg_be))) | + (addr_hit[257] & (|(PINMUX_PERMIT[257] & ~reg_be))) | + (addr_hit[258] & (|(PINMUX_PERMIT[258] & ~reg_be))) | + (addr_hit[259] & (|(PINMUX_PERMIT[259] & ~reg_be))) | + (addr_hit[260] & (|(PINMUX_PERMIT[260] & ~reg_be))) | + (addr_hit[261] & (|(PINMUX_PERMIT[261] & ~reg_be))) | + (addr_hit[262] & (|(PINMUX_PERMIT[262] & ~reg_be))) | + (addr_hit[263] & (|(PINMUX_PERMIT[263] & ~reg_be))) | + (addr_hit[264] & (|(PINMUX_PERMIT[264] & ~reg_be))) | + (addr_hit[265] & (|(PINMUX_PERMIT[265] & ~reg_be))) | + (addr_hit[266] & (|(PINMUX_PERMIT[266] & ~reg_be))) | + (addr_hit[267] & (|(PINMUX_PERMIT[267] & ~reg_be))) | + (addr_hit[268] & (|(PINMUX_PERMIT[268] & ~reg_be))) | + (addr_hit[269] & (|(PINMUX_PERMIT[269] & ~reg_be))) | + (addr_hit[270] & (|(PINMUX_PERMIT[270] & ~reg_be))) | + (addr_hit[271] & (|(PINMUX_PERMIT[271] & ~reg_be))) | + (addr_hit[272] & (|(PINMUX_PERMIT[272] & ~reg_be))) | + (addr_hit[273] & (|(PINMUX_PERMIT[273] & ~reg_be))) | + (addr_hit[274] & (|(PINMUX_PERMIT[274] & ~reg_be))) | + (addr_hit[275] & (|(PINMUX_PERMIT[275] & ~reg_be))) | + (addr_hit[276] & (|(PINMUX_PERMIT[276] & ~reg_be))) | + (addr_hit[277] & (|(PINMUX_PERMIT[277] & ~reg_be))) | + (addr_hit[278] & (|(PINMUX_PERMIT[278] & ~reg_be))) | + (addr_hit[279] & (|(PINMUX_PERMIT[279] & ~reg_be))) | + (addr_hit[280] & (|(PINMUX_PERMIT[280] & ~reg_be))) | + (addr_hit[281] & (|(PINMUX_PERMIT[281] & ~reg_be))) | + (addr_hit[282] & (|(PINMUX_PERMIT[282] & ~reg_be))) | + (addr_hit[283] & (|(PINMUX_PERMIT[283] & ~reg_be))) | + (addr_hit[284] & (|(PINMUX_PERMIT[284] & ~reg_be))) | + (addr_hit[285] & (|(PINMUX_PERMIT[285] & ~reg_be))) | + (addr_hit[286] & (|(PINMUX_PERMIT[286] & ~reg_be))) | + (addr_hit[287] & (|(PINMUX_PERMIT[287] & ~reg_be))) | + (addr_hit[288] & (|(PINMUX_PERMIT[288] & ~reg_be))) | + (addr_hit[289] & (|(PINMUX_PERMIT[289] & ~reg_be))) | + (addr_hit[290] & (|(PINMUX_PERMIT[290] & ~reg_be))) | + (addr_hit[291] & (|(PINMUX_PERMIT[291] & ~reg_be))) | + (addr_hit[292] & (|(PINMUX_PERMIT[292] & ~reg_be))) | + (addr_hit[293] & (|(PINMUX_PERMIT[293] & ~reg_be))) | + (addr_hit[294] & (|(PINMUX_PERMIT[294] & ~reg_be))) | + (addr_hit[295] & (|(PINMUX_PERMIT[295] & ~reg_be))) | + (addr_hit[296] & (|(PINMUX_PERMIT[296] & ~reg_be))) | + (addr_hit[297] & (|(PINMUX_PERMIT[297] & ~reg_be))) | + (addr_hit[298] & (|(PINMUX_PERMIT[298] & ~reg_be))) | + (addr_hit[299] & (|(PINMUX_PERMIT[299] & ~reg_be))) | + (addr_hit[300] & (|(PINMUX_PERMIT[300] & ~reg_be))) | + (addr_hit[301] & (|(PINMUX_PERMIT[301] & ~reg_be))) | + (addr_hit[302] & (|(PINMUX_PERMIT[302] & ~reg_be))) | + (addr_hit[303] & (|(PINMUX_PERMIT[303] & ~reg_be))) | + (addr_hit[304] & (|(PINMUX_PERMIT[304] & ~reg_be))) | + (addr_hit[305] & (|(PINMUX_PERMIT[305] & ~reg_be))) | + (addr_hit[306] & (|(PINMUX_PERMIT[306] & ~reg_be))) | + (addr_hit[307] & (|(PINMUX_PERMIT[307] & ~reg_be))) | + (addr_hit[308] & (|(PINMUX_PERMIT[308] & ~reg_be))) | + (addr_hit[309] & (|(PINMUX_PERMIT[309] & ~reg_be))) | + (addr_hit[310] & (|(PINMUX_PERMIT[310] & ~reg_be))) | + (addr_hit[311] & (|(PINMUX_PERMIT[311] & ~reg_be))) | + (addr_hit[312] & (|(PINMUX_PERMIT[312] & ~reg_be))) | + (addr_hit[313] & (|(PINMUX_PERMIT[313] & ~reg_be))) | + (addr_hit[314] & (|(PINMUX_PERMIT[314] & ~reg_be))) | + (addr_hit[315] & (|(PINMUX_PERMIT[315] & ~reg_be))) | + (addr_hit[316] & (|(PINMUX_PERMIT[316] & ~reg_be))) | + (addr_hit[317] & (|(PINMUX_PERMIT[317] & ~reg_be))) | + (addr_hit[318] & (|(PINMUX_PERMIT[318] & ~reg_be))) | + (addr_hit[319] & (|(PINMUX_PERMIT[319] & ~reg_be))) | + (addr_hit[320] & (|(PINMUX_PERMIT[320] & ~reg_be))) | + (addr_hit[321] & (|(PINMUX_PERMIT[321] & ~reg_be))) | + (addr_hit[322] & (|(PINMUX_PERMIT[322] & ~reg_be))) | + (addr_hit[323] & (|(PINMUX_PERMIT[323] & ~reg_be))) | + (addr_hit[324] & (|(PINMUX_PERMIT[324] & ~reg_be))) | + (addr_hit[325] & (|(PINMUX_PERMIT[325] & ~reg_be))) | + (addr_hit[326] & (|(PINMUX_PERMIT[326] & ~reg_be))) | + (addr_hit[327] & (|(PINMUX_PERMIT[327] & ~reg_be))) | + (addr_hit[328] & (|(PINMUX_PERMIT[328] & ~reg_be))) | + (addr_hit[329] & (|(PINMUX_PERMIT[329] & ~reg_be))) | + (addr_hit[330] & (|(PINMUX_PERMIT[330] & ~reg_be))) | + (addr_hit[331] & (|(PINMUX_PERMIT[331] & ~reg_be))) | + (addr_hit[332] & (|(PINMUX_PERMIT[332] & ~reg_be))) | + (addr_hit[333] & (|(PINMUX_PERMIT[333] & ~reg_be))) | + (addr_hit[334] & (|(PINMUX_PERMIT[334] & ~reg_be))) | + (addr_hit[335] & (|(PINMUX_PERMIT[335] & ~reg_be))) | + (addr_hit[336] & (|(PINMUX_PERMIT[336] & ~reg_be))) | + (addr_hit[337] & (|(PINMUX_PERMIT[337] & ~reg_be))) | + (addr_hit[338] & (|(PINMUX_PERMIT[338] & ~reg_be))) | + (addr_hit[339] & (|(PINMUX_PERMIT[339] & ~reg_be))) | + (addr_hit[340] & (|(PINMUX_PERMIT[340] & ~reg_be))) | + (addr_hit[341] & (|(PINMUX_PERMIT[341] & ~reg_be))) | + (addr_hit[342] & (|(PINMUX_PERMIT[342] & ~reg_be))) | + (addr_hit[343] & (|(PINMUX_PERMIT[343] & ~reg_be))) | + (addr_hit[344] & (|(PINMUX_PERMIT[344] & ~reg_be))) | + (addr_hit[345] & (|(PINMUX_PERMIT[345] & ~reg_be))) | + (addr_hit[346] & (|(PINMUX_PERMIT[346] & ~reg_be))) | + (addr_hit[347] & (|(PINMUX_PERMIT[347] & ~reg_be))) | + (addr_hit[348] & (|(PINMUX_PERMIT[348] & ~reg_be))) | + (addr_hit[349] & (|(PINMUX_PERMIT[349] & ~reg_be))) | + (addr_hit[350] & (|(PINMUX_PERMIT[350] & ~reg_be))) | + (addr_hit[351] & (|(PINMUX_PERMIT[351] & ~reg_be))) | + (addr_hit[352] & (|(PINMUX_PERMIT[352] & ~reg_be))) | + (addr_hit[353] & (|(PINMUX_PERMIT[353] & ~reg_be))) | + (addr_hit[354] & (|(PINMUX_PERMIT[354] & ~reg_be))) | + (addr_hit[355] & (|(PINMUX_PERMIT[355] & ~reg_be))) | + (addr_hit[356] & (|(PINMUX_PERMIT[356] & ~reg_be))) | + (addr_hit[357] & (|(PINMUX_PERMIT[357] & ~reg_be))) | + (addr_hit[358] & (|(PINMUX_PERMIT[358] & ~reg_be))) | + (addr_hit[359] & (|(PINMUX_PERMIT[359] & ~reg_be))) | + (addr_hit[360] & (|(PINMUX_PERMIT[360] & ~reg_be))) | + (addr_hit[361] & (|(PINMUX_PERMIT[361] & ~reg_be))) | + (addr_hit[362] & (|(PINMUX_PERMIT[362] & ~reg_be))) | + (addr_hit[363] & (|(PINMUX_PERMIT[363] & ~reg_be))) | + (addr_hit[364] & (|(PINMUX_PERMIT[364] & ~reg_be))) | + (addr_hit[365] & (|(PINMUX_PERMIT[365] & ~reg_be))) | + (addr_hit[366] & (|(PINMUX_PERMIT[366] & ~reg_be))) | + (addr_hit[367] & (|(PINMUX_PERMIT[367] & ~reg_be))) | + (addr_hit[368] & (|(PINMUX_PERMIT[368] & ~reg_be))) | + (addr_hit[369] & (|(PINMUX_PERMIT[369] & ~reg_be))) | + (addr_hit[370] & (|(PINMUX_PERMIT[370] & ~reg_be))) | + (addr_hit[371] & (|(PINMUX_PERMIT[371] & ~reg_be))) | + (addr_hit[372] & (|(PINMUX_PERMIT[372] & ~reg_be))) | + (addr_hit[373] & (|(PINMUX_PERMIT[373] & ~reg_be))) | + (addr_hit[374] & (|(PINMUX_PERMIT[374] & ~reg_be))) | + (addr_hit[375] & (|(PINMUX_PERMIT[375] & ~reg_be))) | + (addr_hit[376] & (|(PINMUX_PERMIT[376] & ~reg_be))) | + (addr_hit[377] & (|(PINMUX_PERMIT[377] & ~reg_be))) | + (addr_hit[378] & (|(PINMUX_PERMIT[378] & ~reg_be))) | + (addr_hit[379] & (|(PINMUX_PERMIT[379] & ~reg_be))) | + (addr_hit[380] & (|(PINMUX_PERMIT[380] & ~reg_be))) | + (addr_hit[381] & (|(PINMUX_PERMIT[381] & ~reg_be))) | + (addr_hit[382] & (|(PINMUX_PERMIT[382] & ~reg_be))) | + (addr_hit[383] & (|(PINMUX_PERMIT[383] & ~reg_be))) | + (addr_hit[384] & (|(PINMUX_PERMIT[384] & ~reg_be))) | + (addr_hit[385] & (|(PINMUX_PERMIT[385] & ~reg_be))) | + (addr_hit[386] & (|(PINMUX_PERMIT[386] & ~reg_be))) | + (addr_hit[387] & (|(PINMUX_PERMIT[387] & ~reg_be))) | + (addr_hit[388] & (|(PINMUX_PERMIT[388] & ~reg_be))) | + (addr_hit[389] & (|(PINMUX_PERMIT[389] & ~reg_be))) | + (addr_hit[390] & (|(PINMUX_PERMIT[390] & ~reg_be))) | + (addr_hit[391] & (|(PINMUX_PERMIT[391] & ~reg_be))) | + (addr_hit[392] & (|(PINMUX_PERMIT[392] & ~reg_be))) | + (addr_hit[393] & (|(PINMUX_PERMIT[393] & ~reg_be))) | + (addr_hit[394] & (|(PINMUX_PERMIT[394] & ~reg_be))) | + (addr_hit[395] & (|(PINMUX_PERMIT[395] & ~reg_be))) | + (addr_hit[396] & (|(PINMUX_PERMIT[396] & ~reg_be))) | + (addr_hit[397] & (|(PINMUX_PERMIT[397] & ~reg_be))) | + (addr_hit[398] & (|(PINMUX_PERMIT[398] & ~reg_be))) | + (addr_hit[399] & (|(PINMUX_PERMIT[399] & ~reg_be))) | + (addr_hit[400] & (|(PINMUX_PERMIT[400] & ~reg_be))) | + (addr_hit[401] & (|(PINMUX_PERMIT[401] & ~reg_be))) | + (addr_hit[402] & (|(PINMUX_PERMIT[402] & ~reg_be))) | + (addr_hit[403] & (|(PINMUX_PERMIT[403] & ~reg_be))) | + (addr_hit[404] & (|(PINMUX_PERMIT[404] & ~reg_be))) | + (addr_hit[405] & (|(PINMUX_PERMIT[405] & ~reg_be))) | + (addr_hit[406] & (|(PINMUX_PERMIT[406] & ~reg_be))) | + (addr_hit[407] & (|(PINMUX_PERMIT[407] & ~reg_be))) | + (addr_hit[408] & (|(PINMUX_PERMIT[408] & ~reg_be))) | + (addr_hit[409] & (|(PINMUX_PERMIT[409] & ~reg_be))) | + (addr_hit[410] & (|(PINMUX_PERMIT[410] & ~reg_be))) | + (addr_hit[411] & (|(PINMUX_PERMIT[411] & ~reg_be))) | + (addr_hit[412] & (|(PINMUX_PERMIT[412] & ~reg_be))) | + (addr_hit[413] & (|(PINMUX_PERMIT[413] & ~reg_be))) | + (addr_hit[414] & (|(PINMUX_PERMIT[414] & ~reg_be))) | + (addr_hit[415] & (|(PINMUX_PERMIT[415] & ~reg_be))) | + (addr_hit[416] & (|(PINMUX_PERMIT[416] & ~reg_be))) | + (addr_hit[417] & (|(PINMUX_PERMIT[417] & ~reg_be))) | + (addr_hit[418] & (|(PINMUX_PERMIT[418] & ~reg_be))) | + (addr_hit[419] & (|(PINMUX_PERMIT[419] & ~reg_be))) | + (addr_hit[420] & (|(PINMUX_PERMIT[420] & ~reg_be))) | + (addr_hit[421] & (|(PINMUX_PERMIT[421] & ~reg_be))) | + (addr_hit[422] & (|(PINMUX_PERMIT[422] & ~reg_be))) | + (addr_hit[423] & (|(PINMUX_PERMIT[423] & ~reg_be))) | + (addr_hit[424] & (|(PINMUX_PERMIT[424] & ~reg_be))) | + (addr_hit[425] & (|(PINMUX_PERMIT[425] & ~reg_be))) | + (addr_hit[426] & (|(PINMUX_PERMIT[426] & ~reg_be))) | + (addr_hit[427] & (|(PINMUX_PERMIT[427] & ~reg_be))) | + (addr_hit[428] & (|(PINMUX_PERMIT[428] & ~reg_be))) | + (addr_hit[429] & (|(PINMUX_PERMIT[429] & ~reg_be))) | + (addr_hit[430] & (|(PINMUX_PERMIT[430] & ~reg_be))) | + (addr_hit[431] & (|(PINMUX_PERMIT[431] & ~reg_be))) | + (addr_hit[432] & (|(PINMUX_PERMIT[432] & ~reg_be))) | + (addr_hit[433] & (|(PINMUX_PERMIT[433] & ~reg_be))) | + (addr_hit[434] & (|(PINMUX_PERMIT[434] & ~reg_be))) | + (addr_hit[435] & (|(PINMUX_PERMIT[435] & ~reg_be))) | + (addr_hit[436] & (|(PINMUX_PERMIT[436] & ~reg_be))) | + (addr_hit[437] & (|(PINMUX_PERMIT[437] & ~reg_be))) | + (addr_hit[438] & (|(PINMUX_PERMIT[438] & ~reg_be))) | + (addr_hit[439] & (|(PINMUX_PERMIT[439] & ~reg_be))) | + (addr_hit[440] & (|(PINMUX_PERMIT[440] & ~reg_be))) | + (addr_hit[441] & (|(PINMUX_PERMIT[441] & ~reg_be))) | + (addr_hit[442] & (|(PINMUX_PERMIT[442] & ~reg_be))) | + (addr_hit[443] & (|(PINMUX_PERMIT[443] & ~reg_be))) | + (addr_hit[444] & (|(PINMUX_PERMIT[444] & ~reg_be))) | + (addr_hit[445] & (|(PINMUX_PERMIT[445] & ~reg_be))) | + (addr_hit[446] & (|(PINMUX_PERMIT[446] & ~reg_be))) | + (addr_hit[447] & (|(PINMUX_PERMIT[447] & ~reg_be))) | + (addr_hit[448] & (|(PINMUX_PERMIT[448] & ~reg_be))) | + (addr_hit[449] & (|(PINMUX_PERMIT[449] & ~reg_be))) | + (addr_hit[450] & (|(PINMUX_PERMIT[450] & ~reg_be))) | + (addr_hit[451] & (|(PINMUX_PERMIT[451] & ~reg_be))) | + (addr_hit[452] & (|(PINMUX_PERMIT[452] & ~reg_be))) | + (addr_hit[453] & (|(PINMUX_PERMIT[453] & ~reg_be))) | + (addr_hit[454] & (|(PINMUX_PERMIT[454] & ~reg_be))) | + (addr_hit[455] & (|(PINMUX_PERMIT[455] & ~reg_be))) | + (addr_hit[456] & (|(PINMUX_PERMIT[456] & ~reg_be))) | + (addr_hit[457] & (|(PINMUX_PERMIT[457] & ~reg_be))) | + (addr_hit[458] & (|(PINMUX_PERMIT[458] & ~reg_be))) | + (addr_hit[459] & (|(PINMUX_PERMIT[459] & ~reg_be))) | + (addr_hit[460] & (|(PINMUX_PERMIT[460] & ~reg_be))) | + (addr_hit[461] & (|(PINMUX_PERMIT[461] & ~reg_be))) | + (addr_hit[462] & (|(PINMUX_PERMIT[462] & ~reg_be))) | + (addr_hit[463] & (|(PINMUX_PERMIT[463] & ~reg_be))) | + (addr_hit[464] & (|(PINMUX_PERMIT[464] & ~reg_be))) | + (addr_hit[465] & (|(PINMUX_PERMIT[465] & ~reg_be))) | + (addr_hit[466] & (|(PINMUX_PERMIT[466] & ~reg_be))) | + (addr_hit[467] & (|(PINMUX_PERMIT[467] & ~reg_be))) | + (addr_hit[468] & (|(PINMUX_PERMIT[468] & ~reg_be))) | + (addr_hit[469] & (|(PINMUX_PERMIT[469] & ~reg_be))) | + (addr_hit[470] & (|(PINMUX_PERMIT[470] & ~reg_be))) | + (addr_hit[471] & (|(PINMUX_PERMIT[471] & ~reg_be))) | + (addr_hit[472] & (|(PINMUX_PERMIT[472] & ~reg_be))) | + (addr_hit[473] & (|(PINMUX_PERMIT[473] & ~reg_be))) | + (addr_hit[474] & (|(PINMUX_PERMIT[474] & ~reg_be))) | + (addr_hit[475] & (|(PINMUX_PERMIT[475] & ~reg_be))) | + (addr_hit[476] & (|(PINMUX_PERMIT[476] & ~reg_be))) | + (addr_hit[477] & (|(PINMUX_PERMIT[477] & ~reg_be))) | + (addr_hit[478] & (|(PINMUX_PERMIT[478] & ~reg_be))) | + (addr_hit[479] & (|(PINMUX_PERMIT[479] & ~reg_be))) | + (addr_hit[480] & (|(PINMUX_PERMIT[480] & ~reg_be))) | + (addr_hit[481] & (|(PINMUX_PERMIT[481] & ~reg_be))) | + (addr_hit[482] & (|(PINMUX_PERMIT[482] & ~reg_be))) | + (addr_hit[483] & (|(PINMUX_PERMIT[483] & ~reg_be))) | + (addr_hit[484] & (|(PINMUX_PERMIT[484] & ~reg_be))) | + (addr_hit[485] & (|(PINMUX_PERMIT[485] & ~reg_be))) | + (addr_hit[486] & (|(PINMUX_PERMIT[486] & ~reg_be))) | + (addr_hit[487] & (|(PINMUX_PERMIT[487] & ~reg_be))) | + (addr_hit[488] & (|(PINMUX_PERMIT[488] & ~reg_be))) | + (addr_hit[489] & (|(PINMUX_PERMIT[489] & ~reg_be))) | + (addr_hit[490] & (|(PINMUX_PERMIT[490] & ~reg_be))) | + (addr_hit[491] & (|(PINMUX_PERMIT[491] & ~reg_be))) | + (addr_hit[492] & (|(PINMUX_PERMIT[492] & ~reg_be))) | + (addr_hit[493] & (|(PINMUX_PERMIT[493] & ~reg_be))) | + (addr_hit[494] & (|(PINMUX_PERMIT[494] & ~reg_be))) | + (addr_hit[495] & (|(PINMUX_PERMIT[495] & ~reg_be))) | + (addr_hit[496] & (|(PINMUX_PERMIT[496] & ~reg_be))) | + (addr_hit[497] & (|(PINMUX_PERMIT[497] & ~reg_be))) | + (addr_hit[498] & (|(PINMUX_PERMIT[498] & ~reg_be))) | + (addr_hit[499] & (|(PINMUX_PERMIT[499] & ~reg_be))) | + (addr_hit[500] & (|(PINMUX_PERMIT[500] & ~reg_be))) | + (addr_hit[501] & (|(PINMUX_PERMIT[501] & ~reg_be))) | + (addr_hit[502] & (|(PINMUX_PERMIT[502] & ~reg_be))) | + (addr_hit[503] & (|(PINMUX_PERMIT[503] & ~reg_be))) | + (addr_hit[504] & (|(PINMUX_PERMIT[504] & ~reg_be))) | + (addr_hit[505] & (|(PINMUX_PERMIT[505] & ~reg_be))) | + (addr_hit[506] & (|(PINMUX_PERMIT[506] & ~reg_be))) | + (addr_hit[507] & (|(PINMUX_PERMIT[507] & ~reg_be))) | + (addr_hit[508] & (|(PINMUX_PERMIT[508] & ~reg_be))) | + (addr_hit[509] & (|(PINMUX_PERMIT[509] & ~reg_be))) | + (addr_hit[510] & (|(PINMUX_PERMIT[510] & ~reg_be))) | + (addr_hit[511] & (|(PINMUX_PERMIT[511] & ~reg_be))) | + (addr_hit[512] & (|(PINMUX_PERMIT[512] & ~reg_be))) | + (addr_hit[513] & (|(PINMUX_PERMIT[513] & ~reg_be))) | + (addr_hit[514] & (|(PINMUX_PERMIT[514] & ~reg_be))) | + (addr_hit[515] & (|(PINMUX_PERMIT[515] & ~reg_be))) | + (addr_hit[516] & (|(PINMUX_PERMIT[516] & ~reg_be))) | + (addr_hit[517] & (|(PINMUX_PERMIT[517] & ~reg_be))) | + (addr_hit[518] & (|(PINMUX_PERMIT[518] & ~reg_be))) | + (addr_hit[519] & (|(PINMUX_PERMIT[519] & ~reg_be))))); + end + + // Generate write-enables + assign alert_test_we = addr_hit[0] & reg_we & !reg_error; + + assign alert_test_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_0_we = addr_hit[1] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_0_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_1_we = addr_hit[2] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_1_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_2_we = addr_hit[3] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_2_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_3_we = addr_hit[4] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_3_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_4_we = addr_hit[5] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_4_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_5_we = addr_hit[6] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_5_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_6_we = addr_hit[7] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_6_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_7_we = addr_hit[8] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_7_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_8_we = addr_hit[9] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_8_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_9_we = addr_hit[10] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_9_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_10_we = addr_hit[11] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_10_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_11_we = addr_hit[12] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_11_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_12_we = addr_hit[13] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_12_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_13_we = addr_hit[14] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_13_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_14_we = addr_hit[15] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_14_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_15_we = addr_hit[16] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_15_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_16_we = addr_hit[17] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_16_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_17_we = addr_hit[18] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_17_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_18_we = addr_hit[19] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_18_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_19_we = addr_hit[20] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_19_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_20_we = addr_hit[21] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_20_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_21_we = addr_hit[22] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_21_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_22_we = addr_hit[23] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_22_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_23_we = addr_hit[24] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_23_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_24_we = addr_hit[25] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_24_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_25_we = addr_hit[26] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_25_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_26_we = addr_hit[27] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_26_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_27_we = addr_hit[28] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_27_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_28_we = addr_hit[29] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_28_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_29_we = addr_hit[30] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_29_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_30_we = addr_hit[31] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_30_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_31_we = addr_hit[32] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_31_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_32_we = addr_hit[33] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_32_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_33_we = addr_hit[34] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_33_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_34_we = addr_hit[35] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_34_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_35_we = addr_hit[36] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_35_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_36_we = addr_hit[37] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_36_wd = reg_wdata[0]; + assign mio_periph_insel_regwen_37_we = addr_hit[38] & reg_we & !reg_error; + + assign mio_periph_insel_regwen_37_wd = reg_wdata[0]; + assign mio_periph_insel_0_we = addr_hit[39] & reg_we & !reg_error; + + assign mio_periph_insel_0_wd = reg_wdata[5:0]; + assign mio_periph_insel_1_we = addr_hit[40] & reg_we & !reg_error; + + assign mio_periph_insel_1_wd = reg_wdata[5:0]; + assign mio_periph_insel_2_we = addr_hit[41] & reg_we & !reg_error; + + assign mio_periph_insel_2_wd = reg_wdata[5:0]; + assign mio_periph_insel_3_we = addr_hit[42] & reg_we & !reg_error; + + assign mio_periph_insel_3_wd = reg_wdata[5:0]; + assign mio_periph_insel_4_we = addr_hit[43] & reg_we & !reg_error; + + assign mio_periph_insel_4_wd = reg_wdata[5:0]; + assign mio_periph_insel_5_we = addr_hit[44] & reg_we & !reg_error; + + assign mio_periph_insel_5_wd = reg_wdata[5:0]; + assign mio_periph_insel_6_we = addr_hit[45] & reg_we & !reg_error; + + assign mio_periph_insel_6_wd = reg_wdata[5:0]; + assign mio_periph_insel_7_we = addr_hit[46] & reg_we & !reg_error; + + assign mio_periph_insel_7_wd = reg_wdata[5:0]; + assign mio_periph_insel_8_we = addr_hit[47] & reg_we & !reg_error; + + assign mio_periph_insel_8_wd = reg_wdata[5:0]; + assign mio_periph_insel_9_we = addr_hit[48] & reg_we & !reg_error; + + assign mio_periph_insel_9_wd = reg_wdata[5:0]; + assign mio_periph_insel_10_we = addr_hit[49] & reg_we & !reg_error; + + assign mio_periph_insel_10_wd = reg_wdata[5:0]; + assign mio_periph_insel_11_we = addr_hit[50] & reg_we & !reg_error; + + assign mio_periph_insel_11_wd = reg_wdata[5:0]; + assign mio_periph_insel_12_we = addr_hit[51] & reg_we & !reg_error; + + assign mio_periph_insel_12_wd = reg_wdata[5:0]; + assign mio_periph_insel_13_we = addr_hit[52] & reg_we & !reg_error; + + assign mio_periph_insel_13_wd = reg_wdata[5:0]; + assign mio_periph_insel_14_we = addr_hit[53] & reg_we & !reg_error; + + assign mio_periph_insel_14_wd = reg_wdata[5:0]; + assign mio_periph_insel_15_we = addr_hit[54] & reg_we & !reg_error; + + assign mio_periph_insel_15_wd = reg_wdata[5:0]; + assign mio_periph_insel_16_we = addr_hit[55] & reg_we & !reg_error; + + assign mio_periph_insel_16_wd = reg_wdata[5:0]; + assign mio_periph_insel_17_we = addr_hit[56] & reg_we & !reg_error; + + assign mio_periph_insel_17_wd = reg_wdata[5:0]; + assign mio_periph_insel_18_we = addr_hit[57] & reg_we & !reg_error; + + assign mio_periph_insel_18_wd = reg_wdata[5:0]; + assign mio_periph_insel_19_we = addr_hit[58] & reg_we & !reg_error; + + assign mio_periph_insel_19_wd = reg_wdata[5:0]; + assign mio_periph_insel_20_we = addr_hit[59] & reg_we & !reg_error; + + assign mio_periph_insel_20_wd = reg_wdata[5:0]; + assign mio_periph_insel_21_we = addr_hit[60] & reg_we & !reg_error; + + assign mio_periph_insel_21_wd = reg_wdata[5:0]; + assign mio_periph_insel_22_we = addr_hit[61] & reg_we & !reg_error; + + assign mio_periph_insel_22_wd = reg_wdata[5:0]; + assign mio_periph_insel_23_we = addr_hit[62] & reg_we & !reg_error; + + assign mio_periph_insel_23_wd = reg_wdata[5:0]; + assign mio_periph_insel_24_we = addr_hit[63] & reg_we & !reg_error; + + assign mio_periph_insel_24_wd = reg_wdata[5:0]; + assign mio_periph_insel_25_we = addr_hit[64] & reg_we & !reg_error; + + assign mio_periph_insel_25_wd = reg_wdata[5:0]; + assign mio_periph_insel_26_we = addr_hit[65] & reg_we & !reg_error; + + assign mio_periph_insel_26_wd = reg_wdata[5:0]; + assign mio_periph_insel_27_we = addr_hit[66] & reg_we & !reg_error; + + assign mio_periph_insel_27_wd = reg_wdata[5:0]; + assign mio_periph_insel_28_we = addr_hit[67] & reg_we & !reg_error; + + assign mio_periph_insel_28_wd = reg_wdata[5:0]; + assign mio_periph_insel_29_we = addr_hit[68] & reg_we & !reg_error; + + assign mio_periph_insel_29_wd = reg_wdata[5:0]; + assign mio_periph_insel_30_we = addr_hit[69] & reg_we & !reg_error; + + assign mio_periph_insel_30_wd = reg_wdata[5:0]; + assign mio_periph_insel_31_we = addr_hit[70] & reg_we & !reg_error; + + assign mio_periph_insel_31_wd = reg_wdata[5:0]; + assign mio_periph_insel_32_we = addr_hit[71] & reg_we & !reg_error; + + assign mio_periph_insel_32_wd = reg_wdata[5:0]; + assign mio_periph_insel_33_we = addr_hit[72] & reg_we & !reg_error; + + assign mio_periph_insel_33_wd = reg_wdata[5:0]; + assign mio_periph_insel_34_we = addr_hit[73] & reg_we & !reg_error; + + assign mio_periph_insel_34_wd = reg_wdata[5:0]; + assign mio_periph_insel_35_we = addr_hit[74] & reg_we & !reg_error; + + assign mio_periph_insel_35_wd = reg_wdata[5:0]; + assign mio_periph_insel_36_we = addr_hit[75] & reg_we & !reg_error; + + assign mio_periph_insel_36_wd = reg_wdata[5:0]; + assign mio_periph_insel_37_we = addr_hit[76] & reg_we & !reg_error; + + assign mio_periph_insel_37_wd = reg_wdata[5:0]; + assign mio_outsel_regwen_0_we = addr_hit[77] & reg_we & !reg_error; + + assign mio_outsel_regwen_0_wd = reg_wdata[0]; + assign mio_outsel_regwen_1_we = addr_hit[78] & reg_we & !reg_error; + + assign mio_outsel_regwen_1_wd = reg_wdata[0]; + assign mio_outsel_regwen_2_we = addr_hit[79] & reg_we & !reg_error; + + assign mio_outsel_regwen_2_wd = reg_wdata[0]; + assign mio_outsel_regwen_3_we = addr_hit[80] & reg_we & !reg_error; + + assign mio_outsel_regwen_3_wd = reg_wdata[0]; + assign mio_outsel_regwen_4_we = addr_hit[81] & reg_we & !reg_error; + + assign mio_outsel_regwen_4_wd = reg_wdata[0]; + assign mio_outsel_regwen_5_we = addr_hit[82] & reg_we & !reg_error; + + assign mio_outsel_regwen_5_wd = reg_wdata[0]; + assign mio_outsel_regwen_6_we = addr_hit[83] & reg_we & !reg_error; + + assign mio_outsel_regwen_6_wd = reg_wdata[0]; + assign mio_outsel_regwen_7_we = addr_hit[84] & reg_we & !reg_error; + + assign mio_outsel_regwen_7_wd = reg_wdata[0]; + assign mio_outsel_regwen_8_we = addr_hit[85] & reg_we & !reg_error; + + assign mio_outsel_regwen_8_wd = reg_wdata[0]; + assign mio_outsel_regwen_9_we = addr_hit[86] & reg_we & !reg_error; + + assign mio_outsel_regwen_9_wd = reg_wdata[0]; + assign mio_outsel_regwen_10_we = addr_hit[87] & reg_we & !reg_error; + + assign mio_outsel_regwen_10_wd = reg_wdata[0]; + assign mio_outsel_regwen_11_we = addr_hit[88] & reg_we & !reg_error; + + assign mio_outsel_regwen_11_wd = reg_wdata[0]; + assign mio_outsel_regwen_12_we = addr_hit[89] & reg_we & !reg_error; + + assign mio_outsel_regwen_12_wd = reg_wdata[0]; + assign mio_outsel_regwen_13_we = addr_hit[90] & reg_we & !reg_error; + + assign mio_outsel_regwen_13_wd = reg_wdata[0]; + assign mio_outsel_regwen_14_we = addr_hit[91] & reg_we & !reg_error; + + assign mio_outsel_regwen_14_wd = reg_wdata[0]; + assign mio_outsel_regwen_15_we = addr_hit[92] & reg_we & !reg_error; + + assign mio_outsel_regwen_15_wd = reg_wdata[0]; + assign mio_outsel_regwen_16_we = addr_hit[93] & reg_we & !reg_error; + + assign mio_outsel_regwen_16_wd = reg_wdata[0]; + assign mio_outsel_regwen_17_we = addr_hit[94] & reg_we & !reg_error; + + assign mio_outsel_regwen_17_wd = reg_wdata[0]; + assign mio_outsel_regwen_18_we = addr_hit[95] & reg_we & !reg_error; + + assign mio_outsel_regwen_18_wd = reg_wdata[0]; + assign mio_outsel_regwen_19_we = addr_hit[96] & reg_we & !reg_error; + + assign mio_outsel_regwen_19_wd = reg_wdata[0]; + assign mio_outsel_regwen_20_we = addr_hit[97] & reg_we & !reg_error; + + assign mio_outsel_regwen_20_wd = reg_wdata[0]; + assign mio_outsel_regwen_21_we = addr_hit[98] & reg_we & !reg_error; + + assign mio_outsel_regwen_21_wd = reg_wdata[0]; + assign mio_outsel_regwen_22_we = addr_hit[99] & reg_we & !reg_error; + + assign mio_outsel_regwen_22_wd = reg_wdata[0]; + assign mio_outsel_regwen_23_we = addr_hit[100] & reg_we & !reg_error; + + assign mio_outsel_regwen_23_wd = reg_wdata[0]; + assign mio_outsel_regwen_24_we = addr_hit[101] & reg_we & !reg_error; + + assign mio_outsel_regwen_24_wd = reg_wdata[0]; + assign mio_outsel_regwen_25_we = addr_hit[102] & reg_we & !reg_error; + + assign mio_outsel_regwen_25_wd = reg_wdata[0]; + assign mio_outsel_regwen_26_we = addr_hit[103] & reg_we & !reg_error; + + assign mio_outsel_regwen_26_wd = reg_wdata[0]; + assign mio_outsel_regwen_27_we = addr_hit[104] & reg_we & !reg_error; + + assign mio_outsel_regwen_27_wd = reg_wdata[0]; + assign mio_outsel_regwen_28_we = addr_hit[105] & reg_we & !reg_error; + + assign mio_outsel_regwen_28_wd = reg_wdata[0]; + assign mio_outsel_regwen_29_we = addr_hit[106] & reg_we & !reg_error; + + assign mio_outsel_regwen_29_wd = reg_wdata[0]; + assign mio_outsel_regwen_30_we = addr_hit[107] & reg_we & !reg_error; + + assign mio_outsel_regwen_30_wd = reg_wdata[0]; + assign mio_outsel_regwen_31_we = addr_hit[108] & reg_we & !reg_error; + + assign mio_outsel_regwen_31_wd = reg_wdata[0]; + assign mio_outsel_regwen_32_we = addr_hit[109] & reg_we & !reg_error; + + assign mio_outsel_regwen_32_wd = reg_wdata[0]; + assign mio_outsel_regwen_33_we = addr_hit[110] & reg_we & !reg_error; + + assign mio_outsel_regwen_33_wd = reg_wdata[0]; + assign mio_outsel_regwen_34_we = addr_hit[111] & reg_we & !reg_error; + + assign mio_outsel_regwen_34_wd = reg_wdata[0]; + assign mio_outsel_regwen_35_we = addr_hit[112] & reg_we & !reg_error; + + assign mio_outsel_regwen_35_wd = reg_wdata[0]; + assign mio_outsel_regwen_36_we = addr_hit[113] & reg_we & !reg_error; + + assign mio_outsel_regwen_36_wd = reg_wdata[0]; + assign mio_outsel_regwen_37_we = addr_hit[114] & reg_we & !reg_error; + + assign mio_outsel_regwen_37_wd = reg_wdata[0]; + assign mio_outsel_regwen_38_we = addr_hit[115] & reg_we & !reg_error; + + assign mio_outsel_regwen_38_wd = reg_wdata[0]; + assign mio_outsel_regwen_39_we = addr_hit[116] & reg_we & !reg_error; + + assign mio_outsel_regwen_39_wd = reg_wdata[0]; + assign mio_outsel_regwen_40_we = addr_hit[117] & reg_we & !reg_error; + + assign mio_outsel_regwen_40_wd = reg_wdata[0]; + assign mio_outsel_regwen_41_we = addr_hit[118] & reg_we & !reg_error; + + assign mio_outsel_regwen_41_wd = reg_wdata[0]; + assign mio_outsel_regwen_42_we = addr_hit[119] & reg_we & !reg_error; + + assign mio_outsel_regwen_42_wd = reg_wdata[0]; + assign mio_outsel_regwen_43_we = addr_hit[120] & reg_we & !reg_error; + + assign mio_outsel_regwen_43_wd = reg_wdata[0]; + assign mio_outsel_regwen_44_we = addr_hit[121] & reg_we & !reg_error; + + assign mio_outsel_regwen_44_wd = reg_wdata[0]; + assign mio_outsel_regwen_45_we = addr_hit[122] & reg_we & !reg_error; + + assign mio_outsel_regwen_45_wd = reg_wdata[0]; + assign mio_outsel_regwen_46_we = addr_hit[123] & reg_we & !reg_error; + + assign mio_outsel_regwen_46_wd = reg_wdata[0]; + assign mio_outsel_0_we = addr_hit[124] & reg_we & !reg_error; + + assign mio_outsel_0_wd = reg_wdata[5:0]; + assign mio_outsel_1_we = addr_hit[125] & reg_we & !reg_error; + + assign mio_outsel_1_wd = reg_wdata[5:0]; + assign mio_outsel_2_we = addr_hit[126] & reg_we & !reg_error; + + assign mio_outsel_2_wd = reg_wdata[5:0]; + assign mio_outsel_3_we = addr_hit[127] & reg_we & !reg_error; + + assign mio_outsel_3_wd = reg_wdata[5:0]; + assign mio_outsel_4_we = addr_hit[128] & reg_we & !reg_error; + + assign mio_outsel_4_wd = reg_wdata[5:0]; + assign mio_outsel_5_we = addr_hit[129] & reg_we & !reg_error; + + assign mio_outsel_5_wd = reg_wdata[5:0]; + assign mio_outsel_6_we = addr_hit[130] & reg_we & !reg_error; + + assign mio_outsel_6_wd = reg_wdata[5:0]; + assign mio_outsel_7_we = addr_hit[131] & reg_we & !reg_error; + + assign mio_outsel_7_wd = reg_wdata[5:0]; + assign mio_outsel_8_we = addr_hit[132] & reg_we & !reg_error; + + assign mio_outsel_8_wd = reg_wdata[5:0]; + assign mio_outsel_9_we = addr_hit[133] & reg_we & !reg_error; + + assign mio_outsel_9_wd = reg_wdata[5:0]; + assign mio_outsel_10_we = addr_hit[134] & reg_we & !reg_error; + + assign mio_outsel_10_wd = reg_wdata[5:0]; + assign mio_outsel_11_we = addr_hit[135] & reg_we & !reg_error; + + assign mio_outsel_11_wd = reg_wdata[5:0]; + assign mio_outsel_12_we = addr_hit[136] & reg_we & !reg_error; + + assign mio_outsel_12_wd = reg_wdata[5:0]; + assign mio_outsel_13_we = addr_hit[137] & reg_we & !reg_error; + + assign mio_outsel_13_wd = reg_wdata[5:0]; + assign mio_outsel_14_we = addr_hit[138] & reg_we & !reg_error; + + assign mio_outsel_14_wd = reg_wdata[5:0]; + assign mio_outsel_15_we = addr_hit[139] & reg_we & !reg_error; + + assign mio_outsel_15_wd = reg_wdata[5:0]; + assign mio_outsel_16_we = addr_hit[140] & reg_we & !reg_error; + + assign mio_outsel_16_wd = reg_wdata[5:0]; + assign mio_outsel_17_we = addr_hit[141] & reg_we & !reg_error; + + assign mio_outsel_17_wd = reg_wdata[5:0]; + assign mio_outsel_18_we = addr_hit[142] & reg_we & !reg_error; + + assign mio_outsel_18_wd = reg_wdata[5:0]; + assign mio_outsel_19_we = addr_hit[143] & reg_we & !reg_error; + + assign mio_outsel_19_wd = reg_wdata[5:0]; + assign mio_outsel_20_we = addr_hit[144] & reg_we & !reg_error; + + assign mio_outsel_20_wd = reg_wdata[5:0]; + assign mio_outsel_21_we = addr_hit[145] & reg_we & !reg_error; + + assign mio_outsel_21_wd = reg_wdata[5:0]; + assign mio_outsel_22_we = addr_hit[146] & reg_we & !reg_error; + + assign mio_outsel_22_wd = reg_wdata[5:0]; + assign mio_outsel_23_we = addr_hit[147] & reg_we & !reg_error; + + assign mio_outsel_23_wd = reg_wdata[5:0]; + assign mio_outsel_24_we = addr_hit[148] & reg_we & !reg_error; + + assign mio_outsel_24_wd = reg_wdata[5:0]; + assign mio_outsel_25_we = addr_hit[149] & reg_we & !reg_error; + + assign mio_outsel_25_wd = reg_wdata[5:0]; + assign mio_outsel_26_we = addr_hit[150] & reg_we & !reg_error; + + assign mio_outsel_26_wd = reg_wdata[5:0]; + assign mio_outsel_27_we = addr_hit[151] & reg_we & !reg_error; + + assign mio_outsel_27_wd = reg_wdata[5:0]; + assign mio_outsel_28_we = addr_hit[152] & reg_we & !reg_error; + + assign mio_outsel_28_wd = reg_wdata[5:0]; + assign mio_outsel_29_we = addr_hit[153] & reg_we & !reg_error; + + assign mio_outsel_29_wd = reg_wdata[5:0]; + assign mio_outsel_30_we = addr_hit[154] & reg_we & !reg_error; + + assign mio_outsel_30_wd = reg_wdata[5:0]; + assign mio_outsel_31_we = addr_hit[155] & reg_we & !reg_error; + + assign mio_outsel_31_wd = reg_wdata[5:0]; + assign mio_outsel_32_we = addr_hit[156] & reg_we & !reg_error; + + assign mio_outsel_32_wd = reg_wdata[5:0]; + assign mio_outsel_33_we = addr_hit[157] & reg_we & !reg_error; + + assign mio_outsel_33_wd = reg_wdata[5:0]; + assign mio_outsel_34_we = addr_hit[158] & reg_we & !reg_error; + + assign mio_outsel_34_wd = reg_wdata[5:0]; + assign mio_outsel_35_we = addr_hit[159] & reg_we & !reg_error; + + assign mio_outsel_35_wd = reg_wdata[5:0]; + assign mio_outsel_36_we = addr_hit[160] & reg_we & !reg_error; + + assign mio_outsel_36_wd = reg_wdata[5:0]; + assign mio_outsel_37_we = addr_hit[161] & reg_we & !reg_error; + + assign mio_outsel_37_wd = reg_wdata[5:0]; + assign mio_outsel_38_we = addr_hit[162] & reg_we & !reg_error; + + assign mio_outsel_38_wd = reg_wdata[5:0]; + assign mio_outsel_39_we = addr_hit[163] & reg_we & !reg_error; + + assign mio_outsel_39_wd = reg_wdata[5:0]; + assign mio_outsel_40_we = addr_hit[164] & reg_we & !reg_error; + + assign mio_outsel_40_wd = reg_wdata[5:0]; + assign mio_outsel_41_we = addr_hit[165] & reg_we & !reg_error; + + assign mio_outsel_41_wd = reg_wdata[5:0]; + assign mio_outsel_42_we = addr_hit[166] & reg_we & !reg_error; + + assign mio_outsel_42_wd = reg_wdata[5:0]; + assign mio_outsel_43_we = addr_hit[167] & reg_we & !reg_error; + + assign mio_outsel_43_wd = reg_wdata[5:0]; + assign mio_outsel_44_we = addr_hit[168] & reg_we & !reg_error; + + assign mio_outsel_44_wd = reg_wdata[5:0]; + assign mio_outsel_45_we = addr_hit[169] & reg_we & !reg_error; + + assign mio_outsel_45_wd = reg_wdata[5:0]; + assign mio_outsel_46_we = addr_hit[170] & reg_we & !reg_error; + + assign mio_outsel_46_wd = reg_wdata[5:0]; + assign mio_pad_attr_regwen_0_we = addr_hit[171] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_0_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_1_we = addr_hit[172] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_1_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_2_we = addr_hit[173] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_2_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_3_we = addr_hit[174] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_3_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_4_we = addr_hit[175] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_4_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_5_we = addr_hit[176] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_5_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_6_we = addr_hit[177] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_6_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_7_we = addr_hit[178] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_7_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_8_we = addr_hit[179] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_8_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_9_we = addr_hit[180] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_9_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_10_we = addr_hit[181] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_10_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_11_we = addr_hit[182] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_11_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_12_we = addr_hit[183] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_12_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_13_we = addr_hit[184] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_13_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_14_we = addr_hit[185] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_14_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_15_we = addr_hit[186] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_15_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_16_we = addr_hit[187] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_16_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_17_we = addr_hit[188] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_17_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_18_we = addr_hit[189] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_18_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_19_we = addr_hit[190] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_19_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_20_we = addr_hit[191] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_20_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_21_we = addr_hit[192] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_21_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_22_we = addr_hit[193] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_22_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_23_we = addr_hit[194] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_23_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_24_we = addr_hit[195] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_24_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_25_we = addr_hit[196] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_25_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_26_we = addr_hit[197] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_26_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_27_we = addr_hit[198] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_27_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_28_we = addr_hit[199] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_28_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_29_we = addr_hit[200] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_29_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_30_we = addr_hit[201] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_30_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_31_we = addr_hit[202] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_31_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_32_we = addr_hit[203] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_32_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_33_we = addr_hit[204] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_33_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_34_we = addr_hit[205] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_34_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_35_we = addr_hit[206] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_35_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_36_we = addr_hit[207] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_36_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_37_we = addr_hit[208] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_37_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_38_we = addr_hit[209] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_38_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_39_we = addr_hit[210] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_39_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_40_we = addr_hit[211] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_40_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_41_we = addr_hit[212] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_41_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_42_we = addr_hit[213] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_42_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_43_we = addr_hit[214] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_43_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_44_we = addr_hit[215] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_44_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_45_we = addr_hit[216] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_45_wd = reg_wdata[0]; + assign mio_pad_attr_regwen_46_we = addr_hit[217] & reg_we & !reg_error; + + assign mio_pad_attr_regwen_46_wd = reg_wdata[0]; + assign mio_pad_attr_0_re = addr_hit[218] & reg_re & !reg_error; + assign mio_pad_attr_0_we = addr_hit[218] & reg_we & !reg_error; + + assign mio_pad_attr_0_invert_0_wd = reg_wdata[0]; + + assign mio_pad_attr_0_virtual_od_en_0_wd = reg_wdata[1]; + + assign mio_pad_attr_0_pull_en_0_wd = reg_wdata[2]; + + assign mio_pad_attr_0_pull_select_0_wd = reg_wdata[3]; + + assign mio_pad_attr_0_keeper_en_0_wd = reg_wdata[4]; + + assign mio_pad_attr_0_schmitt_en_0_wd = reg_wdata[5]; + + assign mio_pad_attr_0_od_en_0_wd = reg_wdata[6]; + + assign mio_pad_attr_0_input_disable_0_wd = reg_wdata[7]; + + assign mio_pad_attr_0_slew_rate_0_wd = reg_wdata[17:16]; + + assign mio_pad_attr_0_drive_strength_0_wd = reg_wdata[23:20]; + assign mio_pad_attr_1_re = addr_hit[219] & reg_re & !reg_error; + assign mio_pad_attr_1_we = addr_hit[219] & reg_we & !reg_error; + + assign mio_pad_attr_1_invert_1_wd = reg_wdata[0]; + + assign mio_pad_attr_1_virtual_od_en_1_wd = reg_wdata[1]; + + assign mio_pad_attr_1_pull_en_1_wd = reg_wdata[2]; + + assign mio_pad_attr_1_pull_select_1_wd = reg_wdata[3]; + + assign mio_pad_attr_1_keeper_en_1_wd = reg_wdata[4]; + + assign mio_pad_attr_1_schmitt_en_1_wd = reg_wdata[5]; + + assign mio_pad_attr_1_od_en_1_wd = reg_wdata[6]; + + assign mio_pad_attr_1_input_disable_1_wd = reg_wdata[7]; + + assign mio_pad_attr_1_slew_rate_1_wd = reg_wdata[17:16]; + + assign mio_pad_attr_1_drive_strength_1_wd = reg_wdata[23:20]; + assign mio_pad_attr_2_re = addr_hit[220] & reg_re & !reg_error; + assign mio_pad_attr_2_we = addr_hit[220] & reg_we & !reg_error; + + assign mio_pad_attr_2_invert_2_wd = reg_wdata[0]; + + assign mio_pad_attr_2_virtual_od_en_2_wd = reg_wdata[1]; + + assign mio_pad_attr_2_pull_en_2_wd = reg_wdata[2]; + + assign mio_pad_attr_2_pull_select_2_wd = reg_wdata[3]; + + assign mio_pad_attr_2_keeper_en_2_wd = reg_wdata[4]; + + assign mio_pad_attr_2_schmitt_en_2_wd = reg_wdata[5]; + + assign mio_pad_attr_2_od_en_2_wd = reg_wdata[6]; + + assign mio_pad_attr_2_input_disable_2_wd = reg_wdata[7]; + + assign mio_pad_attr_2_slew_rate_2_wd = reg_wdata[17:16]; + + assign mio_pad_attr_2_drive_strength_2_wd = reg_wdata[23:20]; + assign mio_pad_attr_3_re = addr_hit[221] & reg_re & !reg_error; + assign mio_pad_attr_3_we = addr_hit[221] & reg_we & !reg_error; + + assign mio_pad_attr_3_invert_3_wd = reg_wdata[0]; + + assign mio_pad_attr_3_virtual_od_en_3_wd = reg_wdata[1]; + + assign mio_pad_attr_3_pull_en_3_wd = reg_wdata[2]; + + assign mio_pad_attr_3_pull_select_3_wd = reg_wdata[3]; + + assign mio_pad_attr_3_keeper_en_3_wd = reg_wdata[4]; + + assign mio_pad_attr_3_schmitt_en_3_wd = reg_wdata[5]; + + assign mio_pad_attr_3_od_en_3_wd = reg_wdata[6]; + + assign mio_pad_attr_3_input_disable_3_wd = reg_wdata[7]; + + assign mio_pad_attr_3_slew_rate_3_wd = reg_wdata[17:16]; + + assign mio_pad_attr_3_drive_strength_3_wd = reg_wdata[23:20]; + assign mio_pad_attr_4_re = addr_hit[222] & reg_re & !reg_error; + assign mio_pad_attr_4_we = addr_hit[222] & reg_we & !reg_error; + + assign mio_pad_attr_4_invert_4_wd = reg_wdata[0]; + + assign mio_pad_attr_4_virtual_od_en_4_wd = reg_wdata[1]; + + assign mio_pad_attr_4_pull_en_4_wd = reg_wdata[2]; + + assign mio_pad_attr_4_pull_select_4_wd = reg_wdata[3]; + + assign mio_pad_attr_4_keeper_en_4_wd = reg_wdata[4]; + + assign mio_pad_attr_4_schmitt_en_4_wd = reg_wdata[5]; + + assign mio_pad_attr_4_od_en_4_wd = reg_wdata[6]; + + assign mio_pad_attr_4_input_disable_4_wd = reg_wdata[7]; + + assign mio_pad_attr_4_slew_rate_4_wd = reg_wdata[17:16]; + + assign mio_pad_attr_4_drive_strength_4_wd = reg_wdata[23:20]; + assign mio_pad_attr_5_re = addr_hit[223] & reg_re & !reg_error; + assign mio_pad_attr_5_we = addr_hit[223] & reg_we & !reg_error; + + assign mio_pad_attr_5_invert_5_wd = reg_wdata[0]; + + assign mio_pad_attr_5_virtual_od_en_5_wd = reg_wdata[1]; + + assign mio_pad_attr_5_pull_en_5_wd = reg_wdata[2]; + + assign mio_pad_attr_5_pull_select_5_wd = reg_wdata[3]; + + assign mio_pad_attr_5_keeper_en_5_wd = reg_wdata[4]; + + assign mio_pad_attr_5_schmitt_en_5_wd = reg_wdata[5]; + + assign mio_pad_attr_5_od_en_5_wd = reg_wdata[6]; + + assign mio_pad_attr_5_input_disable_5_wd = reg_wdata[7]; + + assign mio_pad_attr_5_slew_rate_5_wd = reg_wdata[17:16]; + + assign mio_pad_attr_5_drive_strength_5_wd = reg_wdata[23:20]; + assign mio_pad_attr_6_re = addr_hit[224] & reg_re & !reg_error; + assign mio_pad_attr_6_we = addr_hit[224] & reg_we & !reg_error; + + assign mio_pad_attr_6_invert_6_wd = reg_wdata[0]; + + assign mio_pad_attr_6_virtual_od_en_6_wd = reg_wdata[1]; + + assign mio_pad_attr_6_pull_en_6_wd = reg_wdata[2]; + + assign mio_pad_attr_6_pull_select_6_wd = reg_wdata[3]; + + assign mio_pad_attr_6_keeper_en_6_wd = reg_wdata[4]; + + assign mio_pad_attr_6_schmitt_en_6_wd = reg_wdata[5]; + + assign mio_pad_attr_6_od_en_6_wd = reg_wdata[6]; + + assign mio_pad_attr_6_input_disable_6_wd = reg_wdata[7]; + + assign mio_pad_attr_6_slew_rate_6_wd = reg_wdata[17:16]; + + assign mio_pad_attr_6_drive_strength_6_wd = reg_wdata[23:20]; + assign mio_pad_attr_7_re = addr_hit[225] & reg_re & !reg_error; + assign mio_pad_attr_7_we = addr_hit[225] & reg_we & !reg_error; + + assign mio_pad_attr_7_invert_7_wd = reg_wdata[0]; + + assign mio_pad_attr_7_virtual_od_en_7_wd = reg_wdata[1]; + + assign mio_pad_attr_7_pull_en_7_wd = reg_wdata[2]; + + assign mio_pad_attr_7_pull_select_7_wd = reg_wdata[3]; + + assign mio_pad_attr_7_keeper_en_7_wd = reg_wdata[4]; + + assign mio_pad_attr_7_schmitt_en_7_wd = reg_wdata[5]; + + assign mio_pad_attr_7_od_en_7_wd = reg_wdata[6]; + + assign mio_pad_attr_7_input_disable_7_wd = reg_wdata[7]; + + assign mio_pad_attr_7_slew_rate_7_wd = reg_wdata[17:16]; + + assign mio_pad_attr_7_drive_strength_7_wd = reg_wdata[23:20]; + assign mio_pad_attr_8_re = addr_hit[226] & reg_re & !reg_error; + assign mio_pad_attr_8_we = addr_hit[226] & reg_we & !reg_error; + + assign mio_pad_attr_8_invert_8_wd = reg_wdata[0]; + + assign mio_pad_attr_8_virtual_od_en_8_wd = reg_wdata[1]; + + assign mio_pad_attr_8_pull_en_8_wd = reg_wdata[2]; + + assign mio_pad_attr_8_pull_select_8_wd = reg_wdata[3]; + + assign mio_pad_attr_8_keeper_en_8_wd = reg_wdata[4]; + + assign mio_pad_attr_8_schmitt_en_8_wd = reg_wdata[5]; + + assign mio_pad_attr_8_od_en_8_wd = reg_wdata[6]; + + assign mio_pad_attr_8_input_disable_8_wd = reg_wdata[7]; + + assign mio_pad_attr_8_slew_rate_8_wd = reg_wdata[17:16]; + + assign mio_pad_attr_8_drive_strength_8_wd = reg_wdata[23:20]; + assign mio_pad_attr_9_re = addr_hit[227] & reg_re & !reg_error; + assign mio_pad_attr_9_we = addr_hit[227] & reg_we & !reg_error; + + assign mio_pad_attr_9_invert_9_wd = reg_wdata[0]; + + assign mio_pad_attr_9_virtual_od_en_9_wd = reg_wdata[1]; + + assign mio_pad_attr_9_pull_en_9_wd = reg_wdata[2]; + + assign mio_pad_attr_9_pull_select_9_wd = reg_wdata[3]; + + assign mio_pad_attr_9_keeper_en_9_wd = reg_wdata[4]; + + assign mio_pad_attr_9_schmitt_en_9_wd = reg_wdata[5]; + + assign mio_pad_attr_9_od_en_9_wd = reg_wdata[6]; + + assign mio_pad_attr_9_input_disable_9_wd = reg_wdata[7]; + + assign mio_pad_attr_9_slew_rate_9_wd = reg_wdata[17:16]; + + assign mio_pad_attr_9_drive_strength_9_wd = reg_wdata[23:20]; + assign mio_pad_attr_10_re = addr_hit[228] & reg_re & !reg_error; + assign mio_pad_attr_10_we = addr_hit[228] & reg_we & !reg_error; + + assign mio_pad_attr_10_invert_10_wd = reg_wdata[0]; + + assign mio_pad_attr_10_virtual_od_en_10_wd = reg_wdata[1]; + + assign mio_pad_attr_10_pull_en_10_wd = reg_wdata[2]; + + assign mio_pad_attr_10_pull_select_10_wd = reg_wdata[3]; + + assign mio_pad_attr_10_keeper_en_10_wd = reg_wdata[4]; + + assign mio_pad_attr_10_schmitt_en_10_wd = reg_wdata[5]; + + assign mio_pad_attr_10_od_en_10_wd = reg_wdata[6]; + + assign mio_pad_attr_10_input_disable_10_wd = reg_wdata[7]; + + assign mio_pad_attr_10_slew_rate_10_wd = reg_wdata[17:16]; + + assign mio_pad_attr_10_drive_strength_10_wd = reg_wdata[23:20]; + assign mio_pad_attr_11_re = addr_hit[229] & reg_re & !reg_error; + assign mio_pad_attr_11_we = addr_hit[229] & reg_we & !reg_error; + + assign mio_pad_attr_11_invert_11_wd = reg_wdata[0]; + + assign mio_pad_attr_11_virtual_od_en_11_wd = reg_wdata[1]; + + assign mio_pad_attr_11_pull_en_11_wd = reg_wdata[2]; + + assign mio_pad_attr_11_pull_select_11_wd = reg_wdata[3]; + + assign mio_pad_attr_11_keeper_en_11_wd = reg_wdata[4]; + + assign mio_pad_attr_11_schmitt_en_11_wd = reg_wdata[5]; + + assign mio_pad_attr_11_od_en_11_wd = reg_wdata[6]; + + assign mio_pad_attr_11_input_disable_11_wd = reg_wdata[7]; + + assign mio_pad_attr_11_slew_rate_11_wd = reg_wdata[17:16]; + + assign mio_pad_attr_11_drive_strength_11_wd = reg_wdata[23:20]; + assign mio_pad_attr_12_re = addr_hit[230] & reg_re & !reg_error; + assign mio_pad_attr_12_we = addr_hit[230] & reg_we & !reg_error; + + assign mio_pad_attr_12_invert_12_wd = reg_wdata[0]; + + assign mio_pad_attr_12_virtual_od_en_12_wd = reg_wdata[1]; + + assign mio_pad_attr_12_pull_en_12_wd = reg_wdata[2]; + + assign mio_pad_attr_12_pull_select_12_wd = reg_wdata[3]; + + assign mio_pad_attr_12_keeper_en_12_wd = reg_wdata[4]; + + assign mio_pad_attr_12_schmitt_en_12_wd = reg_wdata[5]; + + assign mio_pad_attr_12_od_en_12_wd = reg_wdata[6]; + + assign mio_pad_attr_12_input_disable_12_wd = reg_wdata[7]; + + assign mio_pad_attr_12_slew_rate_12_wd = reg_wdata[17:16]; + + assign mio_pad_attr_12_drive_strength_12_wd = reg_wdata[23:20]; + assign mio_pad_attr_13_re = addr_hit[231] & reg_re & !reg_error; + assign mio_pad_attr_13_we = addr_hit[231] & reg_we & !reg_error; + + assign mio_pad_attr_13_invert_13_wd = reg_wdata[0]; + + assign mio_pad_attr_13_virtual_od_en_13_wd = reg_wdata[1]; + + assign mio_pad_attr_13_pull_en_13_wd = reg_wdata[2]; + + assign mio_pad_attr_13_pull_select_13_wd = reg_wdata[3]; + + assign mio_pad_attr_13_keeper_en_13_wd = reg_wdata[4]; + + assign mio_pad_attr_13_schmitt_en_13_wd = reg_wdata[5]; + + assign mio_pad_attr_13_od_en_13_wd = reg_wdata[6]; + + assign mio_pad_attr_13_input_disable_13_wd = reg_wdata[7]; + + assign mio_pad_attr_13_slew_rate_13_wd = reg_wdata[17:16]; + + assign mio_pad_attr_13_drive_strength_13_wd = reg_wdata[23:20]; + assign mio_pad_attr_14_re = addr_hit[232] & reg_re & !reg_error; + assign mio_pad_attr_14_we = addr_hit[232] & reg_we & !reg_error; + + assign mio_pad_attr_14_invert_14_wd = reg_wdata[0]; + + assign mio_pad_attr_14_virtual_od_en_14_wd = reg_wdata[1]; + + assign mio_pad_attr_14_pull_en_14_wd = reg_wdata[2]; + + assign mio_pad_attr_14_pull_select_14_wd = reg_wdata[3]; + + assign mio_pad_attr_14_keeper_en_14_wd = reg_wdata[4]; + + assign mio_pad_attr_14_schmitt_en_14_wd = reg_wdata[5]; + + assign mio_pad_attr_14_od_en_14_wd = reg_wdata[6]; + + assign mio_pad_attr_14_input_disable_14_wd = reg_wdata[7]; + + assign mio_pad_attr_14_slew_rate_14_wd = reg_wdata[17:16]; + + assign mio_pad_attr_14_drive_strength_14_wd = reg_wdata[23:20]; + assign mio_pad_attr_15_re = addr_hit[233] & reg_re & !reg_error; + assign mio_pad_attr_15_we = addr_hit[233] & reg_we & !reg_error; + + assign mio_pad_attr_15_invert_15_wd = reg_wdata[0]; + + assign mio_pad_attr_15_virtual_od_en_15_wd = reg_wdata[1]; + + assign mio_pad_attr_15_pull_en_15_wd = reg_wdata[2]; + + assign mio_pad_attr_15_pull_select_15_wd = reg_wdata[3]; + + assign mio_pad_attr_15_keeper_en_15_wd = reg_wdata[4]; + + assign mio_pad_attr_15_schmitt_en_15_wd = reg_wdata[5]; + + assign mio_pad_attr_15_od_en_15_wd = reg_wdata[6]; + + assign mio_pad_attr_15_input_disable_15_wd = reg_wdata[7]; + + assign mio_pad_attr_15_slew_rate_15_wd = reg_wdata[17:16]; + + assign mio_pad_attr_15_drive_strength_15_wd = reg_wdata[23:20]; + assign mio_pad_attr_16_re = addr_hit[234] & reg_re & !reg_error; + assign mio_pad_attr_16_we = addr_hit[234] & reg_we & !reg_error; + + assign mio_pad_attr_16_invert_16_wd = reg_wdata[0]; + + assign mio_pad_attr_16_virtual_od_en_16_wd = reg_wdata[1]; + + assign mio_pad_attr_16_pull_en_16_wd = reg_wdata[2]; + + assign mio_pad_attr_16_pull_select_16_wd = reg_wdata[3]; + + assign mio_pad_attr_16_keeper_en_16_wd = reg_wdata[4]; + + assign mio_pad_attr_16_schmitt_en_16_wd = reg_wdata[5]; + + assign mio_pad_attr_16_od_en_16_wd = reg_wdata[6]; + + assign mio_pad_attr_16_input_disable_16_wd = reg_wdata[7]; + + assign mio_pad_attr_16_slew_rate_16_wd = reg_wdata[17:16]; + + assign mio_pad_attr_16_drive_strength_16_wd = reg_wdata[23:20]; + assign mio_pad_attr_17_re = addr_hit[235] & reg_re & !reg_error; + assign mio_pad_attr_17_we = addr_hit[235] & reg_we & !reg_error; + + assign mio_pad_attr_17_invert_17_wd = reg_wdata[0]; + + assign mio_pad_attr_17_virtual_od_en_17_wd = reg_wdata[1]; + + assign mio_pad_attr_17_pull_en_17_wd = reg_wdata[2]; + + assign mio_pad_attr_17_pull_select_17_wd = reg_wdata[3]; + + assign mio_pad_attr_17_keeper_en_17_wd = reg_wdata[4]; + + assign mio_pad_attr_17_schmitt_en_17_wd = reg_wdata[5]; + + assign mio_pad_attr_17_od_en_17_wd = reg_wdata[6]; + + assign mio_pad_attr_17_input_disable_17_wd = reg_wdata[7]; + + assign mio_pad_attr_17_slew_rate_17_wd = reg_wdata[17:16]; + + assign mio_pad_attr_17_drive_strength_17_wd = reg_wdata[23:20]; + assign mio_pad_attr_18_re = addr_hit[236] & reg_re & !reg_error; + assign mio_pad_attr_18_we = addr_hit[236] & reg_we & !reg_error; + + assign mio_pad_attr_18_invert_18_wd = reg_wdata[0]; + + assign mio_pad_attr_18_virtual_od_en_18_wd = reg_wdata[1]; + + assign mio_pad_attr_18_pull_en_18_wd = reg_wdata[2]; + + assign mio_pad_attr_18_pull_select_18_wd = reg_wdata[3]; + + assign mio_pad_attr_18_keeper_en_18_wd = reg_wdata[4]; + + assign mio_pad_attr_18_schmitt_en_18_wd = reg_wdata[5]; + + assign mio_pad_attr_18_od_en_18_wd = reg_wdata[6]; + + assign mio_pad_attr_18_input_disable_18_wd = reg_wdata[7]; + + assign mio_pad_attr_18_slew_rate_18_wd = reg_wdata[17:16]; + + assign mio_pad_attr_18_drive_strength_18_wd = reg_wdata[23:20]; + assign mio_pad_attr_19_re = addr_hit[237] & reg_re & !reg_error; + assign mio_pad_attr_19_we = addr_hit[237] & reg_we & !reg_error; + + assign mio_pad_attr_19_invert_19_wd = reg_wdata[0]; + + assign mio_pad_attr_19_virtual_od_en_19_wd = reg_wdata[1]; + + assign mio_pad_attr_19_pull_en_19_wd = reg_wdata[2]; + + assign mio_pad_attr_19_pull_select_19_wd = reg_wdata[3]; + + assign mio_pad_attr_19_keeper_en_19_wd = reg_wdata[4]; + + assign mio_pad_attr_19_schmitt_en_19_wd = reg_wdata[5]; + + assign mio_pad_attr_19_od_en_19_wd = reg_wdata[6]; + + assign mio_pad_attr_19_input_disable_19_wd = reg_wdata[7]; + + assign mio_pad_attr_19_slew_rate_19_wd = reg_wdata[17:16]; + + assign mio_pad_attr_19_drive_strength_19_wd = reg_wdata[23:20]; + assign mio_pad_attr_20_re = addr_hit[238] & reg_re & !reg_error; + assign mio_pad_attr_20_we = addr_hit[238] & reg_we & !reg_error; + + assign mio_pad_attr_20_invert_20_wd = reg_wdata[0]; + + assign mio_pad_attr_20_virtual_od_en_20_wd = reg_wdata[1]; + + assign mio_pad_attr_20_pull_en_20_wd = reg_wdata[2]; + + assign mio_pad_attr_20_pull_select_20_wd = reg_wdata[3]; + + assign mio_pad_attr_20_keeper_en_20_wd = reg_wdata[4]; + + assign mio_pad_attr_20_schmitt_en_20_wd = reg_wdata[5]; + + assign mio_pad_attr_20_od_en_20_wd = reg_wdata[6]; + + assign mio_pad_attr_20_input_disable_20_wd = reg_wdata[7]; + + assign mio_pad_attr_20_slew_rate_20_wd = reg_wdata[17:16]; + + assign mio_pad_attr_20_drive_strength_20_wd = reg_wdata[23:20]; + assign mio_pad_attr_21_re = addr_hit[239] & reg_re & !reg_error; + assign mio_pad_attr_21_we = addr_hit[239] & reg_we & !reg_error; + + assign mio_pad_attr_21_invert_21_wd = reg_wdata[0]; + + assign mio_pad_attr_21_virtual_od_en_21_wd = reg_wdata[1]; + + assign mio_pad_attr_21_pull_en_21_wd = reg_wdata[2]; + + assign mio_pad_attr_21_pull_select_21_wd = reg_wdata[3]; + + assign mio_pad_attr_21_keeper_en_21_wd = reg_wdata[4]; + + assign mio_pad_attr_21_schmitt_en_21_wd = reg_wdata[5]; + + assign mio_pad_attr_21_od_en_21_wd = reg_wdata[6]; + + assign mio_pad_attr_21_input_disable_21_wd = reg_wdata[7]; + + assign mio_pad_attr_21_slew_rate_21_wd = reg_wdata[17:16]; + + assign mio_pad_attr_21_drive_strength_21_wd = reg_wdata[23:20]; + assign mio_pad_attr_22_re = addr_hit[240] & reg_re & !reg_error; + assign mio_pad_attr_22_we = addr_hit[240] & reg_we & !reg_error; + + assign mio_pad_attr_22_invert_22_wd = reg_wdata[0]; + + assign mio_pad_attr_22_virtual_od_en_22_wd = reg_wdata[1]; + + assign mio_pad_attr_22_pull_en_22_wd = reg_wdata[2]; + + assign mio_pad_attr_22_pull_select_22_wd = reg_wdata[3]; + + assign mio_pad_attr_22_keeper_en_22_wd = reg_wdata[4]; + + assign mio_pad_attr_22_schmitt_en_22_wd = reg_wdata[5]; + + assign mio_pad_attr_22_od_en_22_wd = reg_wdata[6]; + + assign mio_pad_attr_22_input_disable_22_wd = reg_wdata[7]; + + assign mio_pad_attr_22_slew_rate_22_wd = reg_wdata[17:16]; + + assign mio_pad_attr_22_drive_strength_22_wd = reg_wdata[23:20]; + assign mio_pad_attr_23_re = addr_hit[241] & reg_re & !reg_error; + assign mio_pad_attr_23_we = addr_hit[241] & reg_we & !reg_error; + + assign mio_pad_attr_23_invert_23_wd = reg_wdata[0]; + + assign mio_pad_attr_23_virtual_od_en_23_wd = reg_wdata[1]; + + assign mio_pad_attr_23_pull_en_23_wd = reg_wdata[2]; + + assign mio_pad_attr_23_pull_select_23_wd = reg_wdata[3]; + + assign mio_pad_attr_23_keeper_en_23_wd = reg_wdata[4]; + + assign mio_pad_attr_23_schmitt_en_23_wd = reg_wdata[5]; + + assign mio_pad_attr_23_od_en_23_wd = reg_wdata[6]; + + assign mio_pad_attr_23_input_disable_23_wd = reg_wdata[7]; + + assign mio_pad_attr_23_slew_rate_23_wd = reg_wdata[17:16]; + + assign mio_pad_attr_23_drive_strength_23_wd = reg_wdata[23:20]; + assign mio_pad_attr_24_re = addr_hit[242] & reg_re & !reg_error; + assign mio_pad_attr_24_we = addr_hit[242] & reg_we & !reg_error; + + assign mio_pad_attr_24_invert_24_wd = reg_wdata[0]; + + assign mio_pad_attr_24_virtual_od_en_24_wd = reg_wdata[1]; + + assign mio_pad_attr_24_pull_en_24_wd = reg_wdata[2]; + + assign mio_pad_attr_24_pull_select_24_wd = reg_wdata[3]; + + assign mio_pad_attr_24_keeper_en_24_wd = reg_wdata[4]; + + assign mio_pad_attr_24_schmitt_en_24_wd = reg_wdata[5]; + + assign mio_pad_attr_24_od_en_24_wd = reg_wdata[6]; + + assign mio_pad_attr_24_input_disable_24_wd = reg_wdata[7]; + + assign mio_pad_attr_24_slew_rate_24_wd = reg_wdata[17:16]; + + assign mio_pad_attr_24_drive_strength_24_wd = reg_wdata[23:20]; + assign mio_pad_attr_25_re = addr_hit[243] & reg_re & !reg_error; + assign mio_pad_attr_25_we = addr_hit[243] & reg_we & !reg_error; + + assign mio_pad_attr_25_invert_25_wd = reg_wdata[0]; + + assign mio_pad_attr_25_virtual_od_en_25_wd = reg_wdata[1]; + + assign mio_pad_attr_25_pull_en_25_wd = reg_wdata[2]; + + assign mio_pad_attr_25_pull_select_25_wd = reg_wdata[3]; + + assign mio_pad_attr_25_keeper_en_25_wd = reg_wdata[4]; + + assign mio_pad_attr_25_schmitt_en_25_wd = reg_wdata[5]; + + assign mio_pad_attr_25_od_en_25_wd = reg_wdata[6]; + + assign mio_pad_attr_25_input_disable_25_wd = reg_wdata[7]; + + assign mio_pad_attr_25_slew_rate_25_wd = reg_wdata[17:16]; + + assign mio_pad_attr_25_drive_strength_25_wd = reg_wdata[23:20]; + assign mio_pad_attr_26_re = addr_hit[244] & reg_re & !reg_error; + assign mio_pad_attr_26_we = addr_hit[244] & reg_we & !reg_error; + + assign mio_pad_attr_26_invert_26_wd = reg_wdata[0]; + + assign mio_pad_attr_26_virtual_od_en_26_wd = reg_wdata[1]; + + assign mio_pad_attr_26_pull_en_26_wd = reg_wdata[2]; + + assign mio_pad_attr_26_pull_select_26_wd = reg_wdata[3]; + + assign mio_pad_attr_26_keeper_en_26_wd = reg_wdata[4]; + + assign mio_pad_attr_26_schmitt_en_26_wd = reg_wdata[5]; + + assign mio_pad_attr_26_od_en_26_wd = reg_wdata[6]; + + assign mio_pad_attr_26_input_disable_26_wd = reg_wdata[7]; + + assign mio_pad_attr_26_slew_rate_26_wd = reg_wdata[17:16]; + + assign mio_pad_attr_26_drive_strength_26_wd = reg_wdata[23:20]; + assign mio_pad_attr_27_re = addr_hit[245] & reg_re & !reg_error; + assign mio_pad_attr_27_we = addr_hit[245] & reg_we & !reg_error; + + assign mio_pad_attr_27_invert_27_wd = reg_wdata[0]; + + assign mio_pad_attr_27_virtual_od_en_27_wd = reg_wdata[1]; + + assign mio_pad_attr_27_pull_en_27_wd = reg_wdata[2]; + + assign mio_pad_attr_27_pull_select_27_wd = reg_wdata[3]; + + assign mio_pad_attr_27_keeper_en_27_wd = reg_wdata[4]; + + assign mio_pad_attr_27_schmitt_en_27_wd = reg_wdata[5]; + + assign mio_pad_attr_27_od_en_27_wd = reg_wdata[6]; + + assign mio_pad_attr_27_input_disable_27_wd = reg_wdata[7]; + + assign mio_pad_attr_27_slew_rate_27_wd = reg_wdata[17:16]; + + assign mio_pad_attr_27_drive_strength_27_wd = reg_wdata[23:20]; + assign mio_pad_attr_28_re = addr_hit[246] & reg_re & !reg_error; + assign mio_pad_attr_28_we = addr_hit[246] & reg_we & !reg_error; + + assign mio_pad_attr_28_invert_28_wd = reg_wdata[0]; + + assign mio_pad_attr_28_virtual_od_en_28_wd = reg_wdata[1]; + + assign mio_pad_attr_28_pull_en_28_wd = reg_wdata[2]; + + assign mio_pad_attr_28_pull_select_28_wd = reg_wdata[3]; + + assign mio_pad_attr_28_keeper_en_28_wd = reg_wdata[4]; + + assign mio_pad_attr_28_schmitt_en_28_wd = reg_wdata[5]; + + assign mio_pad_attr_28_od_en_28_wd = reg_wdata[6]; + + assign mio_pad_attr_28_input_disable_28_wd = reg_wdata[7]; + + assign mio_pad_attr_28_slew_rate_28_wd = reg_wdata[17:16]; + + assign mio_pad_attr_28_drive_strength_28_wd = reg_wdata[23:20]; + assign mio_pad_attr_29_re = addr_hit[247] & reg_re & !reg_error; + assign mio_pad_attr_29_we = addr_hit[247] & reg_we & !reg_error; + + assign mio_pad_attr_29_invert_29_wd = reg_wdata[0]; + + assign mio_pad_attr_29_virtual_od_en_29_wd = reg_wdata[1]; + + assign mio_pad_attr_29_pull_en_29_wd = reg_wdata[2]; + + assign mio_pad_attr_29_pull_select_29_wd = reg_wdata[3]; + + assign mio_pad_attr_29_keeper_en_29_wd = reg_wdata[4]; + + assign mio_pad_attr_29_schmitt_en_29_wd = reg_wdata[5]; + + assign mio_pad_attr_29_od_en_29_wd = reg_wdata[6]; + + assign mio_pad_attr_29_input_disable_29_wd = reg_wdata[7]; + + assign mio_pad_attr_29_slew_rate_29_wd = reg_wdata[17:16]; + + assign mio_pad_attr_29_drive_strength_29_wd = reg_wdata[23:20]; + assign mio_pad_attr_30_re = addr_hit[248] & reg_re & !reg_error; + assign mio_pad_attr_30_we = addr_hit[248] & reg_we & !reg_error; + + assign mio_pad_attr_30_invert_30_wd = reg_wdata[0]; + + assign mio_pad_attr_30_virtual_od_en_30_wd = reg_wdata[1]; + + assign mio_pad_attr_30_pull_en_30_wd = reg_wdata[2]; + + assign mio_pad_attr_30_pull_select_30_wd = reg_wdata[3]; + + assign mio_pad_attr_30_keeper_en_30_wd = reg_wdata[4]; + + assign mio_pad_attr_30_schmitt_en_30_wd = reg_wdata[5]; + + assign mio_pad_attr_30_od_en_30_wd = reg_wdata[6]; + + assign mio_pad_attr_30_input_disable_30_wd = reg_wdata[7]; + + assign mio_pad_attr_30_slew_rate_30_wd = reg_wdata[17:16]; + + assign mio_pad_attr_30_drive_strength_30_wd = reg_wdata[23:20]; + assign mio_pad_attr_31_re = addr_hit[249] & reg_re & !reg_error; + assign mio_pad_attr_31_we = addr_hit[249] & reg_we & !reg_error; + + assign mio_pad_attr_31_invert_31_wd = reg_wdata[0]; + + assign mio_pad_attr_31_virtual_od_en_31_wd = reg_wdata[1]; + + assign mio_pad_attr_31_pull_en_31_wd = reg_wdata[2]; + + assign mio_pad_attr_31_pull_select_31_wd = reg_wdata[3]; + + assign mio_pad_attr_31_keeper_en_31_wd = reg_wdata[4]; + + assign mio_pad_attr_31_schmitt_en_31_wd = reg_wdata[5]; + + assign mio_pad_attr_31_od_en_31_wd = reg_wdata[6]; + + assign mio_pad_attr_31_input_disable_31_wd = reg_wdata[7]; + + assign mio_pad_attr_31_slew_rate_31_wd = reg_wdata[17:16]; + + assign mio_pad_attr_31_drive_strength_31_wd = reg_wdata[23:20]; + assign mio_pad_attr_32_re = addr_hit[250] & reg_re & !reg_error; + assign mio_pad_attr_32_we = addr_hit[250] & reg_we & !reg_error; + + assign mio_pad_attr_32_invert_32_wd = reg_wdata[0]; + + assign mio_pad_attr_32_virtual_od_en_32_wd = reg_wdata[1]; + + assign mio_pad_attr_32_pull_en_32_wd = reg_wdata[2]; + + assign mio_pad_attr_32_pull_select_32_wd = reg_wdata[3]; + + assign mio_pad_attr_32_keeper_en_32_wd = reg_wdata[4]; + + assign mio_pad_attr_32_schmitt_en_32_wd = reg_wdata[5]; + + assign mio_pad_attr_32_od_en_32_wd = reg_wdata[6]; + + assign mio_pad_attr_32_input_disable_32_wd = reg_wdata[7]; + + assign mio_pad_attr_32_slew_rate_32_wd = reg_wdata[17:16]; + + assign mio_pad_attr_32_drive_strength_32_wd = reg_wdata[23:20]; + assign mio_pad_attr_33_re = addr_hit[251] & reg_re & !reg_error; + assign mio_pad_attr_33_we = addr_hit[251] & reg_we & !reg_error; + + assign mio_pad_attr_33_invert_33_wd = reg_wdata[0]; + + assign mio_pad_attr_33_virtual_od_en_33_wd = reg_wdata[1]; + + assign mio_pad_attr_33_pull_en_33_wd = reg_wdata[2]; + + assign mio_pad_attr_33_pull_select_33_wd = reg_wdata[3]; + + assign mio_pad_attr_33_keeper_en_33_wd = reg_wdata[4]; + + assign mio_pad_attr_33_schmitt_en_33_wd = reg_wdata[5]; + + assign mio_pad_attr_33_od_en_33_wd = reg_wdata[6]; + + assign mio_pad_attr_33_input_disable_33_wd = reg_wdata[7]; + + assign mio_pad_attr_33_slew_rate_33_wd = reg_wdata[17:16]; + + assign mio_pad_attr_33_drive_strength_33_wd = reg_wdata[23:20]; + assign mio_pad_attr_34_re = addr_hit[252] & reg_re & !reg_error; + assign mio_pad_attr_34_we = addr_hit[252] & reg_we & !reg_error; + + assign mio_pad_attr_34_invert_34_wd = reg_wdata[0]; + + assign mio_pad_attr_34_virtual_od_en_34_wd = reg_wdata[1]; + + assign mio_pad_attr_34_pull_en_34_wd = reg_wdata[2]; + + assign mio_pad_attr_34_pull_select_34_wd = reg_wdata[3]; + + assign mio_pad_attr_34_keeper_en_34_wd = reg_wdata[4]; + + assign mio_pad_attr_34_schmitt_en_34_wd = reg_wdata[5]; + + assign mio_pad_attr_34_od_en_34_wd = reg_wdata[6]; + + assign mio_pad_attr_34_input_disable_34_wd = reg_wdata[7]; + + assign mio_pad_attr_34_slew_rate_34_wd = reg_wdata[17:16]; + + assign mio_pad_attr_34_drive_strength_34_wd = reg_wdata[23:20]; + assign mio_pad_attr_35_re = addr_hit[253] & reg_re & !reg_error; + assign mio_pad_attr_35_we = addr_hit[253] & reg_we & !reg_error; + + assign mio_pad_attr_35_invert_35_wd = reg_wdata[0]; + + assign mio_pad_attr_35_virtual_od_en_35_wd = reg_wdata[1]; + + assign mio_pad_attr_35_pull_en_35_wd = reg_wdata[2]; + + assign mio_pad_attr_35_pull_select_35_wd = reg_wdata[3]; + + assign mio_pad_attr_35_keeper_en_35_wd = reg_wdata[4]; + + assign mio_pad_attr_35_schmitt_en_35_wd = reg_wdata[5]; + + assign mio_pad_attr_35_od_en_35_wd = reg_wdata[6]; + + assign mio_pad_attr_35_input_disable_35_wd = reg_wdata[7]; + + assign mio_pad_attr_35_slew_rate_35_wd = reg_wdata[17:16]; + + assign mio_pad_attr_35_drive_strength_35_wd = reg_wdata[23:20]; + assign mio_pad_attr_36_re = addr_hit[254] & reg_re & !reg_error; + assign mio_pad_attr_36_we = addr_hit[254] & reg_we & !reg_error; + + assign mio_pad_attr_36_invert_36_wd = reg_wdata[0]; + + assign mio_pad_attr_36_virtual_od_en_36_wd = reg_wdata[1]; + + assign mio_pad_attr_36_pull_en_36_wd = reg_wdata[2]; + + assign mio_pad_attr_36_pull_select_36_wd = reg_wdata[3]; + + assign mio_pad_attr_36_keeper_en_36_wd = reg_wdata[4]; + + assign mio_pad_attr_36_schmitt_en_36_wd = reg_wdata[5]; + + assign mio_pad_attr_36_od_en_36_wd = reg_wdata[6]; + + assign mio_pad_attr_36_input_disable_36_wd = reg_wdata[7]; + + assign mio_pad_attr_36_slew_rate_36_wd = reg_wdata[17:16]; + + assign mio_pad_attr_36_drive_strength_36_wd = reg_wdata[23:20]; + assign mio_pad_attr_37_re = addr_hit[255] & reg_re & !reg_error; + assign mio_pad_attr_37_we = addr_hit[255] & reg_we & !reg_error; + + assign mio_pad_attr_37_invert_37_wd = reg_wdata[0]; + + assign mio_pad_attr_37_virtual_od_en_37_wd = reg_wdata[1]; + + assign mio_pad_attr_37_pull_en_37_wd = reg_wdata[2]; + + assign mio_pad_attr_37_pull_select_37_wd = reg_wdata[3]; + + assign mio_pad_attr_37_keeper_en_37_wd = reg_wdata[4]; + + assign mio_pad_attr_37_schmitt_en_37_wd = reg_wdata[5]; + + assign mio_pad_attr_37_od_en_37_wd = reg_wdata[6]; + + assign mio_pad_attr_37_input_disable_37_wd = reg_wdata[7]; + + assign mio_pad_attr_37_slew_rate_37_wd = reg_wdata[17:16]; + + assign mio_pad_attr_37_drive_strength_37_wd = reg_wdata[23:20]; + assign mio_pad_attr_38_re = addr_hit[256] & reg_re & !reg_error; + assign mio_pad_attr_38_we = addr_hit[256] & reg_we & !reg_error; + + assign mio_pad_attr_38_invert_38_wd = reg_wdata[0]; + + assign mio_pad_attr_38_virtual_od_en_38_wd = reg_wdata[1]; + + assign mio_pad_attr_38_pull_en_38_wd = reg_wdata[2]; + + assign mio_pad_attr_38_pull_select_38_wd = reg_wdata[3]; + + assign mio_pad_attr_38_keeper_en_38_wd = reg_wdata[4]; + + assign mio_pad_attr_38_schmitt_en_38_wd = reg_wdata[5]; + + assign mio_pad_attr_38_od_en_38_wd = reg_wdata[6]; + + assign mio_pad_attr_38_input_disable_38_wd = reg_wdata[7]; + + assign mio_pad_attr_38_slew_rate_38_wd = reg_wdata[17:16]; + + assign mio_pad_attr_38_drive_strength_38_wd = reg_wdata[23:20]; + assign mio_pad_attr_39_re = addr_hit[257] & reg_re & !reg_error; + assign mio_pad_attr_39_we = addr_hit[257] & reg_we & !reg_error; + + assign mio_pad_attr_39_invert_39_wd = reg_wdata[0]; + + assign mio_pad_attr_39_virtual_od_en_39_wd = reg_wdata[1]; + + assign mio_pad_attr_39_pull_en_39_wd = reg_wdata[2]; + + assign mio_pad_attr_39_pull_select_39_wd = reg_wdata[3]; + + assign mio_pad_attr_39_keeper_en_39_wd = reg_wdata[4]; + + assign mio_pad_attr_39_schmitt_en_39_wd = reg_wdata[5]; + + assign mio_pad_attr_39_od_en_39_wd = reg_wdata[6]; + + assign mio_pad_attr_39_input_disable_39_wd = reg_wdata[7]; + + assign mio_pad_attr_39_slew_rate_39_wd = reg_wdata[17:16]; + + assign mio_pad_attr_39_drive_strength_39_wd = reg_wdata[23:20]; + assign mio_pad_attr_40_re = addr_hit[258] & reg_re & !reg_error; + assign mio_pad_attr_40_we = addr_hit[258] & reg_we & !reg_error; + + assign mio_pad_attr_40_invert_40_wd = reg_wdata[0]; + + assign mio_pad_attr_40_virtual_od_en_40_wd = reg_wdata[1]; + + assign mio_pad_attr_40_pull_en_40_wd = reg_wdata[2]; + + assign mio_pad_attr_40_pull_select_40_wd = reg_wdata[3]; + + assign mio_pad_attr_40_keeper_en_40_wd = reg_wdata[4]; + + assign mio_pad_attr_40_schmitt_en_40_wd = reg_wdata[5]; + + assign mio_pad_attr_40_od_en_40_wd = reg_wdata[6]; + + assign mio_pad_attr_40_input_disable_40_wd = reg_wdata[7]; + + assign mio_pad_attr_40_slew_rate_40_wd = reg_wdata[17:16]; + + assign mio_pad_attr_40_drive_strength_40_wd = reg_wdata[23:20]; + assign mio_pad_attr_41_re = addr_hit[259] & reg_re & !reg_error; + assign mio_pad_attr_41_we = addr_hit[259] & reg_we & !reg_error; + + assign mio_pad_attr_41_invert_41_wd = reg_wdata[0]; + + assign mio_pad_attr_41_virtual_od_en_41_wd = reg_wdata[1]; + + assign mio_pad_attr_41_pull_en_41_wd = reg_wdata[2]; + + assign mio_pad_attr_41_pull_select_41_wd = reg_wdata[3]; + + assign mio_pad_attr_41_keeper_en_41_wd = reg_wdata[4]; + + assign mio_pad_attr_41_schmitt_en_41_wd = reg_wdata[5]; + + assign mio_pad_attr_41_od_en_41_wd = reg_wdata[6]; + + assign mio_pad_attr_41_input_disable_41_wd = reg_wdata[7]; + + assign mio_pad_attr_41_slew_rate_41_wd = reg_wdata[17:16]; + + assign mio_pad_attr_41_drive_strength_41_wd = reg_wdata[23:20]; + assign mio_pad_attr_42_re = addr_hit[260] & reg_re & !reg_error; + assign mio_pad_attr_42_we = addr_hit[260] & reg_we & !reg_error; + + assign mio_pad_attr_42_invert_42_wd = reg_wdata[0]; + + assign mio_pad_attr_42_virtual_od_en_42_wd = reg_wdata[1]; + + assign mio_pad_attr_42_pull_en_42_wd = reg_wdata[2]; + + assign mio_pad_attr_42_pull_select_42_wd = reg_wdata[3]; + + assign mio_pad_attr_42_keeper_en_42_wd = reg_wdata[4]; + + assign mio_pad_attr_42_schmitt_en_42_wd = reg_wdata[5]; + + assign mio_pad_attr_42_od_en_42_wd = reg_wdata[6]; + + assign mio_pad_attr_42_input_disable_42_wd = reg_wdata[7]; + + assign mio_pad_attr_42_slew_rate_42_wd = reg_wdata[17:16]; + + assign mio_pad_attr_42_drive_strength_42_wd = reg_wdata[23:20]; + assign mio_pad_attr_43_re = addr_hit[261] & reg_re & !reg_error; + assign mio_pad_attr_43_we = addr_hit[261] & reg_we & !reg_error; + + assign mio_pad_attr_43_invert_43_wd = reg_wdata[0]; + + assign mio_pad_attr_43_virtual_od_en_43_wd = reg_wdata[1]; + + assign mio_pad_attr_43_pull_en_43_wd = reg_wdata[2]; + + assign mio_pad_attr_43_pull_select_43_wd = reg_wdata[3]; + + assign mio_pad_attr_43_keeper_en_43_wd = reg_wdata[4]; + + assign mio_pad_attr_43_schmitt_en_43_wd = reg_wdata[5]; + + assign mio_pad_attr_43_od_en_43_wd = reg_wdata[6]; + + assign mio_pad_attr_43_input_disable_43_wd = reg_wdata[7]; + + assign mio_pad_attr_43_slew_rate_43_wd = reg_wdata[17:16]; + + assign mio_pad_attr_43_drive_strength_43_wd = reg_wdata[23:20]; + assign mio_pad_attr_44_re = addr_hit[262] & reg_re & !reg_error; + assign mio_pad_attr_44_we = addr_hit[262] & reg_we & !reg_error; + + assign mio_pad_attr_44_invert_44_wd = reg_wdata[0]; + + assign mio_pad_attr_44_virtual_od_en_44_wd = reg_wdata[1]; + + assign mio_pad_attr_44_pull_en_44_wd = reg_wdata[2]; + + assign mio_pad_attr_44_pull_select_44_wd = reg_wdata[3]; + + assign mio_pad_attr_44_keeper_en_44_wd = reg_wdata[4]; + + assign mio_pad_attr_44_schmitt_en_44_wd = reg_wdata[5]; + + assign mio_pad_attr_44_od_en_44_wd = reg_wdata[6]; + + assign mio_pad_attr_44_input_disable_44_wd = reg_wdata[7]; + + assign mio_pad_attr_44_slew_rate_44_wd = reg_wdata[17:16]; + + assign mio_pad_attr_44_drive_strength_44_wd = reg_wdata[23:20]; + assign mio_pad_attr_45_re = addr_hit[263] & reg_re & !reg_error; + assign mio_pad_attr_45_we = addr_hit[263] & reg_we & !reg_error; + + assign mio_pad_attr_45_invert_45_wd = reg_wdata[0]; + + assign mio_pad_attr_45_virtual_od_en_45_wd = reg_wdata[1]; + + assign mio_pad_attr_45_pull_en_45_wd = reg_wdata[2]; + + assign mio_pad_attr_45_pull_select_45_wd = reg_wdata[3]; + + assign mio_pad_attr_45_keeper_en_45_wd = reg_wdata[4]; + + assign mio_pad_attr_45_schmitt_en_45_wd = reg_wdata[5]; + + assign mio_pad_attr_45_od_en_45_wd = reg_wdata[6]; + + assign mio_pad_attr_45_input_disable_45_wd = reg_wdata[7]; + + assign mio_pad_attr_45_slew_rate_45_wd = reg_wdata[17:16]; + + assign mio_pad_attr_45_drive_strength_45_wd = reg_wdata[23:20]; + assign mio_pad_attr_46_re = addr_hit[264] & reg_re & !reg_error; + assign mio_pad_attr_46_we = addr_hit[264] & reg_we & !reg_error; + + assign mio_pad_attr_46_invert_46_wd = reg_wdata[0]; + + assign mio_pad_attr_46_virtual_od_en_46_wd = reg_wdata[1]; + + assign mio_pad_attr_46_pull_en_46_wd = reg_wdata[2]; + + assign mio_pad_attr_46_pull_select_46_wd = reg_wdata[3]; + + assign mio_pad_attr_46_keeper_en_46_wd = reg_wdata[4]; + + assign mio_pad_attr_46_schmitt_en_46_wd = reg_wdata[5]; + + assign mio_pad_attr_46_od_en_46_wd = reg_wdata[6]; + + assign mio_pad_attr_46_input_disable_46_wd = reg_wdata[7]; + + assign mio_pad_attr_46_slew_rate_46_wd = reg_wdata[17:16]; + + assign mio_pad_attr_46_drive_strength_46_wd = reg_wdata[23:20]; + assign dio_pad_attr_regwen_0_we = addr_hit[265] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_0_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_1_we = addr_hit[266] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_1_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_2_we = addr_hit[267] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_2_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_3_we = addr_hit[268] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_3_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_4_we = addr_hit[269] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_4_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_5_we = addr_hit[270] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_5_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_6_we = addr_hit[271] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_6_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_7_we = addr_hit[272] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_7_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_8_we = addr_hit[273] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_8_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_9_we = addr_hit[274] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_9_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_10_we = addr_hit[275] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_10_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_11_we = addr_hit[276] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_11_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_12_we = addr_hit[277] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_12_wd = reg_wdata[0]; + assign dio_pad_attr_regwen_13_we = addr_hit[278] & reg_we & !reg_error; + + assign dio_pad_attr_regwen_13_wd = reg_wdata[0]; + assign dio_pad_attr_0_re = addr_hit[279] & reg_re & !reg_error; + assign dio_pad_attr_0_we = addr_hit[279] & reg_we & !reg_error; + + assign dio_pad_attr_0_invert_0_wd = reg_wdata[0]; + + assign dio_pad_attr_0_virtual_od_en_0_wd = reg_wdata[1]; + + assign dio_pad_attr_0_pull_en_0_wd = reg_wdata[2]; + + assign dio_pad_attr_0_pull_select_0_wd = reg_wdata[3]; + + assign dio_pad_attr_0_keeper_en_0_wd = reg_wdata[4]; + + assign dio_pad_attr_0_schmitt_en_0_wd = reg_wdata[5]; + + assign dio_pad_attr_0_od_en_0_wd = reg_wdata[6]; + + assign dio_pad_attr_0_input_disable_0_wd = reg_wdata[7]; + + assign dio_pad_attr_0_slew_rate_0_wd = reg_wdata[17:16]; + + assign dio_pad_attr_0_drive_strength_0_wd = reg_wdata[23:20]; + assign dio_pad_attr_1_re = addr_hit[280] & reg_re & !reg_error; + assign dio_pad_attr_1_we = addr_hit[280] & reg_we & !reg_error; + + assign dio_pad_attr_1_invert_1_wd = reg_wdata[0]; + + assign dio_pad_attr_1_virtual_od_en_1_wd = reg_wdata[1]; + + assign dio_pad_attr_1_pull_en_1_wd = reg_wdata[2]; + + assign dio_pad_attr_1_pull_select_1_wd = reg_wdata[3]; + + assign dio_pad_attr_1_keeper_en_1_wd = reg_wdata[4]; + + assign dio_pad_attr_1_schmitt_en_1_wd = reg_wdata[5]; + + assign dio_pad_attr_1_od_en_1_wd = reg_wdata[6]; + + assign dio_pad_attr_1_input_disable_1_wd = reg_wdata[7]; + + assign dio_pad_attr_1_slew_rate_1_wd = reg_wdata[17:16]; + + assign dio_pad_attr_1_drive_strength_1_wd = reg_wdata[23:20]; + assign dio_pad_attr_2_re = addr_hit[281] & reg_re & !reg_error; + assign dio_pad_attr_2_we = addr_hit[281] & reg_we & !reg_error; + + assign dio_pad_attr_2_invert_2_wd = reg_wdata[0]; + + assign dio_pad_attr_2_virtual_od_en_2_wd = reg_wdata[1]; + + assign dio_pad_attr_2_pull_en_2_wd = reg_wdata[2]; + + assign dio_pad_attr_2_pull_select_2_wd = reg_wdata[3]; + + assign dio_pad_attr_2_keeper_en_2_wd = reg_wdata[4]; + + assign dio_pad_attr_2_schmitt_en_2_wd = reg_wdata[5]; + + assign dio_pad_attr_2_od_en_2_wd = reg_wdata[6]; + + assign dio_pad_attr_2_input_disable_2_wd = reg_wdata[7]; + + assign dio_pad_attr_2_slew_rate_2_wd = reg_wdata[17:16]; + + assign dio_pad_attr_2_drive_strength_2_wd = reg_wdata[23:20]; + assign dio_pad_attr_3_re = addr_hit[282] & reg_re & !reg_error; + assign dio_pad_attr_3_we = addr_hit[282] & reg_we & !reg_error; + + assign dio_pad_attr_3_invert_3_wd = reg_wdata[0]; + + assign dio_pad_attr_3_virtual_od_en_3_wd = reg_wdata[1]; + + assign dio_pad_attr_3_pull_en_3_wd = reg_wdata[2]; + + assign dio_pad_attr_3_pull_select_3_wd = reg_wdata[3]; + + assign dio_pad_attr_3_keeper_en_3_wd = reg_wdata[4]; + + assign dio_pad_attr_3_schmitt_en_3_wd = reg_wdata[5]; + + assign dio_pad_attr_3_od_en_3_wd = reg_wdata[6]; + + assign dio_pad_attr_3_input_disable_3_wd = reg_wdata[7]; + + assign dio_pad_attr_3_slew_rate_3_wd = reg_wdata[17:16]; + + assign dio_pad_attr_3_drive_strength_3_wd = reg_wdata[23:20]; + assign dio_pad_attr_4_re = addr_hit[283] & reg_re & !reg_error; + assign dio_pad_attr_4_we = addr_hit[283] & reg_we & !reg_error; + + assign dio_pad_attr_4_invert_4_wd = reg_wdata[0]; + + assign dio_pad_attr_4_virtual_od_en_4_wd = reg_wdata[1]; + + assign dio_pad_attr_4_pull_en_4_wd = reg_wdata[2]; + + assign dio_pad_attr_4_pull_select_4_wd = reg_wdata[3]; + + assign dio_pad_attr_4_keeper_en_4_wd = reg_wdata[4]; + + assign dio_pad_attr_4_schmitt_en_4_wd = reg_wdata[5]; + + assign dio_pad_attr_4_od_en_4_wd = reg_wdata[6]; + + assign dio_pad_attr_4_input_disable_4_wd = reg_wdata[7]; + + assign dio_pad_attr_4_slew_rate_4_wd = reg_wdata[17:16]; + + assign dio_pad_attr_4_drive_strength_4_wd = reg_wdata[23:20]; + assign dio_pad_attr_5_re = addr_hit[284] & reg_re & !reg_error; + assign dio_pad_attr_5_we = addr_hit[284] & reg_we & !reg_error; + + assign dio_pad_attr_5_invert_5_wd = reg_wdata[0]; + + assign dio_pad_attr_5_virtual_od_en_5_wd = reg_wdata[1]; + + assign dio_pad_attr_5_pull_en_5_wd = reg_wdata[2]; + + assign dio_pad_attr_5_pull_select_5_wd = reg_wdata[3]; + + assign dio_pad_attr_5_keeper_en_5_wd = reg_wdata[4]; + + assign dio_pad_attr_5_schmitt_en_5_wd = reg_wdata[5]; + + assign dio_pad_attr_5_od_en_5_wd = reg_wdata[6]; + + assign dio_pad_attr_5_input_disable_5_wd = reg_wdata[7]; + + assign dio_pad_attr_5_slew_rate_5_wd = reg_wdata[17:16]; + + assign dio_pad_attr_5_drive_strength_5_wd = reg_wdata[23:20]; + assign dio_pad_attr_6_re = addr_hit[285] & reg_re & !reg_error; + assign dio_pad_attr_6_we = addr_hit[285] & reg_we & !reg_error; + + assign dio_pad_attr_6_invert_6_wd = reg_wdata[0]; + + assign dio_pad_attr_6_virtual_od_en_6_wd = reg_wdata[1]; + + assign dio_pad_attr_6_pull_en_6_wd = reg_wdata[2]; + + assign dio_pad_attr_6_pull_select_6_wd = reg_wdata[3]; + + assign dio_pad_attr_6_keeper_en_6_wd = reg_wdata[4]; + + assign dio_pad_attr_6_schmitt_en_6_wd = reg_wdata[5]; + + assign dio_pad_attr_6_od_en_6_wd = reg_wdata[6]; + + assign dio_pad_attr_6_input_disable_6_wd = reg_wdata[7]; + + assign dio_pad_attr_6_slew_rate_6_wd = reg_wdata[17:16]; + + assign dio_pad_attr_6_drive_strength_6_wd = reg_wdata[23:20]; + assign dio_pad_attr_7_re = addr_hit[286] & reg_re & !reg_error; + assign dio_pad_attr_7_we = addr_hit[286] & reg_we & !reg_error; + + assign dio_pad_attr_7_invert_7_wd = reg_wdata[0]; + + assign dio_pad_attr_7_virtual_od_en_7_wd = reg_wdata[1]; + + assign dio_pad_attr_7_pull_en_7_wd = reg_wdata[2]; + + assign dio_pad_attr_7_pull_select_7_wd = reg_wdata[3]; + + assign dio_pad_attr_7_keeper_en_7_wd = reg_wdata[4]; + + assign dio_pad_attr_7_schmitt_en_7_wd = reg_wdata[5]; + + assign dio_pad_attr_7_od_en_7_wd = reg_wdata[6]; + + assign dio_pad_attr_7_input_disable_7_wd = reg_wdata[7]; + + assign dio_pad_attr_7_slew_rate_7_wd = reg_wdata[17:16]; + + assign dio_pad_attr_7_drive_strength_7_wd = reg_wdata[23:20]; + assign dio_pad_attr_8_re = addr_hit[287] & reg_re & !reg_error; + assign dio_pad_attr_8_we = addr_hit[287] & reg_we & !reg_error; + + assign dio_pad_attr_8_invert_8_wd = reg_wdata[0]; + + assign dio_pad_attr_8_virtual_od_en_8_wd = reg_wdata[1]; + + assign dio_pad_attr_8_pull_en_8_wd = reg_wdata[2]; + + assign dio_pad_attr_8_pull_select_8_wd = reg_wdata[3]; + + assign dio_pad_attr_8_keeper_en_8_wd = reg_wdata[4]; + + assign dio_pad_attr_8_schmitt_en_8_wd = reg_wdata[5]; + + assign dio_pad_attr_8_od_en_8_wd = reg_wdata[6]; + + assign dio_pad_attr_8_input_disable_8_wd = reg_wdata[7]; + + assign dio_pad_attr_8_slew_rate_8_wd = reg_wdata[17:16]; + + assign dio_pad_attr_8_drive_strength_8_wd = reg_wdata[23:20]; + assign dio_pad_attr_9_re = addr_hit[288] & reg_re & !reg_error; + assign dio_pad_attr_9_we = addr_hit[288] & reg_we & !reg_error; + + assign dio_pad_attr_9_invert_9_wd = reg_wdata[0]; + + assign dio_pad_attr_9_virtual_od_en_9_wd = reg_wdata[1]; + + assign dio_pad_attr_9_pull_en_9_wd = reg_wdata[2]; + + assign dio_pad_attr_9_pull_select_9_wd = reg_wdata[3]; + + assign dio_pad_attr_9_keeper_en_9_wd = reg_wdata[4]; + + assign dio_pad_attr_9_schmitt_en_9_wd = reg_wdata[5]; + + assign dio_pad_attr_9_od_en_9_wd = reg_wdata[6]; + + assign dio_pad_attr_9_input_disable_9_wd = reg_wdata[7]; + + assign dio_pad_attr_9_slew_rate_9_wd = reg_wdata[17:16]; + + assign dio_pad_attr_9_drive_strength_9_wd = reg_wdata[23:20]; + assign dio_pad_attr_10_re = addr_hit[289] & reg_re & !reg_error; + assign dio_pad_attr_10_we = addr_hit[289] & reg_we & !reg_error; + + assign dio_pad_attr_10_invert_10_wd = reg_wdata[0]; + + assign dio_pad_attr_10_virtual_od_en_10_wd = reg_wdata[1]; + + assign dio_pad_attr_10_pull_en_10_wd = reg_wdata[2]; + + assign dio_pad_attr_10_pull_select_10_wd = reg_wdata[3]; + + assign dio_pad_attr_10_keeper_en_10_wd = reg_wdata[4]; + + assign dio_pad_attr_10_schmitt_en_10_wd = reg_wdata[5]; + + assign dio_pad_attr_10_od_en_10_wd = reg_wdata[6]; + + assign dio_pad_attr_10_input_disable_10_wd = reg_wdata[7]; + + assign dio_pad_attr_10_slew_rate_10_wd = reg_wdata[17:16]; + + assign dio_pad_attr_10_drive_strength_10_wd = reg_wdata[23:20]; + assign dio_pad_attr_11_re = addr_hit[290] & reg_re & !reg_error; + assign dio_pad_attr_11_we = addr_hit[290] & reg_we & !reg_error; + + assign dio_pad_attr_11_invert_11_wd = reg_wdata[0]; + + assign dio_pad_attr_11_virtual_od_en_11_wd = reg_wdata[1]; + + assign dio_pad_attr_11_pull_en_11_wd = reg_wdata[2]; + + assign dio_pad_attr_11_pull_select_11_wd = reg_wdata[3]; + + assign dio_pad_attr_11_keeper_en_11_wd = reg_wdata[4]; + + assign dio_pad_attr_11_schmitt_en_11_wd = reg_wdata[5]; + + assign dio_pad_attr_11_od_en_11_wd = reg_wdata[6]; + + assign dio_pad_attr_11_input_disable_11_wd = reg_wdata[7]; + + assign dio_pad_attr_11_slew_rate_11_wd = reg_wdata[17:16]; + + assign dio_pad_attr_11_drive_strength_11_wd = reg_wdata[23:20]; + assign dio_pad_attr_12_re = addr_hit[291] & reg_re & !reg_error; + assign dio_pad_attr_12_we = addr_hit[291] & reg_we & !reg_error; + + assign dio_pad_attr_12_invert_12_wd = reg_wdata[0]; + + assign dio_pad_attr_12_virtual_od_en_12_wd = reg_wdata[1]; + + assign dio_pad_attr_12_pull_en_12_wd = reg_wdata[2]; + + assign dio_pad_attr_12_pull_select_12_wd = reg_wdata[3]; + + assign dio_pad_attr_12_keeper_en_12_wd = reg_wdata[4]; + + assign dio_pad_attr_12_schmitt_en_12_wd = reg_wdata[5]; + + assign dio_pad_attr_12_od_en_12_wd = reg_wdata[6]; + + assign dio_pad_attr_12_input_disable_12_wd = reg_wdata[7]; + + assign dio_pad_attr_12_slew_rate_12_wd = reg_wdata[17:16]; + + assign dio_pad_attr_12_drive_strength_12_wd = reg_wdata[23:20]; + assign dio_pad_attr_13_re = addr_hit[292] & reg_re & !reg_error; + assign dio_pad_attr_13_we = addr_hit[292] & reg_we & !reg_error; + + assign dio_pad_attr_13_invert_13_wd = reg_wdata[0]; + + assign dio_pad_attr_13_virtual_od_en_13_wd = reg_wdata[1]; + + assign dio_pad_attr_13_pull_en_13_wd = reg_wdata[2]; + + assign dio_pad_attr_13_pull_select_13_wd = reg_wdata[3]; + + assign dio_pad_attr_13_keeper_en_13_wd = reg_wdata[4]; + + assign dio_pad_attr_13_schmitt_en_13_wd = reg_wdata[5]; + + assign dio_pad_attr_13_od_en_13_wd = reg_wdata[6]; + + assign dio_pad_attr_13_input_disable_13_wd = reg_wdata[7]; + + assign dio_pad_attr_13_slew_rate_13_wd = reg_wdata[17:16]; + + assign dio_pad_attr_13_drive_strength_13_wd = reg_wdata[23:20]; + assign mio_pad_sleep_status_0_we = addr_hit[293] & reg_we & !reg_error; + + assign mio_pad_sleep_status_0_en_0_wd = reg_wdata[0]; + + assign mio_pad_sleep_status_0_en_1_wd = reg_wdata[1]; + + assign mio_pad_sleep_status_0_en_2_wd = reg_wdata[2]; + + assign mio_pad_sleep_status_0_en_3_wd = reg_wdata[3]; + + assign mio_pad_sleep_status_0_en_4_wd = reg_wdata[4]; + + assign mio_pad_sleep_status_0_en_5_wd = reg_wdata[5]; + + assign mio_pad_sleep_status_0_en_6_wd = reg_wdata[6]; + + assign mio_pad_sleep_status_0_en_7_wd = reg_wdata[7]; + + assign mio_pad_sleep_status_0_en_8_wd = reg_wdata[8]; + + assign mio_pad_sleep_status_0_en_9_wd = reg_wdata[9]; + + assign mio_pad_sleep_status_0_en_10_wd = reg_wdata[10]; + + assign mio_pad_sleep_status_0_en_11_wd = reg_wdata[11]; + + assign mio_pad_sleep_status_0_en_12_wd = reg_wdata[12]; + + assign mio_pad_sleep_status_0_en_13_wd = reg_wdata[13]; + + assign mio_pad_sleep_status_0_en_14_wd = reg_wdata[14]; + + assign mio_pad_sleep_status_0_en_15_wd = reg_wdata[15]; + + assign mio_pad_sleep_status_0_en_16_wd = reg_wdata[16]; + + assign mio_pad_sleep_status_0_en_17_wd = reg_wdata[17]; + + assign mio_pad_sleep_status_0_en_18_wd = reg_wdata[18]; + + assign mio_pad_sleep_status_0_en_19_wd = reg_wdata[19]; + + assign mio_pad_sleep_status_0_en_20_wd = reg_wdata[20]; + + assign mio_pad_sleep_status_0_en_21_wd = reg_wdata[21]; + + assign mio_pad_sleep_status_0_en_22_wd = reg_wdata[22]; + + assign mio_pad_sleep_status_0_en_23_wd = reg_wdata[23]; + + assign mio_pad_sleep_status_0_en_24_wd = reg_wdata[24]; + + assign mio_pad_sleep_status_0_en_25_wd = reg_wdata[25]; + + assign mio_pad_sleep_status_0_en_26_wd = reg_wdata[26]; + + assign mio_pad_sleep_status_0_en_27_wd = reg_wdata[27]; + + assign mio_pad_sleep_status_0_en_28_wd = reg_wdata[28]; + + assign mio_pad_sleep_status_0_en_29_wd = reg_wdata[29]; + + assign mio_pad_sleep_status_0_en_30_wd = reg_wdata[30]; + + assign mio_pad_sleep_status_0_en_31_wd = reg_wdata[31]; + assign mio_pad_sleep_status_1_we = addr_hit[294] & reg_we & !reg_error; + + assign mio_pad_sleep_status_1_en_32_wd = reg_wdata[0]; + + assign mio_pad_sleep_status_1_en_33_wd = reg_wdata[1]; + + assign mio_pad_sleep_status_1_en_34_wd = reg_wdata[2]; + + assign mio_pad_sleep_status_1_en_35_wd = reg_wdata[3]; + + assign mio_pad_sleep_status_1_en_36_wd = reg_wdata[4]; + + assign mio_pad_sleep_status_1_en_37_wd = reg_wdata[5]; + + assign mio_pad_sleep_status_1_en_38_wd = reg_wdata[6]; + + assign mio_pad_sleep_status_1_en_39_wd = reg_wdata[7]; + + assign mio_pad_sleep_status_1_en_40_wd = reg_wdata[8]; + + assign mio_pad_sleep_status_1_en_41_wd = reg_wdata[9]; + + assign mio_pad_sleep_status_1_en_42_wd = reg_wdata[10]; + + assign mio_pad_sleep_status_1_en_43_wd = reg_wdata[11]; + + assign mio_pad_sleep_status_1_en_44_wd = reg_wdata[12]; + + assign mio_pad_sleep_status_1_en_45_wd = reg_wdata[13]; + + assign mio_pad_sleep_status_1_en_46_wd = reg_wdata[14]; + assign mio_pad_sleep_regwen_0_we = addr_hit[295] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_0_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_1_we = addr_hit[296] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_1_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_2_we = addr_hit[297] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_2_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_3_we = addr_hit[298] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_3_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_4_we = addr_hit[299] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_4_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_5_we = addr_hit[300] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_5_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_6_we = addr_hit[301] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_6_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_7_we = addr_hit[302] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_7_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_8_we = addr_hit[303] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_8_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_9_we = addr_hit[304] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_9_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_10_we = addr_hit[305] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_10_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_11_we = addr_hit[306] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_11_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_12_we = addr_hit[307] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_12_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_13_we = addr_hit[308] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_13_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_14_we = addr_hit[309] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_14_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_15_we = addr_hit[310] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_15_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_16_we = addr_hit[311] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_16_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_17_we = addr_hit[312] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_17_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_18_we = addr_hit[313] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_18_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_19_we = addr_hit[314] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_19_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_20_we = addr_hit[315] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_20_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_21_we = addr_hit[316] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_21_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_22_we = addr_hit[317] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_22_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_23_we = addr_hit[318] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_23_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_24_we = addr_hit[319] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_24_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_25_we = addr_hit[320] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_25_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_26_we = addr_hit[321] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_26_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_27_we = addr_hit[322] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_27_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_28_we = addr_hit[323] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_28_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_29_we = addr_hit[324] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_29_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_30_we = addr_hit[325] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_30_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_31_we = addr_hit[326] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_31_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_32_we = addr_hit[327] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_32_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_33_we = addr_hit[328] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_33_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_34_we = addr_hit[329] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_34_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_35_we = addr_hit[330] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_35_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_36_we = addr_hit[331] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_36_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_37_we = addr_hit[332] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_37_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_38_we = addr_hit[333] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_38_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_39_we = addr_hit[334] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_39_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_40_we = addr_hit[335] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_40_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_41_we = addr_hit[336] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_41_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_42_we = addr_hit[337] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_42_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_43_we = addr_hit[338] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_43_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_44_we = addr_hit[339] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_44_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_45_we = addr_hit[340] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_45_wd = reg_wdata[0]; + assign mio_pad_sleep_regwen_46_we = addr_hit[341] & reg_we & !reg_error; + + assign mio_pad_sleep_regwen_46_wd = reg_wdata[0]; + assign mio_pad_sleep_en_0_we = addr_hit[342] & reg_we & !reg_error; + + assign mio_pad_sleep_en_0_wd = reg_wdata[0]; + assign mio_pad_sleep_en_1_we = addr_hit[343] & reg_we & !reg_error; + + assign mio_pad_sleep_en_1_wd = reg_wdata[0]; + assign mio_pad_sleep_en_2_we = addr_hit[344] & reg_we & !reg_error; + + assign mio_pad_sleep_en_2_wd = reg_wdata[0]; + assign mio_pad_sleep_en_3_we = addr_hit[345] & reg_we & !reg_error; + + assign mio_pad_sleep_en_3_wd = reg_wdata[0]; + assign mio_pad_sleep_en_4_we = addr_hit[346] & reg_we & !reg_error; + + assign mio_pad_sleep_en_4_wd = reg_wdata[0]; + assign mio_pad_sleep_en_5_we = addr_hit[347] & reg_we & !reg_error; + + assign mio_pad_sleep_en_5_wd = reg_wdata[0]; + assign mio_pad_sleep_en_6_we = addr_hit[348] & reg_we & !reg_error; + + assign mio_pad_sleep_en_6_wd = reg_wdata[0]; + assign mio_pad_sleep_en_7_we = addr_hit[349] & reg_we & !reg_error; + + assign mio_pad_sleep_en_7_wd = reg_wdata[0]; + assign mio_pad_sleep_en_8_we = addr_hit[350] & reg_we & !reg_error; + + assign mio_pad_sleep_en_8_wd = reg_wdata[0]; + assign mio_pad_sleep_en_9_we = addr_hit[351] & reg_we & !reg_error; + + assign mio_pad_sleep_en_9_wd = reg_wdata[0]; + assign mio_pad_sleep_en_10_we = addr_hit[352] & reg_we & !reg_error; + + assign mio_pad_sleep_en_10_wd = reg_wdata[0]; + assign mio_pad_sleep_en_11_we = addr_hit[353] & reg_we & !reg_error; + + assign mio_pad_sleep_en_11_wd = reg_wdata[0]; + assign mio_pad_sleep_en_12_we = addr_hit[354] & reg_we & !reg_error; + + assign mio_pad_sleep_en_12_wd = reg_wdata[0]; + assign mio_pad_sleep_en_13_we = addr_hit[355] & reg_we & !reg_error; + + assign mio_pad_sleep_en_13_wd = reg_wdata[0]; + assign mio_pad_sleep_en_14_we = addr_hit[356] & reg_we & !reg_error; + + assign mio_pad_sleep_en_14_wd = reg_wdata[0]; + assign mio_pad_sleep_en_15_we = addr_hit[357] & reg_we & !reg_error; + + assign mio_pad_sleep_en_15_wd = reg_wdata[0]; + assign mio_pad_sleep_en_16_we = addr_hit[358] & reg_we & !reg_error; + + assign mio_pad_sleep_en_16_wd = reg_wdata[0]; + assign mio_pad_sleep_en_17_we = addr_hit[359] & reg_we & !reg_error; + + assign mio_pad_sleep_en_17_wd = reg_wdata[0]; + assign mio_pad_sleep_en_18_we = addr_hit[360] & reg_we & !reg_error; + + assign mio_pad_sleep_en_18_wd = reg_wdata[0]; + assign mio_pad_sleep_en_19_we = addr_hit[361] & reg_we & !reg_error; + + assign mio_pad_sleep_en_19_wd = reg_wdata[0]; + assign mio_pad_sleep_en_20_we = addr_hit[362] & reg_we & !reg_error; + + assign mio_pad_sleep_en_20_wd = reg_wdata[0]; + assign mio_pad_sleep_en_21_we = addr_hit[363] & reg_we & !reg_error; + + assign mio_pad_sleep_en_21_wd = reg_wdata[0]; + assign mio_pad_sleep_en_22_we = addr_hit[364] & reg_we & !reg_error; + + assign mio_pad_sleep_en_22_wd = reg_wdata[0]; + assign mio_pad_sleep_en_23_we = addr_hit[365] & reg_we & !reg_error; + + assign mio_pad_sleep_en_23_wd = reg_wdata[0]; + assign mio_pad_sleep_en_24_we = addr_hit[366] & reg_we & !reg_error; + + assign mio_pad_sleep_en_24_wd = reg_wdata[0]; + assign mio_pad_sleep_en_25_we = addr_hit[367] & reg_we & !reg_error; + + assign mio_pad_sleep_en_25_wd = reg_wdata[0]; + assign mio_pad_sleep_en_26_we = addr_hit[368] & reg_we & !reg_error; + + assign mio_pad_sleep_en_26_wd = reg_wdata[0]; + assign mio_pad_sleep_en_27_we = addr_hit[369] & reg_we & !reg_error; + + assign mio_pad_sleep_en_27_wd = reg_wdata[0]; + assign mio_pad_sleep_en_28_we = addr_hit[370] & reg_we & !reg_error; + + assign mio_pad_sleep_en_28_wd = reg_wdata[0]; + assign mio_pad_sleep_en_29_we = addr_hit[371] & reg_we & !reg_error; + + assign mio_pad_sleep_en_29_wd = reg_wdata[0]; + assign mio_pad_sleep_en_30_we = addr_hit[372] & reg_we & !reg_error; + + assign mio_pad_sleep_en_30_wd = reg_wdata[0]; + assign mio_pad_sleep_en_31_we = addr_hit[373] & reg_we & !reg_error; + + assign mio_pad_sleep_en_31_wd = reg_wdata[0]; + assign mio_pad_sleep_en_32_we = addr_hit[374] & reg_we & !reg_error; + + assign mio_pad_sleep_en_32_wd = reg_wdata[0]; + assign mio_pad_sleep_en_33_we = addr_hit[375] & reg_we & !reg_error; + + assign mio_pad_sleep_en_33_wd = reg_wdata[0]; + assign mio_pad_sleep_en_34_we = addr_hit[376] & reg_we & !reg_error; + + assign mio_pad_sleep_en_34_wd = reg_wdata[0]; + assign mio_pad_sleep_en_35_we = addr_hit[377] & reg_we & !reg_error; + + assign mio_pad_sleep_en_35_wd = reg_wdata[0]; + assign mio_pad_sleep_en_36_we = addr_hit[378] & reg_we & !reg_error; + + assign mio_pad_sleep_en_36_wd = reg_wdata[0]; + assign mio_pad_sleep_en_37_we = addr_hit[379] & reg_we & !reg_error; + + assign mio_pad_sleep_en_37_wd = reg_wdata[0]; + assign mio_pad_sleep_en_38_we = addr_hit[380] & reg_we & !reg_error; + + assign mio_pad_sleep_en_38_wd = reg_wdata[0]; + assign mio_pad_sleep_en_39_we = addr_hit[381] & reg_we & !reg_error; + + assign mio_pad_sleep_en_39_wd = reg_wdata[0]; + assign mio_pad_sleep_en_40_we = addr_hit[382] & reg_we & !reg_error; + + assign mio_pad_sleep_en_40_wd = reg_wdata[0]; + assign mio_pad_sleep_en_41_we = addr_hit[383] & reg_we & !reg_error; + + assign mio_pad_sleep_en_41_wd = reg_wdata[0]; + assign mio_pad_sleep_en_42_we = addr_hit[384] & reg_we & !reg_error; + + assign mio_pad_sleep_en_42_wd = reg_wdata[0]; + assign mio_pad_sleep_en_43_we = addr_hit[385] & reg_we & !reg_error; + + assign mio_pad_sleep_en_43_wd = reg_wdata[0]; + assign mio_pad_sleep_en_44_we = addr_hit[386] & reg_we & !reg_error; + + assign mio_pad_sleep_en_44_wd = reg_wdata[0]; + assign mio_pad_sleep_en_45_we = addr_hit[387] & reg_we & !reg_error; + + assign mio_pad_sleep_en_45_wd = reg_wdata[0]; + assign mio_pad_sleep_en_46_we = addr_hit[388] & reg_we & !reg_error; + + assign mio_pad_sleep_en_46_wd = reg_wdata[0]; + assign mio_pad_sleep_mode_0_we = addr_hit[389] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_0_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_1_we = addr_hit[390] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_1_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_2_we = addr_hit[391] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_2_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_3_we = addr_hit[392] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_3_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_4_we = addr_hit[393] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_4_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_5_we = addr_hit[394] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_5_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_6_we = addr_hit[395] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_6_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_7_we = addr_hit[396] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_7_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_8_we = addr_hit[397] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_8_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_9_we = addr_hit[398] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_9_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_10_we = addr_hit[399] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_10_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_11_we = addr_hit[400] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_11_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_12_we = addr_hit[401] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_12_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_13_we = addr_hit[402] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_13_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_14_we = addr_hit[403] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_14_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_15_we = addr_hit[404] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_15_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_16_we = addr_hit[405] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_16_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_17_we = addr_hit[406] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_17_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_18_we = addr_hit[407] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_18_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_19_we = addr_hit[408] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_19_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_20_we = addr_hit[409] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_20_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_21_we = addr_hit[410] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_21_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_22_we = addr_hit[411] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_22_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_23_we = addr_hit[412] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_23_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_24_we = addr_hit[413] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_24_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_25_we = addr_hit[414] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_25_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_26_we = addr_hit[415] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_26_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_27_we = addr_hit[416] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_27_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_28_we = addr_hit[417] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_28_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_29_we = addr_hit[418] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_29_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_30_we = addr_hit[419] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_30_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_31_we = addr_hit[420] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_31_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_32_we = addr_hit[421] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_32_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_33_we = addr_hit[422] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_33_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_34_we = addr_hit[423] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_34_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_35_we = addr_hit[424] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_35_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_36_we = addr_hit[425] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_36_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_37_we = addr_hit[426] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_37_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_38_we = addr_hit[427] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_38_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_39_we = addr_hit[428] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_39_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_40_we = addr_hit[429] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_40_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_41_we = addr_hit[430] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_41_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_42_we = addr_hit[431] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_42_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_43_we = addr_hit[432] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_43_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_44_we = addr_hit[433] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_44_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_45_we = addr_hit[434] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_45_wd = reg_wdata[1:0]; + assign mio_pad_sleep_mode_46_we = addr_hit[435] & reg_we & !reg_error; + + assign mio_pad_sleep_mode_46_wd = reg_wdata[1:0]; + assign dio_pad_sleep_status_we = addr_hit[436] & reg_we & !reg_error; + + assign dio_pad_sleep_status_en_0_wd = reg_wdata[0]; + + assign dio_pad_sleep_status_en_1_wd = reg_wdata[1]; + + assign dio_pad_sleep_status_en_2_wd = reg_wdata[2]; + + assign dio_pad_sleep_status_en_3_wd = reg_wdata[3]; + + assign dio_pad_sleep_status_en_4_wd = reg_wdata[4]; + + assign dio_pad_sleep_status_en_5_wd = reg_wdata[5]; + + assign dio_pad_sleep_status_en_6_wd = reg_wdata[6]; + + assign dio_pad_sleep_status_en_7_wd = reg_wdata[7]; + + assign dio_pad_sleep_status_en_8_wd = reg_wdata[8]; + + assign dio_pad_sleep_status_en_9_wd = reg_wdata[9]; + + assign dio_pad_sleep_status_en_10_wd = reg_wdata[10]; + + assign dio_pad_sleep_status_en_11_wd = reg_wdata[11]; + + assign dio_pad_sleep_status_en_12_wd = reg_wdata[12]; + + assign dio_pad_sleep_status_en_13_wd = reg_wdata[13]; + assign dio_pad_sleep_regwen_0_we = addr_hit[437] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_0_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_1_we = addr_hit[438] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_1_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_2_we = addr_hit[439] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_2_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_3_we = addr_hit[440] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_3_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_4_we = addr_hit[441] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_4_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_5_we = addr_hit[442] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_5_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_6_we = addr_hit[443] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_6_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_7_we = addr_hit[444] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_7_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_8_we = addr_hit[445] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_8_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_9_we = addr_hit[446] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_9_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_10_we = addr_hit[447] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_10_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_11_we = addr_hit[448] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_11_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_12_we = addr_hit[449] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_12_wd = reg_wdata[0]; + assign dio_pad_sleep_regwen_13_we = addr_hit[450] & reg_we & !reg_error; + + assign dio_pad_sleep_regwen_13_wd = reg_wdata[0]; + assign dio_pad_sleep_en_0_we = addr_hit[451] & reg_we & !reg_error; + + assign dio_pad_sleep_en_0_wd = reg_wdata[0]; + assign dio_pad_sleep_en_1_we = addr_hit[452] & reg_we & !reg_error; + + assign dio_pad_sleep_en_1_wd = reg_wdata[0]; + assign dio_pad_sleep_en_2_we = addr_hit[453] & reg_we & !reg_error; + + assign dio_pad_sleep_en_2_wd = reg_wdata[0]; + assign dio_pad_sleep_en_3_we = addr_hit[454] & reg_we & !reg_error; + + assign dio_pad_sleep_en_3_wd = reg_wdata[0]; + assign dio_pad_sleep_en_4_we = addr_hit[455] & reg_we & !reg_error; + + assign dio_pad_sleep_en_4_wd = reg_wdata[0]; + assign dio_pad_sleep_en_5_we = addr_hit[456] & reg_we & !reg_error; + + assign dio_pad_sleep_en_5_wd = reg_wdata[0]; + assign dio_pad_sleep_en_6_we = addr_hit[457] & reg_we & !reg_error; + + assign dio_pad_sleep_en_6_wd = reg_wdata[0]; + assign dio_pad_sleep_en_7_we = addr_hit[458] & reg_we & !reg_error; + + assign dio_pad_sleep_en_7_wd = reg_wdata[0]; + assign dio_pad_sleep_en_8_we = addr_hit[459] & reg_we & !reg_error; + + assign dio_pad_sleep_en_8_wd = reg_wdata[0]; + assign dio_pad_sleep_en_9_we = addr_hit[460] & reg_we & !reg_error; + + assign dio_pad_sleep_en_9_wd = reg_wdata[0]; + assign dio_pad_sleep_en_10_we = addr_hit[461] & reg_we & !reg_error; + + assign dio_pad_sleep_en_10_wd = reg_wdata[0]; + assign dio_pad_sleep_en_11_we = addr_hit[462] & reg_we & !reg_error; + + assign dio_pad_sleep_en_11_wd = reg_wdata[0]; + assign dio_pad_sleep_en_12_we = addr_hit[463] & reg_we & !reg_error; + + assign dio_pad_sleep_en_12_wd = reg_wdata[0]; + assign dio_pad_sleep_en_13_we = addr_hit[464] & reg_we & !reg_error; + + assign dio_pad_sleep_en_13_wd = reg_wdata[0]; + assign dio_pad_sleep_mode_0_we = addr_hit[465] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_0_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_1_we = addr_hit[466] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_1_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_2_we = addr_hit[467] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_2_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_3_we = addr_hit[468] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_3_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_4_we = addr_hit[469] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_4_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_5_we = addr_hit[470] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_5_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_6_we = addr_hit[471] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_6_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_7_we = addr_hit[472] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_7_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_8_we = addr_hit[473] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_8_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_9_we = addr_hit[474] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_9_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_10_we = addr_hit[475] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_10_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_11_we = addr_hit[476] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_11_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_12_we = addr_hit[477] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_12_wd = reg_wdata[1:0]; + assign dio_pad_sleep_mode_13_we = addr_hit[478] & reg_we & !reg_error; + + assign dio_pad_sleep_mode_13_wd = reg_wdata[1:0]; + assign wkup_detector_regwen_0_we = addr_hit[479] & reg_we & !reg_error; + + assign wkup_detector_regwen_0_wd = reg_wdata[0]; + assign wkup_detector_regwen_1_we = addr_hit[480] & reg_we & !reg_error; + + assign wkup_detector_regwen_1_wd = reg_wdata[0]; + assign wkup_detector_regwen_2_we = addr_hit[481] & reg_we & !reg_error; + + assign wkup_detector_regwen_2_wd = reg_wdata[0]; + assign wkup_detector_regwen_3_we = addr_hit[482] & reg_we & !reg_error; + + assign wkup_detector_regwen_3_wd = reg_wdata[0]; + assign wkup_detector_regwen_4_we = addr_hit[483] & reg_we & !reg_error; + + assign wkup_detector_regwen_4_wd = reg_wdata[0]; + assign wkup_detector_regwen_5_we = addr_hit[484] & reg_we & !reg_error; + + assign wkup_detector_regwen_5_wd = reg_wdata[0]; + assign wkup_detector_regwen_6_we = addr_hit[485] & reg_we & !reg_error; + + assign wkup_detector_regwen_6_wd = reg_wdata[0]; + assign wkup_detector_regwen_7_we = addr_hit[486] & reg_we & !reg_error; + + assign wkup_detector_regwen_7_wd = reg_wdata[0]; + assign wkup_detector_en_0_we = addr_hit[487] & reg_we & !reg_error; + + assign wkup_detector_en_1_we = addr_hit[488] & reg_we & !reg_error; + + assign wkup_detector_en_2_we = addr_hit[489] & reg_we & !reg_error; + + assign wkup_detector_en_3_we = addr_hit[490] & reg_we & !reg_error; + + assign wkup_detector_en_4_we = addr_hit[491] & reg_we & !reg_error; + + assign wkup_detector_en_5_we = addr_hit[492] & reg_we & !reg_error; + + assign wkup_detector_en_6_we = addr_hit[493] & reg_we & !reg_error; + + assign wkup_detector_en_7_we = addr_hit[494] & reg_we & !reg_error; + + assign wkup_detector_0_we = addr_hit[495] & reg_we & !reg_error; + + + + assign wkup_detector_1_we = addr_hit[496] & reg_we & !reg_error; + + + + assign wkup_detector_2_we = addr_hit[497] & reg_we & !reg_error; + + + + assign wkup_detector_3_we = addr_hit[498] & reg_we & !reg_error; + + + + assign wkup_detector_4_we = addr_hit[499] & reg_we & !reg_error; + + + + assign wkup_detector_5_we = addr_hit[500] & reg_we & !reg_error; + + + + assign wkup_detector_6_we = addr_hit[501] & reg_we & !reg_error; + + + + assign wkup_detector_7_we = addr_hit[502] & reg_we & !reg_error; + + + + assign wkup_detector_cnt_th_0_we = addr_hit[503] & reg_we & !reg_error; + + assign wkup_detector_cnt_th_1_we = addr_hit[504] & reg_we & !reg_error; + + assign wkup_detector_cnt_th_2_we = addr_hit[505] & reg_we & !reg_error; + + assign wkup_detector_cnt_th_3_we = addr_hit[506] & reg_we & !reg_error; + + assign wkup_detector_cnt_th_4_we = addr_hit[507] & reg_we & !reg_error; + + assign wkup_detector_cnt_th_5_we = addr_hit[508] & reg_we & !reg_error; + + assign wkup_detector_cnt_th_6_we = addr_hit[509] & reg_we & !reg_error; + + assign wkup_detector_cnt_th_7_we = addr_hit[510] & reg_we & !reg_error; + + assign wkup_detector_padsel_0_we = addr_hit[511] & reg_we & !reg_error; + + assign wkup_detector_padsel_0_wd = reg_wdata[5:0]; + assign wkup_detector_padsel_1_we = addr_hit[512] & reg_we & !reg_error; + + assign wkup_detector_padsel_1_wd = reg_wdata[5:0]; + assign wkup_detector_padsel_2_we = addr_hit[513] & reg_we & !reg_error; + + assign wkup_detector_padsel_2_wd = reg_wdata[5:0]; + assign wkup_detector_padsel_3_we = addr_hit[514] & reg_we & !reg_error; + + assign wkup_detector_padsel_3_wd = reg_wdata[5:0]; + assign wkup_detector_padsel_4_we = addr_hit[515] & reg_we & !reg_error; + + assign wkup_detector_padsel_4_wd = reg_wdata[5:0]; + assign wkup_detector_padsel_5_we = addr_hit[516] & reg_we & !reg_error; + + assign wkup_detector_padsel_5_wd = reg_wdata[5:0]; + assign wkup_detector_padsel_6_we = addr_hit[517] & reg_we & !reg_error; + + assign wkup_detector_padsel_6_wd = reg_wdata[5:0]; + assign wkup_detector_padsel_7_we = addr_hit[518] & reg_we & !reg_error; + + assign wkup_detector_padsel_7_wd = reg_wdata[5:0]; + assign wkup_cause_we = addr_hit[519] & reg_we & !reg_error; + + + + + + + + + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = alert_test_we; + reg_we_check[1] = mio_periph_insel_regwen_0_we; + reg_we_check[2] = mio_periph_insel_regwen_1_we; + reg_we_check[3] = mio_periph_insel_regwen_2_we; + reg_we_check[4] = mio_periph_insel_regwen_3_we; + reg_we_check[5] = mio_periph_insel_regwen_4_we; + reg_we_check[6] = mio_periph_insel_regwen_5_we; + reg_we_check[7] = mio_periph_insel_regwen_6_we; + reg_we_check[8] = mio_periph_insel_regwen_7_we; + reg_we_check[9] = mio_periph_insel_regwen_8_we; + reg_we_check[10] = mio_periph_insel_regwen_9_we; + reg_we_check[11] = mio_periph_insel_regwen_10_we; + reg_we_check[12] = mio_periph_insel_regwen_11_we; + reg_we_check[13] = mio_periph_insel_regwen_12_we; + reg_we_check[14] = mio_periph_insel_regwen_13_we; + reg_we_check[15] = mio_periph_insel_regwen_14_we; + reg_we_check[16] = mio_periph_insel_regwen_15_we; + reg_we_check[17] = mio_periph_insel_regwen_16_we; + reg_we_check[18] = mio_periph_insel_regwen_17_we; + reg_we_check[19] = mio_periph_insel_regwen_18_we; + reg_we_check[20] = mio_periph_insel_regwen_19_we; + reg_we_check[21] = mio_periph_insel_regwen_20_we; + reg_we_check[22] = mio_periph_insel_regwen_21_we; + reg_we_check[23] = mio_periph_insel_regwen_22_we; + reg_we_check[24] = mio_periph_insel_regwen_23_we; + reg_we_check[25] = mio_periph_insel_regwen_24_we; + reg_we_check[26] = mio_periph_insel_regwen_25_we; + reg_we_check[27] = mio_periph_insel_regwen_26_we; + reg_we_check[28] = mio_periph_insel_regwen_27_we; + reg_we_check[29] = mio_periph_insel_regwen_28_we; + reg_we_check[30] = mio_periph_insel_regwen_29_we; + reg_we_check[31] = mio_periph_insel_regwen_30_we; + reg_we_check[32] = mio_periph_insel_regwen_31_we; + reg_we_check[33] = mio_periph_insel_regwen_32_we; + reg_we_check[34] = mio_periph_insel_regwen_33_we; + reg_we_check[35] = mio_periph_insel_regwen_34_we; + reg_we_check[36] = mio_periph_insel_regwen_35_we; + reg_we_check[37] = mio_periph_insel_regwen_36_we; + reg_we_check[38] = mio_periph_insel_regwen_37_we; + reg_we_check[39] = mio_periph_insel_0_gated_we; + reg_we_check[40] = mio_periph_insel_1_gated_we; + reg_we_check[41] = mio_periph_insel_2_gated_we; + reg_we_check[42] = mio_periph_insel_3_gated_we; + reg_we_check[43] = mio_periph_insel_4_gated_we; + reg_we_check[44] = mio_periph_insel_5_gated_we; + reg_we_check[45] = mio_periph_insel_6_gated_we; + reg_we_check[46] = mio_periph_insel_7_gated_we; + reg_we_check[47] = mio_periph_insel_8_gated_we; + reg_we_check[48] = mio_periph_insel_9_gated_we; + reg_we_check[49] = mio_periph_insel_10_gated_we; + reg_we_check[50] = mio_periph_insel_11_gated_we; + reg_we_check[51] = mio_periph_insel_12_gated_we; + reg_we_check[52] = mio_periph_insel_13_gated_we; + reg_we_check[53] = mio_periph_insel_14_gated_we; + reg_we_check[54] = mio_periph_insel_15_gated_we; + reg_we_check[55] = mio_periph_insel_16_gated_we; + reg_we_check[56] = mio_periph_insel_17_gated_we; + reg_we_check[57] = mio_periph_insel_18_gated_we; + reg_we_check[58] = mio_periph_insel_19_gated_we; + reg_we_check[59] = mio_periph_insel_20_gated_we; + reg_we_check[60] = mio_periph_insel_21_gated_we; + reg_we_check[61] = mio_periph_insel_22_gated_we; + reg_we_check[62] = mio_periph_insel_23_gated_we; + reg_we_check[63] = mio_periph_insel_24_gated_we; + reg_we_check[64] = mio_periph_insel_25_gated_we; + reg_we_check[65] = mio_periph_insel_26_gated_we; + reg_we_check[66] = mio_periph_insel_27_gated_we; + reg_we_check[67] = mio_periph_insel_28_gated_we; + reg_we_check[68] = mio_periph_insel_29_gated_we; + reg_we_check[69] = mio_periph_insel_30_gated_we; + reg_we_check[70] = mio_periph_insel_31_gated_we; + reg_we_check[71] = mio_periph_insel_32_gated_we; + reg_we_check[72] = mio_periph_insel_33_gated_we; + reg_we_check[73] = mio_periph_insel_34_gated_we; + reg_we_check[74] = mio_periph_insel_35_gated_we; + reg_we_check[75] = mio_periph_insel_36_gated_we; + reg_we_check[76] = mio_periph_insel_37_gated_we; + reg_we_check[77] = mio_outsel_regwen_0_we; + reg_we_check[78] = mio_outsel_regwen_1_we; + reg_we_check[79] = mio_outsel_regwen_2_we; + reg_we_check[80] = mio_outsel_regwen_3_we; + reg_we_check[81] = mio_outsel_regwen_4_we; + reg_we_check[82] = mio_outsel_regwen_5_we; + reg_we_check[83] = mio_outsel_regwen_6_we; + reg_we_check[84] = mio_outsel_regwen_7_we; + reg_we_check[85] = mio_outsel_regwen_8_we; + reg_we_check[86] = mio_outsel_regwen_9_we; + reg_we_check[87] = mio_outsel_regwen_10_we; + reg_we_check[88] = mio_outsel_regwen_11_we; + reg_we_check[89] = mio_outsel_regwen_12_we; + reg_we_check[90] = mio_outsel_regwen_13_we; + reg_we_check[91] = mio_outsel_regwen_14_we; + reg_we_check[92] = mio_outsel_regwen_15_we; + reg_we_check[93] = mio_outsel_regwen_16_we; + reg_we_check[94] = mio_outsel_regwen_17_we; + reg_we_check[95] = mio_outsel_regwen_18_we; + reg_we_check[96] = mio_outsel_regwen_19_we; + reg_we_check[97] = mio_outsel_regwen_20_we; + reg_we_check[98] = mio_outsel_regwen_21_we; + reg_we_check[99] = mio_outsel_regwen_22_we; + reg_we_check[100] = mio_outsel_regwen_23_we; + reg_we_check[101] = mio_outsel_regwen_24_we; + reg_we_check[102] = mio_outsel_regwen_25_we; + reg_we_check[103] = mio_outsel_regwen_26_we; + reg_we_check[104] = mio_outsel_regwen_27_we; + reg_we_check[105] = mio_outsel_regwen_28_we; + reg_we_check[106] = mio_outsel_regwen_29_we; + reg_we_check[107] = mio_outsel_regwen_30_we; + reg_we_check[108] = mio_outsel_regwen_31_we; + reg_we_check[109] = mio_outsel_regwen_32_we; + reg_we_check[110] = mio_outsel_regwen_33_we; + reg_we_check[111] = mio_outsel_regwen_34_we; + reg_we_check[112] = mio_outsel_regwen_35_we; + reg_we_check[113] = mio_outsel_regwen_36_we; + reg_we_check[114] = mio_outsel_regwen_37_we; + reg_we_check[115] = mio_outsel_regwen_38_we; + reg_we_check[116] = mio_outsel_regwen_39_we; + reg_we_check[117] = mio_outsel_regwen_40_we; + reg_we_check[118] = mio_outsel_regwen_41_we; + reg_we_check[119] = mio_outsel_regwen_42_we; + reg_we_check[120] = mio_outsel_regwen_43_we; + reg_we_check[121] = mio_outsel_regwen_44_we; + reg_we_check[122] = mio_outsel_regwen_45_we; + reg_we_check[123] = mio_outsel_regwen_46_we; + reg_we_check[124] = mio_outsel_0_gated_we; + reg_we_check[125] = mio_outsel_1_gated_we; + reg_we_check[126] = mio_outsel_2_gated_we; + reg_we_check[127] = mio_outsel_3_gated_we; + reg_we_check[128] = mio_outsel_4_gated_we; + reg_we_check[129] = mio_outsel_5_gated_we; + reg_we_check[130] = mio_outsel_6_gated_we; + reg_we_check[131] = mio_outsel_7_gated_we; + reg_we_check[132] = mio_outsel_8_gated_we; + reg_we_check[133] = mio_outsel_9_gated_we; + reg_we_check[134] = mio_outsel_10_gated_we; + reg_we_check[135] = mio_outsel_11_gated_we; + reg_we_check[136] = mio_outsel_12_gated_we; + reg_we_check[137] = mio_outsel_13_gated_we; + reg_we_check[138] = mio_outsel_14_gated_we; + reg_we_check[139] = mio_outsel_15_gated_we; + reg_we_check[140] = mio_outsel_16_gated_we; + reg_we_check[141] = mio_outsel_17_gated_we; + reg_we_check[142] = mio_outsel_18_gated_we; + reg_we_check[143] = mio_outsel_19_gated_we; + reg_we_check[144] = mio_outsel_20_gated_we; + reg_we_check[145] = mio_outsel_21_gated_we; + reg_we_check[146] = mio_outsel_22_gated_we; + reg_we_check[147] = mio_outsel_23_gated_we; + reg_we_check[148] = mio_outsel_24_gated_we; + reg_we_check[149] = mio_outsel_25_gated_we; + reg_we_check[150] = mio_outsel_26_gated_we; + reg_we_check[151] = mio_outsel_27_gated_we; + reg_we_check[152] = mio_outsel_28_gated_we; + reg_we_check[153] = mio_outsel_29_gated_we; + reg_we_check[154] = mio_outsel_30_gated_we; + reg_we_check[155] = mio_outsel_31_gated_we; + reg_we_check[156] = mio_outsel_32_gated_we; + reg_we_check[157] = mio_outsel_33_gated_we; + reg_we_check[158] = mio_outsel_34_gated_we; + reg_we_check[159] = mio_outsel_35_gated_we; + reg_we_check[160] = mio_outsel_36_gated_we; + reg_we_check[161] = mio_outsel_37_gated_we; + reg_we_check[162] = mio_outsel_38_gated_we; + reg_we_check[163] = mio_outsel_39_gated_we; + reg_we_check[164] = mio_outsel_40_gated_we; + reg_we_check[165] = mio_outsel_41_gated_we; + reg_we_check[166] = mio_outsel_42_gated_we; + reg_we_check[167] = mio_outsel_43_gated_we; + reg_we_check[168] = mio_outsel_44_gated_we; + reg_we_check[169] = mio_outsel_45_gated_we; + reg_we_check[170] = mio_outsel_46_gated_we; + reg_we_check[171] = mio_pad_attr_regwen_0_we; + reg_we_check[172] = mio_pad_attr_regwen_1_we; + reg_we_check[173] = mio_pad_attr_regwen_2_we; + reg_we_check[174] = mio_pad_attr_regwen_3_we; + reg_we_check[175] = mio_pad_attr_regwen_4_we; + reg_we_check[176] = mio_pad_attr_regwen_5_we; + reg_we_check[177] = mio_pad_attr_regwen_6_we; + reg_we_check[178] = mio_pad_attr_regwen_7_we; + reg_we_check[179] = mio_pad_attr_regwen_8_we; + reg_we_check[180] = mio_pad_attr_regwen_9_we; + reg_we_check[181] = mio_pad_attr_regwen_10_we; + reg_we_check[182] = mio_pad_attr_regwen_11_we; + reg_we_check[183] = mio_pad_attr_regwen_12_we; + reg_we_check[184] = mio_pad_attr_regwen_13_we; + reg_we_check[185] = mio_pad_attr_regwen_14_we; + reg_we_check[186] = mio_pad_attr_regwen_15_we; + reg_we_check[187] = mio_pad_attr_regwen_16_we; + reg_we_check[188] = mio_pad_attr_regwen_17_we; + reg_we_check[189] = mio_pad_attr_regwen_18_we; + reg_we_check[190] = mio_pad_attr_regwen_19_we; + reg_we_check[191] = mio_pad_attr_regwen_20_we; + reg_we_check[192] = mio_pad_attr_regwen_21_we; + reg_we_check[193] = mio_pad_attr_regwen_22_we; + reg_we_check[194] = mio_pad_attr_regwen_23_we; + reg_we_check[195] = mio_pad_attr_regwen_24_we; + reg_we_check[196] = mio_pad_attr_regwen_25_we; + reg_we_check[197] = mio_pad_attr_regwen_26_we; + reg_we_check[198] = mio_pad_attr_regwen_27_we; + reg_we_check[199] = mio_pad_attr_regwen_28_we; + reg_we_check[200] = mio_pad_attr_regwen_29_we; + reg_we_check[201] = mio_pad_attr_regwen_30_we; + reg_we_check[202] = mio_pad_attr_regwen_31_we; + reg_we_check[203] = mio_pad_attr_regwen_32_we; + reg_we_check[204] = mio_pad_attr_regwen_33_we; + reg_we_check[205] = mio_pad_attr_regwen_34_we; + reg_we_check[206] = mio_pad_attr_regwen_35_we; + reg_we_check[207] = mio_pad_attr_regwen_36_we; + reg_we_check[208] = mio_pad_attr_regwen_37_we; + reg_we_check[209] = mio_pad_attr_regwen_38_we; + reg_we_check[210] = mio_pad_attr_regwen_39_we; + reg_we_check[211] = mio_pad_attr_regwen_40_we; + reg_we_check[212] = mio_pad_attr_regwen_41_we; + reg_we_check[213] = mio_pad_attr_regwen_42_we; + reg_we_check[214] = mio_pad_attr_regwen_43_we; + reg_we_check[215] = mio_pad_attr_regwen_44_we; + reg_we_check[216] = mio_pad_attr_regwen_45_we; + reg_we_check[217] = mio_pad_attr_regwen_46_we; + reg_we_check[218] = mio_pad_attr_0_gated_we; + reg_we_check[219] = mio_pad_attr_1_gated_we; + reg_we_check[220] = mio_pad_attr_2_gated_we; + reg_we_check[221] = mio_pad_attr_3_gated_we; + reg_we_check[222] = mio_pad_attr_4_gated_we; + reg_we_check[223] = mio_pad_attr_5_gated_we; + reg_we_check[224] = mio_pad_attr_6_gated_we; + reg_we_check[225] = mio_pad_attr_7_gated_we; + reg_we_check[226] = mio_pad_attr_8_gated_we; + reg_we_check[227] = mio_pad_attr_9_gated_we; + reg_we_check[228] = mio_pad_attr_10_gated_we; + reg_we_check[229] = mio_pad_attr_11_gated_we; + reg_we_check[230] = mio_pad_attr_12_gated_we; + reg_we_check[231] = mio_pad_attr_13_gated_we; + reg_we_check[232] = mio_pad_attr_14_gated_we; + reg_we_check[233] = mio_pad_attr_15_gated_we; + reg_we_check[234] = mio_pad_attr_16_gated_we; + reg_we_check[235] = mio_pad_attr_17_gated_we; + reg_we_check[236] = mio_pad_attr_18_gated_we; + reg_we_check[237] = mio_pad_attr_19_gated_we; + reg_we_check[238] = mio_pad_attr_20_gated_we; + reg_we_check[239] = mio_pad_attr_21_gated_we; + reg_we_check[240] = mio_pad_attr_22_gated_we; + reg_we_check[241] = mio_pad_attr_23_gated_we; + reg_we_check[242] = mio_pad_attr_24_gated_we; + reg_we_check[243] = mio_pad_attr_25_gated_we; + reg_we_check[244] = mio_pad_attr_26_gated_we; + reg_we_check[245] = mio_pad_attr_27_gated_we; + reg_we_check[246] = mio_pad_attr_28_gated_we; + reg_we_check[247] = mio_pad_attr_29_gated_we; + reg_we_check[248] = mio_pad_attr_30_gated_we; + reg_we_check[249] = mio_pad_attr_31_gated_we; + reg_we_check[250] = mio_pad_attr_32_gated_we; + reg_we_check[251] = mio_pad_attr_33_gated_we; + reg_we_check[252] = mio_pad_attr_34_gated_we; + reg_we_check[253] = mio_pad_attr_35_gated_we; + reg_we_check[254] = mio_pad_attr_36_gated_we; + reg_we_check[255] = mio_pad_attr_37_gated_we; + reg_we_check[256] = mio_pad_attr_38_gated_we; + reg_we_check[257] = mio_pad_attr_39_gated_we; + reg_we_check[258] = mio_pad_attr_40_gated_we; + reg_we_check[259] = mio_pad_attr_41_gated_we; + reg_we_check[260] = mio_pad_attr_42_gated_we; + reg_we_check[261] = mio_pad_attr_43_gated_we; + reg_we_check[262] = mio_pad_attr_44_gated_we; + reg_we_check[263] = mio_pad_attr_45_gated_we; + reg_we_check[264] = mio_pad_attr_46_gated_we; + reg_we_check[265] = dio_pad_attr_regwen_0_we; + reg_we_check[266] = dio_pad_attr_regwen_1_we; + reg_we_check[267] = dio_pad_attr_regwen_2_we; + reg_we_check[268] = dio_pad_attr_regwen_3_we; + reg_we_check[269] = dio_pad_attr_regwen_4_we; + reg_we_check[270] = dio_pad_attr_regwen_5_we; + reg_we_check[271] = dio_pad_attr_regwen_6_we; + reg_we_check[272] = dio_pad_attr_regwen_7_we; + reg_we_check[273] = dio_pad_attr_regwen_8_we; + reg_we_check[274] = dio_pad_attr_regwen_9_we; + reg_we_check[275] = dio_pad_attr_regwen_10_we; + reg_we_check[276] = dio_pad_attr_regwen_11_we; + reg_we_check[277] = dio_pad_attr_regwen_12_we; + reg_we_check[278] = dio_pad_attr_regwen_13_we; + reg_we_check[279] = dio_pad_attr_0_gated_we; + reg_we_check[280] = dio_pad_attr_1_gated_we; + reg_we_check[281] = dio_pad_attr_2_gated_we; + reg_we_check[282] = dio_pad_attr_3_gated_we; + reg_we_check[283] = dio_pad_attr_4_gated_we; + reg_we_check[284] = dio_pad_attr_5_gated_we; + reg_we_check[285] = dio_pad_attr_6_gated_we; + reg_we_check[286] = dio_pad_attr_7_gated_we; + reg_we_check[287] = dio_pad_attr_8_gated_we; + reg_we_check[288] = dio_pad_attr_9_gated_we; + reg_we_check[289] = dio_pad_attr_10_gated_we; + reg_we_check[290] = dio_pad_attr_11_gated_we; + reg_we_check[291] = dio_pad_attr_12_gated_we; + reg_we_check[292] = dio_pad_attr_13_gated_we; + reg_we_check[293] = mio_pad_sleep_status_0_we; + reg_we_check[294] = mio_pad_sleep_status_1_we; + reg_we_check[295] = mio_pad_sleep_regwen_0_we; + reg_we_check[296] = mio_pad_sleep_regwen_1_we; + reg_we_check[297] = mio_pad_sleep_regwen_2_we; + reg_we_check[298] = mio_pad_sleep_regwen_3_we; + reg_we_check[299] = mio_pad_sleep_regwen_4_we; + reg_we_check[300] = mio_pad_sleep_regwen_5_we; + reg_we_check[301] = mio_pad_sleep_regwen_6_we; + reg_we_check[302] = mio_pad_sleep_regwen_7_we; + reg_we_check[303] = mio_pad_sleep_regwen_8_we; + reg_we_check[304] = mio_pad_sleep_regwen_9_we; + reg_we_check[305] = mio_pad_sleep_regwen_10_we; + reg_we_check[306] = mio_pad_sleep_regwen_11_we; + reg_we_check[307] = mio_pad_sleep_regwen_12_we; + reg_we_check[308] = mio_pad_sleep_regwen_13_we; + reg_we_check[309] = mio_pad_sleep_regwen_14_we; + reg_we_check[310] = mio_pad_sleep_regwen_15_we; + reg_we_check[311] = mio_pad_sleep_regwen_16_we; + reg_we_check[312] = mio_pad_sleep_regwen_17_we; + reg_we_check[313] = mio_pad_sleep_regwen_18_we; + reg_we_check[314] = mio_pad_sleep_regwen_19_we; + reg_we_check[315] = mio_pad_sleep_regwen_20_we; + reg_we_check[316] = mio_pad_sleep_regwen_21_we; + reg_we_check[317] = mio_pad_sleep_regwen_22_we; + reg_we_check[318] = mio_pad_sleep_regwen_23_we; + reg_we_check[319] = mio_pad_sleep_regwen_24_we; + reg_we_check[320] = mio_pad_sleep_regwen_25_we; + reg_we_check[321] = mio_pad_sleep_regwen_26_we; + reg_we_check[322] = mio_pad_sleep_regwen_27_we; + reg_we_check[323] = mio_pad_sleep_regwen_28_we; + reg_we_check[324] = mio_pad_sleep_regwen_29_we; + reg_we_check[325] = mio_pad_sleep_regwen_30_we; + reg_we_check[326] = mio_pad_sleep_regwen_31_we; + reg_we_check[327] = mio_pad_sleep_regwen_32_we; + reg_we_check[328] = mio_pad_sleep_regwen_33_we; + reg_we_check[329] = mio_pad_sleep_regwen_34_we; + reg_we_check[330] = mio_pad_sleep_regwen_35_we; + reg_we_check[331] = mio_pad_sleep_regwen_36_we; + reg_we_check[332] = mio_pad_sleep_regwen_37_we; + reg_we_check[333] = mio_pad_sleep_regwen_38_we; + reg_we_check[334] = mio_pad_sleep_regwen_39_we; + reg_we_check[335] = mio_pad_sleep_regwen_40_we; + reg_we_check[336] = mio_pad_sleep_regwen_41_we; + reg_we_check[337] = mio_pad_sleep_regwen_42_we; + reg_we_check[338] = mio_pad_sleep_regwen_43_we; + reg_we_check[339] = mio_pad_sleep_regwen_44_we; + reg_we_check[340] = mio_pad_sleep_regwen_45_we; + reg_we_check[341] = mio_pad_sleep_regwen_46_we; + reg_we_check[342] = mio_pad_sleep_en_0_gated_we; + reg_we_check[343] = mio_pad_sleep_en_1_gated_we; + reg_we_check[344] = mio_pad_sleep_en_2_gated_we; + reg_we_check[345] = mio_pad_sleep_en_3_gated_we; + reg_we_check[346] = mio_pad_sleep_en_4_gated_we; + reg_we_check[347] = mio_pad_sleep_en_5_gated_we; + reg_we_check[348] = mio_pad_sleep_en_6_gated_we; + reg_we_check[349] = mio_pad_sleep_en_7_gated_we; + reg_we_check[350] = mio_pad_sleep_en_8_gated_we; + reg_we_check[351] = mio_pad_sleep_en_9_gated_we; + reg_we_check[352] = mio_pad_sleep_en_10_gated_we; + reg_we_check[353] = mio_pad_sleep_en_11_gated_we; + reg_we_check[354] = mio_pad_sleep_en_12_gated_we; + reg_we_check[355] = mio_pad_sleep_en_13_gated_we; + reg_we_check[356] = mio_pad_sleep_en_14_gated_we; + reg_we_check[357] = mio_pad_sleep_en_15_gated_we; + reg_we_check[358] = mio_pad_sleep_en_16_gated_we; + reg_we_check[359] = mio_pad_sleep_en_17_gated_we; + reg_we_check[360] = mio_pad_sleep_en_18_gated_we; + reg_we_check[361] = mio_pad_sleep_en_19_gated_we; + reg_we_check[362] = mio_pad_sleep_en_20_gated_we; + reg_we_check[363] = mio_pad_sleep_en_21_gated_we; + reg_we_check[364] = mio_pad_sleep_en_22_gated_we; + reg_we_check[365] = mio_pad_sleep_en_23_gated_we; + reg_we_check[366] = mio_pad_sleep_en_24_gated_we; + reg_we_check[367] = mio_pad_sleep_en_25_gated_we; + reg_we_check[368] = mio_pad_sleep_en_26_gated_we; + reg_we_check[369] = mio_pad_sleep_en_27_gated_we; + reg_we_check[370] = mio_pad_sleep_en_28_gated_we; + reg_we_check[371] = mio_pad_sleep_en_29_gated_we; + reg_we_check[372] = mio_pad_sleep_en_30_gated_we; + reg_we_check[373] = mio_pad_sleep_en_31_gated_we; + reg_we_check[374] = mio_pad_sleep_en_32_gated_we; + reg_we_check[375] = mio_pad_sleep_en_33_gated_we; + reg_we_check[376] = mio_pad_sleep_en_34_gated_we; + reg_we_check[377] = mio_pad_sleep_en_35_gated_we; + reg_we_check[378] = mio_pad_sleep_en_36_gated_we; + reg_we_check[379] = mio_pad_sleep_en_37_gated_we; + reg_we_check[380] = mio_pad_sleep_en_38_gated_we; + reg_we_check[381] = mio_pad_sleep_en_39_gated_we; + reg_we_check[382] = mio_pad_sleep_en_40_gated_we; + reg_we_check[383] = mio_pad_sleep_en_41_gated_we; + reg_we_check[384] = mio_pad_sleep_en_42_gated_we; + reg_we_check[385] = mio_pad_sleep_en_43_gated_we; + reg_we_check[386] = mio_pad_sleep_en_44_gated_we; + reg_we_check[387] = mio_pad_sleep_en_45_gated_we; + reg_we_check[388] = mio_pad_sleep_en_46_gated_we; + reg_we_check[389] = mio_pad_sleep_mode_0_gated_we; + reg_we_check[390] = mio_pad_sleep_mode_1_gated_we; + reg_we_check[391] = mio_pad_sleep_mode_2_gated_we; + reg_we_check[392] = mio_pad_sleep_mode_3_gated_we; + reg_we_check[393] = mio_pad_sleep_mode_4_gated_we; + reg_we_check[394] = mio_pad_sleep_mode_5_gated_we; + reg_we_check[395] = mio_pad_sleep_mode_6_gated_we; + reg_we_check[396] = mio_pad_sleep_mode_7_gated_we; + reg_we_check[397] = mio_pad_sleep_mode_8_gated_we; + reg_we_check[398] = mio_pad_sleep_mode_9_gated_we; + reg_we_check[399] = mio_pad_sleep_mode_10_gated_we; + reg_we_check[400] = mio_pad_sleep_mode_11_gated_we; + reg_we_check[401] = mio_pad_sleep_mode_12_gated_we; + reg_we_check[402] = mio_pad_sleep_mode_13_gated_we; + reg_we_check[403] = mio_pad_sleep_mode_14_gated_we; + reg_we_check[404] = mio_pad_sleep_mode_15_gated_we; + reg_we_check[405] = mio_pad_sleep_mode_16_gated_we; + reg_we_check[406] = mio_pad_sleep_mode_17_gated_we; + reg_we_check[407] = mio_pad_sleep_mode_18_gated_we; + reg_we_check[408] = mio_pad_sleep_mode_19_gated_we; + reg_we_check[409] = mio_pad_sleep_mode_20_gated_we; + reg_we_check[410] = mio_pad_sleep_mode_21_gated_we; + reg_we_check[411] = mio_pad_sleep_mode_22_gated_we; + reg_we_check[412] = mio_pad_sleep_mode_23_gated_we; + reg_we_check[413] = mio_pad_sleep_mode_24_gated_we; + reg_we_check[414] = mio_pad_sleep_mode_25_gated_we; + reg_we_check[415] = mio_pad_sleep_mode_26_gated_we; + reg_we_check[416] = mio_pad_sleep_mode_27_gated_we; + reg_we_check[417] = mio_pad_sleep_mode_28_gated_we; + reg_we_check[418] = mio_pad_sleep_mode_29_gated_we; + reg_we_check[419] = mio_pad_sleep_mode_30_gated_we; + reg_we_check[420] = mio_pad_sleep_mode_31_gated_we; + reg_we_check[421] = mio_pad_sleep_mode_32_gated_we; + reg_we_check[422] = mio_pad_sleep_mode_33_gated_we; + reg_we_check[423] = mio_pad_sleep_mode_34_gated_we; + reg_we_check[424] = mio_pad_sleep_mode_35_gated_we; + reg_we_check[425] = mio_pad_sleep_mode_36_gated_we; + reg_we_check[426] = mio_pad_sleep_mode_37_gated_we; + reg_we_check[427] = mio_pad_sleep_mode_38_gated_we; + reg_we_check[428] = mio_pad_sleep_mode_39_gated_we; + reg_we_check[429] = mio_pad_sleep_mode_40_gated_we; + reg_we_check[430] = mio_pad_sleep_mode_41_gated_we; + reg_we_check[431] = mio_pad_sleep_mode_42_gated_we; + reg_we_check[432] = mio_pad_sleep_mode_43_gated_we; + reg_we_check[433] = mio_pad_sleep_mode_44_gated_we; + reg_we_check[434] = mio_pad_sleep_mode_45_gated_we; + reg_we_check[435] = mio_pad_sleep_mode_46_gated_we; + reg_we_check[436] = dio_pad_sleep_status_we; + reg_we_check[437] = dio_pad_sleep_regwen_0_we; + reg_we_check[438] = dio_pad_sleep_regwen_1_we; + reg_we_check[439] = dio_pad_sleep_regwen_2_we; + reg_we_check[440] = dio_pad_sleep_regwen_3_we; + reg_we_check[441] = dio_pad_sleep_regwen_4_we; + reg_we_check[442] = dio_pad_sleep_regwen_5_we; + reg_we_check[443] = dio_pad_sleep_regwen_6_we; + reg_we_check[444] = dio_pad_sleep_regwen_7_we; + reg_we_check[445] = dio_pad_sleep_regwen_8_we; + reg_we_check[446] = dio_pad_sleep_regwen_9_we; + reg_we_check[447] = dio_pad_sleep_regwen_10_we; + reg_we_check[448] = dio_pad_sleep_regwen_11_we; + reg_we_check[449] = dio_pad_sleep_regwen_12_we; + reg_we_check[450] = dio_pad_sleep_regwen_13_we; + reg_we_check[451] = dio_pad_sleep_en_0_gated_we; + reg_we_check[452] = dio_pad_sleep_en_1_gated_we; + reg_we_check[453] = dio_pad_sleep_en_2_gated_we; + reg_we_check[454] = dio_pad_sleep_en_3_gated_we; + reg_we_check[455] = dio_pad_sleep_en_4_gated_we; + reg_we_check[456] = dio_pad_sleep_en_5_gated_we; + reg_we_check[457] = dio_pad_sleep_en_6_gated_we; + reg_we_check[458] = dio_pad_sleep_en_7_gated_we; + reg_we_check[459] = dio_pad_sleep_en_8_gated_we; + reg_we_check[460] = dio_pad_sleep_en_9_gated_we; + reg_we_check[461] = dio_pad_sleep_en_10_gated_we; + reg_we_check[462] = dio_pad_sleep_en_11_gated_we; + reg_we_check[463] = dio_pad_sleep_en_12_gated_we; + reg_we_check[464] = dio_pad_sleep_en_13_gated_we; + reg_we_check[465] = dio_pad_sleep_mode_0_gated_we; + reg_we_check[466] = dio_pad_sleep_mode_1_gated_we; + reg_we_check[467] = dio_pad_sleep_mode_2_gated_we; + reg_we_check[468] = dio_pad_sleep_mode_3_gated_we; + reg_we_check[469] = dio_pad_sleep_mode_4_gated_we; + reg_we_check[470] = dio_pad_sleep_mode_5_gated_we; + reg_we_check[471] = dio_pad_sleep_mode_6_gated_we; + reg_we_check[472] = dio_pad_sleep_mode_7_gated_we; + reg_we_check[473] = dio_pad_sleep_mode_8_gated_we; + reg_we_check[474] = dio_pad_sleep_mode_9_gated_we; + reg_we_check[475] = dio_pad_sleep_mode_10_gated_we; + reg_we_check[476] = dio_pad_sleep_mode_11_gated_we; + reg_we_check[477] = dio_pad_sleep_mode_12_gated_we; + reg_we_check[478] = dio_pad_sleep_mode_13_gated_we; + reg_we_check[479] = wkup_detector_regwen_0_we; + reg_we_check[480] = wkup_detector_regwen_1_we; + reg_we_check[481] = wkup_detector_regwen_2_we; + reg_we_check[482] = wkup_detector_regwen_3_we; + reg_we_check[483] = wkup_detector_regwen_4_we; + reg_we_check[484] = wkup_detector_regwen_5_we; + reg_we_check[485] = wkup_detector_regwen_6_we; + reg_we_check[486] = wkup_detector_regwen_7_we; + reg_we_check[487] = wkup_detector_en_0_we; + reg_we_check[488] = wkup_detector_en_1_we; + reg_we_check[489] = wkup_detector_en_2_we; + reg_we_check[490] = wkup_detector_en_3_we; + reg_we_check[491] = wkup_detector_en_4_we; + reg_we_check[492] = wkup_detector_en_5_we; + reg_we_check[493] = wkup_detector_en_6_we; + reg_we_check[494] = wkup_detector_en_7_we; + reg_we_check[495] = wkup_detector_0_we; + reg_we_check[496] = wkup_detector_1_we; + reg_we_check[497] = wkup_detector_2_we; + reg_we_check[498] = wkup_detector_3_we; + reg_we_check[499] = wkup_detector_4_we; + reg_we_check[500] = wkup_detector_5_we; + reg_we_check[501] = wkup_detector_6_we; + reg_we_check[502] = wkup_detector_7_we; + reg_we_check[503] = wkup_detector_cnt_th_0_we; + reg_we_check[504] = wkup_detector_cnt_th_1_we; + reg_we_check[505] = wkup_detector_cnt_th_2_we; + reg_we_check[506] = wkup_detector_cnt_th_3_we; + reg_we_check[507] = wkup_detector_cnt_th_4_we; + reg_we_check[508] = wkup_detector_cnt_th_5_we; + reg_we_check[509] = wkup_detector_cnt_th_6_we; + reg_we_check[510] = wkup_detector_cnt_th_7_we; + reg_we_check[511] = wkup_detector_padsel_0_gated_we; + reg_we_check[512] = wkup_detector_padsel_1_gated_we; + reg_we_check[513] = wkup_detector_padsel_2_gated_we; + reg_we_check[514] = wkup_detector_padsel_3_gated_we; + reg_we_check[515] = wkup_detector_padsel_4_gated_we; + reg_we_check[516] = wkup_detector_padsel_5_gated_we; + reg_we_check[517] = wkup_detector_padsel_6_gated_we; + reg_we_check[518] = wkup_detector_padsel_7_gated_we; + reg_we_check[519] = wkup_cause_we; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (1'b1) + addr_hit[0]: begin + reg_rdata_next[0] = '0; + end + + addr_hit[1]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_0_qs; + end + + addr_hit[2]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_1_qs; + end + + addr_hit[3]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_2_qs; + end + + addr_hit[4]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_3_qs; + end + + addr_hit[5]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_4_qs; + end + + addr_hit[6]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_5_qs; + end + + addr_hit[7]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_6_qs; + end + + addr_hit[8]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_7_qs; + end + + addr_hit[9]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_8_qs; + end + + addr_hit[10]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_9_qs; + end + + addr_hit[11]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_10_qs; + end + + addr_hit[12]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_11_qs; + end + + addr_hit[13]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_12_qs; + end + + addr_hit[14]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_13_qs; + end + + addr_hit[15]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_14_qs; + end + + addr_hit[16]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_15_qs; + end + + addr_hit[17]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_16_qs; + end + + addr_hit[18]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_17_qs; + end + + addr_hit[19]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_18_qs; + end + + addr_hit[20]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_19_qs; + end + + addr_hit[21]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_20_qs; + end + + addr_hit[22]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_21_qs; + end + + addr_hit[23]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_22_qs; + end + + addr_hit[24]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_23_qs; + end + + addr_hit[25]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_24_qs; + end + + addr_hit[26]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_25_qs; + end + + addr_hit[27]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_26_qs; + end + + addr_hit[28]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_27_qs; + end + + addr_hit[29]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_28_qs; + end + + addr_hit[30]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_29_qs; + end + + addr_hit[31]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_30_qs; + end + + addr_hit[32]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_31_qs; + end + + addr_hit[33]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_32_qs; + end + + addr_hit[34]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_33_qs; + end + + addr_hit[35]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_34_qs; + end + + addr_hit[36]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_35_qs; + end + + addr_hit[37]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_36_qs; + end + + addr_hit[38]: begin + reg_rdata_next[0] = mio_periph_insel_regwen_37_qs; + end + + addr_hit[39]: begin + reg_rdata_next[5:0] = mio_periph_insel_0_qs; + end + + addr_hit[40]: begin + reg_rdata_next[5:0] = mio_periph_insel_1_qs; + end + + addr_hit[41]: begin + reg_rdata_next[5:0] = mio_periph_insel_2_qs; + end + + addr_hit[42]: begin + reg_rdata_next[5:0] = mio_periph_insel_3_qs; + end + + addr_hit[43]: begin + reg_rdata_next[5:0] = mio_periph_insel_4_qs; + end + + addr_hit[44]: begin + reg_rdata_next[5:0] = mio_periph_insel_5_qs; + end + + addr_hit[45]: begin + reg_rdata_next[5:0] = mio_periph_insel_6_qs; + end + + addr_hit[46]: begin + reg_rdata_next[5:0] = mio_periph_insel_7_qs; + end + + addr_hit[47]: begin + reg_rdata_next[5:0] = mio_periph_insel_8_qs; + end + + addr_hit[48]: begin + reg_rdata_next[5:0] = mio_periph_insel_9_qs; + end + + addr_hit[49]: begin + reg_rdata_next[5:0] = mio_periph_insel_10_qs; + end + + addr_hit[50]: begin + reg_rdata_next[5:0] = mio_periph_insel_11_qs; + end + + addr_hit[51]: begin + reg_rdata_next[5:0] = mio_periph_insel_12_qs; + end + + addr_hit[52]: begin + reg_rdata_next[5:0] = mio_periph_insel_13_qs; + end + + addr_hit[53]: begin + reg_rdata_next[5:0] = mio_periph_insel_14_qs; + end + + addr_hit[54]: begin + reg_rdata_next[5:0] = mio_periph_insel_15_qs; + end + + addr_hit[55]: begin + reg_rdata_next[5:0] = mio_periph_insel_16_qs; + end + + addr_hit[56]: begin + reg_rdata_next[5:0] = mio_periph_insel_17_qs; + end + + addr_hit[57]: begin + reg_rdata_next[5:0] = mio_periph_insel_18_qs; + end + + addr_hit[58]: begin + reg_rdata_next[5:0] = mio_periph_insel_19_qs; + end + + addr_hit[59]: begin + reg_rdata_next[5:0] = mio_periph_insel_20_qs; + end + + addr_hit[60]: begin + reg_rdata_next[5:0] = mio_periph_insel_21_qs; + end + + addr_hit[61]: begin + reg_rdata_next[5:0] = mio_periph_insel_22_qs; + end + + addr_hit[62]: begin + reg_rdata_next[5:0] = mio_periph_insel_23_qs; + end + + addr_hit[63]: begin + reg_rdata_next[5:0] = mio_periph_insel_24_qs; + end + + addr_hit[64]: begin + reg_rdata_next[5:0] = mio_periph_insel_25_qs; + end + + addr_hit[65]: begin + reg_rdata_next[5:0] = mio_periph_insel_26_qs; + end + + addr_hit[66]: begin + reg_rdata_next[5:0] = mio_periph_insel_27_qs; + end + + addr_hit[67]: begin + reg_rdata_next[5:0] = mio_periph_insel_28_qs; + end + + addr_hit[68]: begin + reg_rdata_next[5:0] = mio_periph_insel_29_qs; + end + + addr_hit[69]: begin + reg_rdata_next[5:0] = mio_periph_insel_30_qs; + end + + addr_hit[70]: begin + reg_rdata_next[5:0] = mio_periph_insel_31_qs; + end + + addr_hit[71]: begin + reg_rdata_next[5:0] = mio_periph_insel_32_qs; + end + + addr_hit[72]: begin + reg_rdata_next[5:0] = mio_periph_insel_33_qs; + end + + addr_hit[73]: begin + reg_rdata_next[5:0] = mio_periph_insel_34_qs; + end + + addr_hit[74]: begin + reg_rdata_next[5:0] = mio_periph_insel_35_qs; + end + + addr_hit[75]: begin + reg_rdata_next[5:0] = mio_periph_insel_36_qs; + end + + addr_hit[76]: begin + reg_rdata_next[5:0] = mio_periph_insel_37_qs; + end + + addr_hit[77]: begin + reg_rdata_next[0] = mio_outsel_regwen_0_qs; + end + + addr_hit[78]: begin + reg_rdata_next[0] = mio_outsel_regwen_1_qs; + end + + addr_hit[79]: begin + reg_rdata_next[0] = mio_outsel_regwen_2_qs; + end + + addr_hit[80]: begin + reg_rdata_next[0] = mio_outsel_regwen_3_qs; + end + + addr_hit[81]: begin + reg_rdata_next[0] = mio_outsel_regwen_4_qs; + end + + addr_hit[82]: begin + reg_rdata_next[0] = mio_outsel_regwen_5_qs; + end + + addr_hit[83]: begin + reg_rdata_next[0] = mio_outsel_regwen_6_qs; + end + + addr_hit[84]: begin + reg_rdata_next[0] = mio_outsel_regwen_7_qs; + end + + addr_hit[85]: begin + reg_rdata_next[0] = mio_outsel_regwen_8_qs; + end + + addr_hit[86]: begin + reg_rdata_next[0] = mio_outsel_regwen_9_qs; + end + + addr_hit[87]: begin + reg_rdata_next[0] = mio_outsel_regwen_10_qs; + end + + addr_hit[88]: begin + reg_rdata_next[0] = mio_outsel_regwen_11_qs; + end + + addr_hit[89]: begin + reg_rdata_next[0] = mio_outsel_regwen_12_qs; + end + + addr_hit[90]: begin + reg_rdata_next[0] = mio_outsel_regwen_13_qs; + end + + addr_hit[91]: begin + reg_rdata_next[0] = mio_outsel_regwen_14_qs; + end + + addr_hit[92]: begin + reg_rdata_next[0] = mio_outsel_regwen_15_qs; + end + + addr_hit[93]: begin + reg_rdata_next[0] = mio_outsel_regwen_16_qs; + end + + addr_hit[94]: begin + reg_rdata_next[0] = mio_outsel_regwen_17_qs; + end + + addr_hit[95]: begin + reg_rdata_next[0] = mio_outsel_regwen_18_qs; + end + + addr_hit[96]: begin + reg_rdata_next[0] = mio_outsel_regwen_19_qs; + end + + addr_hit[97]: begin + reg_rdata_next[0] = mio_outsel_regwen_20_qs; + end + + addr_hit[98]: begin + reg_rdata_next[0] = mio_outsel_regwen_21_qs; + end + + addr_hit[99]: begin + reg_rdata_next[0] = mio_outsel_regwen_22_qs; + end + + addr_hit[100]: begin + reg_rdata_next[0] = mio_outsel_regwen_23_qs; + end + + addr_hit[101]: begin + reg_rdata_next[0] = mio_outsel_regwen_24_qs; + end + + addr_hit[102]: begin + reg_rdata_next[0] = mio_outsel_regwen_25_qs; + end + + addr_hit[103]: begin + reg_rdata_next[0] = mio_outsel_regwen_26_qs; + end + + addr_hit[104]: begin + reg_rdata_next[0] = mio_outsel_regwen_27_qs; + end + + addr_hit[105]: begin + reg_rdata_next[0] = mio_outsel_regwen_28_qs; + end + + addr_hit[106]: begin + reg_rdata_next[0] = mio_outsel_regwen_29_qs; + end + + addr_hit[107]: begin + reg_rdata_next[0] = mio_outsel_regwen_30_qs; + end + + addr_hit[108]: begin + reg_rdata_next[0] = mio_outsel_regwen_31_qs; + end + + addr_hit[109]: begin + reg_rdata_next[0] = mio_outsel_regwen_32_qs; + end + + addr_hit[110]: begin + reg_rdata_next[0] = mio_outsel_regwen_33_qs; + end + + addr_hit[111]: begin + reg_rdata_next[0] = mio_outsel_regwen_34_qs; + end + + addr_hit[112]: begin + reg_rdata_next[0] = mio_outsel_regwen_35_qs; + end + + addr_hit[113]: begin + reg_rdata_next[0] = mio_outsel_regwen_36_qs; + end + + addr_hit[114]: begin + reg_rdata_next[0] = mio_outsel_regwen_37_qs; + end + + addr_hit[115]: begin + reg_rdata_next[0] = mio_outsel_regwen_38_qs; + end + + addr_hit[116]: begin + reg_rdata_next[0] = mio_outsel_regwen_39_qs; + end + + addr_hit[117]: begin + reg_rdata_next[0] = mio_outsel_regwen_40_qs; + end + + addr_hit[118]: begin + reg_rdata_next[0] = mio_outsel_regwen_41_qs; + end + + addr_hit[119]: begin + reg_rdata_next[0] = mio_outsel_regwen_42_qs; + end + + addr_hit[120]: begin + reg_rdata_next[0] = mio_outsel_regwen_43_qs; + end + + addr_hit[121]: begin + reg_rdata_next[0] = mio_outsel_regwen_44_qs; + end + + addr_hit[122]: begin + reg_rdata_next[0] = mio_outsel_regwen_45_qs; + end + + addr_hit[123]: begin + reg_rdata_next[0] = mio_outsel_regwen_46_qs; + end + + addr_hit[124]: begin + reg_rdata_next[5:0] = mio_outsel_0_qs; + end + + addr_hit[125]: begin + reg_rdata_next[5:0] = mio_outsel_1_qs; + end + + addr_hit[126]: begin + reg_rdata_next[5:0] = mio_outsel_2_qs; + end + + addr_hit[127]: begin + reg_rdata_next[5:0] = mio_outsel_3_qs; + end + + addr_hit[128]: begin + reg_rdata_next[5:0] = mio_outsel_4_qs; + end + + addr_hit[129]: begin + reg_rdata_next[5:0] = mio_outsel_5_qs; + end + + addr_hit[130]: begin + reg_rdata_next[5:0] = mio_outsel_6_qs; + end + + addr_hit[131]: begin + reg_rdata_next[5:0] = mio_outsel_7_qs; + end + + addr_hit[132]: begin + reg_rdata_next[5:0] = mio_outsel_8_qs; + end + + addr_hit[133]: begin + reg_rdata_next[5:0] = mio_outsel_9_qs; + end + + addr_hit[134]: begin + reg_rdata_next[5:0] = mio_outsel_10_qs; + end + + addr_hit[135]: begin + reg_rdata_next[5:0] = mio_outsel_11_qs; + end + + addr_hit[136]: begin + reg_rdata_next[5:0] = mio_outsel_12_qs; + end + + addr_hit[137]: begin + reg_rdata_next[5:0] = mio_outsel_13_qs; + end + + addr_hit[138]: begin + reg_rdata_next[5:0] = mio_outsel_14_qs; + end + + addr_hit[139]: begin + reg_rdata_next[5:0] = mio_outsel_15_qs; + end + + addr_hit[140]: begin + reg_rdata_next[5:0] = mio_outsel_16_qs; + end + + addr_hit[141]: begin + reg_rdata_next[5:0] = mio_outsel_17_qs; + end + + addr_hit[142]: begin + reg_rdata_next[5:0] = mio_outsel_18_qs; + end + + addr_hit[143]: begin + reg_rdata_next[5:0] = mio_outsel_19_qs; + end + + addr_hit[144]: begin + reg_rdata_next[5:0] = mio_outsel_20_qs; + end + + addr_hit[145]: begin + reg_rdata_next[5:0] = mio_outsel_21_qs; + end + + addr_hit[146]: begin + reg_rdata_next[5:0] = mio_outsel_22_qs; + end + + addr_hit[147]: begin + reg_rdata_next[5:0] = mio_outsel_23_qs; + end + + addr_hit[148]: begin + reg_rdata_next[5:0] = mio_outsel_24_qs; + end + + addr_hit[149]: begin + reg_rdata_next[5:0] = mio_outsel_25_qs; + end + + addr_hit[150]: begin + reg_rdata_next[5:0] = mio_outsel_26_qs; + end + + addr_hit[151]: begin + reg_rdata_next[5:0] = mio_outsel_27_qs; + end + + addr_hit[152]: begin + reg_rdata_next[5:0] = mio_outsel_28_qs; + end + + addr_hit[153]: begin + reg_rdata_next[5:0] = mio_outsel_29_qs; + end + + addr_hit[154]: begin + reg_rdata_next[5:0] = mio_outsel_30_qs; + end + + addr_hit[155]: begin + reg_rdata_next[5:0] = mio_outsel_31_qs; + end + + addr_hit[156]: begin + reg_rdata_next[5:0] = mio_outsel_32_qs; + end + + addr_hit[157]: begin + reg_rdata_next[5:0] = mio_outsel_33_qs; + end + + addr_hit[158]: begin + reg_rdata_next[5:0] = mio_outsel_34_qs; + end + + addr_hit[159]: begin + reg_rdata_next[5:0] = mio_outsel_35_qs; + end + + addr_hit[160]: begin + reg_rdata_next[5:0] = mio_outsel_36_qs; + end + + addr_hit[161]: begin + reg_rdata_next[5:0] = mio_outsel_37_qs; + end + + addr_hit[162]: begin + reg_rdata_next[5:0] = mio_outsel_38_qs; + end + + addr_hit[163]: begin + reg_rdata_next[5:0] = mio_outsel_39_qs; + end + + addr_hit[164]: begin + reg_rdata_next[5:0] = mio_outsel_40_qs; + end + + addr_hit[165]: begin + reg_rdata_next[5:0] = mio_outsel_41_qs; + end + + addr_hit[166]: begin + reg_rdata_next[5:0] = mio_outsel_42_qs; + end + + addr_hit[167]: begin + reg_rdata_next[5:0] = mio_outsel_43_qs; + end + + addr_hit[168]: begin + reg_rdata_next[5:0] = mio_outsel_44_qs; + end + + addr_hit[169]: begin + reg_rdata_next[5:0] = mio_outsel_45_qs; + end + + addr_hit[170]: begin + reg_rdata_next[5:0] = mio_outsel_46_qs; + end + + addr_hit[171]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_0_qs; + end + + addr_hit[172]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_1_qs; + end + + addr_hit[173]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_2_qs; + end + + addr_hit[174]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_3_qs; + end + + addr_hit[175]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_4_qs; + end + + addr_hit[176]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_5_qs; + end + + addr_hit[177]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_6_qs; + end + + addr_hit[178]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_7_qs; + end + + addr_hit[179]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_8_qs; + end + + addr_hit[180]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_9_qs; + end + + addr_hit[181]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_10_qs; + end + + addr_hit[182]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_11_qs; + end + + addr_hit[183]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_12_qs; + end + + addr_hit[184]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_13_qs; + end + + addr_hit[185]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_14_qs; + end + + addr_hit[186]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_15_qs; + end + + addr_hit[187]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_16_qs; + end + + addr_hit[188]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_17_qs; + end + + addr_hit[189]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_18_qs; + end + + addr_hit[190]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_19_qs; + end + + addr_hit[191]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_20_qs; + end + + addr_hit[192]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_21_qs; + end + + addr_hit[193]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_22_qs; + end + + addr_hit[194]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_23_qs; + end + + addr_hit[195]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_24_qs; + end + + addr_hit[196]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_25_qs; + end + + addr_hit[197]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_26_qs; + end + + addr_hit[198]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_27_qs; + end + + addr_hit[199]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_28_qs; + end + + addr_hit[200]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_29_qs; + end + + addr_hit[201]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_30_qs; + end + + addr_hit[202]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_31_qs; + end + + addr_hit[203]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_32_qs; + end + + addr_hit[204]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_33_qs; + end + + addr_hit[205]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_34_qs; + end + + addr_hit[206]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_35_qs; + end + + addr_hit[207]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_36_qs; + end + + addr_hit[208]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_37_qs; + end + + addr_hit[209]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_38_qs; + end + + addr_hit[210]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_39_qs; + end + + addr_hit[211]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_40_qs; + end + + addr_hit[212]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_41_qs; + end + + addr_hit[213]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_42_qs; + end + + addr_hit[214]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_43_qs; + end + + addr_hit[215]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_44_qs; + end + + addr_hit[216]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_45_qs; + end + + addr_hit[217]: begin + reg_rdata_next[0] = mio_pad_attr_regwen_46_qs; + end + + addr_hit[218]: begin + reg_rdata_next[0] = mio_pad_attr_0_invert_0_qs; + reg_rdata_next[1] = mio_pad_attr_0_virtual_od_en_0_qs; + reg_rdata_next[2] = mio_pad_attr_0_pull_en_0_qs; + reg_rdata_next[3] = mio_pad_attr_0_pull_select_0_qs; + reg_rdata_next[4] = mio_pad_attr_0_keeper_en_0_qs; + reg_rdata_next[5] = mio_pad_attr_0_schmitt_en_0_qs; + reg_rdata_next[6] = mio_pad_attr_0_od_en_0_qs; + reg_rdata_next[7] = mio_pad_attr_0_input_disable_0_qs; + reg_rdata_next[17:16] = mio_pad_attr_0_slew_rate_0_qs; + reg_rdata_next[23:20] = mio_pad_attr_0_drive_strength_0_qs; + end + + addr_hit[219]: begin + reg_rdata_next[0] = mio_pad_attr_1_invert_1_qs; + reg_rdata_next[1] = mio_pad_attr_1_virtual_od_en_1_qs; + reg_rdata_next[2] = mio_pad_attr_1_pull_en_1_qs; + reg_rdata_next[3] = mio_pad_attr_1_pull_select_1_qs; + reg_rdata_next[4] = mio_pad_attr_1_keeper_en_1_qs; + reg_rdata_next[5] = mio_pad_attr_1_schmitt_en_1_qs; + reg_rdata_next[6] = mio_pad_attr_1_od_en_1_qs; + reg_rdata_next[7] = mio_pad_attr_1_input_disable_1_qs; + reg_rdata_next[17:16] = mio_pad_attr_1_slew_rate_1_qs; + reg_rdata_next[23:20] = mio_pad_attr_1_drive_strength_1_qs; + end + + addr_hit[220]: begin + reg_rdata_next[0] = mio_pad_attr_2_invert_2_qs; + reg_rdata_next[1] = mio_pad_attr_2_virtual_od_en_2_qs; + reg_rdata_next[2] = mio_pad_attr_2_pull_en_2_qs; + reg_rdata_next[3] = mio_pad_attr_2_pull_select_2_qs; + reg_rdata_next[4] = mio_pad_attr_2_keeper_en_2_qs; + reg_rdata_next[5] = mio_pad_attr_2_schmitt_en_2_qs; + reg_rdata_next[6] = mio_pad_attr_2_od_en_2_qs; + reg_rdata_next[7] = mio_pad_attr_2_input_disable_2_qs; + reg_rdata_next[17:16] = mio_pad_attr_2_slew_rate_2_qs; + reg_rdata_next[23:20] = mio_pad_attr_2_drive_strength_2_qs; + end + + addr_hit[221]: begin + reg_rdata_next[0] = mio_pad_attr_3_invert_3_qs; + reg_rdata_next[1] = mio_pad_attr_3_virtual_od_en_3_qs; + reg_rdata_next[2] = mio_pad_attr_3_pull_en_3_qs; + reg_rdata_next[3] = mio_pad_attr_3_pull_select_3_qs; + reg_rdata_next[4] = mio_pad_attr_3_keeper_en_3_qs; + reg_rdata_next[5] = mio_pad_attr_3_schmitt_en_3_qs; + reg_rdata_next[6] = mio_pad_attr_3_od_en_3_qs; + reg_rdata_next[7] = mio_pad_attr_3_input_disable_3_qs; + reg_rdata_next[17:16] = mio_pad_attr_3_slew_rate_3_qs; + reg_rdata_next[23:20] = mio_pad_attr_3_drive_strength_3_qs; + end + + addr_hit[222]: begin + reg_rdata_next[0] = mio_pad_attr_4_invert_4_qs; + reg_rdata_next[1] = mio_pad_attr_4_virtual_od_en_4_qs; + reg_rdata_next[2] = mio_pad_attr_4_pull_en_4_qs; + reg_rdata_next[3] = mio_pad_attr_4_pull_select_4_qs; + reg_rdata_next[4] = mio_pad_attr_4_keeper_en_4_qs; + reg_rdata_next[5] = mio_pad_attr_4_schmitt_en_4_qs; + reg_rdata_next[6] = mio_pad_attr_4_od_en_4_qs; + reg_rdata_next[7] = mio_pad_attr_4_input_disable_4_qs; + reg_rdata_next[17:16] = mio_pad_attr_4_slew_rate_4_qs; + reg_rdata_next[23:20] = mio_pad_attr_4_drive_strength_4_qs; + end + + addr_hit[223]: begin + reg_rdata_next[0] = mio_pad_attr_5_invert_5_qs; + reg_rdata_next[1] = mio_pad_attr_5_virtual_od_en_5_qs; + reg_rdata_next[2] = mio_pad_attr_5_pull_en_5_qs; + reg_rdata_next[3] = mio_pad_attr_5_pull_select_5_qs; + reg_rdata_next[4] = mio_pad_attr_5_keeper_en_5_qs; + reg_rdata_next[5] = mio_pad_attr_5_schmitt_en_5_qs; + reg_rdata_next[6] = mio_pad_attr_5_od_en_5_qs; + reg_rdata_next[7] = mio_pad_attr_5_input_disable_5_qs; + reg_rdata_next[17:16] = mio_pad_attr_5_slew_rate_5_qs; + reg_rdata_next[23:20] = mio_pad_attr_5_drive_strength_5_qs; + end + + addr_hit[224]: begin + reg_rdata_next[0] = mio_pad_attr_6_invert_6_qs; + reg_rdata_next[1] = mio_pad_attr_6_virtual_od_en_6_qs; + reg_rdata_next[2] = mio_pad_attr_6_pull_en_6_qs; + reg_rdata_next[3] = mio_pad_attr_6_pull_select_6_qs; + reg_rdata_next[4] = mio_pad_attr_6_keeper_en_6_qs; + reg_rdata_next[5] = mio_pad_attr_6_schmitt_en_6_qs; + reg_rdata_next[6] = mio_pad_attr_6_od_en_6_qs; + reg_rdata_next[7] = mio_pad_attr_6_input_disable_6_qs; + reg_rdata_next[17:16] = mio_pad_attr_6_slew_rate_6_qs; + reg_rdata_next[23:20] = mio_pad_attr_6_drive_strength_6_qs; + end + + addr_hit[225]: begin + reg_rdata_next[0] = mio_pad_attr_7_invert_7_qs; + reg_rdata_next[1] = mio_pad_attr_7_virtual_od_en_7_qs; + reg_rdata_next[2] = mio_pad_attr_7_pull_en_7_qs; + reg_rdata_next[3] = mio_pad_attr_7_pull_select_7_qs; + reg_rdata_next[4] = mio_pad_attr_7_keeper_en_7_qs; + reg_rdata_next[5] = mio_pad_attr_7_schmitt_en_7_qs; + reg_rdata_next[6] = mio_pad_attr_7_od_en_7_qs; + reg_rdata_next[7] = mio_pad_attr_7_input_disable_7_qs; + reg_rdata_next[17:16] = mio_pad_attr_7_slew_rate_7_qs; + reg_rdata_next[23:20] = mio_pad_attr_7_drive_strength_7_qs; + end + + addr_hit[226]: begin + reg_rdata_next[0] = mio_pad_attr_8_invert_8_qs; + reg_rdata_next[1] = mio_pad_attr_8_virtual_od_en_8_qs; + reg_rdata_next[2] = mio_pad_attr_8_pull_en_8_qs; + reg_rdata_next[3] = mio_pad_attr_8_pull_select_8_qs; + reg_rdata_next[4] = mio_pad_attr_8_keeper_en_8_qs; + reg_rdata_next[5] = mio_pad_attr_8_schmitt_en_8_qs; + reg_rdata_next[6] = mio_pad_attr_8_od_en_8_qs; + reg_rdata_next[7] = mio_pad_attr_8_input_disable_8_qs; + reg_rdata_next[17:16] = mio_pad_attr_8_slew_rate_8_qs; + reg_rdata_next[23:20] = mio_pad_attr_8_drive_strength_8_qs; + end + + addr_hit[227]: begin + reg_rdata_next[0] = mio_pad_attr_9_invert_9_qs; + reg_rdata_next[1] = mio_pad_attr_9_virtual_od_en_9_qs; + reg_rdata_next[2] = mio_pad_attr_9_pull_en_9_qs; + reg_rdata_next[3] = mio_pad_attr_9_pull_select_9_qs; + reg_rdata_next[4] = mio_pad_attr_9_keeper_en_9_qs; + reg_rdata_next[5] = mio_pad_attr_9_schmitt_en_9_qs; + reg_rdata_next[6] = mio_pad_attr_9_od_en_9_qs; + reg_rdata_next[7] = mio_pad_attr_9_input_disable_9_qs; + reg_rdata_next[17:16] = mio_pad_attr_9_slew_rate_9_qs; + reg_rdata_next[23:20] = mio_pad_attr_9_drive_strength_9_qs; + end + + addr_hit[228]: begin + reg_rdata_next[0] = mio_pad_attr_10_invert_10_qs; + reg_rdata_next[1] = mio_pad_attr_10_virtual_od_en_10_qs; + reg_rdata_next[2] = mio_pad_attr_10_pull_en_10_qs; + reg_rdata_next[3] = mio_pad_attr_10_pull_select_10_qs; + reg_rdata_next[4] = mio_pad_attr_10_keeper_en_10_qs; + reg_rdata_next[5] = mio_pad_attr_10_schmitt_en_10_qs; + reg_rdata_next[6] = mio_pad_attr_10_od_en_10_qs; + reg_rdata_next[7] = mio_pad_attr_10_input_disable_10_qs; + reg_rdata_next[17:16] = mio_pad_attr_10_slew_rate_10_qs; + reg_rdata_next[23:20] = mio_pad_attr_10_drive_strength_10_qs; + end + + addr_hit[229]: begin + reg_rdata_next[0] = mio_pad_attr_11_invert_11_qs; + reg_rdata_next[1] = mio_pad_attr_11_virtual_od_en_11_qs; + reg_rdata_next[2] = mio_pad_attr_11_pull_en_11_qs; + reg_rdata_next[3] = mio_pad_attr_11_pull_select_11_qs; + reg_rdata_next[4] = mio_pad_attr_11_keeper_en_11_qs; + reg_rdata_next[5] = mio_pad_attr_11_schmitt_en_11_qs; + reg_rdata_next[6] = mio_pad_attr_11_od_en_11_qs; + reg_rdata_next[7] = mio_pad_attr_11_input_disable_11_qs; + reg_rdata_next[17:16] = mio_pad_attr_11_slew_rate_11_qs; + reg_rdata_next[23:20] = mio_pad_attr_11_drive_strength_11_qs; + end + + addr_hit[230]: begin + reg_rdata_next[0] = mio_pad_attr_12_invert_12_qs; + reg_rdata_next[1] = mio_pad_attr_12_virtual_od_en_12_qs; + reg_rdata_next[2] = mio_pad_attr_12_pull_en_12_qs; + reg_rdata_next[3] = mio_pad_attr_12_pull_select_12_qs; + reg_rdata_next[4] = mio_pad_attr_12_keeper_en_12_qs; + reg_rdata_next[5] = mio_pad_attr_12_schmitt_en_12_qs; + reg_rdata_next[6] = mio_pad_attr_12_od_en_12_qs; + reg_rdata_next[7] = mio_pad_attr_12_input_disable_12_qs; + reg_rdata_next[17:16] = mio_pad_attr_12_slew_rate_12_qs; + reg_rdata_next[23:20] = mio_pad_attr_12_drive_strength_12_qs; + end + + addr_hit[231]: begin + reg_rdata_next[0] = mio_pad_attr_13_invert_13_qs; + reg_rdata_next[1] = mio_pad_attr_13_virtual_od_en_13_qs; + reg_rdata_next[2] = mio_pad_attr_13_pull_en_13_qs; + reg_rdata_next[3] = mio_pad_attr_13_pull_select_13_qs; + reg_rdata_next[4] = mio_pad_attr_13_keeper_en_13_qs; + reg_rdata_next[5] = mio_pad_attr_13_schmitt_en_13_qs; + reg_rdata_next[6] = mio_pad_attr_13_od_en_13_qs; + reg_rdata_next[7] = mio_pad_attr_13_input_disable_13_qs; + reg_rdata_next[17:16] = mio_pad_attr_13_slew_rate_13_qs; + reg_rdata_next[23:20] = mio_pad_attr_13_drive_strength_13_qs; + end + + addr_hit[232]: begin + reg_rdata_next[0] = mio_pad_attr_14_invert_14_qs; + reg_rdata_next[1] = mio_pad_attr_14_virtual_od_en_14_qs; + reg_rdata_next[2] = mio_pad_attr_14_pull_en_14_qs; + reg_rdata_next[3] = mio_pad_attr_14_pull_select_14_qs; + reg_rdata_next[4] = mio_pad_attr_14_keeper_en_14_qs; + reg_rdata_next[5] = mio_pad_attr_14_schmitt_en_14_qs; + reg_rdata_next[6] = mio_pad_attr_14_od_en_14_qs; + reg_rdata_next[7] = mio_pad_attr_14_input_disable_14_qs; + reg_rdata_next[17:16] = mio_pad_attr_14_slew_rate_14_qs; + reg_rdata_next[23:20] = mio_pad_attr_14_drive_strength_14_qs; + end + + addr_hit[233]: begin + reg_rdata_next[0] = mio_pad_attr_15_invert_15_qs; + reg_rdata_next[1] = mio_pad_attr_15_virtual_od_en_15_qs; + reg_rdata_next[2] = mio_pad_attr_15_pull_en_15_qs; + reg_rdata_next[3] = mio_pad_attr_15_pull_select_15_qs; + reg_rdata_next[4] = mio_pad_attr_15_keeper_en_15_qs; + reg_rdata_next[5] = mio_pad_attr_15_schmitt_en_15_qs; + reg_rdata_next[6] = mio_pad_attr_15_od_en_15_qs; + reg_rdata_next[7] = mio_pad_attr_15_input_disable_15_qs; + reg_rdata_next[17:16] = mio_pad_attr_15_slew_rate_15_qs; + reg_rdata_next[23:20] = mio_pad_attr_15_drive_strength_15_qs; + end + + addr_hit[234]: begin + reg_rdata_next[0] = mio_pad_attr_16_invert_16_qs; + reg_rdata_next[1] = mio_pad_attr_16_virtual_od_en_16_qs; + reg_rdata_next[2] = mio_pad_attr_16_pull_en_16_qs; + reg_rdata_next[3] = mio_pad_attr_16_pull_select_16_qs; + reg_rdata_next[4] = mio_pad_attr_16_keeper_en_16_qs; + reg_rdata_next[5] = mio_pad_attr_16_schmitt_en_16_qs; + reg_rdata_next[6] = mio_pad_attr_16_od_en_16_qs; + reg_rdata_next[7] = mio_pad_attr_16_input_disable_16_qs; + reg_rdata_next[17:16] = mio_pad_attr_16_slew_rate_16_qs; + reg_rdata_next[23:20] = mio_pad_attr_16_drive_strength_16_qs; + end + + addr_hit[235]: begin + reg_rdata_next[0] = mio_pad_attr_17_invert_17_qs; + reg_rdata_next[1] = mio_pad_attr_17_virtual_od_en_17_qs; + reg_rdata_next[2] = mio_pad_attr_17_pull_en_17_qs; + reg_rdata_next[3] = mio_pad_attr_17_pull_select_17_qs; + reg_rdata_next[4] = mio_pad_attr_17_keeper_en_17_qs; + reg_rdata_next[5] = mio_pad_attr_17_schmitt_en_17_qs; + reg_rdata_next[6] = mio_pad_attr_17_od_en_17_qs; + reg_rdata_next[7] = mio_pad_attr_17_input_disable_17_qs; + reg_rdata_next[17:16] = mio_pad_attr_17_slew_rate_17_qs; + reg_rdata_next[23:20] = mio_pad_attr_17_drive_strength_17_qs; + end + + addr_hit[236]: begin + reg_rdata_next[0] = mio_pad_attr_18_invert_18_qs; + reg_rdata_next[1] = mio_pad_attr_18_virtual_od_en_18_qs; + reg_rdata_next[2] = mio_pad_attr_18_pull_en_18_qs; + reg_rdata_next[3] = mio_pad_attr_18_pull_select_18_qs; + reg_rdata_next[4] = mio_pad_attr_18_keeper_en_18_qs; + reg_rdata_next[5] = mio_pad_attr_18_schmitt_en_18_qs; + reg_rdata_next[6] = mio_pad_attr_18_od_en_18_qs; + reg_rdata_next[7] = mio_pad_attr_18_input_disable_18_qs; + reg_rdata_next[17:16] = mio_pad_attr_18_slew_rate_18_qs; + reg_rdata_next[23:20] = mio_pad_attr_18_drive_strength_18_qs; + end + + addr_hit[237]: begin + reg_rdata_next[0] = mio_pad_attr_19_invert_19_qs; + reg_rdata_next[1] = mio_pad_attr_19_virtual_od_en_19_qs; + reg_rdata_next[2] = mio_pad_attr_19_pull_en_19_qs; + reg_rdata_next[3] = mio_pad_attr_19_pull_select_19_qs; + reg_rdata_next[4] = mio_pad_attr_19_keeper_en_19_qs; + reg_rdata_next[5] = mio_pad_attr_19_schmitt_en_19_qs; + reg_rdata_next[6] = mio_pad_attr_19_od_en_19_qs; + reg_rdata_next[7] = mio_pad_attr_19_input_disable_19_qs; + reg_rdata_next[17:16] = mio_pad_attr_19_slew_rate_19_qs; + reg_rdata_next[23:20] = mio_pad_attr_19_drive_strength_19_qs; + end + + addr_hit[238]: begin + reg_rdata_next[0] = mio_pad_attr_20_invert_20_qs; + reg_rdata_next[1] = mio_pad_attr_20_virtual_od_en_20_qs; + reg_rdata_next[2] = mio_pad_attr_20_pull_en_20_qs; + reg_rdata_next[3] = mio_pad_attr_20_pull_select_20_qs; + reg_rdata_next[4] = mio_pad_attr_20_keeper_en_20_qs; + reg_rdata_next[5] = mio_pad_attr_20_schmitt_en_20_qs; + reg_rdata_next[6] = mio_pad_attr_20_od_en_20_qs; + reg_rdata_next[7] = mio_pad_attr_20_input_disable_20_qs; + reg_rdata_next[17:16] = mio_pad_attr_20_slew_rate_20_qs; + reg_rdata_next[23:20] = mio_pad_attr_20_drive_strength_20_qs; + end + + addr_hit[239]: begin + reg_rdata_next[0] = mio_pad_attr_21_invert_21_qs; + reg_rdata_next[1] = mio_pad_attr_21_virtual_od_en_21_qs; + reg_rdata_next[2] = mio_pad_attr_21_pull_en_21_qs; + reg_rdata_next[3] = mio_pad_attr_21_pull_select_21_qs; + reg_rdata_next[4] = mio_pad_attr_21_keeper_en_21_qs; + reg_rdata_next[5] = mio_pad_attr_21_schmitt_en_21_qs; + reg_rdata_next[6] = mio_pad_attr_21_od_en_21_qs; + reg_rdata_next[7] = mio_pad_attr_21_input_disable_21_qs; + reg_rdata_next[17:16] = mio_pad_attr_21_slew_rate_21_qs; + reg_rdata_next[23:20] = mio_pad_attr_21_drive_strength_21_qs; + end + + addr_hit[240]: begin + reg_rdata_next[0] = mio_pad_attr_22_invert_22_qs; + reg_rdata_next[1] = mio_pad_attr_22_virtual_od_en_22_qs; + reg_rdata_next[2] = mio_pad_attr_22_pull_en_22_qs; + reg_rdata_next[3] = mio_pad_attr_22_pull_select_22_qs; + reg_rdata_next[4] = mio_pad_attr_22_keeper_en_22_qs; + reg_rdata_next[5] = mio_pad_attr_22_schmitt_en_22_qs; + reg_rdata_next[6] = mio_pad_attr_22_od_en_22_qs; + reg_rdata_next[7] = mio_pad_attr_22_input_disable_22_qs; + reg_rdata_next[17:16] = mio_pad_attr_22_slew_rate_22_qs; + reg_rdata_next[23:20] = mio_pad_attr_22_drive_strength_22_qs; + end + + addr_hit[241]: begin + reg_rdata_next[0] = mio_pad_attr_23_invert_23_qs; + reg_rdata_next[1] = mio_pad_attr_23_virtual_od_en_23_qs; + reg_rdata_next[2] = mio_pad_attr_23_pull_en_23_qs; + reg_rdata_next[3] = mio_pad_attr_23_pull_select_23_qs; + reg_rdata_next[4] = mio_pad_attr_23_keeper_en_23_qs; + reg_rdata_next[5] = mio_pad_attr_23_schmitt_en_23_qs; + reg_rdata_next[6] = mio_pad_attr_23_od_en_23_qs; + reg_rdata_next[7] = mio_pad_attr_23_input_disable_23_qs; + reg_rdata_next[17:16] = mio_pad_attr_23_slew_rate_23_qs; + reg_rdata_next[23:20] = mio_pad_attr_23_drive_strength_23_qs; + end + + addr_hit[242]: begin + reg_rdata_next[0] = mio_pad_attr_24_invert_24_qs; + reg_rdata_next[1] = mio_pad_attr_24_virtual_od_en_24_qs; + reg_rdata_next[2] = mio_pad_attr_24_pull_en_24_qs; + reg_rdata_next[3] = mio_pad_attr_24_pull_select_24_qs; + reg_rdata_next[4] = mio_pad_attr_24_keeper_en_24_qs; + reg_rdata_next[5] = mio_pad_attr_24_schmitt_en_24_qs; + reg_rdata_next[6] = mio_pad_attr_24_od_en_24_qs; + reg_rdata_next[7] = mio_pad_attr_24_input_disable_24_qs; + reg_rdata_next[17:16] = mio_pad_attr_24_slew_rate_24_qs; + reg_rdata_next[23:20] = mio_pad_attr_24_drive_strength_24_qs; + end + + addr_hit[243]: begin + reg_rdata_next[0] = mio_pad_attr_25_invert_25_qs; + reg_rdata_next[1] = mio_pad_attr_25_virtual_od_en_25_qs; + reg_rdata_next[2] = mio_pad_attr_25_pull_en_25_qs; + reg_rdata_next[3] = mio_pad_attr_25_pull_select_25_qs; + reg_rdata_next[4] = mio_pad_attr_25_keeper_en_25_qs; + reg_rdata_next[5] = mio_pad_attr_25_schmitt_en_25_qs; + reg_rdata_next[6] = mio_pad_attr_25_od_en_25_qs; + reg_rdata_next[7] = mio_pad_attr_25_input_disable_25_qs; + reg_rdata_next[17:16] = mio_pad_attr_25_slew_rate_25_qs; + reg_rdata_next[23:20] = mio_pad_attr_25_drive_strength_25_qs; + end + + addr_hit[244]: begin + reg_rdata_next[0] = mio_pad_attr_26_invert_26_qs; + reg_rdata_next[1] = mio_pad_attr_26_virtual_od_en_26_qs; + reg_rdata_next[2] = mio_pad_attr_26_pull_en_26_qs; + reg_rdata_next[3] = mio_pad_attr_26_pull_select_26_qs; + reg_rdata_next[4] = mio_pad_attr_26_keeper_en_26_qs; + reg_rdata_next[5] = mio_pad_attr_26_schmitt_en_26_qs; + reg_rdata_next[6] = mio_pad_attr_26_od_en_26_qs; + reg_rdata_next[7] = mio_pad_attr_26_input_disable_26_qs; + reg_rdata_next[17:16] = mio_pad_attr_26_slew_rate_26_qs; + reg_rdata_next[23:20] = mio_pad_attr_26_drive_strength_26_qs; + end + + addr_hit[245]: begin + reg_rdata_next[0] = mio_pad_attr_27_invert_27_qs; + reg_rdata_next[1] = mio_pad_attr_27_virtual_od_en_27_qs; + reg_rdata_next[2] = mio_pad_attr_27_pull_en_27_qs; + reg_rdata_next[3] = mio_pad_attr_27_pull_select_27_qs; + reg_rdata_next[4] = mio_pad_attr_27_keeper_en_27_qs; + reg_rdata_next[5] = mio_pad_attr_27_schmitt_en_27_qs; + reg_rdata_next[6] = mio_pad_attr_27_od_en_27_qs; + reg_rdata_next[7] = mio_pad_attr_27_input_disable_27_qs; + reg_rdata_next[17:16] = mio_pad_attr_27_slew_rate_27_qs; + reg_rdata_next[23:20] = mio_pad_attr_27_drive_strength_27_qs; + end + + addr_hit[246]: begin + reg_rdata_next[0] = mio_pad_attr_28_invert_28_qs; + reg_rdata_next[1] = mio_pad_attr_28_virtual_od_en_28_qs; + reg_rdata_next[2] = mio_pad_attr_28_pull_en_28_qs; + reg_rdata_next[3] = mio_pad_attr_28_pull_select_28_qs; + reg_rdata_next[4] = mio_pad_attr_28_keeper_en_28_qs; + reg_rdata_next[5] = mio_pad_attr_28_schmitt_en_28_qs; + reg_rdata_next[6] = mio_pad_attr_28_od_en_28_qs; + reg_rdata_next[7] = mio_pad_attr_28_input_disable_28_qs; + reg_rdata_next[17:16] = mio_pad_attr_28_slew_rate_28_qs; + reg_rdata_next[23:20] = mio_pad_attr_28_drive_strength_28_qs; + end + + addr_hit[247]: begin + reg_rdata_next[0] = mio_pad_attr_29_invert_29_qs; + reg_rdata_next[1] = mio_pad_attr_29_virtual_od_en_29_qs; + reg_rdata_next[2] = mio_pad_attr_29_pull_en_29_qs; + reg_rdata_next[3] = mio_pad_attr_29_pull_select_29_qs; + reg_rdata_next[4] = mio_pad_attr_29_keeper_en_29_qs; + reg_rdata_next[5] = mio_pad_attr_29_schmitt_en_29_qs; + reg_rdata_next[6] = mio_pad_attr_29_od_en_29_qs; + reg_rdata_next[7] = mio_pad_attr_29_input_disable_29_qs; + reg_rdata_next[17:16] = mio_pad_attr_29_slew_rate_29_qs; + reg_rdata_next[23:20] = mio_pad_attr_29_drive_strength_29_qs; + end + + addr_hit[248]: begin + reg_rdata_next[0] = mio_pad_attr_30_invert_30_qs; + reg_rdata_next[1] = mio_pad_attr_30_virtual_od_en_30_qs; + reg_rdata_next[2] = mio_pad_attr_30_pull_en_30_qs; + reg_rdata_next[3] = mio_pad_attr_30_pull_select_30_qs; + reg_rdata_next[4] = mio_pad_attr_30_keeper_en_30_qs; + reg_rdata_next[5] = mio_pad_attr_30_schmitt_en_30_qs; + reg_rdata_next[6] = mio_pad_attr_30_od_en_30_qs; + reg_rdata_next[7] = mio_pad_attr_30_input_disable_30_qs; + reg_rdata_next[17:16] = mio_pad_attr_30_slew_rate_30_qs; + reg_rdata_next[23:20] = mio_pad_attr_30_drive_strength_30_qs; + end + + addr_hit[249]: begin + reg_rdata_next[0] = mio_pad_attr_31_invert_31_qs; + reg_rdata_next[1] = mio_pad_attr_31_virtual_od_en_31_qs; + reg_rdata_next[2] = mio_pad_attr_31_pull_en_31_qs; + reg_rdata_next[3] = mio_pad_attr_31_pull_select_31_qs; + reg_rdata_next[4] = mio_pad_attr_31_keeper_en_31_qs; + reg_rdata_next[5] = mio_pad_attr_31_schmitt_en_31_qs; + reg_rdata_next[6] = mio_pad_attr_31_od_en_31_qs; + reg_rdata_next[7] = mio_pad_attr_31_input_disable_31_qs; + reg_rdata_next[17:16] = mio_pad_attr_31_slew_rate_31_qs; + reg_rdata_next[23:20] = mio_pad_attr_31_drive_strength_31_qs; + end + + addr_hit[250]: begin + reg_rdata_next[0] = mio_pad_attr_32_invert_32_qs; + reg_rdata_next[1] = mio_pad_attr_32_virtual_od_en_32_qs; + reg_rdata_next[2] = mio_pad_attr_32_pull_en_32_qs; + reg_rdata_next[3] = mio_pad_attr_32_pull_select_32_qs; + reg_rdata_next[4] = mio_pad_attr_32_keeper_en_32_qs; + reg_rdata_next[5] = mio_pad_attr_32_schmitt_en_32_qs; + reg_rdata_next[6] = mio_pad_attr_32_od_en_32_qs; + reg_rdata_next[7] = mio_pad_attr_32_input_disable_32_qs; + reg_rdata_next[17:16] = mio_pad_attr_32_slew_rate_32_qs; + reg_rdata_next[23:20] = mio_pad_attr_32_drive_strength_32_qs; + end + + addr_hit[251]: begin + reg_rdata_next[0] = mio_pad_attr_33_invert_33_qs; + reg_rdata_next[1] = mio_pad_attr_33_virtual_od_en_33_qs; + reg_rdata_next[2] = mio_pad_attr_33_pull_en_33_qs; + reg_rdata_next[3] = mio_pad_attr_33_pull_select_33_qs; + reg_rdata_next[4] = mio_pad_attr_33_keeper_en_33_qs; + reg_rdata_next[5] = mio_pad_attr_33_schmitt_en_33_qs; + reg_rdata_next[6] = mio_pad_attr_33_od_en_33_qs; + reg_rdata_next[7] = mio_pad_attr_33_input_disable_33_qs; + reg_rdata_next[17:16] = mio_pad_attr_33_slew_rate_33_qs; + reg_rdata_next[23:20] = mio_pad_attr_33_drive_strength_33_qs; + end + + addr_hit[252]: begin + reg_rdata_next[0] = mio_pad_attr_34_invert_34_qs; + reg_rdata_next[1] = mio_pad_attr_34_virtual_od_en_34_qs; + reg_rdata_next[2] = mio_pad_attr_34_pull_en_34_qs; + reg_rdata_next[3] = mio_pad_attr_34_pull_select_34_qs; + reg_rdata_next[4] = mio_pad_attr_34_keeper_en_34_qs; + reg_rdata_next[5] = mio_pad_attr_34_schmitt_en_34_qs; + reg_rdata_next[6] = mio_pad_attr_34_od_en_34_qs; + reg_rdata_next[7] = mio_pad_attr_34_input_disable_34_qs; + reg_rdata_next[17:16] = mio_pad_attr_34_slew_rate_34_qs; + reg_rdata_next[23:20] = mio_pad_attr_34_drive_strength_34_qs; + end + + addr_hit[253]: begin + reg_rdata_next[0] = mio_pad_attr_35_invert_35_qs; + reg_rdata_next[1] = mio_pad_attr_35_virtual_od_en_35_qs; + reg_rdata_next[2] = mio_pad_attr_35_pull_en_35_qs; + reg_rdata_next[3] = mio_pad_attr_35_pull_select_35_qs; + reg_rdata_next[4] = mio_pad_attr_35_keeper_en_35_qs; + reg_rdata_next[5] = mio_pad_attr_35_schmitt_en_35_qs; + reg_rdata_next[6] = mio_pad_attr_35_od_en_35_qs; + reg_rdata_next[7] = mio_pad_attr_35_input_disable_35_qs; + reg_rdata_next[17:16] = mio_pad_attr_35_slew_rate_35_qs; + reg_rdata_next[23:20] = mio_pad_attr_35_drive_strength_35_qs; + end + + addr_hit[254]: begin + reg_rdata_next[0] = mio_pad_attr_36_invert_36_qs; + reg_rdata_next[1] = mio_pad_attr_36_virtual_od_en_36_qs; + reg_rdata_next[2] = mio_pad_attr_36_pull_en_36_qs; + reg_rdata_next[3] = mio_pad_attr_36_pull_select_36_qs; + reg_rdata_next[4] = mio_pad_attr_36_keeper_en_36_qs; + reg_rdata_next[5] = mio_pad_attr_36_schmitt_en_36_qs; + reg_rdata_next[6] = mio_pad_attr_36_od_en_36_qs; + reg_rdata_next[7] = mio_pad_attr_36_input_disable_36_qs; + reg_rdata_next[17:16] = mio_pad_attr_36_slew_rate_36_qs; + reg_rdata_next[23:20] = mio_pad_attr_36_drive_strength_36_qs; + end + + addr_hit[255]: begin + reg_rdata_next[0] = mio_pad_attr_37_invert_37_qs; + reg_rdata_next[1] = mio_pad_attr_37_virtual_od_en_37_qs; + reg_rdata_next[2] = mio_pad_attr_37_pull_en_37_qs; + reg_rdata_next[3] = mio_pad_attr_37_pull_select_37_qs; + reg_rdata_next[4] = mio_pad_attr_37_keeper_en_37_qs; + reg_rdata_next[5] = mio_pad_attr_37_schmitt_en_37_qs; + reg_rdata_next[6] = mio_pad_attr_37_od_en_37_qs; + reg_rdata_next[7] = mio_pad_attr_37_input_disable_37_qs; + reg_rdata_next[17:16] = mio_pad_attr_37_slew_rate_37_qs; + reg_rdata_next[23:20] = mio_pad_attr_37_drive_strength_37_qs; + end + + addr_hit[256]: begin + reg_rdata_next[0] = mio_pad_attr_38_invert_38_qs; + reg_rdata_next[1] = mio_pad_attr_38_virtual_od_en_38_qs; + reg_rdata_next[2] = mio_pad_attr_38_pull_en_38_qs; + reg_rdata_next[3] = mio_pad_attr_38_pull_select_38_qs; + reg_rdata_next[4] = mio_pad_attr_38_keeper_en_38_qs; + reg_rdata_next[5] = mio_pad_attr_38_schmitt_en_38_qs; + reg_rdata_next[6] = mio_pad_attr_38_od_en_38_qs; + reg_rdata_next[7] = mio_pad_attr_38_input_disable_38_qs; + reg_rdata_next[17:16] = mio_pad_attr_38_slew_rate_38_qs; + reg_rdata_next[23:20] = mio_pad_attr_38_drive_strength_38_qs; + end + + addr_hit[257]: begin + reg_rdata_next[0] = mio_pad_attr_39_invert_39_qs; + reg_rdata_next[1] = mio_pad_attr_39_virtual_od_en_39_qs; + reg_rdata_next[2] = mio_pad_attr_39_pull_en_39_qs; + reg_rdata_next[3] = mio_pad_attr_39_pull_select_39_qs; + reg_rdata_next[4] = mio_pad_attr_39_keeper_en_39_qs; + reg_rdata_next[5] = mio_pad_attr_39_schmitt_en_39_qs; + reg_rdata_next[6] = mio_pad_attr_39_od_en_39_qs; + reg_rdata_next[7] = mio_pad_attr_39_input_disable_39_qs; + reg_rdata_next[17:16] = mio_pad_attr_39_slew_rate_39_qs; + reg_rdata_next[23:20] = mio_pad_attr_39_drive_strength_39_qs; + end + + addr_hit[258]: begin + reg_rdata_next[0] = mio_pad_attr_40_invert_40_qs; + reg_rdata_next[1] = mio_pad_attr_40_virtual_od_en_40_qs; + reg_rdata_next[2] = mio_pad_attr_40_pull_en_40_qs; + reg_rdata_next[3] = mio_pad_attr_40_pull_select_40_qs; + reg_rdata_next[4] = mio_pad_attr_40_keeper_en_40_qs; + reg_rdata_next[5] = mio_pad_attr_40_schmitt_en_40_qs; + reg_rdata_next[6] = mio_pad_attr_40_od_en_40_qs; + reg_rdata_next[7] = mio_pad_attr_40_input_disable_40_qs; + reg_rdata_next[17:16] = mio_pad_attr_40_slew_rate_40_qs; + reg_rdata_next[23:20] = mio_pad_attr_40_drive_strength_40_qs; + end + + addr_hit[259]: begin + reg_rdata_next[0] = mio_pad_attr_41_invert_41_qs; + reg_rdata_next[1] = mio_pad_attr_41_virtual_od_en_41_qs; + reg_rdata_next[2] = mio_pad_attr_41_pull_en_41_qs; + reg_rdata_next[3] = mio_pad_attr_41_pull_select_41_qs; + reg_rdata_next[4] = mio_pad_attr_41_keeper_en_41_qs; + reg_rdata_next[5] = mio_pad_attr_41_schmitt_en_41_qs; + reg_rdata_next[6] = mio_pad_attr_41_od_en_41_qs; + reg_rdata_next[7] = mio_pad_attr_41_input_disable_41_qs; + reg_rdata_next[17:16] = mio_pad_attr_41_slew_rate_41_qs; + reg_rdata_next[23:20] = mio_pad_attr_41_drive_strength_41_qs; + end + + addr_hit[260]: begin + reg_rdata_next[0] = mio_pad_attr_42_invert_42_qs; + reg_rdata_next[1] = mio_pad_attr_42_virtual_od_en_42_qs; + reg_rdata_next[2] = mio_pad_attr_42_pull_en_42_qs; + reg_rdata_next[3] = mio_pad_attr_42_pull_select_42_qs; + reg_rdata_next[4] = mio_pad_attr_42_keeper_en_42_qs; + reg_rdata_next[5] = mio_pad_attr_42_schmitt_en_42_qs; + reg_rdata_next[6] = mio_pad_attr_42_od_en_42_qs; + reg_rdata_next[7] = mio_pad_attr_42_input_disable_42_qs; + reg_rdata_next[17:16] = mio_pad_attr_42_slew_rate_42_qs; + reg_rdata_next[23:20] = mio_pad_attr_42_drive_strength_42_qs; + end + + addr_hit[261]: begin + reg_rdata_next[0] = mio_pad_attr_43_invert_43_qs; + reg_rdata_next[1] = mio_pad_attr_43_virtual_od_en_43_qs; + reg_rdata_next[2] = mio_pad_attr_43_pull_en_43_qs; + reg_rdata_next[3] = mio_pad_attr_43_pull_select_43_qs; + reg_rdata_next[4] = mio_pad_attr_43_keeper_en_43_qs; + reg_rdata_next[5] = mio_pad_attr_43_schmitt_en_43_qs; + reg_rdata_next[6] = mio_pad_attr_43_od_en_43_qs; + reg_rdata_next[7] = mio_pad_attr_43_input_disable_43_qs; + reg_rdata_next[17:16] = mio_pad_attr_43_slew_rate_43_qs; + reg_rdata_next[23:20] = mio_pad_attr_43_drive_strength_43_qs; + end + + addr_hit[262]: begin + reg_rdata_next[0] = mio_pad_attr_44_invert_44_qs; + reg_rdata_next[1] = mio_pad_attr_44_virtual_od_en_44_qs; + reg_rdata_next[2] = mio_pad_attr_44_pull_en_44_qs; + reg_rdata_next[3] = mio_pad_attr_44_pull_select_44_qs; + reg_rdata_next[4] = mio_pad_attr_44_keeper_en_44_qs; + reg_rdata_next[5] = mio_pad_attr_44_schmitt_en_44_qs; + reg_rdata_next[6] = mio_pad_attr_44_od_en_44_qs; + reg_rdata_next[7] = mio_pad_attr_44_input_disable_44_qs; + reg_rdata_next[17:16] = mio_pad_attr_44_slew_rate_44_qs; + reg_rdata_next[23:20] = mio_pad_attr_44_drive_strength_44_qs; + end + + addr_hit[263]: begin + reg_rdata_next[0] = mio_pad_attr_45_invert_45_qs; + reg_rdata_next[1] = mio_pad_attr_45_virtual_od_en_45_qs; + reg_rdata_next[2] = mio_pad_attr_45_pull_en_45_qs; + reg_rdata_next[3] = mio_pad_attr_45_pull_select_45_qs; + reg_rdata_next[4] = mio_pad_attr_45_keeper_en_45_qs; + reg_rdata_next[5] = mio_pad_attr_45_schmitt_en_45_qs; + reg_rdata_next[6] = mio_pad_attr_45_od_en_45_qs; + reg_rdata_next[7] = mio_pad_attr_45_input_disable_45_qs; + reg_rdata_next[17:16] = mio_pad_attr_45_slew_rate_45_qs; + reg_rdata_next[23:20] = mio_pad_attr_45_drive_strength_45_qs; + end + + addr_hit[264]: begin + reg_rdata_next[0] = mio_pad_attr_46_invert_46_qs; + reg_rdata_next[1] = mio_pad_attr_46_virtual_od_en_46_qs; + reg_rdata_next[2] = mio_pad_attr_46_pull_en_46_qs; + reg_rdata_next[3] = mio_pad_attr_46_pull_select_46_qs; + reg_rdata_next[4] = mio_pad_attr_46_keeper_en_46_qs; + reg_rdata_next[5] = mio_pad_attr_46_schmitt_en_46_qs; + reg_rdata_next[6] = mio_pad_attr_46_od_en_46_qs; + reg_rdata_next[7] = mio_pad_attr_46_input_disable_46_qs; + reg_rdata_next[17:16] = mio_pad_attr_46_slew_rate_46_qs; + reg_rdata_next[23:20] = mio_pad_attr_46_drive_strength_46_qs; + end + + addr_hit[265]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_0_qs; + end + + addr_hit[266]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_1_qs; + end + + addr_hit[267]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_2_qs; + end + + addr_hit[268]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_3_qs; + end + + addr_hit[269]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_4_qs; + end + + addr_hit[270]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_5_qs; + end + + addr_hit[271]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_6_qs; + end + + addr_hit[272]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_7_qs; + end + + addr_hit[273]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_8_qs; + end + + addr_hit[274]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_9_qs; + end + + addr_hit[275]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_10_qs; + end + + addr_hit[276]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_11_qs; + end + + addr_hit[277]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_12_qs; + end + + addr_hit[278]: begin + reg_rdata_next[0] = dio_pad_attr_regwen_13_qs; + end + + addr_hit[279]: begin + reg_rdata_next[0] = dio_pad_attr_0_invert_0_qs; + reg_rdata_next[1] = dio_pad_attr_0_virtual_od_en_0_qs; + reg_rdata_next[2] = dio_pad_attr_0_pull_en_0_qs; + reg_rdata_next[3] = dio_pad_attr_0_pull_select_0_qs; + reg_rdata_next[4] = dio_pad_attr_0_keeper_en_0_qs; + reg_rdata_next[5] = dio_pad_attr_0_schmitt_en_0_qs; + reg_rdata_next[6] = dio_pad_attr_0_od_en_0_qs; + reg_rdata_next[7] = dio_pad_attr_0_input_disable_0_qs; + reg_rdata_next[17:16] = dio_pad_attr_0_slew_rate_0_qs; + reg_rdata_next[23:20] = dio_pad_attr_0_drive_strength_0_qs; + end + + addr_hit[280]: begin + reg_rdata_next[0] = dio_pad_attr_1_invert_1_qs; + reg_rdata_next[1] = dio_pad_attr_1_virtual_od_en_1_qs; + reg_rdata_next[2] = dio_pad_attr_1_pull_en_1_qs; + reg_rdata_next[3] = dio_pad_attr_1_pull_select_1_qs; + reg_rdata_next[4] = dio_pad_attr_1_keeper_en_1_qs; + reg_rdata_next[5] = dio_pad_attr_1_schmitt_en_1_qs; + reg_rdata_next[6] = dio_pad_attr_1_od_en_1_qs; + reg_rdata_next[7] = dio_pad_attr_1_input_disable_1_qs; + reg_rdata_next[17:16] = dio_pad_attr_1_slew_rate_1_qs; + reg_rdata_next[23:20] = dio_pad_attr_1_drive_strength_1_qs; + end + + addr_hit[281]: begin + reg_rdata_next[0] = dio_pad_attr_2_invert_2_qs; + reg_rdata_next[1] = dio_pad_attr_2_virtual_od_en_2_qs; + reg_rdata_next[2] = dio_pad_attr_2_pull_en_2_qs; + reg_rdata_next[3] = dio_pad_attr_2_pull_select_2_qs; + reg_rdata_next[4] = dio_pad_attr_2_keeper_en_2_qs; + reg_rdata_next[5] = dio_pad_attr_2_schmitt_en_2_qs; + reg_rdata_next[6] = dio_pad_attr_2_od_en_2_qs; + reg_rdata_next[7] = dio_pad_attr_2_input_disable_2_qs; + reg_rdata_next[17:16] = dio_pad_attr_2_slew_rate_2_qs; + reg_rdata_next[23:20] = dio_pad_attr_2_drive_strength_2_qs; + end + + addr_hit[282]: begin + reg_rdata_next[0] = dio_pad_attr_3_invert_3_qs; + reg_rdata_next[1] = dio_pad_attr_3_virtual_od_en_3_qs; + reg_rdata_next[2] = dio_pad_attr_3_pull_en_3_qs; + reg_rdata_next[3] = dio_pad_attr_3_pull_select_3_qs; + reg_rdata_next[4] = dio_pad_attr_3_keeper_en_3_qs; + reg_rdata_next[5] = dio_pad_attr_3_schmitt_en_3_qs; + reg_rdata_next[6] = dio_pad_attr_3_od_en_3_qs; + reg_rdata_next[7] = dio_pad_attr_3_input_disable_3_qs; + reg_rdata_next[17:16] = dio_pad_attr_3_slew_rate_3_qs; + reg_rdata_next[23:20] = dio_pad_attr_3_drive_strength_3_qs; + end + + addr_hit[283]: begin + reg_rdata_next[0] = dio_pad_attr_4_invert_4_qs; + reg_rdata_next[1] = dio_pad_attr_4_virtual_od_en_4_qs; + reg_rdata_next[2] = dio_pad_attr_4_pull_en_4_qs; + reg_rdata_next[3] = dio_pad_attr_4_pull_select_4_qs; + reg_rdata_next[4] = dio_pad_attr_4_keeper_en_4_qs; + reg_rdata_next[5] = dio_pad_attr_4_schmitt_en_4_qs; + reg_rdata_next[6] = dio_pad_attr_4_od_en_4_qs; + reg_rdata_next[7] = dio_pad_attr_4_input_disable_4_qs; + reg_rdata_next[17:16] = dio_pad_attr_4_slew_rate_4_qs; + reg_rdata_next[23:20] = dio_pad_attr_4_drive_strength_4_qs; + end + + addr_hit[284]: begin + reg_rdata_next[0] = dio_pad_attr_5_invert_5_qs; + reg_rdata_next[1] = dio_pad_attr_5_virtual_od_en_5_qs; + reg_rdata_next[2] = dio_pad_attr_5_pull_en_5_qs; + reg_rdata_next[3] = dio_pad_attr_5_pull_select_5_qs; + reg_rdata_next[4] = dio_pad_attr_5_keeper_en_5_qs; + reg_rdata_next[5] = dio_pad_attr_5_schmitt_en_5_qs; + reg_rdata_next[6] = dio_pad_attr_5_od_en_5_qs; + reg_rdata_next[7] = dio_pad_attr_5_input_disable_5_qs; + reg_rdata_next[17:16] = dio_pad_attr_5_slew_rate_5_qs; + reg_rdata_next[23:20] = dio_pad_attr_5_drive_strength_5_qs; + end + + addr_hit[285]: begin + reg_rdata_next[0] = dio_pad_attr_6_invert_6_qs; + reg_rdata_next[1] = dio_pad_attr_6_virtual_od_en_6_qs; + reg_rdata_next[2] = dio_pad_attr_6_pull_en_6_qs; + reg_rdata_next[3] = dio_pad_attr_6_pull_select_6_qs; + reg_rdata_next[4] = dio_pad_attr_6_keeper_en_6_qs; + reg_rdata_next[5] = dio_pad_attr_6_schmitt_en_6_qs; + reg_rdata_next[6] = dio_pad_attr_6_od_en_6_qs; + reg_rdata_next[7] = dio_pad_attr_6_input_disable_6_qs; + reg_rdata_next[17:16] = dio_pad_attr_6_slew_rate_6_qs; + reg_rdata_next[23:20] = dio_pad_attr_6_drive_strength_6_qs; + end + + addr_hit[286]: begin + reg_rdata_next[0] = dio_pad_attr_7_invert_7_qs; + reg_rdata_next[1] = dio_pad_attr_7_virtual_od_en_7_qs; + reg_rdata_next[2] = dio_pad_attr_7_pull_en_7_qs; + reg_rdata_next[3] = dio_pad_attr_7_pull_select_7_qs; + reg_rdata_next[4] = dio_pad_attr_7_keeper_en_7_qs; + reg_rdata_next[5] = dio_pad_attr_7_schmitt_en_7_qs; + reg_rdata_next[6] = dio_pad_attr_7_od_en_7_qs; + reg_rdata_next[7] = dio_pad_attr_7_input_disable_7_qs; + reg_rdata_next[17:16] = dio_pad_attr_7_slew_rate_7_qs; + reg_rdata_next[23:20] = dio_pad_attr_7_drive_strength_7_qs; + end + + addr_hit[287]: begin + reg_rdata_next[0] = dio_pad_attr_8_invert_8_qs; + reg_rdata_next[1] = dio_pad_attr_8_virtual_od_en_8_qs; + reg_rdata_next[2] = dio_pad_attr_8_pull_en_8_qs; + reg_rdata_next[3] = dio_pad_attr_8_pull_select_8_qs; + reg_rdata_next[4] = dio_pad_attr_8_keeper_en_8_qs; + reg_rdata_next[5] = dio_pad_attr_8_schmitt_en_8_qs; + reg_rdata_next[6] = dio_pad_attr_8_od_en_8_qs; + reg_rdata_next[7] = dio_pad_attr_8_input_disable_8_qs; + reg_rdata_next[17:16] = dio_pad_attr_8_slew_rate_8_qs; + reg_rdata_next[23:20] = dio_pad_attr_8_drive_strength_8_qs; + end + + addr_hit[288]: begin + reg_rdata_next[0] = dio_pad_attr_9_invert_9_qs; + reg_rdata_next[1] = dio_pad_attr_9_virtual_od_en_9_qs; + reg_rdata_next[2] = dio_pad_attr_9_pull_en_9_qs; + reg_rdata_next[3] = dio_pad_attr_9_pull_select_9_qs; + reg_rdata_next[4] = dio_pad_attr_9_keeper_en_9_qs; + reg_rdata_next[5] = dio_pad_attr_9_schmitt_en_9_qs; + reg_rdata_next[6] = dio_pad_attr_9_od_en_9_qs; + reg_rdata_next[7] = dio_pad_attr_9_input_disable_9_qs; + reg_rdata_next[17:16] = dio_pad_attr_9_slew_rate_9_qs; + reg_rdata_next[23:20] = dio_pad_attr_9_drive_strength_9_qs; + end + + addr_hit[289]: begin + reg_rdata_next[0] = dio_pad_attr_10_invert_10_qs; + reg_rdata_next[1] = dio_pad_attr_10_virtual_od_en_10_qs; + reg_rdata_next[2] = dio_pad_attr_10_pull_en_10_qs; + reg_rdata_next[3] = dio_pad_attr_10_pull_select_10_qs; + reg_rdata_next[4] = dio_pad_attr_10_keeper_en_10_qs; + reg_rdata_next[5] = dio_pad_attr_10_schmitt_en_10_qs; + reg_rdata_next[6] = dio_pad_attr_10_od_en_10_qs; + reg_rdata_next[7] = dio_pad_attr_10_input_disable_10_qs; + reg_rdata_next[17:16] = dio_pad_attr_10_slew_rate_10_qs; + reg_rdata_next[23:20] = dio_pad_attr_10_drive_strength_10_qs; + end + + addr_hit[290]: begin + reg_rdata_next[0] = dio_pad_attr_11_invert_11_qs; + reg_rdata_next[1] = dio_pad_attr_11_virtual_od_en_11_qs; + reg_rdata_next[2] = dio_pad_attr_11_pull_en_11_qs; + reg_rdata_next[3] = dio_pad_attr_11_pull_select_11_qs; + reg_rdata_next[4] = dio_pad_attr_11_keeper_en_11_qs; + reg_rdata_next[5] = dio_pad_attr_11_schmitt_en_11_qs; + reg_rdata_next[6] = dio_pad_attr_11_od_en_11_qs; + reg_rdata_next[7] = dio_pad_attr_11_input_disable_11_qs; + reg_rdata_next[17:16] = dio_pad_attr_11_slew_rate_11_qs; + reg_rdata_next[23:20] = dio_pad_attr_11_drive_strength_11_qs; + end + + addr_hit[291]: begin + reg_rdata_next[0] = dio_pad_attr_12_invert_12_qs; + reg_rdata_next[1] = dio_pad_attr_12_virtual_od_en_12_qs; + reg_rdata_next[2] = dio_pad_attr_12_pull_en_12_qs; + reg_rdata_next[3] = dio_pad_attr_12_pull_select_12_qs; + reg_rdata_next[4] = dio_pad_attr_12_keeper_en_12_qs; + reg_rdata_next[5] = dio_pad_attr_12_schmitt_en_12_qs; + reg_rdata_next[6] = dio_pad_attr_12_od_en_12_qs; + reg_rdata_next[7] = dio_pad_attr_12_input_disable_12_qs; + reg_rdata_next[17:16] = dio_pad_attr_12_slew_rate_12_qs; + reg_rdata_next[23:20] = dio_pad_attr_12_drive_strength_12_qs; + end + + addr_hit[292]: begin + reg_rdata_next[0] = dio_pad_attr_13_invert_13_qs; + reg_rdata_next[1] = dio_pad_attr_13_virtual_od_en_13_qs; + reg_rdata_next[2] = dio_pad_attr_13_pull_en_13_qs; + reg_rdata_next[3] = dio_pad_attr_13_pull_select_13_qs; + reg_rdata_next[4] = dio_pad_attr_13_keeper_en_13_qs; + reg_rdata_next[5] = dio_pad_attr_13_schmitt_en_13_qs; + reg_rdata_next[6] = dio_pad_attr_13_od_en_13_qs; + reg_rdata_next[7] = dio_pad_attr_13_input_disable_13_qs; + reg_rdata_next[17:16] = dio_pad_attr_13_slew_rate_13_qs; + reg_rdata_next[23:20] = dio_pad_attr_13_drive_strength_13_qs; + end + + addr_hit[293]: begin + reg_rdata_next[0] = mio_pad_sleep_status_0_en_0_qs; + reg_rdata_next[1] = mio_pad_sleep_status_0_en_1_qs; + reg_rdata_next[2] = mio_pad_sleep_status_0_en_2_qs; + reg_rdata_next[3] = mio_pad_sleep_status_0_en_3_qs; + reg_rdata_next[4] = mio_pad_sleep_status_0_en_4_qs; + reg_rdata_next[5] = mio_pad_sleep_status_0_en_5_qs; + reg_rdata_next[6] = mio_pad_sleep_status_0_en_6_qs; + reg_rdata_next[7] = mio_pad_sleep_status_0_en_7_qs; + reg_rdata_next[8] = mio_pad_sleep_status_0_en_8_qs; + reg_rdata_next[9] = mio_pad_sleep_status_0_en_9_qs; + reg_rdata_next[10] = mio_pad_sleep_status_0_en_10_qs; + reg_rdata_next[11] = mio_pad_sleep_status_0_en_11_qs; + reg_rdata_next[12] = mio_pad_sleep_status_0_en_12_qs; + reg_rdata_next[13] = mio_pad_sleep_status_0_en_13_qs; + reg_rdata_next[14] = mio_pad_sleep_status_0_en_14_qs; + reg_rdata_next[15] = mio_pad_sleep_status_0_en_15_qs; + reg_rdata_next[16] = mio_pad_sleep_status_0_en_16_qs; + reg_rdata_next[17] = mio_pad_sleep_status_0_en_17_qs; + reg_rdata_next[18] = mio_pad_sleep_status_0_en_18_qs; + reg_rdata_next[19] = mio_pad_sleep_status_0_en_19_qs; + reg_rdata_next[20] = mio_pad_sleep_status_0_en_20_qs; + reg_rdata_next[21] = mio_pad_sleep_status_0_en_21_qs; + reg_rdata_next[22] = mio_pad_sleep_status_0_en_22_qs; + reg_rdata_next[23] = mio_pad_sleep_status_0_en_23_qs; + reg_rdata_next[24] = mio_pad_sleep_status_0_en_24_qs; + reg_rdata_next[25] = mio_pad_sleep_status_0_en_25_qs; + reg_rdata_next[26] = mio_pad_sleep_status_0_en_26_qs; + reg_rdata_next[27] = mio_pad_sleep_status_0_en_27_qs; + reg_rdata_next[28] = mio_pad_sleep_status_0_en_28_qs; + reg_rdata_next[29] = mio_pad_sleep_status_0_en_29_qs; + reg_rdata_next[30] = mio_pad_sleep_status_0_en_30_qs; + reg_rdata_next[31] = mio_pad_sleep_status_0_en_31_qs; + end + + addr_hit[294]: begin + reg_rdata_next[0] = mio_pad_sleep_status_1_en_32_qs; + reg_rdata_next[1] = mio_pad_sleep_status_1_en_33_qs; + reg_rdata_next[2] = mio_pad_sleep_status_1_en_34_qs; + reg_rdata_next[3] = mio_pad_sleep_status_1_en_35_qs; + reg_rdata_next[4] = mio_pad_sleep_status_1_en_36_qs; + reg_rdata_next[5] = mio_pad_sleep_status_1_en_37_qs; + reg_rdata_next[6] = mio_pad_sleep_status_1_en_38_qs; + reg_rdata_next[7] = mio_pad_sleep_status_1_en_39_qs; + reg_rdata_next[8] = mio_pad_sleep_status_1_en_40_qs; + reg_rdata_next[9] = mio_pad_sleep_status_1_en_41_qs; + reg_rdata_next[10] = mio_pad_sleep_status_1_en_42_qs; + reg_rdata_next[11] = mio_pad_sleep_status_1_en_43_qs; + reg_rdata_next[12] = mio_pad_sleep_status_1_en_44_qs; + reg_rdata_next[13] = mio_pad_sleep_status_1_en_45_qs; + reg_rdata_next[14] = mio_pad_sleep_status_1_en_46_qs; + end + + addr_hit[295]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_0_qs; + end + + addr_hit[296]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_1_qs; + end + + addr_hit[297]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_2_qs; + end + + addr_hit[298]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_3_qs; + end + + addr_hit[299]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_4_qs; + end + + addr_hit[300]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_5_qs; + end + + addr_hit[301]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_6_qs; + end + + addr_hit[302]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_7_qs; + end + + addr_hit[303]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_8_qs; + end + + addr_hit[304]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_9_qs; + end + + addr_hit[305]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_10_qs; + end + + addr_hit[306]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_11_qs; + end + + addr_hit[307]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_12_qs; + end + + addr_hit[308]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_13_qs; + end + + addr_hit[309]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_14_qs; + end + + addr_hit[310]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_15_qs; + end + + addr_hit[311]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_16_qs; + end + + addr_hit[312]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_17_qs; + end + + addr_hit[313]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_18_qs; + end + + addr_hit[314]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_19_qs; + end + + addr_hit[315]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_20_qs; + end + + addr_hit[316]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_21_qs; + end + + addr_hit[317]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_22_qs; + end + + addr_hit[318]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_23_qs; + end + + addr_hit[319]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_24_qs; + end + + addr_hit[320]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_25_qs; + end + + addr_hit[321]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_26_qs; + end + + addr_hit[322]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_27_qs; + end + + addr_hit[323]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_28_qs; + end + + addr_hit[324]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_29_qs; + end + + addr_hit[325]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_30_qs; + end + + addr_hit[326]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_31_qs; + end + + addr_hit[327]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_32_qs; + end + + addr_hit[328]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_33_qs; + end + + addr_hit[329]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_34_qs; + end + + addr_hit[330]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_35_qs; + end + + addr_hit[331]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_36_qs; + end + + addr_hit[332]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_37_qs; + end + + addr_hit[333]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_38_qs; + end + + addr_hit[334]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_39_qs; + end + + addr_hit[335]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_40_qs; + end + + addr_hit[336]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_41_qs; + end + + addr_hit[337]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_42_qs; + end + + addr_hit[338]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_43_qs; + end + + addr_hit[339]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_44_qs; + end + + addr_hit[340]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_45_qs; + end + + addr_hit[341]: begin + reg_rdata_next[0] = mio_pad_sleep_regwen_46_qs; + end + + addr_hit[342]: begin + reg_rdata_next[0] = mio_pad_sleep_en_0_qs; + end + + addr_hit[343]: begin + reg_rdata_next[0] = mio_pad_sleep_en_1_qs; + end + + addr_hit[344]: begin + reg_rdata_next[0] = mio_pad_sleep_en_2_qs; + end + + addr_hit[345]: begin + reg_rdata_next[0] = mio_pad_sleep_en_3_qs; + end + + addr_hit[346]: begin + reg_rdata_next[0] = mio_pad_sleep_en_4_qs; + end + + addr_hit[347]: begin + reg_rdata_next[0] = mio_pad_sleep_en_5_qs; + end + + addr_hit[348]: begin + reg_rdata_next[0] = mio_pad_sleep_en_6_qs; + end + + addr_hit[349]: begin + reg_rdata_next[0] = mio_pad_sleep_en_7_qs; + end + + addr_hit[350]: begin + reg_rdata_next[0] = mio_pad_sleep_en_8_qs; + end + + addr_hit[351]: begin + reg_rdata_next[0] = mio_pad_sleep_en_9_qs; + end + + addr_hit[352]: begin + reg_rdata_next[0] = mio_pad_sleep_en_10_qs; + end + + addr_hit[353]: begin + reg_rdata_next[0] = mio_pad_sleep_en_11_qs; + end + + addr_hit[354]: begin + reg_rdata_next[0] = mio_pad_sleep_en_12_qs; + end + + addr_hit[355]: begin + reg_rdata_next[0] = mio_pad_sleep_en_13_qs; + end + + addr_hit[356]: begin + reg_rdata_next[0] = mio_pad_sleep_en_14_qs; + end + + addr_hit[357]: begin + reg_rdata_next[0] = mio_pad_sleep_en_15_qs; + end + + addr_hit[358]: begin + reg_rdata_next[0] = mio_pad_sleep_en_16_qs; + end + + addr_hit[359]: begin + reg_rdata_next[0] = mio_pad_sleep_en_17_qs; + end + + addr_hit[360]: begin + reg_rdata_next[0] = mio_pad_sleep_en_18_qs; + end + + addr_hit[361]: begin + reg_rdata_next[0] = mio_pad_sleep_en_19_qs; + end + + addr_hit[362]: begin + reg_rdata_next[0] = mio_pad_sleep_en_20_qs; + end + + addr_hit[363]: begin + reg_rdata_next[0] = mio_pad_sleep_en_21_qs; + end + + addr_hit[364]: begin + reg_rdata_next[0] = mio_pad_sleep_en_22_qs; + end + + addr_hit[365]: begin + reg_rdata_next[0] = mio_pad_sleep_en_23_qs; + end + + addr_hit[366]: begin + reg_rdata_next[0] = mio_pad_sleep_en_24_qs; + end + + addr_hit[367]: begin + reg_rdata_next[0] = mio_pad_sleep_en_25_qs; + end + + addr_hit[368]: begin + reg_rdata_next[0] = mio_pad_sleep_en_26_qs; + end + + addr_hit[369]: begin + reg_rdata_next[0] = mio_pad_sleep_en_27_qs; + end + + addr_hit[370]: begin + reg_rdata_next[0] = mio_pad_sleep_en_28_qs; + end + + addr_hit[371]: begin + reg_rdata_next[0] = mio_pad_sleep_en_29_qs; + end + + addr_hit[372]: begin + reg_rdata_next[0] = mio_pad_sleep_en_30_qs; + end + + addr_hit[373]: begin + reg_rdata_next[0] = mio_pad_sleep_en_31_qs; + end + + addr_hit[374]: begin + reg_rdata_next[0] = mio_pad_sleep_en_32_qs; + end + + addr_hit[375]: begin + reg_rdata_next[0] = mio_pad_sleep_en_33_qs; + end + + addr_hit[376]: begin + reg_rdata_next[0] = mio_pad_sleep_en_34_qs; + end + + addr_hit[377]: begin + reg_rdata_next[0] = mio_pad_sleep_en_35_qs; + end + + addr_hit[378]: begin + reg_rdata_next[0] = mio_pad_sleep_en_36_qs; + end + + addr_hit[379]: begin + reg_rdata_next[0] = mio_pad_sleep_en_37_qs; + end + + addr_hit[380]: begin + reg_rdata_next[0] = mio_pad_sleep_en_38_qs; + end + + addr_hit[381]: begin + reg_rdata_next[0] = mio_pad_sleep_en_39_qs; + end + + addr_hit[382]: begin + reg_rdata_next[0] = mio_pad_sleep_en_40_qs; + end + + addr_hit[383]: begin + reg_rdata_next[0] = mio_pad_sleep_en_41_qs; + end + + addr_hit[384]: begin + reg_rdata_next[0] = mio_pad_sleep_en_42_qs; + end + + addr_hit[385]: begin + reg_rdata_next[0] = mio_pad_sleep_en_43_qs; + end + + addr_hit[386]: begin + reg_rdata_next[0] = mio_pad_sleep_en_44_qs; + end + + addr_hit[387]: begin + reg_rdata_next[0] = mio_pad_sleep_en_45_qs; + end + + addr_hit[388]: begin + reg_rdata_next[0] = mio_pad_sleep_en_46_qs; + end + + addr_hit[389]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_0_qs; + end + + addr_hit[390]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_1_qs; + end + + addr_hit[391]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_2_qs; + end + + addr_hit[392]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_3_qs; + end + + addr_hit[393]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_4_qs; + end + + addr_hit[394]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_5_qs; + end + + addr_hit[395]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_6_qs; + end + + addr_hit[396]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_7_qs; + end + + addr_hit[397]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_8_qs; + end + + addr_hit[398]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_9_qs; + end + + addr_hit[399]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_10_qs; + end + + addr_hit[400]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_11_qs; + end + + addr_hit[401]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_12_qs; + end + + addr_hit[402]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_13_qs; + end + + addr_hit[403]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_14_qs; + end + + addr_hit[404]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_15_qs; + end + + addr_hit[405]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_16_qs; + end + + addr_hit[406]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_17_qs; + end + + addr_hit[407]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_18_qs; + end + + addr_hit[408]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_19_qs; + end + + addr_hit[409]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_20_qs; + end + + addr_hit[410]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_21_qs; + end + + addr_hit[411]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_22_qs; + end + + addr_hit[412]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_23_qs; + end + + addr_hit[413]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_24_qs; + end + + addr_hit[414]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_25_qs; + end + + addr_hit[415]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_26_qs; + end + + addr_hit[416]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_27_qs; + end + + addr_hit[417]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_28_qs; + end + + addr_hit[418]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_29_qs; + end + + addr_hit[419]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_30_qs; + end + + addr_hit[420]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_31_qs; + end + + addr_hit[421]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_32_qs; + end + + addr_hit[422]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_33_qs; + end + + addr_hit[423]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_34_qs; + end + + addr_hit[424]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_35_qs; + end + + addr_hit[425]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_36_qs; + end + + addr_hit[426]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_37_qs; + end + + addr_hit[427]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_38_qs; + end + + addr_hit[428]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_39_qs; + end + + addr_hit[429]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_40_qs; + end + + addr_hit[430]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_41_qs; + end + + addr_hit[431]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_42_qs; + end + + addr_hit[432]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_43_qs; + end + + addr_hit[433]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_44_qs; + end + + addr_hit[434]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_45_qs; + end + + addr_hit[435]: begin + reg_rdata_next[1:0] = mio_pad_sleep_mode_46_qs; + end + + addr_hit[436]: begin + reg_rdata_next[0] = dio_pad_sleep_status_en_0_qs; + reg_rdata_next[1] = dio_pad_sleep_status_en_1_qs; + reg_rdata_next[2] = dio_pad_sleep_status_en_2_qs; + reg_rdata_next[3] = dio_pad_sleep_status_en_3_qs; + reg_rdata_next[4] = dio_pad_sleep_status_en_4_qs; + reg_rdata_next[5] = dio_pad_sleep_status_en_5_qs; + reg_rdata_next[6] = dio_pad_sleep_status_en_6_qs; + reg_rdata_next[7] = dio_pad_sleep_status_en_7_qs; + reg_rdata_next[8] = dio_pad_sleep_status_en_8_qs; + reg_rdata_next[9] = dio_pad_sleep_status_en_9_qs; + reg_rdata_next[10] = dio_pad_sleep_status_en_10_qs; + reg_rdata_next[11] = dio_pad_sleep_status_en_11_qs; + reg_rdata_next[12] = dio_pad_sleep_status_en_12_qs; + reg_rdata_next[13] = dio_pad_sleep_status_en_13_qs; + end + + addr_hit[437]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_0_qs; + end + + addr_hit[438]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_1_qs; + end + + addr_hit[439]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_2_qs; + end + + addr_hit[440]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_3_qs; + end + + addr_hit[441]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_4_qs; + end + + addr_hit[442]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_5_qs; + end + + addr_hit[443]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_6_qs; + end + + addr_hit[444]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_7_qs; + end + + addr_hit[445]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_8_qs; + end + + addr_hit[446]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_9_qs; + end + + addr_hit[447]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_10_qs; + end + + addr_hit[448]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_11_qs; + end + + addr_hit[449]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_12_qs; + end + + addr_hit[450]: begin + reg_rdata_next[0] = dio_pad_sleep_regwen_13_qs; + end + + addr_hit[451]: begin + reg_rdata_next[0] = dio_pad_sleep_en_0_qs; + end + + addr_hit[452]: begin + reg_rdata_next[0] = dio_pad_sleep_en_1_qs; + end + + addr_hit[453]: begin + reg_rdata_next[0] = dio_pad_sleep_en_2_qs; + end + + addr_hit[454]: begin + reg_rdata_next[0] = dio_pad_sleep_en_3_qs; + end + + addr_hit[455]: begin + reg_rdata_next[0] = dio_pad_sleep_en_4_qs; + end + + addr_hit[456]: begin + reg_rdata_next[0] = dio_pad_sleep_en_5_qs; + end + + addr_hit[457]: begin + reg_rdata_next[0] = dio_pad_sleep_en_6_qs; + end + + addr_hit[458]: begin + reg_rdata_next[0] = dio_pad_sleep_en_7_qs; + end + + addr_hit[459]: begin + reg_rdata_next[0] = dio_pad_sleep_en_8_qs; + end + + addr_hit[460]: begin + reg_rdata_next[0] = dio_pad_sleep_en_9_qs; + end + + addr_hit[461]: begin + reg_rdata_next[0] = dio_pad_sleep_en_10_qs; + end + + addr_hit[462]: begin + reg_rdata_next[0] = dio_pad_sleep_en_11_qs; + end + + addr_hit[463]: begin + reg_rdata_next[0] = dio_pad_sleep_en_12_qs; + end + + addr_hit[464]: begin + reg_rdata_next[0] = dio_pad_sleep_en_13_qs; + end + + addr_hit[465]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_0_qs; + end + + addr_hit[466]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_1_qs; + end + + addr_hit[467]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_2_qs; + end + + addr_hit[468]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_3_qs; + end + + addr_hit[469]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_4_qs; + end + + addr_hit[470]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_5_qs; + end + + addr_hit[471]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_6_qs; + end + + addr_hit[472]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_7_qs; + end + + addr_hit[473]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_8_qs; + end + + addr_hit[474]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_9_qs; + end + + addr_hit[475]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_10_qs; + end + + addr_hit[476]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_11_qs; + end + + addr_hit[477]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_12_qs; + end + + addr_hit[478]: begin + reg_rdata_next[1:0] = dio_pad_sleep_mode_13_qs; + end + + addr_hit[479]: begin + reg_rdata_next[0] = wkup_detector_regwen_0_qs; + end + + addr_hit[480]: begin + reg_rdata_next[0] = wkup_detector_regwen_1_qs; + end + + addr_hit[481]: begin + reg_rdata_next[0] = wkup_detector_regwen_2_qs; + end + + addr_hit[482]: begin + reg_rdata_next[0] = wkup_detector_regwen_3_qs; + end + + addr_hit[483]: begin + reg_rdata_next[0] = wkup_detector_regwen_4_qs; + end + + addr_hit[484]: begin + reg_rdata_next[0] = wkup_detector_regwen_5_qs; + end + + addr_hit[485]: begin + reg_rdata_next[0] = wkup_detector_regwen_6_qs; + end + + addr_hit[486]: begin + reg_rdata_next[0] = wkup_detector_regwen_7_qs; + end + + addr_hit[487]: begin + reg_rdata_next = DW'(wkup_detector_en_0_qs); + end + addr_hit[488]: begin + reg_rdata_next = DW'(wkup_detector_en_1_qs); + end + addr_hit[489]: begin + reg_rdata_next = DW'(wkup_detector_en_2_qs); + end + addr_hit[490]: begin + reg_rdata_next = DW'(wkup_detector_en_3_qs); + end + addr_hit[491]: begin + reg_rdata_next = DW'(wkup_detector_en_4_qs); + end + addr_hit[492]: begin + reg_rdata_next = DW'(wkup_detector_en_5_qs); + end + addr_hit[493]: begin + reg_rdata_next = DW'(wkup_detector_en_6_qs); + end + addr_hit[494]: begin + reg_rdata_next = DW'(wkup_detector_en_7_qs); + end + addr_hit[495]: begin + reg_rdata_next = DW'(wkup_detector_0_qs); + end + addr_hit[496]: begin + reg_rdata_next = DW'(wkup_detector_1_qs); + end + addr_hit[497]: begin + reg_rdata_next = DW'(wkup_detector_2_qs); + end + addr_hit[498]: begin + reg_rdata_next = DW'(wkup_detector_3_qs); + end + addr_hit[499]: begin + reg_rdata_next = DW'(wkup_detector_4_qs); + end + addr_hit[500]: begin + reg_rdata_next = DW'(wkup_detector_5_qs); + end + addr_hit[501]: begin + reg_rdata_next = DW'(wkup_detector_6_qs); + end + addr_hit[502]: begin + reg_rdata_next = DW'(wkup_detector_7_qs); + end + addr_hit[503]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_0_qs); + end + addr_hit[504]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_1_qs); + end + addr_hit[505]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_2_qs); + end + addr_hit[506]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_3_qs); + end + addr_hit[507]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_4_qs); + end + addr_hit[508]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_5_qs); + end + addr_hit[509]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_6_qs); + end + addr_hit[510]: begin + reg_rdata_next = DW'(wkup_detector_cnt_th_7_qs); + end + addr_hit[511]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_0_qs; + end + + addr_hit[512]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_1_qs; + end + + addr_hit[513]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_2_qs; + end + + addr_hit[514]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_3_qs; + end + + addr_hit[515]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_4_qs; + end + + addr_hit[516]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_5_qs; + end + + addr_hit[517]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_6_qs; + end + + addr_hit[518]: begin + reg_rdata_next[5:0] = wkup_detector_padsel_7_qs; + end + + addr_hit[519]: begin + reg_rdata_next = DW'(wkup_cause_qs); + end + default: begin + reg_rdata_next = '1; + end + endcase + end + + // shadow busy + logic shadow_busy; + assign shadow_busy = 1'b0; + + // register busy + logic reg_busy_sel; + assign reg_busy = reg_busy_sel | shadow_busy; + always_comb begin + reg_busy_sel = '0; + unique case (1'b1) + addr_hit[487]: begin + reg_busy_sel = wkup_detector_en_0_busy; + end + addr_hit[488]: begin + reg_busy_sel = wkup_detector_en_1_busy; + end + addr_hit[489]: begin + reg_busy_sel = wkup_detector_en_2_busy; + end + addr_hit[490]: begin + reg_busy_sel = wkup_detector_en_3_busy; + end + addr_hit[491]: begin + reg_busy_sel = wkup_detector_en_4_busy; + end + addr_hit[492]: begin + reg_busy_sel = wkup_detector_en_5_busy; + end + addr_hit[493]: begin + reg_busy_sel = wkup_detector_en_6_busy; + end + addr_hit[494]: begin + reg_busy_sel = wkup_detector_en_7_busy; + end + addr_hit[495]: begin + reg_busy_sel = wkup_detector_0_busy; + end + addr_hit[496]: begin + reg_busy_sel = wkup_detector_1_busy; + end + addr_hit[497]: begin + reg_busy_sel = wkup_detector_2_busy; + end + addr_hit[498]: begin + reg_busy_sel = wkup_detector_3_busy; + end + addr_hit[499]: begin + reg_busy_sel = wkup_detector_4_busy; + end + addr_hit[500]: begin + reg_busy_sel = wkup_detector_5_busy; + end + addr_hit[501]: begin + reg_busy_sel = wkup_detector_6_busy; + end + addr_hit[502]: begin + reg_busy_sel = wkup_detector_7_busy; + end + addr_hit[503]: begin + reg_busy_sel = wkup_detector_cnt_th_0_busy; + end + addr_hit[504]: begin + reg_busy_sel = wkup_detector_cnt_th_1_busy; + end + addr_hit[505]: begin + reg_busy_sel = wkup_detector_cnt_th_2_busy; + end + addr_hit[506]: begin + reg_busy_sel = wkup_detector_cnt_th_3_busy; + end + addr_hit[507]: begin + reg_busy_sel = wkup_detector_cnt_th_4_busy; + end + addr_hit[508]: begin + reg_busy_sel = wkup_detector_cnt_th_5_busy; + end + addr_hit[509]: begin + reg_busy_sel = wkup_detector_cnt_th_6_busy; + end + addr_hit[510]: begin + reg_busy_sel = wkup_detector_cnt_th_7_busy; + end + addr_hit[519]: begin + reg_busy_sel = wkup_cause_busy; + end + default: begin + reg_busy_sel = '0; + end + endcase + end + + + // 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_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_strap_sampling.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_strap_sampling.sv new file mode 100644 index 0000000000000..5e86371390854 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_strap_sampling.sv @@ -0,0 +1,454 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module pinmux_strap_sampling + import pinmux_pkg::*; + import pinmux_reg_pkg::*; + import prim_pad_wrapper_pkg::*; + import lc_ctrl_pkg::*; +#( + // Taget-specific pinmux configuration passed down from the + // target-specific top-level. + parameter target_cfg_t TargetCfg = DefaultTargetCfg +) ( + input clk_i, + input rst_ni, + input prim_mubi_pkg::mubi4_t scanmode_i, + // To padring side + output pad_attr_t [NumIOs-1:0] attr_padring_o, + output logic [NumIOs-1:0] out_padring_o, + output logic [NumIOs-1:0] oe_padring_o, + input logic [NumIOs-1:0] in_padring_i, + // To core side + input pad_attr_t [NumIOs-1:0] attr_core_i, + input logic [NumIOs-1:0] out_core_i, + input logic [NumIOs-1:0] oe_core_i, + output logic [NumIOs-1:0] in_core_o, + // Used for TAP qualification + input logic strap_en_i, + input lc_tx_t lc_dft_en_i, + input lc_tx_t lc_hw_debug_en_i, + input lc_tx_t lc_check_byp_en_i, + input lc_tx_t lc_escalate_en_i, + output lc_tx_t pinmux_hw_debug_en_o, + // Sampled values for DFT straps + output dft_strap_test_req_t dft_strap_test_o, + // Hold tap strap select + input dft_hold_tap_sel_i, + // Qualified JTAG signals for TAPs + output jtag_pkg::jtag_req_t lc_jtag_o, + input jtag_pkg::jtag_rsp_t lc_jtag_i, + output jtag_pkg::jtag_req_t rv_jtag_o, + input jtag_pkg::jtag_rsp_t rv_jtag_i, + output jtag_pkg::jtag_req_t dft_jtag_o, + input jtag_pkg::jtag_rsp_t dft_jtag_i +); + + + ///////////////////////////////////// + // Life cycle signal synchronizers // + ///////////////////////////////////// + + prim_mubi_pkg::mubi4_t [0:0] scanmode; + + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) // clock/reset below is only used for SVAs. + ) u_por_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o(scanmode) + ); + + typedef enum logic [1:0] { + DftEnSample, + DftEnTapSel, + DftEnLast + } lc_dft_en_e; + + lc_tx_t [DftEnLast-1:0] lc_dft_en; + prim_lc_sync #( + .NumCopies(int'(DftEnLast)) + ) u_prim_lc_sync_lc_dft_en ( + .clk_i, + .rst_ni, + .lc_en_i(lc_dft_en_i), + .lc_en_o(lc_dft_en) + ); + lc_tx_t [0:0] lc_hw_debug_en; + prim_lc_sync #( + .NumCopies(1) + ) u_prim_lc_sync_lc_hw_debug_en ( + .clk_i, + .rst_ni, + .lc_en_i(lc_hw_debug_en_i), + .lc_en_o(lc_hw_debug_en) + ); + lc_tx_t [0:0] lc_check_byp_en; + prim_lc_sync #( + .NumCopies(1) + ) u_prim_lc_sync_lc_check_byp_en ( + .clk_i, + .rst_ni, + .lc_en_i(lc_check_byp_en_i), + .lc_en_o(lc_check_byp_en) + ); + lc_tx_t [0:0] lc_escalate_en; + prim_lc_sync #( + .NumCopies(1) + ) u_prim_lc_sync_lc_escalate_en ( + .clk_i, + .rst_ni, + .lc_en_i(lc_escalate_en_i), + .lc_en_o(lc_escalate_en) + ); + + + ///////////////////////////// + // LC_HW_DEBUG_EN Latching // + ///////////////////////////// + + // In order to keep a RV_DM JTAG debug session alive during NDM reset, we need to memorize the + // state of lc_hw_debug_en, since OTP/LC will be reset as part of NDM reset (the only parts not + // reset are in the pwr/rst/clkmgrs, RV_DM and this strap sampling module). We sample the life + // cycle signal state when the strap sampling pulse is asserted bu the PWRMGR. This pulse is + // asserted once during boot (and not after an NDM reset). + // + // Note that DFT TAP selection is not affected by this since we always consume the life value for + // lc_dft_en. We also make sure to invalidate the sampled lc_hw_debug_en whenever lc_check_byp_en + // or lc_escalate_en are not OFF. lc_escalate_en is asserted as part of an escalation, and + // lc_check_byp_en is asserted whenever a life cycle transition is initiated (it causes the OTP + // controller to skip background checks on the life cycle partition as it undergoes + // modification). This makes sure that the sampled value here does not survive a life cycle + // transition. + // + // Finally, note that there is secondary gating on the RV_DM and DFT TAPs that is always consuming + // live lc_hw_debug_en and lc_dft_en signals for added protection. + + // Convert the strap enable pulse to a mubi signal and mask lc_hw_debug_en with it. + lc_tx_t lc_strap_en, lc_hw_debug_en_masked; + assign lc_strap_en = lc_tx_bool_to_lc_tx(strap_en_i); + assign lc_hw_debug_en_masked = lc_tx_and_hi(lc_strap_en, lc_hw_debug_en[0]); + + // Output ON if + // - If the strap sampling pulse is asserted and lc_hw_debug_en is ON + // - If the pinmux_hw_debug_en_q is already set to ON (this is the latching feedback loop) + // Note: make sure we use a hardened, rectifying OR function since otherwise two non-strict + // values may produce a strict ON value. + lc_tx_t hw_debug_en_set, pinmux_hw_debug_en_q; + prim_lc_or_hardened #( + .ActVal(On) + ) u_prim_lc_or_hardened ( + .clk_i, + .rst_ni, + .lc_en_a_i(lc_hw_debug_en_masked), + .lc_en_b_i(pinmux_hw_debug_en_q), + .lc_en_o (hw_debug_en_set) + ); + + // Output ON if both lc_check_byp_en and lc_escalate_en are set to OFF. + lc_tx_t hw_debug_en_gating; + assign hw_debug_en_gating = lc_tx_inv(lc_tx_and_lo(lc_check_byp_en[0], lc_escalate_en[0])); + + // Gate the hw_debug_en_set signal and feed it into the latching flop. + lc_tx_t pinmux_hw_debug_en_d; + assign pinmux_hw_debug_en_d = lc_tx_and_hi(hw_debug_en_set, hw_debug_en_gating); + + prim_lc_sender u_prim_lc_sender_pinmux_hw_debug_en ( + .clk_i, + .rst_ni, + .lc_en_i(pinmux_hw_debug_en_d), + .lc_en_o(pinmux_hw_debug_en_q) + ); + + typedef enum logic [1:0] { + HwDebugEnSample, + HwDebugEnTapSel, + HwDebugEnRvDmOut, + HwDebugEnLast + } pinmux_hw_debug_en_e; + + lc_tx_t [HwDebugEnLast-1:0] pinmux_hw_debug_en; + prim_lc_sync #( + .NumCopies(int'(HwDebugEnLast)), + .AsyncOn(0) // no sync needed + ) u_prim_lc_sync_pinmux_hw_debug_en ( + .clk_i, + .rst_ni, + .lc_en_i(pinmux_hw_debug_en_q), + .lc_en_o(pinmux_hw_debug_en) + ); + + // SEC_CM: PINMUX_HW_DEBUG_EN.INTERSIG.MUBI + // We send this latched version over to the RV_DM in order to gate the JTAG signals and TAP side. + // Note that the bus side will remain gated with the live lc_hw_debug_en value inside RV_DM. + assign pinmux_hw_debug_en_o = pinmux_hw_debug_en[HwDebugEnRvDmOut]; + + // Check that we can correctly latch upon strap_en_i + `ASSERT(LcHwDebugEnSet_A, + (lc_tx_test_true_strict(lc_hw_debug_en[0]) || + lc_tx_test_true_strict(pinmux_hw_debug_en_q)) && + lc_tx_test_false_strict(lc_check_byp_en[0]) && + lc_tx_test_false_strict(lc_escalate_en[0]) && + strap_en_i + |=> + lc_tx_test_true_strict(pinmux_hw_debug_en_q)) + // Check that latching ON can only occur if lc_hw_debug_en_i is set. + `ASSERT(LcHwDebugEnSetRev0_A, + lc_tx_test_false_loose(pinmux_hw_debug_en_q) ##1 + lc_tx_test_true_strict(pinmux_hw_debug_en_q) + |-> + $past(lc_tx_test_true_strict(lc_hw_debug_en[0]))) + // Check that latching ON can only occur if strap_en_i is set. + `ASSERT(LcHwDebugEnSetRev1_A, + lc_tx_test_false_loose(pinmux_hw_debug_en_q) ##1 + lc_tx_test_true_strict(pinmux_hw_debug_en_q) + |-> + $past(strap_en_i)) + // Check that any non-OFF value on lc_check_byp_en_i and + // lc_escalate_en_i clears the latched value. + `ASSERT(LcHwDebugEnClear_A, + lc_tx_test_true_loose(lc_check_byp_en[0]) || + lc_tx_test_true_loose(lc_escalate_en[0]) + |=> + lc_tx_test_false_loose(pinmux_hw_debug_en_q)) + + ////////////////////////// + // Strap Sampling Logic // + ////////////////////////// + + logic dft_strap_valid_d, dft_strap_valid_q; + logic lc_strap_sample_en, rv_strap_sample_en, dft_strap_sample_en; + logic [NTapStraps-1:0] tap_strap_d, tap_strap_q; + logic [NDFTStraps-1:0] dft_strap_d, dft_strap_q; + + // SEC_CM: TAP.MUX.LC_GATED + // The LC strap at index 0 has a slightly different + // enable condition than the DFT strap at index 1. + assign tap_strap_d[0] = (lc_strap_sample_en) ? in_padring_i[TargetCfg.tap_strap0_idx] : + tap_strap_q[0]; + assign tap_strap_d[1] = (rv_strap_sample_en) ? in_padring_i[TargetCfg.tap_strap1_idx] : + tap_strap_q[1]; + + // We're always using the DFT strap sample enable for the DFT straps. + assign dft_strap_d = (dft_strap_sample_en) ? {in_padring_i[TargetCfg.dft_strap1_idx], + in_padring_i[TargetCfg.dft_strap0_idx]} : + dft_strap_q; + + assign dft_strap_valid_d = dft_strap_sample_en | dft_strap_valid_q; + assign dft_strap_test_o.valid = dft_strap_valid_q; + assign dft_strap_test_o.straps = dft_strap_q; + + + // During dft enabled states, we continously sample all straps unless + // told not to do so by external dft logic + logic tap_sampling_en; + logic dft_hold_tap_sel; + // Delay the strap sampling pulse by one cycle so that the pinmux_hw_debug_en above can + // propagate through the pinmux_hw_debug_en_q flop. + logic strap_en_q; + + prim_buf #( + .Width(1) + ) u_buf_hold_tap ( + .in_i(dft_hold_tap_sel_i), + .out_o(dft_hold_tap_sel) + ); + assign tap_sampling_en = lc_tx_test_true_strict(lc_dft_en[DftEnSample]) & ~dft_hold_tap_sel; + + always_comb begin : p_strap_sampling + lc_strap_sample_en = 1'b0; + rv_strap_sample_en = 1'b0; + dft_strap_sample_en = 1'b0; + // Initial strap sampling pulse from pwrmgr, + // qualified by life cycle signals. + // The DFT-mode straps are always sampled only once. + if (strap_en_q && tap_sampling_en) begin + dft_strap_sample_en = 1'b1; + end + // In DFT-enabled life cycle states we continously + // sample the TAP straps to be able to switch back and + // forth between different TAPs. + if (strap_en_q || tap_sampling_en) begin + lc_strap_sample_en = 1'b1; + if (lc_tx_test_true_strict(pinmux_hw_debug_en[HwDebugEnSample])) begin + rv_strap_sample_en = 1'b1; + end + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_strap_sample + if (!rst_ni) begin + tap_strap_q <= '0; + dft_strap_q <= '0; + dft_strap_valid_q <= 1'b0; + strap_en_q <= 1'b0; + end else begin + tap_strap_q <= tap_strap_d; + dft_strap_q <= dft_strap_d; + dft_strap_valid_q <= dft_strap_valid_d; + strap_en_q <= strap_en_i; + end + end + + /////////////////////// + // TAP Selection Mux // + /////////////////////// + + logic jtag_en; + tap_strap_t tap_strap; + jtag_pkg::jtag_req_t jtag_req, lc_jtag_req, rv_jtag_req, dft_jtag_req; + jtag_pkg::jtag_rsp_t jtag_rsp, lc_jtag_rsp, rv_jtag_rsp, dft_jtag_rsp; + + // This muxes the JTAG signals to the correct TAP, based on the + // sampled straps. Further, the individual JTAG signals are gated + // using the corresponding life cycle signal. + assign tap_strap = tap_strap_t'(tap_strap_q); + `ASSERT_KNOWN(TapStrapKnown_A, tap_strap) + + always_comb begin : p_tap_mux + jtag_rsp = '0; + // Note that this holds the JTAGs in reset + // when they are not selected. + lc_jtag_req = '0; + rv_jtag_req = '0; + dft_jtag_req = '0; + // This activates the TDO override further below. + jtag_en = 1'b0; + + unique case (tap_strap) + LcTapSel: begin + lc_jtag_req = jtag_req; + jtag_rsp = lc_jtag_rsp; + jtag_en = 1'b1; + end + RvTapSel: begin + if (lc_tx_test_true_strict(pinmux_hw_debug_en[HwDebugEnTapSel])) begin + rv_jtag_req = jtag_req; + jtag_rsp = rv_jtag_rsp; + jtag_en = 1'b1; + end + end + DftTapSel: begin + if (lc_tx_test_true_strict(lc_dft_en[DftEnTapSel])) begin + dft_jtag_req = jtag_req; + jtag_rsp = dft_jtag_rsp; + jtag_en = 1'b1; + end + end + default: ; + endcase // tap_strap_t'(tap_strap_q) + end + + // Insert hand instantiated buffers for + // these signals to prevent further optimization. + pinmux_jtag_buf u_pinmux_jtag_buf_lc ( + .req_i(lc_jtag_req), + .req_o(lc_jtag_o), + .rsp_i(lc_jtag_i), + .rsp_o(lc_jtag_rsp) + ); + pinmux_jtag_buf u_pinmux_jtag_buf_rv ( + .req_i(rv_jtag_req), + .req_o(rv_jtag_o), + .rsp_i(rv_jtag_i), + .rsp_o(rv_jtag_rsp) + ); + pinmux_jtag_buf u_pinmux_jtag_buf_dft ( + .req_i(dft_jtag_req), + .req_o(dft_jtag_o), + .rsp_i(dft_jtag_i), + .rsp_o(dft_jtag_rsp) + ); + + ////////////////////// + // TAP Input Muxes // + ////////////////////// + + // Inputs connections + assign jtag_req.tck = in_padring_i[TargetCfg.tck_idx]; + assign jtag_req.tms = in_padring_i[TargetCfg.tms_idx]; + assign jtag_req.tdi = in_padring_i[TargetCfg.tdi_idx]; + + // Note that this resets the selected TAP controller in + // scanmode. If the TAP controller needs to be active during + // reset, this reset bypass needs to be adapted accordingly. + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_rst_por_aon_n_mux ( + .clk0_i(in_padring_i[TargetCfg.trst_idx]), + .clk1_i(rst_ni), + .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode[0])), + .clk_o(jtag_req.trst_n) + ); + + // Input tie-off muxes and output overrides + for (genvar k = 0; k < NumIOs; k++) begin : gen_input_tie_off + if (k == TargetCfg.tck_idx || + k == TargetCfg.tms_idx || + k == TargetCfg.trst_idx || + k == TargetCfg.tdi_idx || + k == TargetCfg.tdo_idx) begin : gen_jtag_signal + + // Tie off inputs. + assign in_core_o[k] = (jtag_en) ? 1'b0 : in_padring_i[k]; + + if (k == TargetCfg.tdo_idx) begin : gen_output_mux + // Override TDO output. + assign out_padring_o[k] = (jtag_en) ? jtag_rsp.tdo : out_core_i[k]; + assign oe_padring_o[k] = (jtag_en) ? jtag_rsp.tdo_oe : oe_core_i[k]; + end else begin : gen_output_tie_off + // Make sure these pads are set to high-z. + assign out_padring_o[k] = (jtag_en) ? 1'b0 : out_core_i[k]; + assign oe_padring_o[k] = (jtag_en) ? 1'b0 : oe_core_i[k]; + end + + // Also reset all corresponding pad attributes to the default ('0) when JTAG is enabled. + // This disables functional pad features that may have been set, e.g., pull-up/pull-down. + // Do enable schmitt trigger on JTAG clock and JTAG reset for better signal integrity. + if (k == TargetCfg.tck_idx || k == TargetCfg.trst_idx) begin : gen_schmitt_en + assign attr_padring_o[k] = (jtag_en) ? '{schmitt_en: 1'b1, default: '0} : attr_core_i[k]; + end else begin : gen_no_schmitt + assign attr_padring_o[k] = (jtag_en) ? '0 : attr_core_i[k]; + end + end else begin : gen_other_inputs + assign attr_padring_o[k] = attr_core_i[k]; + assign in_core_o[k] = in_padring_i[k]; + assign out_padring_o[k] = out_core_i[k]; + assign oe_padring_o[k] = oe_core_i[k]; + end + end + + //////////////// + // Assertions // + //////////////// + + `ASSERT_INIT(tck_idxRange_A, TargetCfg.tck_idx >= 0 && TargetCfg.tck_idx < NumIOs) + `ASSERT_INIT(tms_idxRange_A, TargetCfg.tms_idx >= 0 && TargetCfg.tms_idx < NumIOs) + `ASSERT_INIT(trst_idxRange_A, TargetCfg.trst_idx >= 0 && TargetCfg.trst_idx < NumIOs) + `ASSERT_INIT(tdi_idxRange_A, TargetCfg.tdi_idx >= 0 && TargetCfg.tdi_idx < NumIOs) + `ASSERT_INIT(tdo_idxRange_A, TargetCfg.tdo_idx >= 0 && TargetCfg.tdo_idx < NumIOs) + + `ASSERT_INIT(tap_strap0_idxRange_A, TargetCfg.tap_strap0_idx >= 0 && + TargetCfg.tap_strap0_idx < NumIOs) + `ASSERT_INIT(tap_strap1_idxRange_A, TargetCfg.tap_strap1_idx >= 0 && + TargetCfg.tap_strap1_idx < NumIOs) + `ASSERT_INIT(dft_strap0_idxRange_A, TargetCfg.dft_strap0_idx >= 0 && + TargetCfg.dft_strap0_idx < NumIOs) + `ASSERT_INIT(dft_strap1_idxRange_A, TargetCfg.dft_strap1_idx >= 0 && + TargetCfg.dft_strap1_idx < NumIOs) + + `ASSERT(RvTapOff0_A, lc_hw_debug_en_i == Off ##2 strap_en_i && pinmux_hw_debug_en_q == Off + |=> rv_jtag_o == '0) + `ASSERT(RvTapOff1_A, pinmux_hw_debug_en[0] == Off |-> rv_jtag_o == '0) + `ASSERT(DftTapOff0_A, lc_dft_en_i == Off |-> ##2 dft_jtag_o == '0) + + // These assumptions are only used in FPV. They will cause failures in simulations. + `ASSUME_FPV(RvTapOff2_A, lc_hw_debug_en_i == Off ##2 strap_en_i && pinmux_hw_debug_en_q == Off + |=> rv_jtag_i == '0) + `ASSUME_FPV(RvTapOff3_A, pinmux_hw_debug_en[0] == Off |-> rv_jtag_i == '0) + `ASSUME_FPV(DftTapOff1_A, lc_dft_en_i == Off |-> ##2 dft_jtag_i == '0) + +endmodule : pinmux_strap_sampling diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_wkup.sv b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_wkup.sv new file mode 100644 index 0000000000000..b8b9a04b71e90 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/rtl/pinmux_wkup.sv @@ -0,0 +1,91 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +module pinmux_wkup + import pinmux_pkg::*; + import pinmux_reg_pkg::*; +#( + parameter int Cycles = 4 +) ( + input clk_i, + input rst_ni, + input wkup_en_i, + input filter_en_i, + input wkup_mode_e wkup_mode_i, + input [WkupCntWidth-1:0] wkup_cnt_th_i, + input pin_value_i, + // Wakeup request pulse signal + output logic aon_wkup_pulse_o +); + + //////////////////////////// + // Optional Signal Filter // + //////////////////////////// + + // This uses a lower value for filtering than GPIO since the always-on clock is slower. If the + // filter is disabled, this reduces to a plain 2-stage flop synchronizer. + logic filter_out_d, filter_out_q; + prim_filter #( + .AsyncOn(1), // Instantiate 2-stage synchronizer + .Cycles(Cycles) + ) u_prim_filter ( + .clk_i, + .rst_ni, + .enable_i(filter_en_i), + .filter_i(pin_value_i), + .filter_o(filter_out_d) + ); + + ////////////////////// + // Pattern Matching // + ////////////////////// + + logic rising, falling; + assign falling = ~filter_out_d & filter_out_q; + assign rising = filter_out_d & ~filter_out_q; + + logic cnt_en, cnt_eq_th; + logic [WkupCntWidth-1:0] cnt_d, cnt_q; + assign cnt_d = (cnt_eq_th) ? '0 : (cnt_en) ? cnt_q + 1'b1 : '0; + + assign cnt_eq_th = (cnt_q >= wkup_cnt_th_i); + + always_comb begin : p_mode + aon_wkup_pulse_o = 1'b0; + cnt_en = 1'b0; + if (wkup_en_i) begin + unique case (wkup_mode_i) + Negedge: begin + aon_wkup_pulse_o = falling; + end + Edge: begin + aon_wkup_pulse_o = rising | falling; + end + HighTimed: begin + cnt_en = filter_out_d; + aon_wkup_pulse_o = cnt_eq_th; + end + LowTimed: begin + cnt_en = ~filter_out_d; + aon_wkup_pulse_o = cnt_eq_th; + end + // Default to rising + default: begin + aon_wkup_pulse_o = rising; + end + endcase + end + end + + always_ff @(posedge clk_i or negedge rst_ni) begin : p_aon_pattern + if (!rst_ni) begin + filter_out_q <= 1'b0; + cnt_q <= '0; + end else begin + filter_out_q <= filter_out_d; + cnt_q <= cnt_d; + end + end + +endmodule : pinmux_wkup diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/syn/constraints.sdc b/hw/top_englishbreakfast/ip_autogen/pinmux/syn/constraints.sdc new file mode 100644 index 0000000000000..4ca2bfef15cab --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/syn/constraints.sdc @@ -0,0 +1,58 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# Generic constraints file for simple testsynthesis flow + +# note that we do not fix hold timing in this flow +set SETUP_CLOCK_UNCERTAINTY 0.5 + +##################### +# main clock # +##################### +set MAIN_CLK_PIN clk_i +set MAIN_RST_PIN rst_ni +set AON_CLK_PIN clk_aon_i + + +# set main clock to 125 MHz +set MAIN_TCK 8.0 +set_ideal_network ${MAIN_CLK_PIN} +set_ideal_network ${MAIN_RST_PIN} +set_clock_uncertainty ${SETUP_CLOCK_UNCERTAINTY} ${MAIN_CLK_PIN} + +# other timing constraint in ns +set IN_DEL 1.0 +set OUT_DEL 1.0 +set DELAY ${MAIN_TCK} + +create_clock ${MAIN_CLK_PIN} -period ${MAIN_TCK} +create_clock ${AON_CLK_PIN} -period ${MAIN_TCK} + +# in to out +set_max_delay ${DELAY} -from [all_inputs] -to [all_outputs] +# in to reg / reg to out +set_input_delay ${IN_DEL} [remove_from_collection [all_inputs] [get_ports -of_objects [get_clocks]]] -clock ${MAIN_CLK_PIN} +set_output_delay ${OUT_DEL} [all_outputs] -clock ${MAIN_CLK_PIN} + +set_clock_groups -name group1 -async \ + -group [get_clocks ${MAIN_CLK_PIN} ] \ + -group [get_clocks ${AON_CLK_PIN} ] \ + +##################### +# I/O drive/load # +##################### + +# attach load and drivers to IOs to get a more realistic estimate +set_driving_cell -no_design_rule -lib_cell ${DRIVING_CELL} -pin ${DRIVING_CELL_PIN} [all_inputs] +set_load [load_of ${LOAD_CELL_LIB}/${LOAD_CELL}/${LOAD_CELL_PIN}] [all_outputs] + +# set a nonzero critical range to be able to spot the violating paths better +# in the report +set_critical_range 0.5 ${DUT} + +##################### +# Size Only Cells # +##################### + +set_size_only -all_instances [get_cells -h *u_size_only*] true diff --git a/hw/top_englishbreakfast/ip_autogen/pinmux/syn/pinmux_syn_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/pinmux/syn/pinmux_syn_cfg.hjson new file mode 100644 index 0000000000000..28a2e8acaf38c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pinmux/syn/pinmux_syn_cfg.hjson @@ -0,0 +1,19 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + // Top level dut name (sv module). + name: pinmux + + // Fusesoc core file used for building the file list. + fusesoc_core: lowrisc:opentitan:top_englishbreakfast_pinmux:0.1 + + import_cfgs: [// Project wide common synthesis config file + "{proj_root}/hw/syn/tools/dvsim/common_syn_cfg.hjson"], + + // Timing constraints for this module + sdc_file: "{proj_root}/hw/top_englishbreakfast/ip_autogen/pinmux/syn/constraints.sdc" + + // Technology specific timing constraints for this module + foundry_sdc_file: "{foundry_root}/top_englishbreakfast/syn/foundry.constraints.sdc" +} diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/BUILD b/hw/top_englishbreakfast/ip_autogen/pwrmgr/BUILD new file mode 100644 index 0000000000000..dda56de039e27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/pwrmgr/README.md b/hw/top_englishbreakfast/ip_autogen/pwrmgr/README.md new file mode 100644 index 0000000000000..7e54ab45a8515 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/README.md @@ -0,0 +1,36 @@ +# Power Manager HWIP Technical Specification +[`pwrmgr`](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/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/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr.hjson b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr.hjson new file mode 100644 index 0000000000000..a19103d020fbe --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr.hjson @@ -0,0 +1,847 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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.1", + life_stage: "L1", + design_stage: "D3", + 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.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.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.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: "cpu_pwrmgr", + type: "uni", + name: "pwr_cpu", + act: "rcv", + package: "rv_core_ibex_pkg", + }, + + { struct: "logic", + width: 3, + type: "uni", + name: "wakeups", + act: "rcv", + package: "", + }, + + { struct: "logic", + width: 1, + 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", + width: "1" + package: "rom_ctrl_pkg", + default: "rom_ctrl_pkg::PWRMGR_DATA_DEFAULT" + }, + + { 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: "3", + 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: "0", + 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: "1", + 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: "2", + local: "true" + }, + + + { name: "NumRstReqs", + desc: "Number of peripheral reset requets", + type: "int", + default: "1", + 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: "NumRomInputs", + desc: "Number of inputs from ROM_CTRL", + type: "int", + default: "1", + local: "true" + }, + { + name: "EscNumSeverities" + desc: "Number of escalation severities" + type: "int" + default: "4" + local: "false" + }, + { + name: "EscPingCountWidth" + desc: "Width of ping count for the escalation receiver" + type: "int" + default: "16" + local: "false" + }, + + { name: "ResetMainPwrIdx", + desc: "Reset req idx for MainPwr", + type: "int", + default: "1", + local: "true" + }, + { name: "ResetEscIdx", + desc: "Reset req idx for Esc", + type: "int", + default: "2", + local: "true" + }, + { name: "ResetNdmIdx", + desc: "Reset req idx for Ndm", + type: "int", + default: "3", + 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: "2:0", + name: "REASONS", + desc: "Various peripheral wake reasons" + }, + { bits: "3", + 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: "4", + 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_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson new file mode 100644 index 0000000000000..d867437b7c554 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_sec_cm_testplan.hjson @@ -0,0 +1,219 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson new file mode 100644 index 0000000000000..aad3a73fc5690 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/pwrmgr_testplan.hjson @@ -0,0 +1,369 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "pwrmgr" + 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", + "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: escalation_timeout + desc: '''This tests the escalation timeout feature. + + If the escalation network doesn't respond to an outgoing "health" + requests within 128 cycles pwrmgr should issue an escalation reset + request. + + **Stimulus**: + - Cause the external escalation network to stop responding, either + disabling the clock or jamming the differential pairs. + + **Check**: + - After 128 cycles of inactivity an escalation reset should be + triggered. + ''' + stage: V3 + tests: ["pwrmgr_escalation_timeout"] + } + { + 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/top_englishbreakfast/ip_autogen/pwrmgr/data/top_englishbreakfast_pwrmgr.ipconfig.hjson b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/top_englishbreakfast_pwrmgr.ipconfig.hjson new file mode 100644 index 0000000000000..b97989ff9d0e8 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/data/top_englishbreakfast_pwrmgr.ipconfig.hjson @@ -0,0 +1,66 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + instance_name: top_englishbreakfast_pwrmgr + param_values: + { + NumWkups: 3 + Wkups: + [ + { + name: pin_wkup_req + width: "1" + module: pinmux_aon + } + { + name: usb_wkup_req + width: "1" + module: pinmux_aon + } + { + name: wkup_req + width: "1" + module: aon_timer_aon + } + ] + rst_reqs: + { + peripheral: + [ + { + name: aon_timer_rst_req + width: "1" + module: aon_timer_aon + desc: watchdog reset requestt + } + ] + int: + [ + { + name: MainPwr + desc: main power glitch reset request + module: pwrmgr_aon + } + { + name: Esc + desc: escalation reset request + module: alert_handler + } + ] + debug: + [ + { + name: Ndm + desc: non-debug-module reset request + module: rv_dm + } + ] + } + NumRstReqs: 1 + wait_for_external_reset: false + NumRomInputs: 1 + top_pkg_vlnv: lowrisc:constants:top_englishbreakfast_top_pkg + topname: englishbreakfast + } +} diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/defs.bzl b/hw/top_englishbreakfast/ip_autogen/pwrmgr/defs.bzl new file mode 100644 index 0000000000000..af63c18fbf175 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +load("//rules/opentitan:hw.bzl", "opentitan_ip") + +PWRMGR = opentitan_ip( + name = "pwrmgr", + hjson = "//hw/top_englishbreakfast/ip_autogen/pwrmgr:data/pwrmgr.hjson", +) diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/checklist.md b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/checklist.md new file mode 100644 index 0000000000000..2cb33d32f77e0 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/checklist.md @@ -0,0 +1,266 @@ +# 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][] | Done | +RTL | [TODO_COMPLETE][] | Done | +Code Quality | [LINT_COMPLETE][] | Done | +Code Quality | [CDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Code Quality | [RDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Review | [REVIEW_RTL][] | Done | +Review | [REVIEW_DELETED_FF][] | Done | +Review | [REVIEW_SW_CHANGE][] | Done | +Review | [REVIEW_SW_ERRATA][] | Done | +Review | Reviewer(s) | Done | @matutem, @vogelpi, @adk +Review | Signoff date | Done | 2024-08-06 + +[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][] | Done | +Tests | [FPV_ASSERTIONS_PROVEN_AT_V3][] | NA | +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][] | NA | +Coverage | [FPV_COI_COVERAGE_AT_100][] | NA | +Code Quality | [ALL_TODOS_RESOLVED][] | Done | +Code Quality | [NO_TOOL_WARNINGS_THROWN][] | Not Started | +Code Quality | [TB_LINT_COMPLETE][] | Done | +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/top_englishbreakfast/ip_autogen/pwrmgr/doc/interfaces.md b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/interfaces.md new file mode 100644 index 0000000000000..ded6ced95b86d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/interfaces.md @@ -0,0 +1,67 @@ +# 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 | rv_core_ibex_pkg::cpu_pwrmgr | uni | rcv | 1 | | +| wakeups | logic | uni | rcv | 3 | | +| rstreqs | logic | uni | rcv | 1 | | +| 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/top_englishbreakfast/ip_autogen/pwrmgr/doc/programmers_guide.md b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/programmers_guide.md new file mode 100644 index 0000000000000..4fb6b768d973c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/programmers_guide.md @@ -0,0 +1,81 @@ +# 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 interrupt handling. +2. Mask all interrupt sources that should not prevent low power entry. + - Note that merely *disabling* interrupt handling with the `mie` global interrupt-enable bit on the processing host is insufficient. + - Interrupt sources that are not masked can cause the [fall through exit](theory_of_operation.md#fall-through-handling). +3. Enable desired wakeup and reset sources in [`WAKEUP_EN`](registers.md#wakeup_en) and [`RESET_EN`](registers.md#reset_en). +4. Perform any system-specific low power entry steps, e.g. + - Interrupt checks (if something became pending prior to disable) +5. Configure low power mode configuration in [`CONTROL`](registers.md#control). + - [`LOW_POWER_HINT`](registers.md#control--low_power_hint) must be set to trigger low power entry when the CPU sleeps. +7. Set and poll [`CFG_CDC_SYNC`](registers.md#cfg_cdc_sync) to ensure above settings propagate across clock domains. +8. Execute wait-for-interrupt instruction on the processing host. + +Note that entering low power mode requires that pwrmgr's `pwr_cpu_i.core_sleeping` input be at logic high long enough to be sampled. +A wait-for-interrupt instruction does not guarantee entry into low power, since the CPU could immediately resume execution in some cases. + +### 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. + +In addition, a CPU's sleeping signal that is too short for the power manager to sample will not trigger even an attempt to go to low power. +In such cases, there will be no bits set in [`WAKE_INFO`](registers.md#wake_info), and no side effects of pwrmgr entering low power mode will trigger. + +To check the exit condition, software can follow these steps: +1. Clear low power hint in [`CONTROL`](registers.md#control) and poll until it becomes cleared. + + - Until the hint clears, the values in [`WAKE_INFO`](registers.md#wake_info) may not reflect the true exit condition. +2. Check [`WAKE_INFO`](registers.md#wake_info) to get the condition. + - If no bits are set, then this was a fast fall through, where low power entry was not attempted. + +## 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/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_connectivity.svg b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_connectivity.svg new file mode 100644 index 0000000000000..b525330ca1408 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_connectivity.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_fsms.svg b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_fsms.svg new file mode 100644 index 0000000000000..962794cd0ab79 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/pwrmgr_fsms.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/registers.md b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/registers.md new file mode 100644 index 0000000000000..00c874db5ff5e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/registers.md @@ -0,0 +1,427 @@ +# 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: `0x7` +- 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}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:3 | | | | Reserved | +| 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: `0x7` + +### 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}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:-------------------------------| +| 31:3 | | | | Reserved | +| 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: `0x1` +- Register enable: [`RESET_EN_REGWEN`](#reset_en_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN_0", "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 | 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: `0x1` + +### Fields + +```wavejson +{"reg": [{"name": "VAL_0", "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_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: `0x1f` + +### Fields + +```wavejson +{"reg": [{"name": "REASONS", "bits": 3, "attr": ["rw1c"], "rotate": -90}, {"name": "FALL_THROUGH", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "ABORT", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"bits": 27}], "config": {"lanes": 1, "fontsize": 10, "vspace": 140}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:-----------------------------------------| +| 31:5 | | | Reserved | +| 4 | rw1c | 0x0 | [ABORT](#wake_info--abort) | +| 3 | rw1c | 0x0 | [FALL_THROUGH](#wake_info--fall_through) | +| 2: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/top_englishbreakfast/ip_autogen/pwrmgr/doc/theory_of_operation.md b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/theory_of_operation.md new file mode 100644 index 0000000000000..5f197a894c9e3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/doc/theory_of_operation.md @@ -0,0 +1,304 @@ +# 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](../../../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](../../../../ip/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](../../../../ip/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](../../../../ip/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. +Recording needs clocks to be active, and during low power they are usually not. +For this reason, it is important for wakeups to be level and remain active until software clears them. + +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](../../../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/top_englishbreakfast/ip_autogen/pwrmgr/dv/README.md b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/README.md new file mode 100644 index 0000000000000..a616024a1f30f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/README.md @@ -0,0 +1,255 @@ +# 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/top_englishbreakfast/ip_autogen/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/top_englishbreakfast/ip_autogen/pwrmgr/dv/tb.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tb.sv). +It instantiates the PWRMGR DUT module [`hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/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)) + +### 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/top_englishbreakfast/ip_autogen/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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/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`: + Waits for the fast fsm to be active or inactive, indicated by whether the `fetch_en_o` output become On or Off respectively. + We mostly call this expecting it to be active 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv) module binds a few modules containing assertions to the IP as follows: +* TLUL assertions: the `tlul_assert` [assertions](../../../../ip/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/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson -i pwrmgr_smoke +``` + +## Testplan +[Testplan](../data/pwrmgr_testplan.hjson) diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_bind.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_bind.sv new file mode 100644 index 0000000000000..2faa6c04575b9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_bind.sv @@ -0,0 +1,33 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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_ctrl0_good_mubi_cov_if ( + .rst_ni (rst_ni), + .mubi (rom_ctrl_i[0].done) + ); + + bind pwrmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_rom_ctrl0_done_mubi_cov_if ( + .rst_ni (rst_ni), + .mubi (rom_ctrl_i[0].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/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el new file mode 100644 index 0000000000000..6e3e974019c86 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_cov_manual_excl.el @@ -0,0 +1,34 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_tgl_excl.cfg b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_tgl_excl.cfg new file mode 100644 index 0000000000000..9d1f7fd2c62b1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/cov/pwrmgr_tgl_excl.cfg @@ -0,0 +1,9 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +//====================================================================== +// This file contains outputs of pwrmgr tied to constants. +//====================================================================== + +-module_node pwrmgr pwr_ast_o.slow_clk_en diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/doc/tb.svg b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/doc/tb.svg new file mode 100644 index 0000000000000..285ef6948e4dc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/doc/tb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core new file mode 100644 index 0000000000000..a4949119e41e1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.core @@ -0,0 +1,57 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr_env:0.1 +description: "PWRMGR DV UVM environment" +filesets: + files_dv: + depend: + - lowrisc:dv:ralgen + - lowrisc:dv:cip_lib + - lowrisc:ip:rv_core_ibex_pkg + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + - lowrisc:constants:top_englishbreakfast_top_pkg + 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_escalation_timeout_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: ../../data/pwrmgr.hjson + +targets: + default: + filesets: + - files_dv + generate: + - ral diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.sv new file mode 100644 index 0000000000000..96646b5f2a912 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env.sv @@ -0,0 +1,57 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cfg.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cfg.sv new file mode 100644 index 0000000000000..113b8b6ea03bc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cfg.sv @@ -0,0 +1,52 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 #(.PowerDomains(pwrmgr_pkg::PowerDomains)) 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cov.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cov.sv new file mode 100644 index 0000000000000..b348b99ea00b3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_cov.sv @@ -0,0 +1,193 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_pkg.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_pkg.sv new file mode 100644 index 0000000000000..abfb1c051a061 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_env_pkg.sv @@ -0,0 +1,89 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv new file mode 100644 index 0000000000000..ed590d1345df9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_if.sv @@ -0,0 +1,219 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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; + rv_core_ibex_pkg::cpu_pwrmgr_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 [pwrmgr_reg_pkg::NumRomInputs-1:0] 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 = rv_core_ibex_pkg::CPU_PWRMGR_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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_scoreboard.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_scoreboard.sv new file mode 100644 index 0000000000000..007c98fb8e8a4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_scoreboard.sv @@ -0,0 +1,367 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 when the clock is + // meant to be enabled, or by driving rst_esc_ni active when the dut is not expecting it. + task monitor_escalation_timeout(); + fork + forever + @(posedge cfg.esc_clk_rst_vif.clk_gate) begin + if (cfg.pwrmgr_vif.pwr_clk_req.io_ip_clk_en) begin + // A timeout could be triggered if the escalation clock is stopped for too many clk_i + // cycles. The precise threshold is somewhat unpredictable for reasons explained in + // the pwrmgr_escalation_timeout sequence, and the sequence is such that 121 cycles + // works as a threshold to avoid unpredictable stoppages. + `uvm_info(`gfn, "Detected unexpected clk_esc_i stop", UVM_MEDIUM) + fork + begin : isolation_fork + // This fork is so we can wait for a number of cycles with the clock inactive, + // and stop waiting if the escalation clock gate is re-opened. + fork + begin + cfg.clk_rst_vif.wait_clks(121); + if (cfg.esc_clk_rst_vif.clk_gate && cfg.pwrmgr_vif.pwr_ast_req.io_clk_en && + cfg.pwrmgr_vif.pwr_clk_req.io_ip_clk_en) begin + `uvm_info(`gfn, "clk_esc_i has been inactive enough to trigger an alert", + UVM_MEDIUM) + `uvm_info(`gfn, "set_exp_alert from monitor_escalation_timeout clock gated", + UVM_MEDIUM) + set_exp_alert("fatal_fault", 1, 500); + end + end + // This stops the wait if the gate is re-opened. + @(negedge cfg.esc_clk_rst_vif.clk_gate); + join_any + disable fork; + end + join + 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.reset_asserted(); + 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[0] 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[0].done, + cfg.pwrmgr_vif.rom_ctrl[0].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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv new file mode 100644 index 0000000000000..ec7f602fbcb4c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/pwrmgr_virtual_sequencer.sv @@ -0,0 +1,14 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv new file mode 100644 index 0000000000000..4c8bb62548ea9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_aborted_low_power_vseq.sv @@ -0,0 +1,126 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + + 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(FastFsmActive); + + `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(); + cfg.slow_clk_rst_vif.wait_clks(4); + end + `uvm_info(`gfn, "Test done", UVM_MEDIUM) + endtask + +endclass : pwrmgr_aborted_low_power_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv new file mode 100644 index 0000000000000..75f1a7b7da956 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_base_vseq.sv @@ -0,0 +1,843 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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; + + typedef enum int { + FastFsmActive, + FastFsmInactive + } fast_fsm_activity_e; + + // 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(FastFsmActive) + fork + wait_for_fast_fsm(FastFsmActive); + 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(.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 + // Wait for the rst_lc_src_n[1] input to go inactive. + if (cfg.pwrmgr_vif.pwr_rst_rsp.rst_lc_src_n[1] != 1'b1) + @(posedge cfg.pwrmgr_vif.pwr_rst_rsp.rst_lc_src_n[1]); + 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_src_n[1] goes active, because when + // peripherals are reset they should drop their reset requests. + if (cfg.pwrmgr_vif.pwr_rst_rsp.rst_lc_src_n[1] != 1'b0) + @(negedge cfg.pwrmgr_vif.pwr_rst_rsp.rst_lc_src_n[1]); + 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)); + wait_for_csr_to_propagate_to_slow_domain(); + 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 or inactive, indicated by the + // fetch_en output going On or Off respectively. + task wait_for_fast_fsm(fast_fsm_activity_e activity = FastFsmActive); + lc_ctrl_pkg::lc_tx_t fetch_en = activity == FastFsmActive ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off; + `uvm_info(`gfn, $sformatf("starting wait for pwrmgr %s", activity.name), UVM_MEDIUM) + `DV_SPINWAIT(wait (cfg.pwrmgr_vif.fetch_en == fetch_en);, + "timeout waiting for pwrmgr fast fsm target activity", FetchEnTimeoutNs) + `uvm_info(`gfn, $sformatf("pwrmgr reached %s", activity.name), UVM_MEDIUM) + endtask + + // Waits for the lc_rst output going inactive, which would complete a device reset. + // This should not be called for shallow sleep, since there is no lc_rst request. + task wait_for_lc_rst_release(); + `uvm_info(`gfn, "starting wait for release of lc_rst for non-aon domain", UVM_MEDIUM) + `DV_WAIT(cfg.pwrmgr_vif.pwr_rst_req.rst_lc_req[1] == 1'b1, + "timeout waiting for lc_rst[1] to be active", FetchEnTimeoutNs) + `DV_WAIT(cfg.pwrmgr_vif.pwr_rst_req.rst_lc_req[1] == 1'b0, + "timeout waiting for lc_rst[1] to be inactive", FetchEnTimeoutNs) + `uvm_info(`gfn, "pwrmgr fast released lc_req[1]", 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 %s (0x%x)", cause.name, 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 + + // Checks that wake_status meets expectations. Notice different bits of wake_status can + // be updated at different times, according to their arrival order. Also, whenever reset + // goes active this comparison stops. + 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 arrived at different time because they are + // triggered outside pwrmgr, so wait a couple more cycles until there is a match or there + // is a reset. + repeat (2) begin + if (cfg.pwrmgr_vif.wakeup_status == expected_wakeups || !cfg.clk_rst_vif.rst_n) return; + cfg.clk_rst_vif.wait_clks(1); + end + `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 == exp_value);, + $sformatf("wake info wait timeout exp:%p actual:%p", exp_value, + cfg.pwrmgr_vif.wake_info), + 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[0] = 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[0].done != prim_mubi_pkg::MuBi4True) begin + cfg.pwrmgr_vif.rom_ctrl[0].good = get_rand_mubi4_val( + .t_weight(1), .f_weight(1), .other_weight(1) + ); + cfg.pwrmgr_vif.rom_ctrl[0].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[0].good = get_rand_mubi4_val( + .t_weight(1), .f_weight(1), .other_weight(1) + ); + cfg.pwrmgr_vif.rom_ctrl[0].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[0].good = get_rand_mubi4_val( + .t_weight(1), .f_weight(1), .other_weight(1) + ); + cfg.pwrmgr_vif.rom_ctrl[0].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[0].good = get_rand_mubi4_val( + .t_weight(1), .f_weight(1), .other_weight(1) + ); + cfg.pwrmgr_vif.rom_ctrl[0].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[0].good = prim_mubi_pkg::MuBi4True; + cfg.pwrmgr_vif.rom_ctrl[0].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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv new file mode 100644 index 0000000000000..e3e131efee28e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_common_vseq.sv @@ -0,0 +1,113 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv new file mode 100644 index 0000000000000..d80e87d056145 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_disable_rom_integrity_check_vseq.sv @@ -0,0 +1,130 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + 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[0].done = get_rand_mubi4_val( + .t_weight(1), .f_weight(3), .other_weight(1)); + cfg.pwrmgr_vif.rom_ctrl[0].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[0].done, + cfg.pwrmgr_vif.rom_ctrl[0].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[0].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[0].done = prim_mubi_pkg::MuBi4True; + cfg.slow_clk_rst_vif.wait_clks(2); + end + + if (cfg.pwrmgr_vif.rom_ctrl[0].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[0].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(FastFsmActive); + `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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv new file mode 100644 index 0000000000000..195adc3c8b645 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_esc_clk_rst_malfunc_vseq.sv @@ -0,0 +1,42 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + // 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(FastFsmActive); + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv new file mode 100644 index 0000000000000..12a8c851ef386 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_escalation_timeout_vseq.sv @@ -0,0 +1,88 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Description: +// This test checks that an escalation reset is generated when the escalation clock stops for +// enough cycles. +class pwrmgr_escalation_timeout_vseq extends pwrmgr_base_vseq; + `uvm_object_utils(pwrmgr_escalation_timeout_vseq) + + `uvm_object_new + + // The following two parameters are used to determine when to perform checks. + + // The number of clock cycles with a stopped escalation clock before raising escalation is 128. + // But the logic can wait for up to 7 more cycles before it starts the counter, and there is + // some additional fast clock cycles of delay in the logic that triggers the escalation to + // be signalled. This adds 12 extra cycles to be conservative. + localparam int EscTimeoutMainClkThreshold = 128 + 7 + 12; + + // In addition, there is a clock domain crossing to the slow clock, which can add a couple slow + // clocks cycles plus an extra cycle for the input to meet the next clock cycle. + localparam int EscTimeoutSlowClkThreshold = 2 + 1; + + int trans_cnt = 0; + constraint num_trans_c {num_trans inside {[1 : 5]};} + + // This stops the escalation clock for a certain number of cycles, and + // checks a reset occurs or not, depending on expect_reset. + task check_stopped_esc_clk(int stop_cycles, bit expect_reset); + fork + begin + `uvm_info(`gfn, $sformatf( + "Stopping escalation clock for %0d cycles %s expecting reset", + stop_cycles, expect_reset ? "" : "not "), + UVM_MEDIUM) + cfg.esc_clk_rst_vif.stop_clk(); + // The clock will be restarted while handling a reset, so no need to restart it here. + if (!expect_reset) begin + cfg.clk_rst_vif.wait_clks(stop_cycles); + `uvm_info(`gfn, "Restarting escalation clock", UVM_MEDIUM) + cfg.esc_clk_rst_vif.start_clk(); + cfg.esc_clk_rst_vif.wait_clks(4000); + end + end + begin + if (expect_reset) begin + // The expectation is to create an outgoing reset request, disable cpu fetching, and the + // reset cause to indicate a hardware request. + // Turn the cycle counts into a number of nanoseconds for waiting with timeout. + // The clk_rst_vifs give the period in pico seconds so divide by 1000. + int wait_ns = (EscTimeoutMainClkThreshold * cfg.clk_rst_vif.clk_period_ps + + EscTimeoutSlowClkThreshold * cfg.slow_clk_rst_vif.clk_period_ps) / 1000; + `DV_SPINWAIT( + wait(cfg.pwrmgr_vif.fetch_en != lc_ctrl_pkg::On && + cfg.pwrmgr_vif.pwr_rst_req.rstreqs[pwrmgr_reg_pkg::ResetEscIdx] == 1'b1 && + cfg.pwrmgr_vif.pwr_rst_req.reset_cause == pwrmgr_pkg::HwReq); + `uvm_info(`gfn, "escalation reset completed", UVM_LOW), + "escalation reset was not completed as expected", wait_ns) + end else begin + repeat (8000) begin + cfg.clk_rst_vif.wait_clks(1); + if (cfg.pwrmgr_vif.fetch_en != lc_ctrl_pkg::On) begin + `uvm_error(`gfn, "Unexpected cpu fetch disable, indicating a reset") + end + end + end + end + join + endtask + + virtual task body(); + wait_for_fast_fsm(FastFsmActive); + cfg.slow_clk_rst_vif.set_freq_mhz(1); + cfg.esc_clk_rst_vif.wait_clks(200); + // The timeout is not accurately predictable for two reasons: + // - The initial count for the timeout can be from 0 to 7, which means the timeout could + // happen between 121 and 128 cycles after the clock. + // - The timeout has a req-ack synchronizer which has some randomness due to the phase. + // This adds a few more cycles of uncertainty. + // Keep the clock stopped for less than 118 cycles should be safe to avoid an alert. + check_stopped_esc_clk(118, 1'b0); + check_stopped_esc_clk(2000, 1'b1); + wait_for_fast_fsm(FastFsmActive); + check_stopped_esc_clk(136, 1'b1); + endtask : body + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv new file mode 100644 index 0000000000000..0a27b8454f11d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_glitch_vseq.sv @@ -0,0 +1,42 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv new file mode 100644 index 0000000000000..19cfba5ff531d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_global_esc_vseq.sv @@ -0,0 +1,63 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv new file mode 100644 index 0000000000000..c65bcbfa3cae3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_invalid_vseq.sv @@ -0,0 +1,140 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + `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(FastFsmActive); + 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(); + + `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.slow_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(FastFsmActive); + `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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv new file mode 100644 index 0000000000000..75064051a6a74 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_lowpower_wakeup_race_vseq.sv @@ -0,0 +1,138 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + + 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(); + + set_nvms_idle(); + + // This will send the wakeup and trigger low power entry so they almost coincide. + fork + begin + cfg.slow_clk_rst_vif.wait_clks(cycles_before_transition); + // Initiate low power transition. + cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); + end + begin + cfg.slow_clk_rst_vif.wait_clks(cycles_before_early_wakeup); + // Send the wakeups. + cfg.pwrmgr_vif.update_wakeups(wakeups); + end + join + + wait_for_fast_fsm(FastFsmInactive); + + // 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. + // We wait until the cycle following the fast fsm lc_rst release. + if (ral.control.main_pd_n.get_mirrored_value() == 1'b0) begin + wait_for_lc_rst_release(); + check_wake_status(wakeups & wakeups_en); + `uvm_info(`gfn, $sformatf("Got wake_status=0x%x", wakeups & wakeups_en), UVM_MEDIUM) + end + 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(FastFsmActive); + `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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv new file mode 100644 index 0000000000000..21ec86f1cc5c7 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_repeat_wakeup_reset_vseq.sv @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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[0].done = prim_mubi_pkg::MuBi4False; + cfg.pwrmgr_vif.rom_ctrl[0].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[0].good = prim_mubi_pkg::MuBi4True; + cfg.clk_rst_vif.wait_clks(5); + cfg.pwrmgr_vif.rom_ctrl[0].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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv new file mode 100644 index 0000000000000..7b0f55f83d260 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_invalid_vseq.sv @@ -0,0 +1,129 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + 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(FastFsmActive); + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv new file mode 100644 index 0000000000000..eca20c05a4111 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_reset_vseq.sv @@ -0,0 +1,79 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + + 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, and it needs a couple additional slow + // clock cycles for a synchronizer to be ready to mask incoming resets. + wait_for_csr_to_propagate_to_slow_domain(); + cfg.slow_clk_rst_vif.wait_clks(2); + + // 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(FastFsmActive); + `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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv new file mode 100644 index 0000000000000..b8682b1b3c62c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sec_cm_ctrl_config_regwen_vseq.sv @@ -0,0 +1,48 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 and core_sleep is high, +// issue random write to PWRMGR.CONTROL and check +// PWRMGR.CONTROL value is not changed, except for LOW_POWER_HINT. +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, compare_mask; + // CONTROL.LOW_POWER_HINT is hardware-writeable, so mask it from checking. + // It gets cleared very quickly. + compare_mask = '1; + compare_mask = compare_mask - ral.control.low_power_hint.get_field_mask(); + + 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), .compare_mask(compare_mask)); + `uvm_info(`gfn, "csr done", UVM_HIGH) + end + endtask : proc_illegal_ctrl_access + + virtual task initiate_low_power_transition(); + super.initiate_low_power_transition(); + // The access checks can only happen if the bus is powered and the clock + // is active. + if ((ral.control.main_pd_n.get_mirrored_value() == 1'b1) && + (ral.control.io_clk_en.get_mirrored_value() == 1'b1)) begin + proc_illegal_ctrl_access(); + end + endtask +endclass : pwrmgr_sec_cm_ctrl_config_regwen_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv new file mode 100644 index 0000000000000..b54c5cc08dd73 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_smoke_vseq.sv @@ -0,0 +1,90 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + 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(); + + // Initiate low power transition. + cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); + wait_for_reset_cause(pwrmgr_pkg::LowPwrEntry); + + // Now bring it back. + cfg.slow_clk_rst_vif.wait_clks(cycles_before_wakeup); + cfg.pwrmgr_vif.update_wakeups(wakeups); + + wait_for_fast_fsm(FastFsmActive); + `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(FastFsmActive); + + // 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv new file mode 100644 index 0000000000000..a088b2975b230 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_stress_all_vseq.sv @@ -0,0 +1,42 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv new file mode 100644 index 0000000000000..5fdceafb753e7 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_sw_reset_vseq.sv @@ -0,0 +1,54 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + + 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(FastFsmActive); + `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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv new file mode 100644 index 0000000000000..bc09a19a0370d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_vseq_list.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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_escalation_timeout_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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv new file mode 100644 index 0000000000000..37ec341221ef9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_reset_vseq.sv @@ -0,0 +1,168 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/doc/theory_of_operation.html#rom-integrity-checks + virtual task twirl_rom_response(); + cfg.pwrmgr_vif.rom_ctrl[0].done = prim_mubi_pkg::MuBi4False; + cfg.pwrmgr_vif.rom_ctrl[0].good = prim_mubi_pkg::MuBi4False; + @(cfg.pwrmgr_vif.fast_state == pwrmgr_pkg::FastPwrStateAckPwrUp); + cfg.pwrmgr_vif.rom_ctrl[0].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[0].good = prim_mubi_pkg::MuBi4False; + cfg.clk_rst_vif.wait_clks(5); + cfg.pwrmgr_vif.rom_ctrl[0].good = prim_mubi_pkg::MuBi4True; + cfg.clk_rst_vif.wait_clks(5); + cfg.pwrmgr_vif.rom_ctrl[0].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(FastFsmActive); + + 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(); + + // 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(FastFsmActive); + + 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[0].good = prim_mubi_pkg::MuBi4True; + cfg.clk_rst_vif.wait_clks(5); + cfg.pwrmgr_vif.rom_ctrl[0].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/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv new file mode 100644 index 0000000000000..7c6176d144084 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/env/seq_lib/pwrmgr_wakeup_vseq.sv @@ -0,0 +1,130 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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(FastFsmActive); + 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, wakeups=0x%x, enables=0x%x", + enabled_wakeups, wakeups, wakeups_en), + 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(); + + // Initiate low power transition. + initiate_low_power_transition(); + + 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.slow_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(FastFsmActive); + `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 + + virtual task initiate_low_power_transition(); + cfg.pwrmgr_vif.update_cpu_sleeping(1'b1); + set_nvms_idle(); + endtask +endclass : pwrmgr_wakeup_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim.core new file mode 100644 index 0000000000000..63f81c3200bbb --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim.core @@ -0,0 +1,30 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr_sim:0.1 +description: "PWRMGR DV sim target" +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_pwrmgr:0.1 + files_dv: + depend: + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_test:0.1 + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_sva:0.1 + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_unit_only_sva:0.1 + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson new file mode 100644 index 0000000000000..c0dbeecc54817 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/pwrmgr_sim_cfg.hjson @@ -0,0 +1,161 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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:opentitan:top_englishbreakfast_pwrmgr_sim:0.1 + + // Testplan hjson file. + testplan: "{self_dir}/../data/pwrmgr_testplan.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"] + + // Exclusion files + vcs_cov_excl_files: ["{self_dir}/cov/pwrmgr_cov_manual_excl.el"] + + // Overrides + overrides: [ + { + name: design_level + value: "top" + } + // Handle generated coverage exclusion. + { + name: default_vcs_cov_cfg_file + value: "-cm_hier {dv_root}/tools/vcs/cover.cfg+{dv_root}/tools/vcs/common_cov_excl.cfg+{self_dir}/cov/pwrmgr_tgl_excl.cfg" + } + ] + + // Add additional tops for simulation. + sim_tops: ["pwrmgr_bind", + "pwrmgr_cov_bind", + "pwrmgr_unit_only_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_escalation_timeout + uvm_test_seq: pwrmgr_escalation_timeout_vseq + } + { + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv new file mode 100644 index 0000000000000..7dcc0b676a44c --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_ast_sva_if.sv @@ -0,0 +1,145 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 MinClkWaitCycles = 0; + localparam int MinPdnWaitCycles = 0; + localparam int MaxClkWaitCycles = 60; + localparam int MaxPdnWaitCycles = 110; + + bit disable_sva; + bit reset_or_disable; + + always_comb reset_or_disable = !rst_slow_ni || disable_sva; + + `define CLK_WAIT_BOUNDS ##[MinClkWaitCycles:MaxClkWaitCycles] + `define PDN_WAIT_BOUNDS ##[MinPdnWaitCycles:MaxPdnWaitCycles] + + // 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv new file mode 100644 index 0000000000000..1e37f68d4185b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_bind.sv @@ -0,0 +1,86 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 clkmgr_pwrmgr_sva_if #(.IS_USB(0)) clkmgr_pwrmgr_io_sva_if ( + .clk_i, + .rst_ni, + .clk_en(pwr_clk_o.io_ip_clk_en), + .status(pwr_clk_i.io_status) + ); + + bind pwrmgr clkmgr_pwrmgr_sva_if #(.IS_USB(0)) clkmgr_pwrmgr_main_sva_if ( + .clk_i, + .rst_ni, + .clk_en(pwr_clk_o.main_ip_clk_en), + .status(pwr_clk_i.main_status) + ); + + bind pwrmgr clkmgr_pwrmgr_sva_if #(.IS_USB(1)) clkmgr_pwrmgr_usb_sva_if ( + .clk_i, + .rst_ni, + .clk_en(pwr_clk_o.usb_ip_clk_en), + .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, + .io_clk_en(pwr_clk_o.io_ip_clk_en), + .pwr_rst_o, + .esc_timeout(esc_timeout_lc_q), + .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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv new file mode 100644 index 0000000000000..355b52cef9492 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_clock_enables_sva_if.sv @@ -0,0 +1,59 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv new file mode 100644 index 0000000000000..47d32756ee5cf --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstreqs_sva_if.sv @@ -0,0 +1,102 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 MinMainRstCycles = 0; + localparam int MaxMainRstCycles = 400; + `define MAIN_RST_CYCLES ##[MinMainRstCycles:MaxMainRstCycles] + + // 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 FastToSlowFreqRatio = 120; + + localparam int MinEscRstCycles = 0; + localparam int MaxEscRstCycles = 4 * FastToSlowFreqRatio; + `define ESC_RST_CYCLES ##[MinEscRstCycles:MaxEscRstCycles] + + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv new file mode 100644 index 0000000000000..69e868ec7f15d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sec_cm_checker_assert.sv @@ -0,0 +1,165 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This has a number of assertions to check security countermeasures. They are +// individually described in their comments. +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 logic io_clk_en, + 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 esc_timeout, + 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. + // Check that rom integrity checks are disabled when lc_dft_en_i and lc_hw_debug_en_i are active. + `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) + + // Check that rom integrity checks are enabled when either lc_dft_en_i or lc_hw_debug_en_i are + // inactive. + `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 or transition to Invalid. + `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) + + // Check that when rom_intg_chk_done is mubi true the fast state machine will transition + // from FastPwrStateRomCheckDone to either FastPwrStateRomCheckGood or Invalid. + `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) + + // Check that when one of rom_intg_chk_good or rom_intg_chk_dis is mubi true the fast + // state machine will transition from FastPwrStateRomCheckGood to FastPwrStateActive + // or Invalid. + `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) + + // For testpoints sec_cm_esc_rx_clk_bkgn_chk, sec_cm_esc_rx_clk_local_esc. + // If the escalation clock (clk_esc_i) stops for too many cycles and is not + // disabled, an escalation timeout should be requested until rst_lc_ni goes + // active. + // The bound of cycles is 128 cycles for the counter, 8 cycles maximum for the + // counter to engage, and 2 cycles for a synchronizer. Use negedge of clk_i + // to sample clk_esc_i as 1 when active, and 0 when inactive. + `ASSERT(EscClkStopEscTimeout_A, !clk_esc_i && io_clk_en [* (128 + 8 + 2)] |=> + esc_timeout || !rst_lc_ni, !clk_i, reset_or_disable) + + // For testpoints sec_cm_esc_rx_clk_bkgn_chk, sec_cm_esc_rx_clk_local_esc. + // Escalation timeout should not be requested when rst_nc_ni is active. + `ASSERT(EscTimeoutStoppedByClReset_A, + !rst_lc_ni |-> !esc_timeout, clk_i, reset_or_disable) + + // For testpoints sec_cm_esc_rx_clk_bkgn_chk, sec_cm_esc_rx_clk_local_esc. + // If escalation timeout is detected a reset request will be generated. + `ASSERT(EscTimeoutTriggersReset_A, esc_timeout |=> ##[1:3] slow_esc_rst_req, + clk_slow_i, !rst_slow_ni || disable_sva) + + // pwr_rst_o.rstreqs checker + // For testpoints sec_cm_esc_rx_clk_bkgn_chk, sec_cm_esc_rx_clk_local_esc. + // If a slow clock domain escalation reset is requested, rstreqs[ResetEscIdx] + // should be asserted after some cycles unless rst_lc_n becomes active. + `ASSERT(RstreqChkEsctimeout_A, + $rose( + slow_esc_rst_req + ) ##1 slow_esc_rst_req |-> ##[0:10] pwr_rst_o.rstreqs[ResetEscIdx] || !rst_lc_ni, + clk_i, reset_or_disable) + + // For testpoint 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) + + // For testpoint sec_cm_ctrl_flow_global_esc. + // If a slow clock domain escalation reset request is set, the output escalation + // reset pwr_rst_o.rstreqs[ResetEscIdx] should be asserted after some cycles. + `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) + + // For testpoint 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core new file mode 100644 index 0000000000000..8a5268ef5d041 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_sva.core @@ -0,0 +1,43 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr_sva:0.1 +description: "PWRMGR assertion modules and bind file." +filesets: + files_dv: + depend: + - lowrisc:tlul:headers + - lowrisc:fpv:csr_assert_gen + - lowrisc:dv:clkmgr_pwrmgr_sva_if + - lowrisc:dv:pwrmgr_rstmgr_sva_if:0.1 + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + 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:opentitan:top_englishbreakfast_pwrmgr:0.1 + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../../data/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/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_bind.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_bind.sv new file mode 100644 index 0000000000000..511af2f854d97 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_bind.sv @@ -0,0 +1,23 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This binds assertions that should not be bound at chip level. +module pwrmgr_unit_only_bind; + + bind pwrmgr pwrmgr_rstmgr_sva_if #( + .PowerDomains(pwrmgr_pkg::PowerDomains) + ) 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) + ); + +endmodule : pwrmgr_unit_only_bind diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_sva.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_sva.core new file mode 100644 index 0000000000000..b044ac8b788f1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_unit_only_sva.core @@ -0,0 +1,36 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr_unit_only_sva:0.1 +description: "PWRMGR assertion interfaces not suitable for chip level bind file." +filesets: + files_dv: + depend: + - lowrisc:tlul:headers + - lowrisc:fpv:csr_assert_gen + - lowrisc:dv:pwrmgr_rstmgr_sva_if + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg:0.1 + - lowrisc:opentitan:top_englishbreakfast_pwrmgr:0.1 + + files: + - pwrmgr_unit_only_bind.sv + file_type: systemVerilogSource + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../../data/pwrmgr.hjson + +targets: + default: &default_target + filesets: + - files_dv + generate: + - csr_assert_gen + formal: + <<: *default_target + filesets: + - files_dv + toplevel: pwrmgr diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tb.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tb.sv new file mode 100644 index 0000000000000..ab83adf8c1409 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tb.sv @@ -0,0 +1,140 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 [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) + ); + 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#(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/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_base_test.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_base_test.sv new file mode 100644 index 0000000000000..0432cfc12b3e7 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_base_test.sv @@ -0,0 +1,20 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test.core new file mode 100644 index 0000000000000..7fd778fb54644 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr_test:0.1 +description: "PWRMGR DV UVM test" +filesets: + files_dv: + depend: + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_env:0.1 + 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/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test_pkg.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test_pkg.sv new file mode 100644 index 0000000000000..afbd194155618 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/tests/pwrmgr_test_pkg.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.vlt b/hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.vlt new file mode 100644 index 0000000000000..a38de163cf134 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.vlt @@ -0,0 +1,5 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.waiver b/hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.waiver new file mode 100644 index 0000000000000..75aee6c3c1161 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr.waiver @@ -0,0 +1,5 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr_pkg.vlt b/hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr_pkg.vlt new file mode 100644 index 0000000000000..a5949a211be74 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/lint/pwrmgr_pkg.vlt @@ -0,0 +1,12 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr.core new file mode 100644 index 0000000000000..ca7a375cf9d10 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr.core @@ -0,0 +1,81 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr:0.1 +description: "Power manager RTL" + +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:rv_core_ibex_pkg + - lowrisc:prim:sparse_fsm + - lowrisc:prim:mubi + - lowrisc:prim:clock_buf + - lowrisc:prim:measure + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg:0.1 + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_reg:0.1 + files: + - 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: + 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/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_pkg.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_pkg.core new file mode 100644 index 0000000000000..7efedab736090 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_pkg.core @@ -0,0 +1,32 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg:0.1 +description: "Power manager package" +virtual: + - lowrisc:ip_interfaces:pwrmgr_pkg + +filesets: + files_rtl: + depend: + - lowrisc:tlul:headers + files: + - rtl/pwrmgr_reg_pkg.sv + - 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/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_reg.core b/hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_reg.core new file mode 100644 index 0000000000000..3fb99a5fe2783 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/pwrmgr_reg.core @@ -0,0 +1,21 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_pwrmgr_reg:0.1 +description: "Power manager registers" + +filesets: + files_rtl: + depend: + - lowrisc:ip:tlul + - lowrisc:prim:subreg + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + files: + - rtl/pwrmgr_reg_top.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr.sv new file mode 100644 index 0000000000000..0941673ab526a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr.sv @@ -0,0 +1,760 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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}}, + parameter int unsigned EscNumSeverities = 4, + parameter int unsigned EscPingCountWidth = 16 +) ( + // 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 rv_core_ibex_pkg::cpu_pwrmgr_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 [NumRomInputs-1:0] 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 (EscNumSeverities), + .PING_CNT_DW (EscPingCountWidth) + ) 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, which will cause slow_peri_reqs_masked.rstreqs[ResetEscIdx] to drop. + `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] !slow_peri_reqs_masked.rstreqs[ResetEscIdx] || 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, esc_timeout_lc_d, esc_timeout_lc_q; + // 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) + ); + + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_esc_timeout_sync ( + .clk_i(clk_lc), + .rst_ni(rst_lc_n), + .d_i(esc_timeout), + .q_o(esc_timeout_lc_d) + ); + + always_ff @(posedge clk_lc or negedge rst_lc_n) begin + if (!rst_lc_n) begin + esc_timeout_lc_q <= '0; + end else if (esc_timeout_lc_d) begin + // once latched, do not clear until reset + esc_timeout_lc_q <= 1'b1; + end + end + + + //////////////////////////// + /// 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_lc_q; + 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 [NumRomInputs-1:0] rom_ctrl_done_async; + prim_mubi_pkg::mubi4_t [NumRomInputs-1:0] rom_ctrl_done; + prim_mubi_pkg::mubi4_t rom_ctrl_done_combined; + prim_mubi_pkg::mubi4_t rom_ctrl_good_combined; + + logic core_sleeping; + logic low_power_entry; + + //////////////////////////// + /// 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) + ); + + // 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_entry) 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_lc_q; + 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 + //////////////////////////// + + // Assign to array for convenience in CDC block below. + for (genvar k = 0; k < NumRomInputs; k ++) begin : gen_done_assign + assign rom_ctrl_done_async[k] = rom_ctrl_i[k].done; + end + + 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_done_async), + .rom_ctrl_done_o(rom_ctrl_done), + + // core sleeping + .core_sleeping_i(pwr_cpu_i.core_sleeping), + .core_sleeping_o(core_sleeping) + + ); + + always_comb begin + rom_ctrl_done_combined = prim_mubi_pkg::MuBi4True; + rom_ctrl_good_combined = prim_mubi_pkg::MuBi4True; + for (int k = 0; k < NumRomInputs; k++) begin + rom_ctrl_done_combined = + prim_mubi_pkg::mubi4_and_hi(rom_ctrl_done_combined, rom_ctrl_done[k]); + // rom_ctrl_i.good is not synchronized as it acts as a "payload" signal + // to "done". Good is only observed if "done" is high. + rom_ctrl_good_combined = + prim_mubi_pkg::mubi4_and_hi(rom_ctrl_good_combined, rom_ctrl_i[k].good); + end + end + + 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; + assign low_power_entry = core_sleeping & low_power_hint; + + 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 (low_power_entry), + .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_combined), + .rom_ctrl_good_i (rom_ctrl_good_combined), + + // processing element + .fetch_en_o, + + // pinmux and other peripherals + .strap_o, + .strap_sampled_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/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv new file mode 100644 index 0000000000000..d761c467b7d17 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc.sv @@ -0,0 +1,335 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 [NumRomInputs-1:0] rom_ctrl_done_i, + output prim_mubi_pkg::mubi4_t [NumRomInputs-1:0] 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) + ); + + for (genvar k = 0; k < NumRomInputs; k++) begin : gen_rom_inputs + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(1), + .StabilityCheck(1) + ) u_sync_rom_ctrl ( + .clk_i, + .rst_ni, + .mubi_i(rom_ctrl_done_i[k]), + .mubi_o({rom_ctrl_done_o[k]}) + ); + end + + //////////////////////////////// + // 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/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc_pulse.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc_pulse.sv new file mode 100644 index 0000000000000..ad7c501439ef3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_cdc_pulse.sv @@ -0,0 +1,91 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv new file mode 100644 index 0000000000000..b1470c3bdef42 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_fsm.sv @@ -0,0 +1,542 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 strap_sampled_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 + + // 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_o <= 1'b0; + end else if (&rst_sys_req_q) begin + strap_sampled_o <= 1'b0; + end else if (strap_o) begin + strap_sampled_o <= 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 initialization + 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_o; + 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/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv new file mode 100644 index 0000000000000..795060b1a5394 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_pkg.sv @@ -0,0 +1,272 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 + }; + + // 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 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/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_pkg.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_pkg.sv new file mode 100644 index 0000000000000..3d8a41d677db3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_pkg.sv @@ -0,0 +1,277 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 = 3; + parameter int PINMUX_AON_PIN_WKUP_REQ_IDX = 0; + parameter int PINMUX_AON_USB_WKUP_REQ_IDX = 1; + parameter int AON_TIMER_AON_WKUP_REQ_IDX = 2; + parameter int NumRstReqs = 1; + parameter int NumIntRstReqs = 2; + parameter int NumDebugRstReqs = 1; + parameter int NumRomInputs = 1; + parameter int ResetMainPwrIdx = 1; + parameter int ResetEscIdx = 2; + parameter int ResetNdmIdx = 3; + 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; + } main_pd_n; + struct packed { + logic q; + } usb_clk_en_active; + struct packed { + logic q; + } usb_clk_en_lp; + struct packed { + logic q; + } io_clk_en; + struct packed { + logic q; + } core_clk_en; + struct packed { + logic q; + } low_power_hint; + } 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; + } abort; + struct packed { + logic q; + logic qe; + } fall_through; + struct packed { + logic [2:0] q; + logic qe; + } reasons; + } pwrmgr_reg2hw_wake_info_reg_t; + + typedef struct packed { + struct packed { + logic q; + } main_pd_glitch; + struct packed { + logic q; + } esc_timeout; + struct packed { + logic q; + } reg_intg_err; + } 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 [2: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; // [29:29] + pwrmgr_reg2hw_intr_enable_reg_t intr_enable; // [28:28] + pwrmgr_reg2hw_intr_test_reg_t intr_test; // [27:26] + pwrmgr_reg2hw_alert_test_reg_t alert_test; // [25:24] + pwrmgr_reg2hw_control_reg_t control; // [23:18] + pwrmgr_reg2hw_cfg_cdc_sync_reg_t cfg_cdc_sync; // [17:16] + pwrmgr_reg2hw_wakeup_en_mreg_t [2:0] wakeup_en; // [15:13] + pwrmgr_reg2hw_reset_en_mreg_t [0:0] reset_en; // [12:12] + pwrmgr_reg2hw_wake_info_capture_dis_reg_t wake_info_capture_dis; // [11:11] + pwrmgr_reg2hw_wake_info_reg_t wake_info; // [10: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; // [27:26] + pwrmgr_hw2reg_ctrl_cfg_regwen_reg_t ctrl_cfg_regwen; // [25:25] + pwrmgr_hw2reg_control_reg_t control; // [24:23] + pwrmgr_hw2reg_cfg_cdc_sync_reg_t cfg_cdc_sync; // [22:21] + pwrmgr_hw2reg_wake_status_mreg_t [2:0] wake_status; // [20:15] + pwrmgr_hw2reg_reset_status_mreg_t [0:0] reset_status; // [14:13] + pwrmgr_hw2reg_escalate_reset_status_reg_t escalate_reset_status; // [12:11] + pwrmgr_hw2reg_wake_info_reg_t wake_info; // [10: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 [4:0] PWRMGR_WAKE_INFO_RESVAL = 5'h 0; + parameter logic [2:0] PWRMGR_WAKE_INFO_REASONS_RESVAL = 3'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_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_top.sv new file mode 100644 index 0000000000000..b2414167d2136 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_reg_top.sv @@ -0,0 +1,1241 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 +); + + 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 = 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 wake_status_val_0_qs; + logic wake_status_val_1_qs; + logic wake_status_val_2_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 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 [2:0] wake_info_reasons_qs; + logic [2: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) + ); + + + // 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) + ); + + + // 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[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]: 2:0 + prim_subreg_ext #( + .DW (3) + ) 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]: 3:3 + 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]: 4:4 + 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 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_wd = reg_wdata[0]; + 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[2:0]; + + assign wake_info_fall_through_wd = reg_wdata[3]; + + assign wake_info_abort_wd = reg_wdata[4]; + + // 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; + 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; + end + + addr_hit[10]: begin + reg_rdata_next[0] = reset_en_regwen_qs; + end + + addr_hit[11]: begin + reg_rdata_next[0] = reset_en_qs; + end + + addr_hit[12]: begin + reg_rdata_next[0] = reset_status_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[2:0] = wake_info_reasons_qs; + reg_rdata_next[3] = wake_info_fall_through_qs; + reg_rdata_next[4] = 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_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_slow_fsm.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_slow_fsm.sv new file mode 100644 index 0000000000000..f78105a85874d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_slow_fsm.sv @@ -0,0 +1,358 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_wake_info.sv b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_wake_info.sv new file mode 100644 index 0000000000000..ada62ea1d1a95 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/rtl/pwrmgr_wake_info.sv @@ -0,0 +1,74 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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/top_englishbreakfast/ip_autogen/pwrmgr/util/reg_pwrmgr.py b/hw/top_englishbreakfast/ip_autogen/pwrmgr/util/reg_pwrmgr.py new file mode 100755 index 0000000000000..736fbb81f8998 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/pwrmgr/util/reg_pwrmgr.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/rstmgr/BUILD b/hw/top_englishbreakfast/ip_autogen/rstmgr/BUILD new file mode 100644 index 0000000000000..dda56de039e27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/rstmgr/README.md b/hw/top_englishbreakfast/ip_autogen/rstmgr/README.md new file mode 100644 index 0000000000000..e907ed1e44655 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/README.md @@ -0,0 +1,29 @@ +# Reset Manager HWIP Technical Specification + +[`rstmgr`](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/latest/report.html): +![](https://dashboards.lowrisc.org/badges/dv/rstmgr/test.svg) +![](https://dashboards.lowrisc.org/badges/dv/rstmgr/passing.svg) +![](https://dashboards.lowrisc.org/badges/dv/rstmgr/functional.svg) +![](https://dashboards.lowrisc.org/badges/dv/rstmgr/code.svg) + +[`rstmgr_cnsty_chk`](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/latest/report.html): +![](https://dashboards.lowrisc.org/badges/dv/rstmgr_cnsty_chk/test.svg) +![](https://dashboards.lowrisc.org/badges/dv/rstmgr_cnsty_chk/passing.svg) +![](https://dashboards.lowrisc.org/badges/dv/rstmgr_cnsty_chk/functional.svg) +![](https://dashboards.lowrisc.org/badges/dv/rstmgr_cnsty_chk/code.svg) + +# Overview + +This document describes the functionality of the reset controller and its interaction with the rest of the OpenTitan system. + +## Features + +* Stretch incoming POR. +* Cascaded system resets. +* Peripheral system reset requests. +* RISC-V non-debug-module reset support. +* Limited and selective software controlled module reset. +* Always-on reset information register. +* Always-on alert crash dump register. +* Always-on CPU crash dump register. +* Reset consistency checks. diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.cfg.example.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.cfg.example.hjson new file mode 100644 index 0000000000000..028899301a0c1 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.cfg.example.hjson @@ -0,0 +1,48 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Example configuration +{ + // Reset attributes + // name: name of reset. + // + // gen: whether the reset is generated + // 1: it is a generated reset inside rstmgr + // 0: it is a hardwired design reset inside rstmgr (roots and por) + // + // type: the reset type [ext, top] + // ext: the reset is coming in from the ports, external to earlgrey + // int: the reset is only used inside rstmgr + // top: the reset is output from rstmgr to top level struct + // + // root: The parent reset + // If type is "ext", there is no root, since it is external + // + // domain: The power domain + // If no domain, it means there is no choice, just inherits from root. + // Otherwise, selects the domain to which it is related + // 0 is defaulted for always on. + // TBD: This should eventually be changed to a name->index project wide lookup + // + // clk: related clock domain for synchronous release + // If type is "por", there is not related clock, since it is + // likely external or generated from a voltage comparator + // + resets: [ + { name: "rst_ni", gen: 0, type: "ext" } + { name: "por_aon", gen: 0, type: "top", root: "rst_ni", clk: "aon" } + { name: "lc_src", gen: 0, type: "int", root: "por", clk: "io_div2" } + { name: "sys_src", gen: 0, type: "int", root: "por", clk: "io_div2" } + { name: "por", gen: 1, type: "top", root: "por_aon", clk: "main" } + { name: "por_io", gen: 1, type: "top", root: "por_aon", clk: "io" } + { name: "por_io_div2", gen: 1, type: "top", root: "por_aon", clk: "io_div2" } + { name: "por_usb", gen: 1, type: "top", root: "por_aon", clk: "usb" } + { name: "lc", gen: 1, type: "top", domain: "0", root: "lc_src", clk: "io_div2" } + { name: "sys", gen: 1, type: "top", domain: "0", root: "sys_src", clk: "main" } + { name: "sys_io", gen: 1, type: "top", domain: "0", root: "sys_src", clk: "io_div2" } + { name: "sys_aon", gen: 1, type: "top", domain: "0", root: "sys_src", clk: "aon" } + { name: "spi_device", gen: 1, type: "top", domain: "0", root: "sys_src", clk: "io_div2", sw: 1 } + { name: "usb", gen: 1, type: "top", domain: "0", root: "sys_src", clk: "usb", sw: 1 } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.hjson new file mode 100644 index 0000000000000..c4dfb734016fd --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr.hjson @@ -0,0 +1,605 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + + + +# RSTMGR register template +# +{ + name: "rstmgr", + human_name: "Reset Manager", + one_line_desc: "Controls the on-chip reset signals, records reset cause and CPU crash dump for software", + one_paragraph_desc: ''' + Reset Manager controls the on-chip reset. + It receives one root power-on reset signal for each power domain from AST and feeds one reset signal for each on-chip reset domain to the OpenTitan hardware blocks. + Resets can be requested by Power Manager, which internally arbitrates peripheral resets, e.g., from AON Timer and Alert Handler, RISC-V Debug Module, and to a limited extent by software. + Through always-on registers, software can get information on the reset cause, as well as alert and CPU status prior to a triggered reset (crash dump). + To deter fault injection (FI) attacks, several countermeasures are implemented, including consistency checks of leaf resets and support for shadow resets. + ''' + // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. + cip_id: "22", + design_spec: "../doc", + dv_doc: "../doc/dv", + hw_checklist: "../doc/checklist", + sw_checklist: "/sw/device/lib/dif/dif_rstmgr", + revisions: [ + { + version: "1.0.0", + life_stage: "L1", + design_stage: "D3", + verification_stage: "V2S", + dif_stage: "S2", + } + ] + clocking: [ + {clock: "clk_i", reset: "rst_ni", primary: true}, + {clock: "clk_aon_i"}, + {clock: "clk_io_div4_i"}, + {clock: "clk_main_i"}, + {clock: "clk_io_i"}, + {clock: "clk_io_div2_i"}, + {clock: "clk_usb_i"}, + {clock: "clk_por_i", reset: "rst_por_ni"}, + ] + bus_interfaces: [ + { protocol: "tlul", direction: "device" } + ], + alert_list: [ + { name: "fatal_fault", + desc: ''' + This fatal alert is triggered when a fatal structural fault is detected. + Structural faults include errors such as sparse fsm errors and tlul integrity errors. + ''' + } + { name: "fatal_cnsty_fault", + desc: ''' + This fatal alert is triggered when a reset consistency fault is detected. + It is separated from the category above for clearer error collection and debug. + ''' + } + ], + countermeasures: [ + { name: "BUS.INTEGRITY", + desc: "End-to-end bus integrity scheme." + } + { name: "SCAN.INTERSIG.MUBI", + desc: "scan control signals are multibit" + } + { name: "LEAF.RST.BKGN_CHK", + desc: "Background consistency checks for each leaf reset." + } + { name: "LEAF.RST.SHADOW", + desc: "Leaf resets to blocks containing shadow registers are shadowed" + } + { name: "LEAF.FSM.SPARSE", + desc: "Sparsely encoded fsm for each leaf rst check. The Hamming delta is only 3 as there are a significant number of leaf resets" + } + { name: "SW_RST.CONFIG.REGWEN", + desc: "Software reset controls are protected by regwen" + } + { name: "DUMP_CTRL.CONFIG.REGWEN", + desc: "Crash dump controls are protected by regwen" + } + ] + regwidth: "32", + scan: "true", + scan_reset: "true", + param_list: [ + { name: "RdWidth", + desc: "Read width for crash info", + type: "int", + default: "32", + local: "true" + }, + + { name: "IdxWidth", + desc: "Index width for crash info", + type: "int", + default: "4", + local: "true" + }, + + { name: "NumHwResets", + desc: "Number of hardware reset requests, inclusive of debug resets and pwrmgr's internal resets ", + type: "int", + default: "4", + local: "true" + }, + + { name: "NumSwResets", + desc: "Number of software resets", + type: "int", + default: "3", + local: "true" + }, + + { name: "NumTotalResets", + desc: "Number of total reset requests, inclusive of hw/sw, por and low power exit", + type: "int", + default: "7", + local: "true" + }, + + { name: "SecCheck", + type: "bit", + default: "1'b1", + desc: ''' + When 1, enable rstmgr reset consistency checks. + When 0, there are no consistency checks. + ''' + local: "false", + expose: "true" + }, + + { name: "SecMaxSyncDelay", + type: "int", + default: "2", + desc: ''' + The maximum synchronization delay for parent / child reset checks. + ''' + local: "false", + expose: "true" + }, + ], + features: [ + { name: "RSTMGR.SW_RST.CHIP_RESET", + desc: "Cause a reset of all but some AON and system debug blocks via CSR." + } + { name: "RSTMGR.SW_RST.SPI_DEVICE_REQUEST", + desc: "Trigger reset of SPI_DEVICE peripheral via CSR." + } + { name: "RSTMGR.SW_RST.SPI_DEVICE_ENABLE", + desc: "Enable reset of SPI_DEVICE peripheral via CSR." + } + { name: "RSTMGR.SW_RST.SPI_HOST0_REQUEST", + desc: "Trigger reset of SPI_HOST0 peripheral via CSR." + } + { name: "RSTMGR.SW_RST.SPI_HOST0_ENABLE", + desc: "Enable reset of SPI_HOST0 peripheral via CSR." + } + { name: "RSTMGR.SW_RST.USB_REQUEST", + desc: "Trigger reset of USB peripheral via CSR." + } + { name: "RSTMGR.SW_RST.USB_ENABLE", + desc: "Enable reset of USB peripheral via CSR." + } + { name: "RSTMGR.RESET_INFO.CAPTURE", + desc: "Capture information about the causes of a reset." + } + { name: "RSTMGR.RESET_INFO.CLEAR", + desc: "Clear information about the causes of a reset." + } + { name: "RSTMGR.ALERT_INFO.CAPTURE", + desc: "Capture alert crash dump information upon reset." + } + { name: "RSTMGR.ALERT_INFO.ENABLE", + desc: "Enable capture of alert crash dump information." + } + { name: "RSTMGR.CPU_INFO.CAPTURE", + desc: "Capture cpu crash dump information upon reset." + } + { name: "RSTMGR.CPU_INFO.ENABLE", + desc: "Enable capture of cpu crash dump information." + } + { name: "RSTMGR.ALERT_HANDLER.RESET_STATUS", + desc: "Inform alert handler about reset enable status for each reset." + } + ] + // Define rstmgr struct package + inter_signal_list: [ + { struct: "logic", + type: "uni", + name: "por_n", + act: "rcv", + width: "2" + desc: ''' + Root power on reset signals from ast. + There is one root reset signal for each core power domain. + ''' + }, + + { struct: "pwr_rst", // pwr_rst_req_t, pwr_rst_rsp_t + type: "req_rsp", + name: "pwr", // resets_o (req), resets_i (rsp) + act: "rsp", + desc: ''' + Reset request signals from power manager. + Power manager can request for specific domains of the lc/sys reset tree to assert. + ''' + }, + + { struct: "rstmgr_out", + type: "uni", + name: "resets", + act: "req", + package: "rstmgr_pkg", // Origin package (only needs for the req) + desc: ''' + Leaf resets fed to the system. + ''' + }, + + { struct: "rstmgr_rst_en", + type: "uni", + name: "rst_en", + act: "req", + package: "rstmgr_pkg", // Origin package (only needs for the req) + desc: ''' + Low-power-group outputs used by alert handler. + ''' + }, + + { struct: "alert_crashdump", + type: "uni", + name: "alert_dump", + act: "rcv", + package: "alert_pkg", + desc: ''' + Alert handler crash dump information. + ''' + }, + + { struct: "cpu_crash_dump", + type: "uni", + name: "cpu_dump", + act: "rcv", + package: "rv_core_ibex_pkg", + desc: ''' + Main processing element crash dump information. + ''' + }, + + { struct: "mubi4", + type: "uni", + name: "sw_rst_req", + act: "req", + package: "prim_mubi_pkg", + desc: ''' + Software requested system reset to pwrmgr. + ''' + }, + + // Exported resets + ], + + registers: [ + + { name: "RESET_REQ", + desc: ''' + Software requested system reset. + ''', + swaccess: "rw", + hwaccess: "hrw", + fields: [ + { bits: "3:0", + mubi: true + name: "VAL", + desc: ''' + When set to kMultiBitBool4True, a reset to power manager is requested. + Upon completion of reset, this bit is automatically cleared by hardware. + ''' + resval: false + }, + ], + tags: [// This register will cause a system reset, directed test only + "excl:CsrAllTests:CsrExclWrite"] + }, + + { name: "RESET_INFO", + desc: ''' + Device reset reason. + ''', + swaccess: "rw1c", + hwaccess: "hwo", + sync: "clk_por_i", + fields: [ + { bits: "0", + hwaccess: "none", + name: "POR", + desc: ''' + Indicates when a device has reset due to power up. + ''' + resval: "1" + }, + + { bits: "1", + name: "LOW_POWER_EXIT", + desc: ''' + Indicates when a device has reset due low power exit. + ''' + resval: "0" + }, + + { bits: "2", + hwaccess: "hrw", + name: "SW_RESET", + desc: ''' + Indicates when a device has reset due to !!RESET_REQ. + ''' + resval: "0" + }, + + // reset requests include escalation reset, main power glitch, + // ndm reset request + other peripheral requests + { bits: "6:3", + hwaccess: "hrw", + name: "HW_REQ", + desc: ''' + Indicates when a device has reset due to a hardware requested reset. + The bit mapping is as follows: + b3: aon_timer_aon: watchdog reset requestt + b4: pwrmgr_aon: main power glitch reset request + b5: alert_handler: escalation reset request + b6: rv_dm: non-debug-module reset request + ''' + resval: "0" + }, + ] + }, + + { name: "ALERT_REGWEN", + desc: "Alert write enable", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1" + desc: ''' + When 1, !!ALERT_INFO_CTRL can be modified. + ''' + }, + ] + } + + { name: "ALERT_INFO_CTRL", + desc: ''' + Alert info dump controls. + ''', + swaccess: "rw", + hwaccess: "hro", + sync: "clk_por_i", + regwen: "ALERT_REGWEN", + fields: [ + { bits: "0", + name: "EN", + hwaccess: "hrw", + desc: ''' + Enable alert dump to capture new information. + This field is automatically set to 0 upon system reset (even if rstmgr is not reset). + ''' + resval: "0" + }, + + { bits: "4+IdxWidth-1:4", + name: "INDEX", + desc: ''' + Controls which 32-bit value to read. + ''' + resval: "0" + }, + ] + }, + + { name: "ALERT_INFO_ATTR", + desc: ''' + Alert info dump attributes. + ''', + swaccess: "ro", + hwaccess: "hwo", + sync: "clk_por_i", + hwext: "true", + fields: [ + { bits: "IdxWidth-1:0", + name: "CNT_AVAIL", + swaccess: "ro", + hwaccess: "hwo", + desc: ''' + The number of 32-bit values contained in the alert info dump. + ''' + resval: "0", + tags: [// This field is tied to a design constant, thus the + // default value is never 0. Since there is not a way + // to express this behavior at the moment, exclude from automated checks. + "excl:CsrAllTests:CsrExclCheck"] + }, + ] + }, + + { name: "ALERT_INFO", + desc: ''' + Alert dump information prior to last reset. + Which value read is controlled by the !!ALERT_INFO_CTRL register. + ''', + swaccess: "ro", + hwaccess: "hwo", + sync: "clk_por_i", + hwext: "true", + fields: [ + { bits: "31:0", + name: "VALUE", + desc: ''' + The current 32-bit value of crash dump. + ''' + resval: "0", + }, + ] + }, + { name: "CPU_REGWEN", + desc: "Cpu write enable", + swaccess: "rw0c", + hwaccess: "none", + fields: [ + { bits: "0", + name: "EN", + resval: "1" + desc: ''' + When 1, !!CPU_INFO_CTRL can be modified. + ''' + }, + ] + } + + { name: "CPU_INFO_CTRL", + desc: ''' + Cpu info dump controls. + ''', + swaccess: "rw", + hwaccess: "hro", + sync: "clk_por_i", + regwen: "CPU_REGWEN", + fields: [ + { bits: "0", + name: "EN", + hwaccess: "hrw", + desc: ''' + Enable cpu dump to capture new information. + This field is automatically set to 0 upon system reset (even if rstmgr is not reset). + ''' + resval: "0" + }, + + { bits: "4+IdxWidth-1:4", + name: "INDEX", + desc: ''' + Controls which 32-bit value to read. + ''' + resval: "0" + }, + ] + }, + + { name: "CPU_INFO_ATTR", + desc: ''' + Cpu info dump attributes. + ''', + swaccess: "ro", + hwaccess: "hwo", + sync: "clk_por_i", + hwext: "true", + fields: [ + { bits: "IdxWidth-1:0", + name: "CNT_AVAIL", + swaccess: "ro", + hwaccess: "hwo", + desc: ''' + The number of 32-bit values contained in the cpu info dump. + ''' + resval: "0", + tags: [// This field is tied to a design constant, thus the + // default value is never 0. Since there is not a way + // to express this behavior at the moment, exclude from automated checks. + "excl:CsrAllTests:CsrExclCheck"] + }, + ] + }, + + { name: "CPU_INFO", + desc: ''' + Cpu dump information prior to last reset. + Which value read is controlled by the !!CPU_INFO_CTRL register. + ''', + swaccess: "ro", + hwaccess: "hwo", + sync: "clk_por_i", + hwext: "true", + fields: [ + { bits: "31:0", + name: "VALUE", + desc: ''' + The current 32-bit value of crash dump. + ''' + resval: "0", + }, + ] + }, + + + # Templated registers for software control + + { multireg: { + cname: "RSTMGR_SW_RST", + name: "SW_RST_REGWEN", + desc: ''' + Register write enable for software controllable resets. + When a particular bit value is 0, the corresponding value in !!SW_RST_CTRL_N can no longer be changed. + When a particular bit value is 1, the corresponding value in !!SW_RST_CTRL_N can be changed. + ''', + count: "NumSwResets", + swaccess: "rw0c", + hwaccess: "none", + compact: false, + fields: [ + { + bits: "0", + name: "EN", + desc: "Register write enable for software controllable resets", + resval: "1", + }, + ], + } + } + + { multireg: { + cname: "RSTMGR_SW_RST", + name: "SW_RST_CTRL_N", + desc: ''' + Software controllable resets. + When a particular bit value is 0, the corresponding module is held in reset. + When a particular bit value is 1, the corresponding module is not held in reset. + ''', + count: "NumSwResets", + swaccess: "rw", + hwaccess: "hro", + regwen: "SW_RST_REGWEN", + regwen_multi: true, + fields: [ + { + bits: "0", + name: "VAL", + desc: "Software reset value", + resval: "1", + }, + ], + tags: [// Don't reset other IPs as it will affect CSR access on these IPs. + // In addition, rapid flips of these bits can occasionally cause the reset + // consistency checkers to trigger alerts, which also update err_code bits. + "excl:CsrAllTests:CsrExclWrite"] + } + } + + { name: "ERR_CODE", + desc: ''' + A bit vector of all the errors that have occurred in reset manager + ''', + swaccess: "ro", + hwaccess: "hrw", + fields: [ + { bits: "0", + name: "REG_INTG_ERR", + desc: ''' + The register file has experienced an integrity error. + ''' + resval: "0" + }, + + { bits: "1", + name: "RESET_CONSISTENCY_ERR", + desc: ''' + A inconsistent parent / child reset was observed. + ''' + resval: "0" + }, + + { bits: "2", + name: "FSM_ERR", + desc: ''' + Sparsely encoded fsm error. + ''' + resval: "0" + }, + + ] + }, + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_sec_cm_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_sec_cm_testplan.hjson new file mode 100644 index 0000000000000..096bd7f57771e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_sec_cm_testplan.hjson @@ -0,0 +1,108 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// .../rstmgr/data/rstmgr.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: +// .../rstmgr/data/rstmgr_testplan.hjson +{ + testpoints: [ + { + name: sec_cm_bus_integrity + desc: '''Verify the countermeasure(s) BUS.INTEGRITY. + This entry is covered by tl_access_test. + ''' + stage: V2S + tests: ["rstmgr_tl_intg_err"] + } + { + name: sec_cm_scan_intersig_mubi + desc: '''Verify the countermeasure(s) SCAN.INTERSIG.MUBI. + + **Stimulus**: + Same as smoke test but drive scanmode_i with a constant invalid + value during the test. + + **Check**: + If dut accepts any of invalid values, test will fail by turning dut to scanmode. + ''' + stage: V2S + tests: ["rstmgr_sec_cm_scan_intersig_mubi"] + } + { + name: sec_cm_leaf_rst_bkgn_chk + desc: '''Verify the countermeasure(s) LEAF.RST.BKGN_CHK. + + ** Stimulus**: + Execute a series of reset event - lowpower, hwreq, and + sw reset -. And at the beginning of these events, create + reset consistency error to one of 25 leaf modules. + (exclude u_daon_por_io_div4 and u_daon_por_io_div4_shadowed, + see #11858, #12729 for details) + Do the same test for all 25 modules. + + **Check**: + Upon asserting each reset consistency error, + check alert_fatal_cnsty_fault is asserted. + ''' + stage: V2S + tests: ["rstmgr_leaf_rst_cnsty"] + } + { + name: sec_cm_leaf_rst_shadow + desc: '''Verify the countermeasure(s) LEAF.RST.SHADOW. + After power up, create glitch to a shadow leaf reset module. + Check if normal leaf reset module is not triggerred. + Do over all {shadow, normal} leaf reset module pairs + ''' + stage: V2S + tests: ["rstmgr_leaf_rst_shadow_attack"] + } + { + name: sec_cm_leaf_fsm_sparse + desc: '''Verify the countermeasure(s) LEAF.FSM.SPARSE. + + Force leaf rst check state to illegal value. + This is triggered by common cm primitives + ''' + stage: V2S + tests: ["rstmgr_sec_cm"] + } + { + name: sec_cm_sw_rst_config_regwen + desc: '''Verify the countermeasure(s) SW_RST.CONFIG.REGWEN. + + RSTMGR.SW_RST_CTRL_N. + This is covered by auto csr test. + ''' + stage: V2S + tests: ["rstmgr_csr_rw"] + } + { + name: sec_cm_dump_ctrl_config_regwen + desc: '''Verify the countermeasure(s) DUMP_CTRL.CONFIG.REGWEN. + + RSTMGR.ALERT_INFO_CTRL and RSTMGR.CPU_INFO_CTRL + This is covered by auto csr test. + ''' + stage: V2S + tests: ["rstmgr_csr_rw"] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_testplan.hjson new file mode 100644 index 0000000000000..be44e83d038f4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/rstmgr_testplan.hjson @@ -0,0 +1,247 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "rstmgr" + import_testplans: ["hw/dv/tools/dvsim/testplans/alert_test_testplan.hjson", + "hw/dv/tools/dvsim/testplans/csr_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", + "rstmgr_sec_cm_testplan.hjson"] + + testpoints: [ + { + name: smoke + desc: ''' + Smoke test accessing a major datapath within the rstmgr. + + Checks the behavior of rstmgr when receiving various reset requests. + + **Stimulus**: + - Send a scan reset. + - Send a low power entry reset. + - Send a peripheral reset request. + - Send a debug reset. + - Configure a software request for peripheral reset. + - Set alert and cpu dump inputs to random values. + + **Checks**: + - Checks the reset_info matches expected values. + - Checks the `alert_info` CSR correctly captures the input info. + - Checks the `cpu_info` CSR correctly captures the input info. + - Checks the output reset pins corresponding to sw resettable + units match `sw_rst_ctrl_n` CSR. + ''' + stage: V1 + tests: ["rstmgr_smoke"] + } + { + name: reset_stretcher + desc: '''Test the POR reset signal must be stable for multiple cycles. + + The POR reset signal must remain active for at least 32 consecutive + cycles before going inactive for the rest of the reset tree to go + inactive. + + **Stimulus**: + - Activate POR, and de-activate it at a random width less than 32 + cycles between de-activations for N de-activations. + + **Checks**: + - With SVA check the output reset is only set if the input reset + has had at least 32 cycles of steady input reset active. + ''' + stage: V2 + tests: ["rstmgr_por_stretcher"] + } + { + name: sw_rst + desc: '''Test the sw_rst functionality. + + The `sw_rst_regwen` and `sw_rst_ctrl_n` CSRs control the specific + reset outputs to peripherals in the following sequence: + - Test all `sw_rst_ctrl_n` bits when `sw_rst_regwen` is all 1's. + - Clear each `sw_rst_regwen` bit to verify the corresponding resets + are masked. + + **Stimulus**: + - Write `sw_rst_ctrl_n` CSR with random values when regwen is all 1's. + - Clear each `sw_rst_regwen` bit and write `sw_rst_ctrl_n` CSR with + all 0's. + - After each regwen bit check set `sw_rst_ctrl_n` to all 1's. + + **Checks**: + - Check that the zero bits in `sw_rst_ctrl_n` enabled by + `sw_rst_regwen` cause the respective resets to become active. + - Check that the zero bits in `sw_rst_ctrl_n` disabled by + `sw_rst_regwen` have no effect on resets. + - Check the `reset_info`, `cpu_info`, and `alert_info` CSRs are not modified. + ''' + stage: V2 + tests: ["rstmgr_sw_rst"] + } + { + name: sw_rst_reset_race + desc: '''Test sw_rst and reset close in time. + + Sends sw_rst and regular resets in close temporal proximity. + + **Stimulus**: + - Write `sw_rst_ctrl_n` CSR with random values when regwen is all 1's. + - Send a hardware reset. + - Release resets. + + **Checks**: + - Check the `reset_info` CSR. + - Reset behavior is checked by SVA. + ''' + stage: V2 + tests: ["rstmgr_sw_rst_reset_race"] + } + { + name: reset_info + desc: '''Test the reporting of reset reason. + + **Stimulus**: + - Generate the different resets recorded in `reset_info` CSR. + - Randomly clear `reset_info` (it is rw1c). + + **Checks**: + - The resulting setting of `reset_info` is as expected. + - Each bit was set at least once. + - Each bit was cleared at least once. + ''' + stage: V2 + tests: ["rstmgr_reset"] + } + { + name: cpu_info + desc: '''Test the cpu_info recording. + + The `cpu_info` CSR register(s) can capture the contents of the + `cpu_dump_i` input when resets happen and it is enabled. + + **Stimulus**: + - Regularly modify the `cpu_dump_i` input. + - With `cpu_regwen` on, randomly set `cpu_info_ctrl.en` to control + whether the dump should be captured. + - Generate reset(s) as in `smoke` testpoint. + + **Checks**: + - Verify the `cpu_info` is only captured when enabled. + - Verify the `cpu_info` contents at each `cpu_info_ctrl.index` + matches the expected value. + ''' + stage: V2 + tests: ["rstmgr_reset"] + } + { + name: alert_info + desc: '''Test the alert_info recording. + + The `alert_info` CSR register(s) can capture the contents of the + `alert_dump_i` input when resets happen and it is enabled. + + **Stimulus**: + - Regularly modify the `alert_dump_i` input. + - With `alert_regwen` on, randomly set `alert_info_ctrl.en` to + control whether the dump should be captured. + - Generate reset(s) as in `smoke` testpoint. + + **Checks**: + - Verify the `alert_info` is only captured when enabled. + - Verify the `alert_info` contents at each `alert_info_ctrl.index` + matches the expected value. + ''' + stage: V2 + tests: ["rstmgr_reset"] + } + { + name: reset_info_capture + desc: '''Test the capture blocking effect of rst_cpu_n input. + + After an AON reset reset capture is blocked until the input + rst_cpu_n goes inactive. + + **Stimulus**: + - Wait for a random number of resets before setting rst_cpu_n + inactive. + + **Checks**: + - Non-AON resets prior to this event don't capture. + ''' + stage: V2 + tests: ["rstmgr_reset"] + } + { + name: stress_all + desc: '''This runs random tests sequentially. + + Stress with the following sequences: + - rstmgr_reset_vseq + - rstmgr_smoke_vseq + - rstmgr_sw_rst_vseq + ''' + stage: V2 + tests: ["rstmgr_stress_all"] + } + ] + + covergroups: [ + { + name: reset_stretcher_cg + desc: '''Collects coverage on the reset_stretcher functionality. + + The stretcher counter is reset when por_n_i is not stable. + Collect both the count at the point of instability, and the + number of times the counter was reset. + ''' + } + { + name: alert_info_capture_cg + desc: '''Collects coverage on reset type and enable when reset occurs. + + Uses `reset_cp` that records the reset encoded as in `reset_info` + CSR, and `ctrl_en_cp` capturing `alert_info_ctrl.en` CSR, and + creates the per-reset_cp bit cross. + ''' + } + { + name: alert_info_access_cg + desc: '''Collects coverage on the reads of alert_info. + + This captures `alert_info_ctrl.index` CSR to verify all fields + of alert_info have been read. + ''' + } + { + name: cpu_info_capture_cg + desc: '''Collects coverage on the reset and enable when reset occurs. + + Uses `reset_cp` that records the reset encoded as in `reset_info` + CSR, and `ctrl_en_cp` capturing `cpu_info_ctrl.en` CSR, and creates + the per-reset_cp bit cross. + ''' + } + { + name: cpu_info_access_cg + desc: '''Collects coverage on the reads of cpu_info. + + This captures `cpu_info_ctrl.index` CSR to verify all fields + of cpu_info have been read. + ''' + } + { + name: sw_rst_cg + desc: '''Collects coverage on the software reset functionality. + + Each bit of the pair `sw_rst_regwen` and `sw_rst_ctrl_n` CSRs + independently control if the corresponding output reset is + activated. + This collects one coverpoint for each, and their cross. + ''' + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/data/top_englishbreakfast_rstmgr.ipconfig.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/top_englishbreakfast_rstmgr.ipconfig.hjson new file mode 100644 index 0000000000000..87e0e685f1650 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/data/top_englishbreakfast_rstmgr.ipconfig.hjson @@ -0,0 +1,459 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + instance_name: top_englishbreakfast_rstmgr + param_values: + { + clks: + [ + aon + io_div4 + main + io + io_div2 + usb + ] + reqs: + { + peripheral: + [ + { + name: aon_timer_rst_req + width: "1" + module: aon_timer_aon + desc: watchdog reset requestt + } + ] + int: + [ + { + name: MainPwr + desc: main power glitch reset request + module: pwrmgr_aon + } + { + name: Esc + desc: escalation reset request + module: alert_handler + } + ] + debug: + [ + { + name: Ndm + desc: non-debug-module reset request + module: rv_dm + } + ] + } + power_domains: + [ + Aon + "0" + ] + num_rstreqs: 1 + sw_rsts: + [ + spi_device + spi_host0 + usb + ] + output_rsts: + [ + { + name: por_aon + gen: false + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_aon_n + clock: aon + } + { + name: por + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_n + parent: por_aon + clock: main + } + { + name: por_io + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_io_n + parent: por_aon + clock: io + } + { + name: por_io_div2 + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_io_div2_n + parent: por_aon + clock: io_div2 + } + { + name: por_io_div4 + gen: true + type: top + domains: + [ + Aon + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_por_io_div4_n + parent: por_aon + clock: io_div4 + } + { + name: por_usb + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_usb_n + parent: por_aon + clock: usb + } + { + name: lc + gen: true + type: top + domains: + [ + "0" + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_lc_n + parent: lc_src + clock: main + } + { + name: lc_io_div4 + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_lc_io_div4_n + parent: lc_src + clock: io_div4 + } + { + name: sys + gen: true + type: top + domains: + [ + "0" + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_sys_n + parent: sys_src + clock: main + } + { + name: sys_io_div4 + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_sys_io_div4_n + parent: sys_src + clock: io_div4 + } + { + name: sys_aon + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_sys_aon_n + parent: sys_src + clock: aon + } + { + name: spi_device + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_spi_device_n + parent: sys_src + clock: io_div2 + } + { + name: spi_host0 + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_spi_host0_n + parent: sys_src + clock: io + } + { + name: usb + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_usb_n + parent: sys_src + clock: usb + } + ] + leaf_rsts: + [ + { + name: por + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_n + parent: por_aon + clock: main + } + { + name: por_io + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_io_n + parent: por_aon + clock: io + } + { + name: por_io_div2 + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_io_div2_n + parent: por_aon + clock: io_div2 + } + { + name: por_io_div4 + gen: true + type: top + domains: + [ + Aon + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_por_io_div4_n + parent: por_aon + clock: io_div4 + } + { + name: por_usb + gen: true + type: top + domains: + [ + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_por_usb_n + parent: por_aon + clock: usb + } + { + name: lc + gen: true + type: top + domains: + [ + "0" + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_lc_n + parent: lc_src + clock: main + } + { + name: lc_io_div4 + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_lc_io_div4_n + parent: lc_src + clock: io_div4 + } + { + name: sys + gen: true + type: top + domains: + [ + "0" + ] + shadowed: true + sw: false + path: rstmgr_aon_resets.rst_sys_n + parent: sys_src + clock: main + } + { + name: sys_io_div4 + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_sys_io_div4_n + parent: sys_src + clock: io_div4 + } + { + name: sys_aon + gen: true + type: top + domains: + [ + "0" + Aon + ] + shadowed: false + sw: false + path: rstmgr_aon_resets.rst_sys_aon_n + parent: sys_src + clock: aon + } + { + name: spi_device + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_spi_device_n + parent: sys_src + clock: io_div2 + } + { + name: spi_host0 + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_spi_host0_n + parent: sys_src + clock: io + } + { + name: usb + gen: true + type: top + domains: + [ + "0" + ] + shadowed: false + sw: true + path: rstmgr_aon_resets.rst_usb_n + parent: sys_src + clock: usb + } + ] + rst_ni: lc_io_div4 + export_rsts: {} + alert_handler_vlnv_prefix: top_earlgrey_ + with_alert_handler: false + pwrmgr_vlnv_prefix: top_englishbreakfast_ + top_pkg_vlnv: lowrisc:constants:top_englishbreakfast_top_pkg + topname: englishbreakfast + } +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/defs.bzl b/hw/top_englishbreakfast/ip_autogen/rstmgr/defs.bzl new file mode 100644 index 0000000000000..5ee0c2442344f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +load("//rules/opentitan:hw.bzl", "opentitan_ip") + +RSTMGR = opentitan_ip( + name = "rstmgr", + hjson = "//hw/top_englishbreakfast/ip_autogen/rstmgr:data/rstmgr.hjson", +) diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/checklist.md b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/checklist.md new file mode 100644 index 0000000000000..1e01155675d9d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/checklist.md @@ -0,0 +1,266 @@ +# RSTMGR Checklist + +This checklist is for [Hardware Stage](../../../../../doc/project_governance/development_stages.md) transitions for the [RSTMGR 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 | [RSTMGR 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][] | NA | +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][] | Done | +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][] | Done | +RTL | [TODO_COMPLETE][] | Done | +Code Quality | [LINT_COMPLETE][] | Done | With waivers approved by TC on 2024-08-08 +Code Quality | [CDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Code Quality | [RDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Review | [REVIEW_RTL][] | Done | +Review | [REVIEW_DELETED_FF][] | Done | +Review | [REVIEW_SW_CHANGE][] | Done | +Review | [REVIEW_SW_ERRATA][] | Done | +Review | Reviewer(s) | Done | matutem@, vogelpi@, adk@ +Review | Signoff date | Done | 2024-08-08 + +[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 | [RSTMGR DV document](../dv/README.md) +Documentation | [TESTPLAN_COMPLETED][] | Done | [RSTMGR 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 | Exception: 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][] | N/A | +Tests | [FPV_ALL_ASSUMPTIONS_REVIEWED][] | N/A | +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][] | N/A | +Coverage | [FPV_COI_COVERAGE_V2][] | N/A | +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 | +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/top_englishbreakfast/ip_autogen/rstmgr/doc/interfaces.md b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/interfaces.md new file mode 100644 index 0000000000000..ca17d91be12ef --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/interfaces.md @@ -0,0 +1,55 @@ +# Hardware Interfaces + + +The following table lists the instantiation parameters of `rstmgr`. + +Parameter | Default | Description +----------------------------|---------------|--------------- +`SecCheck` | 1 | Enables reset consistency checks on the leaf reset. Each check contains a small FSM. +`SecMaxSyncDelay` | 2 | The default synchronization delay assumptions used in reset consistency checks. If a design uses a sync cell with more stages of delay, that value should be supplied. + + + + +Referring to the [Comportable guideline for peripheral device functionality](https://opentitan.org/book/doc/contributing/hw/comportability), the module **`rstmgr`** has the following hardware interfaces defined +- Primary Clock: **`clk_i`** +- Other Clocks: **`clk_aon_i`**, **`clk_io_div4_i`**, **`clk_main_i`**, **`clk_io_i`**, **`clk_io_div2_i`**, **`clk_usb_i`**, **`clk_por_i`** +- Bus Device Interfaces (TL-UL): **`tl`** +- Bus Host Interfaces (TL-UL): *none* +- Peripheral Pins for Chip IO: *none* +- Interrupts: *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 | +|:------------|:---------------------------------|:--------|:------|--------:|:-----------------------------------------------------------------------------------------------------------------------------| +| por_n | logic | uni | rcv | 2 | Root power on reset signals from ast. There is one root reset signal for each core power domain. | +| pwr | pwr_rst | req_rsp | rsp | 1 | Reset request signals from power manager. Power manager can request for specific domains of the lc/sys reset tree to assert. | +| resets | rstmgr_pkg::rstmgr_out | uni | req | 1 | Leaf resets fed to the system. | +| rst_en | rstmgr_pkg::rstmgr_rst_en | uni | req | 1 | Low-power-group outputs used by alert handler. | +| alert_dump | alert_pkg::alert_crashdump | uni | rcv | 1 | Alert handler crash dump information. | +| cpu_dump | rv_core_ibex_pkg::cpu_crash_dump | uni | rcv | 1 | Main processing element crash dump information. | +| sw_rst_req | prim_mubi_pkg::mubi4 | uni | req | 1 | Software requested system reset to pwrmgr. | +| tl | tlul_pkg::tl | req_rsp | rsp | 1 | | + +## Security Alerts + +| Alert Name | Description | +|:------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------| +| fatal_fault | This fatal alert is triggered when a fatal structural fault is detected. Structural faults include errors such as sparse fsm errors and tlul integrity errors. | +| fatal_cnsty_fault | This fatal alert is triggered when a reset consistency fault is detected. It is separated from the category above for clearer error collection and debug. | + +## Security Countermeasures + +| Countermeasure ID | Description | +|:-------------------------------|:---------------------------------------------------------------------------------------------------------------------------| +| RSTMGR.BUS.INTEGRITY | End-to-end bus integrity scheme. | +| RSTMGR.SCAN.INTERSIG.MUBI | scan control signals are multibit | +| RSTMGR.LEAF.RST.BKGN_CHK | Background consistency checks for each leaf reset. | +| RSTMGR.LEAF.RST.SHADOW | Leaf resets to blocks containing shadow registers are shadowed | +| RSTMGR.LEAF.FSM.SPARSE | Sparsely encoded fsm for each leaf rst check. The Hamming delta is only 3 as there are a significant number of leaf resets | +| RSTMGR.SW_RST.CONFIG.REGWEN | Software reset controls are protected by regwen | +| RSTMGR.DUMP_CTRL.CONFIG.REGWEN | Crash dump controls are protected by regwen | + + + diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/programmers_guide.md b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/programmers_guide.md new file mode 100644 index 0000000000000..8f46814c81ca8 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/programmers_guide.md @@ -0,0 +1,5 @@ +# Programmer's Guide + +## Device Interface Functions (DIFs) + +- [Device Interface Functions](../../../../../sw/device/lib/dif/dif_rstmgr.h) diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/registers.md b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/registers.md new file mode 100644 index 0000000000000..b55698c97c27d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/registers.md @@ -0,0 +1,316 @@ +# Registers + + +## Summary + +| Name | Offset | Length | Description | +|:---------------------------------------------|:---------|---------:|:-------------------------------------------------------------------| +| rstmgr.[`ALERT_TEST`](#alert_test) | 0x0 | 4 | Alert Test Register | +| rstmgr.[`RESET_REQ`](#reset_req) | 0x4 | 4 | Software requested system reset. | +| rstmgr.[`RESET_INFO`](#reset_info) | 0x8 | 4 | Device reset reason. | +| rstmgr.[`ALERT_REGWEN`](#alert_regwen) | 0xc | 4 | Alert write enable | +| rstmgr.[`ALERT_INFO_CTRL`](#alert_info_ctrl) | 0x10 | 4 | Alert info dump controls. | +| rstmgr.[`ALERT_INFO_ATTR`](#alert_info_attr) | 0x14 | 4 | Alert info dump attributes. | +| rstmgr.[`ALERT_INFO`](#alert_info) | 0x18 | 4 | Alert dump information prior to last reset. | +| rstmgr.[`CPU_REGWEN`](#cpu_regwen) | 0x1c | 4 | Cpu write enable | +| rstmgr.[`CPU_INFO_CTRL`](#cpu_info_ctrl) | 0x20 | 4 | Cpu info dump controls. | +| rstmgr.[`CPU_INFO_ATTR`](#cpu_info_attr) | 0x24 | 4 | Cpu info dump attributes. | +| rstmgr.[`CPU_INFO`](#cpu_info) | 0x28 | 4 | Cpu dump information prior to last reset. | +| rstmgr.[`SW_RST_REGWEN_0`](#sw_rst_regwen) | 0x2c | 4 | Register write enable for software controllable resets. | +| rstmgr.[`SW_RST_REGWEN_1`](#sw_rst_regwen) | 0x30 | 4 | Register write enable for software controllable resets. | +| rstmgr.[`SW_RST_REGWEN_2`](#sw_rst_regwen) | 0x34 | 4 | Register write enable for software controllable resets. | +| rstmgr.[`SW_RST_CTRL_N_0`](#sw_rst_ctrl_n) | 0x38 | 4 | Software controllable resets. | +| rstmgr.[`SW_RST_CTRL_N_1`](#sw_rst_ctrl_n) | 0x3c | 4 | Software controllable resets. | +| rstmgr.[`SW_RST_CTRL_N_2`](#sw_rst_ctrl_n) | 0x40 | 4 | Software controllable resets. | +| rstmgr.[`ERR_CODE`](#err_code) | 0x44 | 4 | A bit vector of all the errors that have occurred in reset manager | + +## ALERT_TEST +Alert Test Register +- Offset: `0x0` +- Reset default: `0x0` +- Reset mask: `0x3` + +### Fields + +```wavejson +{"reg": [{"name": "fatal_fault", "bits": 1, "attr": ["wo"], "rotate": -90}, {"name": "fatal_cnsty_fault", "bits": 1, "attr": ["wo"], "rotate": -90}, {"bits": 30}], "config": {"lanes": 1, "fontsize": 10, "vspace": 190}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:------------------|:-------------------------------------------------| +| 31:2 | | | | Reserved | +| 1 | wo | 0x0 | fatal_cnsty_fault | Write 1 to trigger one alert event of this kind. | +| 0 | wo | 0x0 | fatal_fault | Write 1 to trigger one alert event of this kind. | + +## RESET_REQ +Software requested system reset. +- Offset: `0x4` +- Reset default: `0x9` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "VAL", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:------------------------------------------------------------------------------------------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | rw | 0x9 | VAL | When set to kMultiBitBool4True, a reset to power manager is requested. Upon completion of reset, this bit is automatically cleared by hardware. | + +## RESET_INFO +Device reset reason. +- Offset: `0x8` +- Reset default: `0x1` +- Reset mask: `0x7f` + +### Fields + +```wavejson +{"reg": [{"name": "POR", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "LOW_POWER_EXIT", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "SW_RESET", "bits": 1, "attr": ["rw1c"], "rotate": -90}, {"name": "HW_REQ", "bits": 4, "attr": ["rw1c"], "rotate": 0}, {"bits": 25}], "config": {"lanes": 1, "fontsize": 10, "vspace": 160}} +``` + +| Bits | Type | Reset | Name | +|:------:|:------:|:-------:|:----------------------------------------------| +| 31:7 | | | Reserved | +| 6:3 | rw1c | 0x0 | [HW_REQ](#reset_info--hw_req) | +| 2 | rw1c | 0x0 | [SW_RESET](#reset_info--sw_reset) | +| 1 | rw1c | 0x0 | [LOW_POWER_EXIT](#reset_info--low_power_exit) | +| 0 | rw1c | 0x1 | [POR](#reset_info--por) | + +### RESET_INFO . HW_REQ +Indicates when a device has reset due to a hardware requested reset. +The bit mapping is as follows: +b3: aon_timer_aon: watchdog reset requestt +b4: pwrmgr_aon: main power glitch reset request +b5: alert_handler: escalation reset request +b6: rv_dm: non-debug-module reset request + +### RESET_INFO . SW_RESET +Indicates when a device has reset due to [`RESET_REQ.`](#reset_req) + +### RESET_INFO . LOW_POWER_EXIT +Indicates when a device has reset due low power exit. + +### RESET_INFO . POR +Indicates when a device has reset due to power up. + +## ALERT_REGWEN +Alert write enable +- Offset: `0xc` +- 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, [`ALERT_INFO_CTRL`](#alert_info_ctrl) can be modified. | + +## ALERT_INFO_CTRL +Alert info dump controls. +- Offset: `0x10` +- Reset default: `0x0` +- Reset mask: `0xf1` +- Register enable: [`ALERT_REGWEN`](#alert_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 3}, {"name": "INDEX", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:------------------------------------------------------------------------------------------------------------------------------------| +| 31:8 | | | | Reserved | +| 7:4 | rw | 0x0 | INDEX | Controls which 32-bit value to read. | +| 3:1 | | | | Reserved | +| 0 | rw | 0x0 | EN | Enable alert dump to capture new information. This field is automatically set to 0 upon system reset (even if rstmgr is not reset). | + +## ALERT_INFO_ATTR +Alert info dump attributes. +- Offset: `0x14` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "CNT_AVAIL", "bits": 4, "attr": ["ro"], "rotate": -90}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 110}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:----------|:--------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | ro | 0x0 | CNT_AVAIL | The number of 32-bit values contained in the alert info dump. | + +## ALERT_INFO + Alert dump information prior to last reset. + Which value read is controlled by the [`ALERT_INFO_CTRL`](#alert_info_ctrl) register. +- Offset: `0x18` +- Reset default: `0x0` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "VALUE", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------------------| +| 31:0 | ro | 0x0 | VALUE | The current 32-bit value of crash dump. | + +## CPU_REGWEN +Cpu write enable +- 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, [`CPU_INFO_CTRL`](#cpu_info_ctrl) can be modified. | + +## CPU_INFO_CTRL +Cpu info dump controls. +- Offset: `0x20` +- Reset default: `0x0` +- Reset mask: `0xf1` +- Register enable: [`CPU_REGWEN`](#cpu_regwen) + +### Fields + +```wavejson +{"reg": [{"name": "EN", "bits": 1, "attr": ["rw"], "rotate": -90}, {"bits": 3}, {"name": "INDEX", "bits": 4, "attr": ["rw"], "rotate": 0}, {"bits": 24}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------------------------------------------------------------------------------------------------------------| +| 31:8 | | | | Reserved | +| 7:4 | rw | 0x0 | INDEX | Controls which 32-bit value to read. | +| 3:1 | | | | Reserved | +| 0 | rw | 0x0 | EN | Enable cpu dump to capture new information. This field is automatically set to 0 upon system reset (even if rstmgr is not reset). | + +## CPU_INFO_ATTR +Cpu info dump attributes. +- Offset: `0x24` +- Reset default: `0x0` +- Reset mask: `0xf` + +### Fields + +```wavejson +{"reg": [{"name": "CNT_AVAIL", "bits": 4, "attr": ["ro"], "rotate": -90}, {"bits": 28}], "config": {"lanes": 1, "fontsize": 10, "vspace": 110}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:----------|:------------------------------------------------------------| +| 31:4 | | | | Reserved | +| 3:0 | ro | 0x0 | CNT_AVAIL | The number of 32-bit values contained in the cpu info dump. | + +## CPU_INFO + Cpu dump information prior to last reset. + Which value read is controlled by the [`CPU_INFO_CTRL`](#cpu_info_ctrl) register. +- Offset: `0x28` +- Reset default: `0x0` +- Reset mask: `0xffffffff` + +### Fields + +```wavejson +{"reg": [{"name": "VALUE", "bits": 32, "attr": ["ro"], "rotate": 0}], "config": {"lanes": 1, "fontsize": 10, "vspace": 80}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:-------|:----------------------------------------| +| 31:0 | ro | 0x0 | VALUE | The current 32-bit value of crash dump. | + +## SW_RST_REGWEN +Register write enable for software controllable resets. +When a particular bit value is 0, the corresponding value in [`SW_RST_CTRL_N`](#sw_rst_ctrl_n) can no longer be changed. +When a particular bit value is 1, the corresponding value in [`SW_RST_CTRL_N`](#sw_rst_ctrl_n) can be changed. +- Reset default: `0x1` +- Reset mask: `0x1` + +### Instances + +| Name | Offset | +|:----------------|:---------| +| SW_RST_REGWEN_0 | 0x2c | +| SW_RST_REGWEN_1 | 0x30 | +| SW_RST_REGWEN_2 | 0x34 | + + +### 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 | Register write enable for software controllable resets | + +## SW_RST_CTRL_N +Software controllable resets. +When a particular bit value is 0, the corresponding module is held in reset. +When a particular bit value is 1, the corresponding module is not held in reset. +- Reset default: `0x1` +- Reset mask: `0x1` +- Register enable: [`SW_RST_REGWEN`](#sw_rst_regwen) + +### Instances + +| Name | Offset | +|:----------------|:---------| +| SW_RST_CTRL_N_0 | 0x38 | +| SW_RST_CTRL_N_1 | 0x3c | +| SW_RST_CTRL_N_2 | 0x40 | + + +### 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 | 0x1 | VAL | Software reset value | + +## ERR_CODE +A bit vector of all the errors that have occurred in reset manager +- Offset: `0x44` +- Reset default: `0x0` +- Reset mask: `0x7` + +### Fields + +```wavejson +{"reg": [{"name": "REG_INTG_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "RESET_CONSISTENCY_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "FSM_ERR", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 29}], "config": {"lanes": 1, "fontsize": 10, "vspace": 230}} +``` + +| Bits | Type | Reset | Name | Description | +|:------:|:------:|:-------:|:----------------------|:------------------------------------------------------| +| 31:3 | | | | Reserved | +| 2 | ro | 0x0 | FSM_ERR | Sparsely encoded fsm error. | +| 1 | ro | 0x0 | RESET_CONSISTENCY_ERR | A inconsistent parent / child reset was observed. | +| 0 | ro | 0x0 | REG_INTG_ERR | The register file has experienced an integrity error. | + + + diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/reset_topology.svg b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/reset_topology.svg new file mode 100644 index 0000000000000..81510a296435e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/reset_topology.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/theory_of_operation.md b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/theory_of_operation.md new file mode 100644 index 0000000000000..debdd824ff459 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/doc/theory_of_operation.md @@ -0,0 +1,305 @@ +# Theory of Operation + +The OpenTitan reset topology and reset controller block diagram are shown in the diagram below. +The reset controller is closely related to the [power controller](../../pwrmgr/README.md), please refer to that spec for details on how reset controller inputs are controlled. + +![Reset Topology](../doc/reset_topology.svg) + +## Reset Topology + +The topology can be summarized as follows: + +* There are two reset domains + * Test Domain - Driven by `TRSTn` + * Core Domain - Driven by internal [POR circuitry](../../../ip/ast/README.md). +* Test domain is comprised of the following components + * SOC TAP and related DFT circuits + * RISC-V TAP (part of the `rv_dm` module) + +The test domain does not have sub reset trees. +`TRSTn` is used directly by all components in the domain. + +The Core domain consists of all remaining logic and contains 4 sub reset trees, see table below. + + + + + + + + + + + + + + + + + + + + + + +
+Reset Tree + Description +
rst_por_n + POR reset tree. +

+This reset is driven by ast, stretched inside the reset manager and resets all core domain logic in the design. +

rst_lc_n + Life Cycle reset tree. +

+This reset is derived from rst_por_n and resets all logic in the design except:

    + +
  • rv_dm +
  • A small portion of pinmux
+
rst_sys_n + Debug reset tree. +

+This reset is derived from rst_por_n and resets debug domain logic excluded in the life cycle reset tree

    +
rst_{module}_n + Module specific reset. +

+This reset is derived from rst_lc_n and sets only the targeted module and nothing else. +

+For OpenTitan, the only current targets are spi_device, all instances of spi_host, all instances of i2c and usbdev +

+ +The reset trees are cascaded upon one another in this order: +- `rst_por_n` -> `rst_lc_n` -> `rst_module_n` +- `rst_por_n` -> `rst_sys_n` -> `rst_module_n` +This means when a particular reset asserts, all downstream resets also assert. + +The primary difference between `rst_lc_n` and `rst_sys_n` is that the former controls the reset state of most logic in the system, while the latter controls the reset state only of the debug domain. +This separation is required because the debug domain may request the system to reset while retaining debug info and control. +This is particularly useful if one wanted to debug something early during the boot flow, and thus needed to set a break point after requesting a debug reset. + +The reset topology also contains additional properties: +* Selective processor HART resets, such as `hartreset` in `dmcontrol`, are not implemented, as it causes a security policy inconsistency with the remaining system. + * Specifically, these selective resets can cause the cascaded property shown above to not be obeyed. +* Modules do not implement local resets that wipe configuration registers, especially if there are configuration locks. + * Modules are allowed to implement local soft resets that clear datapaths; but these are examined on a case by case basis for possible security side channels. +* In a production system, the Test Reset Input (`TRSTn`) should be explicitly asserted through system integration. + * In a production system, `TRSTn` only needs to be released for RMA transitions and nothing else. +. + +## Reset Manager + +The reset manager handles the reset of the core domain, and also holds relevant reset information in CSR registers, such as: + +* [`RESET_INFO`](registers.md#reset_info) indicates why the system was reset. +* [`ALERT_INFO`](registers.md#alert_info) contains the recorded alert status prior to system reset. + * This is useful in case the reset was triggered by an alert escalation. +* [`CPU_INFO`](registers.md#cpu_info) contains recorded CPU state prior to system reset. + * This is useful in case the reset was triggered by a watchdog where the host hung on a particular bus transaction. + +Additionally, the reset manager, along with the power manager, accepts requests from the system and asserts resets for the appropriate clock trees. +These requests primarily come from the following sources: +* Peripherals capable of reset requests: such as [sysrst_ctrl](../../../../ip/sysrst_ctrl/README.md) and [always on timers ](../../../../ip/aon_timer/README.md). +* Debug modules such as `rv_dm`. +* Power manager request for low power entry and exit. +* Escalation reset requests such as those from `alert_handler` or `pwrmgr` itself. +* Direct software request for reset. + +### Shadow Resets + +OpenTitan supports the shadow configuration registers. +These are registers stored in two constantly checking copies to ensure the values are not maliciously or accidentally disturbed. +For these components, the reset manager outputs a shadow reset dedicated to resetting only the shadow storage. +This reset separation ensures that a targetted attack on the reset line cannot easily defeat shadow registers. + +### Reset Consistency Checks + +The reset manager implements reset consistency checks to ensure that triggered resets are supposed to happen and not due to some fault in the system. +Every leaf reset in the system has an associated consistency checker. + +The consistency check ensures that when a leaf reset asserts, either its parent reset must have asserted, or the software request, if available, has asserted. +While this sounds simple in principle, the check itself crosses up to 3 clock domains and must be carefully managed. + +First, the parent and leaf resets are used to asynchronously assert a flag indication. +This flag indication is then synchronized into the reset manager's local clock domain. + +The reset manager then checks as follows: +- If a leaf reset has asserted, check to see either its parent or software request (synchronous to the local domain) has asserted. + +- If the condition is not true, it is possible the parent reset indication is still being synchronized, thus we wait for the parent indication. + +- It is also possible the parent indication was seen first, but the leaf condition was not, in this case, we wait for the leaf indication. + +- A timeout period corresponding to the maximum synchronization delay is used to cover both waits. + - If the appropriate pairing is not seen in the given amount of time, signal an error, as the leaf reset asserted without cause. + +- If all reset conditions are satisfied, wait for the reset release to gracefully complete the cycle. + + +## Design Details + +The reset manager generates the resets required by the system by synchronizing reset tree components to appropriate output clocks. +As a result, a particular reset tree (for example `rst_lc_n`) may have multiple outputs depending on the clock domains of its consumers. + +Each reset tree is discussed in detail below. + +## POR Reset Tree + +The POR reset tree, `rst_por_n`, is the root reset of the entire device. +If this reset ever asserts, everything in the design is reset. + +The `ast` input `aon_pok` is used as the root reset indication. +It is filtered and stretched to cover any slow voltage ramp scenarios. +The stretch parameters are design time configurations. + +* The filter acts as a synchronizer and is by default 3 stages. +* The count by default is 32. + * The counter increments only when all stages of the filter are 1. + * If any stage at any point becomes '0', the reset counter returns to 0 and downstream logic is driven to reset again. +* Both functions are expected to operate on slow, always available KHz clocks. + + +## Life Cycle Reset Tree + +Life cycle reset, `rst_lc_n` asserts under the following conditions: +* Whenever `rst_por_n` asserts. +* Whenever a peripheral reset request (always on timer watchdog, rbox reset request, alert handler escalation, direct software request) is received. + +The `rst_lc_n` tree contains both always-on and non-always-on versions. +How many non-always-on versions is dependent on how many power domains are supported by the system. + +## System Reset Tree + +System reset, `rst_sys_n` , assertion depends on life cycle state. + +When in PROD and PROD_END states, `rst_sys_n` is identical to `rst_lc_n`. + +When in TEST, RMA and DEV states, `rst_sys_n` is identical to `rst_lc_n` unless the reset request is `ndmreset_req`. +`ndmreset_req` is issued by the debug module of the system, it requests for all logic, except those needed to maintain debug state to reset. + +Since `ndmreset_req` is valid only during TEST, RMA and DEV states, it is the only place where the reset is differentiated. +During these states, when `ndmreset_req` is issued, all logic except the debug module and associated glue logic are reset. + +The `rst_sys_n` tree contains both always-on and non-always-on versions. +How many non-always-on versions is dependent on how many power domains are supported by the system. + +## Output Leaf Resets + +The reset trees discussed above are not directly output to the system for consumption. +Instead, the output leaf resets are synchronized versions of the various root resets. +How many leaf resets there are and to which clock is decided by the system and templated through the reset manager module. + +Assuming a leaf output has N power domains and M clock domains, it potentially means one reset tree may output NxM outputs to satisfy all the reset scenario combinations. + +## Power Domains and Reset Trees + +It is alluded above that reset trees may contain both always-on and non-always-on versions. +This distinction is required to support power manager's various low power states. +When a power domain goes offline, all of its components must reset, regardless of the reset tree to which it belongs. + +For example, assume a system with two power domains - `Domain A` is always-on, and `Domain B` is non-always-on. +When `Domain B` is powered off, all of `Domain B`'s resets, from `rst_lc_n`, `rst_sys_n` to `rst_module_n` are asserted. +However, the corresponding resets for `Domain A` are left untouched because it has not been powered off. + +## Software Controlled Resets + +Certain leaf resets can be directly controlled by software. +Due to security considerations, most leaf resets cannot be controlled, only a few blocks are given exceptions. +The only blocks currently allowed to software reset are `spi_device`, `usbdev`, `spi_host` and `i2c`. + +The criteria for selecting which block is software reset controllable is meant to be overly restrictive. +Unless there is a clear need, the default option is to not provide reset control. + +In general, the following rules apply: +* If a module has configuration register lockdown, it cannot be software resettable. +* If a module operates on secret data (keys), it cannot be software resettable. + * Or a software reset should render the secret data unusable until some initialization routine is run to reduce the Hamming leakage of secret data. +* If a module can alter the software's perception of time or general control flow (timer or interrupt aggregator), it cannot be software resettable. +* If a module contains sensor functions for security, it cannot be software resettable. +* If a module controls life cycle or related function, it cannot be software resettable. + +## Summary + +The following table summarizes the different reset requests and which part of each reset tree, along with what power domain is affected. + +Reset Request Type | Example | POR Reset Tree | LC Reset Tree | SYS Reset Tree | Module Specific Reset +----------------------------------| --------------------------------------------------------------| ---------------| ------------- | --------------- | ---------------------- +POR | VCC toggle, POR_N pad toggle | all domains | all domains | all domains | all domains +HW reset Request | `aon_timer` reset request, `alert_handler` escalation request | | all domains | all domains | all domains +Directed SW system reset request | `rstmgr` SW_RESET | | all domains | all domains | all domains +Ndm reset request (PROD/PROD_END) | `rv_dm` non-debug-module reset request in PROD | | all domains | all domains | all domains +Ndm reset request (Other states) | `rv_dm` non-debug-module reset request in DEV | | all domains | | all domains +SW low power entry | wait-for-interrupt deep sleep entry | | non-aon domains | non-aon domains | non-aon domains +SW controlled reset request | `rstmgr` SW_RST_CTRL_N | | | | all domains + + +## Reset Information + +The reset information register is a reflection of the reset state from the perspective of the system. +In OpenTitan, since there is only 1 host, it is thus from the perspective of the processor. +This also suggests that if the design had multiple processors, there would need to be multiple such registers. + +If a reset does not cause the processor to reset, there is no reason for the reset information to change (this is also why there is a strong security link between the reset of the processor and the rest of the system). +The following are the currently defined reset reasons and their meaning: + +Reset Cause | Description +------------------------|--------------- +`POR` | Cold boot, the system was reset through POR circuitry. +`LOW_POWER_EXIT` | Warm boot, the system was reset through low power exit. +`NDM RESET` | Warm boot, the system was reset through `rv_dm` non-debug-module request. +`SW_REQ` | Warm boot, the system was reset through [`RESET_REQ`](registers.md#reset_req). +`HW_REQ` | Warm boot, the system was reset through peripheral requests. There may be multiple such requests. + + +The reset info register is write 1 clear. +It is software responsibility to clear old reset reasons; the reset manager simply records based on the rules below. + +Excluding power on reset, which is always recorded when the device POR circuitry is triggered, the other resets are recorded when authorized by the reset manager. +Reset manager authorization is based on reset categories as indicated by the power manager. +The power manager has three reset categories that are mutually exclusive: +* No reset has been triggered by pwrmgr. +* Low power entry reset has been triggered by pwrmgr. +* Software or peripheral reset request has been triggered by pwrmgr. + +The reset categories are sent to the reset manager so that it can decide which reason to record when the processor reset is observed. +Non-debug-module resets are allowed only when no resets have been triggered by pwrmgr. + +Since a reset could be motivated by multiple reasons (a security escalation during low power transition for example), the reset information registers constantly record all reset causes in which it is allowed. +The only case where this is not done is `POR`, where active recording is silenced until the first processor reset release. + +Even though four reset causes are labeled as warm boot, their effects on the system are not identical. + +* When the reset cause is `LOW_POWER_EXIT`, it means only the non-always-on domains have been reset. + * Always-on domains retain their pre-low power values. +* When the reset cause is `NDM_RESET`, it means only the `rst_sys_n` tree has asserted for all power domains. +* When the reset cause is `HW_REQ` or `SW_REQ`, it means everything other than power / clock / reset managers have reset. + +This behavioral difference may be important to software, as it implies the configuration of the system may need to be different. + +## Crash Dump Information + +The reset manager manages crash dump information for software debugging across unexpected resets and watchdogs. +When enabled, the latest alert information and latest CPU information are captured in always-on registers. + +When the software resumes after the reset, it is then able to examine the last CPU state or the last set of alert information to understand why the system has reset. + +The enable for such debug capture can be locked such that it never captures. + +### Alert Information + +The alert information register contains the value of the alert crash dump prior to a triggered reset. +Since this information differs in length between system implementation, the alert information register only displays 32-bits at a time. +The [`ALERT_INFO_ATTR`](registers.md#alert_info_attr) register indicates how many 32-bit data segments must be read. + +To enable alert crash dump capture, set [`ALERT_INFO_CTRL.EN`](registers.md#alert_info_ctrl) to 1. +Once the system has reset, check [`ALERT_INFO_ATTR.CNT_AVAIL`](registers.md#alert_info_attr) for how many reads need to be done. +Set [`ALERT_INFO_CTRL.INDEX`](registers.md#alert_info_ctrl) to the desired segment, and then read the output from [`ALERT_INFO`](registers.md#alert_info). + +### CPU Information + +The CPU information register contains the value of the CPU state prior to a triggered reset. +Since this information differs in length between system implementation, the information register only displays 32-bits at a time. + +For more details on the CPU dump details, please see [crash dump](../../../../ip/rv_core_ibex/README.md#crash-dump-collection). + +The [`CPU_INFO_ATTR`](registers.md#cpu_info_attr) register indicates how many 32-bit data segments must be read. +Software then simply needs to write in [`CPU_INFO_CTRL.INDEX`](registers.md#cpu_info_ctrl) which segment it wishes and then read out the [`CPU_INFO`](registers.md#cpu_info) register. diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/README.md b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/README.md new file mode 100644 index 0000000000000..58fad690dbb24 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/README.md @@ -0,0 +1,121 @@ +# RSTMGR DV document + +* **DV** + * Verify all RSTMGR 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 + +* [Design & verification stage](../../../../README.md) + * [HW development stages](../../../../../doc/project_governance/development_stages.md) +* [Simulation results](https://reports.opentitan.org/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/latest/report.html) + +For detailed information on RSTMGR design features, please see the [RSTMGR HWIP technical specification](../README.md). + +RSTMGR testbench has been constructed based on the [CIP testbench architecture](../../../../dv/sv/cip_lib/README.md). + +![Block diagram](./doc/tb.svg) + +The top level testbench is located at [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tb.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tb.sv). +It instantiates the RSTMGR DUT module [`hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr.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) +* RSTMGR interface [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_if.sv) +* Alerts ([`alert_esc_if`](../../../../dv/sv/alert_esc_agent/README.md)) + +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) + +All common types and methods defined at the package level can be found in +`rstmgr_env_pkg`. Some of them in use are: +```systemverilog + typedef logic [NumSwResets-1:0] sw_rst_t; + typedef logic [$bits(alert_pkg::alert_crashdump_t)-1:0] linearized_alert_dump_t; + typedef virtual pwrmgr_rstmgr_sva_if #(.CHECK_RSTREQS(0)) parameterized_pwrmgr_rstmgr_sva_vif; +``` +The RSTMGR testbench instantiates (already handled in CIP base env) [tl_agent](../../../../dv/sv/tl_agent/README.md). +This provides the ability to drive and independently monitor random traffic via the TL host interface into the RSTMGR device. + +RSTMGR testbench instantiates (already handled in CIP base env) [alert_agents](../../../../dv/sv/alert_esc_agent/README.md): +[list alert names]. +The alert_agents provide the ability to drive and independently monitor alert handshakes via alert interfaces in RSTMGR device. + +The RSTMGR 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). + +The following test sequences and covergroups are described in more detail in the testplan at `hw/top_englishbreakfast/ip_autogen/pwrmgr/data/rstmgr_testplan.hjson`, and also included [below](#testplan). + +This IP is only reset via the `por_n_i` input, and by `scan_rst_ni` qualified by `scanmode_i` being active. +The regular `rst_ni` input is connected to its own `resets_o.rst_por_io_div4_n[0]` output, so the reset output from `clk_rst_if` is not connected. +Similarly, all reset outputs from other `clk_rst_if` instances are ignored, and only their clock output is used. +This is consistent with this IP being in charge of all derived resets in the chip. + +Besides the POR resets above, the test sequences mostly assert various reset requests from pwrmgr and trigger resets vir RESET_REQ CSR. +Alert and CPU dump info is randomized and checked on resets. + +The test sequences reside in [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib). +All test sequences are extended from `rstmgr_base_vseq`, which is extended from `cip_base_vseq` and serves as a starting point. +It provides commonly used handles, variables, functions and tasks that the test sequences can simple use / call. +Some of the most commonly used tasks / functions are as follows: +* task `wait_for_cpu_out_of_reset`: + Waits for the `resets_o.rst_sys_n[1]` output to go high, indicating the CPU is out of reset and CSRs can be accessed. +* task `check_cpu_dump_info`: + Reads and compares each field in the `cpu_info` CSR against the given cpu dump. +* task `check_software_reset_csr_and_pins`: + Reads and compares the `sw_rst_ctrl_n` CSR and the output reset ports against the given value. + +Other sequences follow: +* `rstmgr_smoke_vseq` tests the rstmgr through software initiated low power, peripheral reset, ndm reset, and software initiated resets. +* `rstmgr_reset_stretcher_vseq` tests the `resets_o.rst_por_aon_n[0]` output is asserted after 32 stable cycles of `ast_i.aon_pok`. +* `rstmgr_sw_rst_vseq` tests the functionality provided by the `sw_rst_regwen` and `sw_rst_ctrl_n`. +* `rstmgr_reset_info_vseq` tests the `reset_info` CSR contents correspond to the different resets. +* `rstmgr_cpu_info_vseq` tests the `cpu_info` CSR contents capture to the `cpu_dump_i` present at the time of a reset. +* `rstmgr_alert_info_vseq` tests the `alert_info` CSR contents capture to the `alert_dump_i` present at the time of a reset. + +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: +* `reset_stretcher_cg` +* `alert_info_cg` +* `cpu_info_cg` +* `alert_info_capture_cg` +* `cpu_info_capture_cg` +* `sw_rst_cg` + +Most self checking is done using SVA, and via explicit CSR reads. +The latter are described in the testplan. + +* TLUL assertions: The `tb/rstmgr_bind.sv` file binds the `tlul_assert` [assertions](../../../../ip/tlul/doc/TlulProtocolChecker.md) to the IP to ensure TileLink interface protocol compliance. +* Unknown checks on DUT outputs: The RTL has assertions to ensure all outputs are initialized to known values after coming out of reset. +* Response to pwrmgr's `rst_lc_req` and `rst_sys_req` inputs: these trigger transitions in `rst_lc_src_n` and `rst_sys_rst_n` outputs. + Checked via SVAs in [`hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv). +* Response to `cpu_i.ndmreset_req` input: after it is asserted, rstmgr's `rst_sys_src_n` should go active. + Checked via SVA in [`hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/pwrmgr/dv/sva/pwrmgr_rstmgr_sva_if.sv). +* Resets cascade hierarchically per [Reset Topology](../doc/theory_of_operation.md#reset-topology). + Checked via SVA in [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv). +* POR must be active for at least 32 consecutive cycles before going inactive before output resets go inactive. + Checked via SVA in [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv). +* The scan reset `scan_rst_ni` qualified by `scanmode_i` triggers all cascaded resets that `por_n_i` does. + Checked via SVA in [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv). +* Software resets to peripherals also cascade hierarchically. + Checked via SVA in [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv). +* The output `rst_en_o` for alert_handler tracks their corresponding resets. + Checked via SVA in both [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv) and [`hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv`](https://github.com/lowRISC/opentitan/blob/master/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv). +* The `alert` and `cpu_info_attr` indicate the number of 32-bit words needed to capture their inputs. + Checked via SVA in `hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_attrs_sva_if.sv`. + +The rstmgr_cnsty_chk module is a D2S component. +It depends on very specific timing, and requires tampering stimulus to verify its functionality. +It has its own separate dv environment and tests at `hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk`. +It is excluded from coverage for the rstmgr dv 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/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim_cfg.hjson -i rstmgr_smoke +``` + +[Testplan](../data/rstmgr_testplan.hjson) diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cov_bind.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cov_bind.sv new file mode 100644 index 0000000000000..03781409cc624 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cov_bind.sv @@ -0,0 +1,13 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: +// Reset manager coverage bindings for multi bus input +module rstmgr_cov_bind; + // sec cm coverage bind + bind rstmgr cip_mubi_cov_if #(.Width(prim_mubi_pkg::MuBi4Width)) u_scanmode_mubi_cov_if ( + .rst_ni (rst_ni), + .mubi (scanmode_i) + ); +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cover.cfg b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cover.cfg new file mode 100644 index 0000000000000..7dc7cd2f1dc4f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_cover.cfg @@ -0,0 +1,9 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Remove rstmgr_cnsty_chk module tree since it is a pre-verified sub-module. +-moduletree rstmgr_cnsty_chk +begin tgl + +module rstmgr_cnsty_chk +end diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_tgl_excl.cfg b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_tgl_excl.cfg new file mode 100644 index 0000000000000..d1ead50dcfef9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_tgl_excl.cfg @@ -0,0 +1,34 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +//====================================================================== +// This file contains outputs of rstmgr tied to constants. +//====================================================================== + +-module_node rstmgr resets_o.rst_por_n[Domain0Sel] +-module_node rstmgr rst_en_o.por[Domain0Sel] +-module_node rstmgr resets_o.rst_por_io_n[Domain0Sel] +-module_node rstmgr rst_en_o.por_io[Domain0Sel] +-module_node rstmgr resets_o.rst_por_io_div2_n[Domain0Sel] +-module_node rstmgr rst_en_o.por_io_div2[Domain0Sel] +-module_node rstmgr resets_o.rst_por_io_div4_n[Domain0Sel] +-module_node rstmgr rst_en_o.por_io_div4[Domain0Sel] +-module_node rstmgr resets_o.rst_por_io_div4_shadowed_n[Domain0Sel] +-module_node rstmgr rst_en_o.por_io_div4_shadowed[Domain0Sel] +-module_node rstmgr resets_o.rst_por_usb_n[Domain0Sel] +-module_node rstmgr rst_en_o.por_usb[Domain0Sel] +-module_node rstmgr resets_o.rst_lc_n[DomainAonSel] +-module_node rstmgr rst_en_o.lc[DomainAonSel] +-module_node rstmgr resets_o.rst_lc_shadowed_n[DomainAonSel] +-module_node rstmgr rst_en_o.lc_shadowed[DomainAonSel] +-module_node rstmgr resets_o.rst_sys_n[DomainAonSel] +-module_node rstmgr rst_en_o.sys[DomainAonSel] +-module_node rstmgr resets_o.rst_sys_shadowed_n[DomainAonSel] +-module_node rstmgr rst_en_o.sys_shadowed[DomainAonSel] +-module_node rstmgr resets_o.rst_spi_device_n[DomainAonSel] +-module_node rstmgr rst_en_o.spi_device[DomainAonSel] +-module_node rstmgr resets_o.rst_spi_host0_n[DomainAonSel] +-module_node rstmgr rst_en_o.spi_host0[DomainAonSel] +-module_node rstmgr resets_o.rst_usb_n[DomainAonSel] +-module_node rstmgr rst_en_o.usb[DomainAonSel] diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_unr_excl.el b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_unr_excl.el new file mode 100644 index 0000000000000..2426c55284a4e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/cov/rstmgr_unr_excl.el @@ -0,0 +1,88 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Generated UNR file from Synopsys UNR tool with D2S rstmgr_cnsty_chk module +// excluded. +// +//================================================== +// This file contains the Excluded objects +// Generated By User: maturana +// Format Version: 2 +// Date: Tue Jan 17 12:16:09 2023 +// ExclMode: default +//================================================== +CHECKSUM: "258095983 1288805244" +INSTANCE: tb.dut +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_i2c2_n [0] "logic resets_o.rst_i2c2_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_i2c2_n [0] "logic resets_o.rst_i2c2_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_i2c1_n [0] "logic resets_o.rst_i2c1_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_i2c1_n [0] "logic resets_o.rst_i2c1_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_i2c0_n [0] "logic resets_o.rst_i2c0_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_i2c0_n [0] "logic resets_o.rst_i2c0_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_usb_aon_n [0] "logic resets_o.rst_usb_aon_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_usb_aon_n [0] "logic resets_o.rst_usb_aon_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_usb_n [0] "logic resets_o.rst_usb_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_usb_n [0] "logic resets_o.rst_usb_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_spi_host1_n [0] "logic resets_o.rst_spi_host1_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_spi_host1_n [0] "logic resets_o.rst_spi_host1_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_spi_host0_n [0] "logic resets_o.rst_spi_host0_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_spi_host0_n [0] "logic resets_o.rst_spi_host0_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_spi_device_n [0] "logic resets_o.rst_spi_device_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_spi_device_n [0] "logic resets_o.rst_spi_device_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_sys_io_div4_n [1] "logic resets_o.rst_sys_io_div4_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_sys_io_div4_n [1] "logic resets_o.rst_sys_io_div4_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_sys_n [0] "logic resets_o.rst_sys_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_sys_n [0] "logic resets_o.rst_sys_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_lc_aon_n [1] "logic resets_o.rst_lc_aon_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_lc_aon_n [1] "logic resets_o.rst_lc_aon_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_por_usb_n [1] "logic resets_o.rst_por_usb_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_por_usb_n [1] "logic resets_o.rst_por_usb_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_por_io_div4_n [1] "logic resets_o.rst_por_io_div4_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_por_io_div4_n [1] "logic resets_o.rst_por_io_div4_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_por_io_div2_n [1] "logic resets_o.rst_por_io_div2_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_por_io_div2_n [1] "logic resets_o.rst_por_io_div2_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_por_io_n [1] "logic resets_o.rst_por_io_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_por_io_n [1] "logic resets_o.rst_por_io_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 0to1 resets_o.rst_por_n [1] "logic resets_o.rst_por_n[1:0]" +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 resets_o.rst_por_n [1] "logic resets_o.rst_por_n[1:0]" +CHECKSUM: "7550215 3610141655" +INSTANCE: tb.dut.u_d0_lc_shadowed.gen_rst_chk.u_rst_chk +ANNOTATION: "VC_COV_UNR" +Toggle 1to0 err_o "logic err_o" +CHECKSUM: "74367784 3785313510" +INSTANCE: tb.dut.u_reg.u_reg_if +ANNOTATION: "VC_COV_UNR" +Condition 18 "3340270436" "(addr_align_err | malformed_meta_err | tl_err | instr_error | intg_error) 1 -1" (5 "01000") diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/doc/tb.svg b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/doc/tb.svg new file mode 100644 index 0000000000000..8a1940ac4dcd7 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/doc/tb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.core new file mode 100644 index 0000000000000..69cd54b89bcd8 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.core @@ -0,0 +1,54 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_env:0.1 +description: "RSTMGR DV UVM environment" +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_rstmgr + + files_dv: + depend: + - lowrisc:dv:ralgen + - lowrisc:dv:cip_lib + - lowrisc:opentitan:top_englishbreakfast_rstmgr_pkg + - lowrisc:constants:top_englishbreakfast_top_pkg + + files: + - rstmgr_env_pkg.sv + - rstmgr_env_cfg.sv: {is_include_file: true} + - rstmgr_env_cov.sv: {is_include_file: true} + - rstmgr_virtual_sequencer.sv: {is_include_file: true} + - rstmgr_scoreboard.sv: {is_include_file: true} + - rstmgr_env.sv: {is_include_file: true} + - seq_lib/rstmgr_vseq_list.sv: {is_include_file: true} + - seq_lib/rstmgr_base_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_common_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_por_stretcher_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_reset_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_smoke_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_stress_all_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_sw_rst_reset_race_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_sw_rst_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_sec_cm_scan_intersig_mubi_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_leaf_rst_cnsty_vseq.sv: {is_include_file: true} + - seq_lib/rstmgr_leaf_rst_shadow_attack_vseq.sv: {is_include_file: true} + - rstmgr_if.sv + file_type: systemVerilogSource + +generate: + ral: + generator: ralgen + parameters: + name: rstmgr + ip_hjson: ../../data/rstmgr.hjson + +targets: + default: + filesets: + - files_dv + - files_rtl + generate: + - ral diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.sv new file mode 100644 index 0000000000000..482611aa412e5 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env.sv @@ -0,0 +1,67 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class rstmgr_env extends cip_base_env #( + .CFG_T (rstmgr_env_cfg), + .COV_T (rstmgr_env_cov), + .VIRTUAL_SEQUENCER_T(rstmgr_virtual_sequencer), + .SCOREBOARD_T (rstmgr_scoreboard) +); + `uvm_component_utils(rstmgr_env) + + `uvm_component_new + + function void build_phase(uvm_phase phase); + super.build_phase(phase); + + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "aon_clk_rst_vif", cfg.aon_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get aon_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "io_clk_rst_vif", cfg.io_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get io_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "io_div2_clk_rst_vif", cfg.io_div2_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get io_div2_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "io_div4_clk_rst_vif", cfg.io_div4_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get io_div4_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "main_clk_rst_vif", cfg.main_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get main_clk_rst_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual clk_rst_if)::get( + this, "", "usb_clk_rst_vif", cfg.usb_clk_rst_vif + )) begin + `uvm_fatal(`gfn, "failed to get usb_clk_rst_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 + if (!uvm_config_db#(virtual rstmgr_cascading_sva_if)::get( + this, "", "rstmgr_cascading_sva_vif", cfg.rstmgr_cascading_sva_vif + )) begin + `uvm_fatal(`gfn, "failed to get rstmgr_cascading_sva_vif from uvm_config_db") + end + if (!uvm_config_db#(virtual rstmgr_if)::get(this, "", "rstmgr_vif", cfg.rstmgr_vif)) begin + `uvm_fatal(`gfn, "failed to get rstmgr_vif from uvm_config_db") + end + endfunction + + function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + endfunction + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cfg.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cfg.sv new file mode 100644 index 0000000000000..bb859a6517726 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cfg.sv @@ -0,0 +1,37 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class rstmgr_env_cfg extends cip_base_env_cfg #( + .RAL_T(rstmgr_reg_block) +); + + // This scoreboard handle is used to flag expected errors. + rstmgr_scoreboard scoreboard; + + // ext component cfgs + + `uvm_object_utils_begin(rstmgr_env_cfg) + `uvm_object_utils_end + + `uvm_object_new + + virtual clk_rst_if aon_clk_rst_vif; + virtual clk_rst_if io_clk_rst_vif; + virtual clk_rst_if io_div2_clk_rst_vif; + virtual clk_rst_if io_div4_clk_rst_vif; + virtual clk_rst_if main_clk_rst_vif; + virtual clk_rst_if usb_clk_rst_vif; + virtual pwrmgr_rstmgr_sva_if #(.PowerDomains(rstmgr_pkg::PowerDomains)) pwrmgr_rstmgr_sva_vif; + virtual rstmgr_cascading_sva_if rstmgr_cascading_sva_vif; + virtual rstmgr_if rstmgr_vif; + + virtual function void initialize(bit [31:0] csr_base_addr = '1); + list_of_alerts = rstmgr_env_pkg::LIST_OF_ALERTS; + super.initialize(csr_base_addr); + + tl_intg_alert_fields[ral.err_code.reg_intg_err] = 1; + m_tl_agent_cfg.max_outstanding_req = 1; + endfunction + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cov.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cov.sv new file mode 100644 index 0000000000000..3872317a8a752 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_cov.sv @@ -0,0 +1,104 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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. + */ + +class rstmgr_sw_rst_cg_wrap; + covergroup sw_rst_cg(string name) with function sample (bit enable, bit rst_n); + option.name = name; + option.per_instance = 1; + + enable_cp: coverpoint enable; + rst_n_cp: coverpoint rst_n; + + sw_rst_cross: cross enable, rst_n; + endgroup + + function new(string name); + sw_rst_cg = new(name); + endfunction + + function void sample (bit enable, bit rst_n); + sw_rst_cg.sample(enable, rst_n); + endfunction +endclass + +class rstmgr_env_cov extends cip_base_env_cov #( + .CFG_T(rstmgr_env_cfg) +); + `uvm_component_utils(rstmgr_env_cov) + + // the base class provides the following handles for use: + // rstmgr_env_cfg: cfg + + rstmgr_sw_rst_cg_wrap sw_rst_cg_wrap[NumSwResets]; + + covergroup alert_info_capture_cg with function sample (logic [7:0] reset_info, logic enable); + reset_info_cp: coverpoint reset_info { + bins reset_info_cp[] = {1, 2, 4, 8, 16, 32, 64, 128}; + bins others = default; + } + enable_cp: coverpoint enable; + capture_cross: cross reset_info_cp, enable_cp; + endgroup + + covergroup alert_info_access_cg with function sample (logic [3:0] index); + index_cp: coverpoint index { + bins valid[] = {[0 : ($bits(alert_crashdump_t) + 31) / 32 - 1]}; + bins others = default; + } + endgroup + + covergroup cpu_info_capture_cg with function sample (logic [7:0] reset_info, logic enable); + reset_info_cp: coverpoint reset_info { + bins reset_info_cp[] = {1, 2, 4, 8, 16, 32, 64, 128}; + bins others = default; + } + enable_cp: coverpoint enable; + capture_cross: cross reset_info_cp, enable_cp; + endgroup + + covergroup cpu_info_access_cg with function sample (logic [3:0] index); + index_cp: coverpoint index { + bins valid[] = {[0 : ($bits(rv_core_ibex_pkg::cpu_crash_dump_t) + 31) / 32 - 1]}; + bins others = default; + } + endgroup + + covergroup reset_stretcher_cg with function sample (byte length, byte count); + length_cp: coverpoint length { + bins lb[8] = {[1 : 40]}; + bins others = default; + } + count_cp: coverpoint count { + bins cb[4] = {[0 : 15]}; + bins others = default; + } + endgroup + + function new(string name, uvm_component parent); + super.new(name, parent); + foreach (sw_rst_cg_wrap[i]) begin + string cg_name = $sformatf("sw_rst_ctrl_n[%0d]", i); + sw_rst_cg_wrap[i] = new(cg_name); + end + alert_info_capture_cg = new(); + alert_info_access_cg = new(); + cpu_info_capture_cg = new(); + cpu_info_access_cg = new(); + reset_stretcher_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/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_pkg.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_pkg.sv new file mode 100644 index 0000000000000..f00cf85cec113 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_env_pkg.sv @@ -0,0 +1,110 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package rstmgr_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 rstmgr_ral_pkg::*; + + import prim_mubi_pkg::mubi4_t; + import prim_mubi_pkg::MuBi4False; + import prim_mubi_pkg::MuBi4True; + + import rstmgr_reg_pkg::NumHwResets; + import rstmgr_reg_pkg::NumSwResets; + + import alert_pkg::alert_crashdump_t; + import rv_core_ibex_pkg::cpu_crash_dump_t; + + import sec_cm_pkg::*; + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + // parameters + parameter string LIST_OF_ALERTS[] = {"fatal_fault", "fatal_cnsty_fault"}; + parameter uint NUM_ALERTS = 2; + + // Sorted instances of rstmgr_leaf_rst modules in top_earlgrey's rstmgr. + // This can be generated from the source using + // grep -A 5 rstmgr_leaf_rst | \ + // egrep '^[ ]+\) u_' | sed 's/[ )(]//g' | sort | \ + // sed 's/\(.*\)/ \"\1\",/' + parameter string LIST_OF_LEAFS[] = { + "u_d0_i2c0", + "u_d0_i2c1", + "u_d0_i2c2", + "u_d0_lc", + "u_d0_lc_io", + "u_d0_lc_io_div2", + // There are 4 rstmgr_leaf_rst instances with security checks disabled. + // "u_d0_lc_io_div4", + // "u_d0_lc_io_div4_shadowed", + "u_d0_lc_shadowed", + "u_d0_lc_usb", + "u_d0_spi_device", + "u_d0_spi_host0", + "u_d0_spi_host1", + "u_d0_sys", + "u_d0_usb", + "u_d0_usb_aon", + "u_daon_lc", + "u_daon_lc_aon", + "u_daon_lc_io", + "u_daon_lc_io_div2", + // Same as comment above. + // "u_daon_lc_io_div4", + // "u_daon_lc_io_div4_shadowed", + "u_daon_lc_shadowed", + "u_daon_lc_usb", + "u_daon_por", + "u_daon_por_io", + "u_daon_por_io_div2", + "u_daon_por_io_div4", + "u_daon_por_usb", + "u_daon_sys_io_div4" + }; + + // Instances of rstmgr_leaf_rst modules which have a shadow pair. + parameter string LIST_OF_SHADOW_LEAFS[] = { + "u_d0_lc", + "u_d0_lc_io_div4", + "u_daon_lc", + "u_daon_lc_io_div4" + }; + + // types + typedef logic [NumSwResets-1:0] sw_rst_t; + typedef class rstmgr_scoreboard; + + typedef logic [$bits(alert_crashdump_t)-1:0] linearized_alert_dump_t; + + // This is used to capture the values of CSR fields are reset by POR only, so these CSR + // values can be restored to their pre-reset value right after a reset is done and undo + // the dv_base reset clearing them. + typedef struct packed { + logic alert_info_ctrl_en; + logic [3:0] alert_info_ctrl_index; + logic cpu_info_ctrl_en; + logic [3:0] cpu_info_ctrl_index; + } rstmgr_values_of_por_csr_fields_t; + + // functions + + // package sources + `include "rstmgr_env_cfg.sv" + `include "rstmgr_env_cov.sv" + `include "rstmgr_virtual_sequencer.sv" + `include "rstmgr_scoreboard.sv" + `include "rstmgr_env.sv" + `include "rstmgr_vseq_list.sv" + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_if.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_if.sv new file mode 100644 index 0000000000000..fdab940f2bb65 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_if.sv @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// clkmgr interface. + +interface rstmgr_if ( + input logic clk_aon, + input logic clk, + input logic rst_n +); + + import rstmgr_env_pkg::*; + import rstmgr_pkg::PowerDomains; + + logic [PowerDomains-1:0] por_n; + + pwrmgr_pkg::pwr_rst_req_t pwr_i; + pwrmgr_pkg::pwr_rst_rsp_t pwr_o; + + prim_mubi_pkg::mubi4_t sw_rst_req_o; + + // cpu related inputs + rstmgr_pkg::rstmgr_cpu_t cpu_i; + + // Interface to alert handler + alert_pkg::alert_crashdump_t alert_dump_i; + + // Interface to cpu crash dump + rv_core_ibex_pkg::cpu_crash_dump_t cpu_dump_i; + + // dft bypass + logic scan_rst_ni; + prim_mubi_pkg::mubi4_t scanmode_i; + + // Reset status for alert handler. + rstmgr_pkg::rstmgr_rst_en_t rst_en_o; + + // reset outputs + rstmgr_pkg::rstmgr_out_t resets_o; + + // Supporting code. + int aon_cycles; + always @(posedge clk_aon) aon_cycles += 1; + + // Internal DUT signals. +`ifndef PATH_TO_DUT + `define PATH_TO_DUT tb.dut +`endif + + logic [7:0] reset_info; + always_comb begin + reset_info = { + `PATH_TO_DUT.u_reg.reset_info_hw_req_qs, + `PATH_TO_DUT.u_reg.reset_info_sw_reset_qs, + `PATH_TO_DUT.u_reg.reset_info_low_power_exit_qs, + `PATH_TO_DUT.u_reg.reset_info_por_qs + }; + end + + logic alert_info_en; + always_comb alert_info_en = `PATH_TO_DUT.reg2hw.alert_info_ctrl.en.q; + + logic cpu_info_en; + always_comb cpu_info_en = `PATH_TO_DUT.reg2hw.cpu_info_ctrl.en.q; + + bit rst_ni_inactive; + always_comb rst_ni_inactive = resets_o.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]; +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_scoreboard.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_scoreboard.sv new file mode 100644 index 0000000000000..2a095fda859ae --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_scoreboard.sv @@ -0,0 +1,312 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class rstmgr_scoreboard extends cip_base_scoreboard #( + .CFG_T(rstmgr_env_cfg), + .RAL_T(rstmgr_reg_block), + .COV_T(rstmgr_env_cov) +); + `uvm_component_utils(rstmgr_scoreboard) + + // local variables + static const string sw_rst_ctrl_n_preffix = "sw_rst_ctrl_n_"; + + // This is used to capture and restore upon a regular reset the CSR values that are reset + // by POR only, since the CIP and lower layers will reset all CSRs. + rstmgr_values_of_por_csr_fields_t por_fields; + + // TLM agent fifos + + // local queues to hold incoming packets pending comparison + + `uvm_component_new + + function void connect_phase(uvm_phase phase); + super.connect_phase(phase); + cfg.scoreboard = this; + endfunction + + task run_phase(uvm_phase phase); + super.run_phase(phase); + // Initial capture to be able to restore after POR. + capture_por_csr_fields(); + fork + monitor_por(); + monitor_capture(); + monitor_tlul_rst(); + join_none + endtask + + // Start coverage collection after the very first POR negedge, since that transition is not + // useful for coverage. + local task monitor_por(); + int stretch_start; + int reset_count; + if (!cfg.en_cov) return; + @(negedge cfg.rstmgr_vif.por_n); + forever + @cfg.rstmgr_vif.por_n begin + if (cfg.rstmgr_vif.por_n == 1'b1) stretch_start = cfg.rstmgr_vif.aon_cycles; + else begin + int stretch_cycles = cfg.rstmgr_vif.aon_cycles - stretch_start; + ++reset_count; + `DV_CHECK_GT(stretch_cycles, 0) + cov.reset_stretcher_cg.sample(stretch_cycles, reset_count); + end + end + endtask + + local task monitor_capture(); + if (!cfg.en_cov) return; + forever + @cfg.rstmgr_vif.reset_info begin + if (cfg.rstmgr_vif.reset_info != '0) begin + cov.alert_info_capture_cg.sample(cfg.rstmgr_vif.reset_info, cfg.rstmgr_vif.alert_info_en); + cov.cpu_info_capture_cg.sample(cfg.rstmgr_vif.reset_info, cfg.rstmgr_vif.cpu_info_en); + end + end + endtask + + // Monitor tlul reset to update csr_utils_pkg::under_reset variable. This is needed + // because the tlul reset in rstmgr is generated internally, unlike any other modules + // where it is controlled by clk_rst_vif. + local task monitor_tlul_rst(); + forever + @cfg.m_tl_agent_cfg.vif.rst_n begin + if (!cfg.m_tl_agent_cfg.vif.rst_n) begin + `uvm_info(`gfn, "tl got reset", UVM_MEDIUM) + under_reset = 1; + end else begin + `uvm_info(`gfn, "tl got out of reset", UVM_MEDIUM) + under_reset = 0; + clear_outstanding_access(); + cfg.clk_rst_vif.wait_clks(1); + restore_por_csr_fields(); + end + end + endtask + + // This converts the trailing digits in a name to a number. + // It is fatal if there are no trailing digits. + local function int get_index_from_multibit_name(string name); + string suffix; + int last_char_index = name.len() - 1; + int i; + for (i = 0; i <= last_char_index; ++i) begin + byte character = name[last_char_index - i]; + if (character < "0" || character > "9") break; + end + `DV_CHECK(i > 0) + suffix = name.substr(last_char_index - i, last_char_index); + return suffix.atoi(); + endfunction + + local function bit blocked_by_regwen(string ral_name); + bit blocked = 0; + + if (ral_name == "alert_info_ctrl") + blocked = `gmv(ral.alert_regwen) == 0; + if (ral_name == "cpu_info_ctrl") + blocked = `gmv(ral.cpu_regwen) == 0; + // And only the various "sw_rst_ctrl_n may be blocked, so ignore all others. + if (uvm_re_match({sw_rst_ctrl_n_preffix, "*"}, ral_name)) + return 0; + case (ral_name[sw_rst_ctrl_n_preffix.len()]) + "0": blocked = `gmv(ral.sw_rst_regwen[0]) == 0; + "1": blocked = `gmv(ral.sw_rst_regwen[1]) == 0; + "2": blocked = `gmv(ral.sw_rst_regwen[2]) == 0; + "3": blocked = `gmv(ral.sw_rst_regwen[3]) == 0; + "4": blocked = `gmv(ral.sw_rst_regwen[4]) == 0; + "5": blocked = `gmv(ral.sw_rst_regwen[5]) == 0; + "6": blocked = `gmv(ral.sw_rst_regwen[6]) == 0; + "7": blocked = `gmv(ral.sw_rst_regwen[7]) == 0; + default: + `uvm_fatal(`gfn, $sformatf("invalid csr: %0s", ral_name)) + endcase + `uvm_info(`gfn, $sformatf( + "blocked_by_regwen: csr = %0s is %0sblocked", ral_name, blocked ? "" : "not "), + UVM_MEDIUM) + return blocked; + endfunction + + virtual task process_tl_access(tl_seq_item item, tl_channels_e channel, string ral_name); + uvm_reg csr; + bit do_read_check = 1'b1; + 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 and is not blocked by a regwen, make + // updates right away. + if (addr_phase_write) begin + if (!blocked_by_regwen(csr.get_name())) + 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 + "alert_test": begin + // Write only. + do_read_check = 1'b0; + end + "reset_req": begin + end + "reset_info": begin + // RW1C. + do_read_check = 1'b0; + end + "alert_regwen": begin + // RW0C. + end + "alert_info_ctrl": begin + // The en bit is cleared by any hardware reset, but other bits are only cleared by POR. + end + "alert_info_attr": begin + // Read only. + do_read_check = 1'b0; + end + "alert_info": begin + // Read only. + do_read_check = 1'b0; + if (cfg.en_cov) begin + cov.alert_info_access_cg.sample(ral.alert_info_ctrl.index.get()); + end + end + "cpu_regwen": begin + // RW0C. + end + "cpu_info_ctrl": begin + // The en bit is cleared by any hardware reset, but other bits are only cleared by POR. + end + "cpu_info_attr": begin + // Read only. + do_read_check = 1'b0; + end + "cpu_info": begin + // Read only. + do_read_check = 1'b0; + if (cfg.en_cov) begin + cov.cpu_info_access_cg.sample(ral.cpu_info_ctrl.index.get()); + end + end + "err_code": begin + // Set by hardware. + do_read_check = 1'b0; + end + default: begin + if (!uvm_re_match({sw_rst_ctrl_n_preffix, "*"}, csr.get_name())) begin + `uvm_info(`gfn, $sformatf("write to %0s with 0x%x", csr.get_name(), item.a_data), + UVM_MEDIUM) + if (cfg.en_cov && addr_phase_write) begin + int i = get_index_from_multibit_name(csr.get_name()); + logic enable = ral.sw_rst_regwen[i].get(); + cov.sw_rst_cg_wrap[i].sample(enable, item.a_data); + end + end else if (!uvm_re_match("sw_rst_regwen_*", csr.get_name())) begin + // RW0C, so check. + end else begin + `uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name())) + end + end + endcase + + // On reads, if do_read_check, is set, then check mirrored_value against item.d_data + if (data_phase_read) begin + if (do_read_check) begin + uvm_reg_data_t mirrored_value = csr.get_mirrored_value(); + case (csr.get_name()) + "alert_info_ctrl", + "cpu_info_ctrl": begin + // Override bit 0 since it can be cleared by hardware. + `DV_CHECK_EQ((mirrored_value | 1), (item.d_data | 1), $sformatf( + "reg name: %0s, before masking: mirrored value 0x%x, data read 0x%x", + csr.get_full_name(), mirrored_value, item.d_data)) + end + default: + `DV_CHECK_EQ(mirrored_value, item.d_data, $sformatf( + "reg name: %0s", csr.get_full_name())) + endcase + end + void'(csr.predict(.value(item.d_data), .kind(UVM_PREDICT_READ))); + end + endtask + + local function void capture_por_csr_fields(); + por_fields.alert_info_ctrl_en = `gmv(ral.alert_info_ctrl.en); + `uvm_info(`gfn, $sformatf("captured alert_info_ctrl.en 0x%x", por_fields.alert_info_ctrl_en), + UVM_MEDIUM) + por_fields.alert_info_ctrl_index = `gmv(ral.alert_info_ctrl.index); + `uvm_info(`gfn, $sformatf( + "captured alert_info_ctrl.index 0x%x", por_fields.alert_info_ctrl_index), UVM_MEDIUM) + por_fields.cpu_info_ctrl_en = `gmv(ral.cpu_info_ctrl.en); + `uvm_info(`gfn, $sformatf( + "captured cpu_info_ctrl.en 0x%x", por_fields.cpu_info_ctrl_en), UVM_MEDIUM) + por_fields.cpu_info_ctrl_index = `gmv(ral.cpu_info_ctrl.index); + `uvm_info(`gfn, $sformatf( + "captured cpu_info_ctrl.index 0x%x", por_fields.cpu_info_ctrl_index), UVM_MEDIUM) + endfunction + + // Restore the alert and cpu_info_ctrl index values, and the enable bits only on low power reset + // since all other resets clear them. + local task restore_por_csr_fields(); + if (cfg.rstmgr_vif.reset_info[ral.reset_info.low_power_exit.get_lsb_pos()]) begin + `uvm_info(`gfn, $sformatf( + "Restoring alert_info_ctrl.en to 0x%x", por_fields.alert_info_ctrl_en), UVM_MEDIUM) + csr_wr(.ptr(ral.alert_info_ctrl.en), .value(por_fields.alert_info_ctrl_en), .backdoor(1), + .predict(1)); + `uvm_info(`gfn, $sformatf("Restoring cpu_info_ctrl.en to 0x%x", por_fields.cpu_info_ctrl_en), + UVM_MEDIUM) + csr_wr(.ptr(ral.cpu_info_ctrl.en), .value(por_fields.cpu_info_ctrl_en), .backdoor(1), + .predict(1)); + end + `uvm_info(`gfn, $sformatf( + "Restoring alert_info_ctrl.index to 0x%x", por_fields.alert_info_ctrl_index), + UVM_MEDIUM) + csr_wr(.ptr(ral.alert_info_ctrl.index), .value(por_fields.alert_info_ctrl_index), .backdoor(1), + .predict(1)); + `uvm_info(`gfn, $sformatf( + "After restoring alert_info_ctrl mirrored value 0x%x", `gmv(ral.alert_info_ctrl)), + UVM_MEDIUM) + `uvm_info(`gfn, $sformatf( + "Restoring cpu_info_ctrl.index to 0x%x", por_fields.cpu_info_ctrl_index), UVM_MEDIUM) + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(por_fields.cpu_info_ctrl_index), .backdoor(1), + .predict(1)); + `uvm_info(`gfn, $sformatf( + "After restoring cpu_info_ctrl mirrored value 0x%x", `gmv(ral.cpu_info_ctrl)), + UVM_MEDIUM) + endtask + + // There are a handful of registers that are reset on POR only, but the dv_base classes + // will clear all mirrored values on reset. Rather than changing all that code to handle + // resets more accurately here we just capture the mirrored values of all such CSRs + // before reset, and apply them back once reset is handled. It would be really clean if + // they could be restored here right after reset, but restore is a task so it cannot be + // called within a function. + virtual function void reset(string kind = "HARD"); + capture_por_csr_fields(); + 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/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_virtual_sequencer.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_virtual_sequencer.sv new file mode 100644 index 0000000000000..f81afdab42b27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/rstmgr_virtual_sequencer.sv @@ -0,0 +1,14 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class rstmgr_virtual_sequencer extends cip_base_virtual_sequencer #( + .CFG_T(rstmgr_env_cfg), + .COV_T(rstmgr_env_cov) +); + `uvm_component_utils(rstmgr_virtual_sequencer) + + + `uvm_component_new + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv new file mode 100644 index 0000000000000..bb2485acf7a1b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_base_vseq.sv @@ -0,0 +1,556 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class rstmgr_base_vseq extends cip_base_vseq #( + .RAL_T (rstmgr_reg_block), + .CFG_T (rstmgr_env_cfg), + .COV_T (rstmgr_env_cov), + .VIRTUAL_SEQUENCER_T(rstmgr_virtual_sequencer) +); + + `uvm_object_utils(rstmgr_base_vseq) + + `uvm_object_new + + // Set clock frequencies per spec, except the aon is 200kHZ, which is + // too slow and could slow testing down for no good reason. + localparam int AON_FREQ_MHZ = 3; + localparam int IO_FREQ_MHZ = 96; + localparam int IO_DIV2_FREQ_MHZ = 48; + localparam int IO_DIV4_FREQ_MHZ = 24; + localparam int MAIN_FREQ_MHZ = 100; + localparam int USB_FREQ_MHZ = 48; + + // POR needs to be stable not less than 32 clock cycles, plus some extra, before it + // propagates to the rest of the logic. + localparam int POR_CLK_CYCLES = 40; + + // This is only used for the various clocks to start ticking, so can be any small number. + localparam int BOGUS_RESET_CLK_CYCLES = 2; + + // Some extra cycles from reset going inactive before the CPU's reset goes inactive. + localparam int CPU_RESET_CLK_CYCLES = 10; + + // The different types of reset. + typedef enum int { + ResetPOR, + ResetScan, + ResetLowPower, + ResetSw, + ResetHw, + ResetLast + } reset_e; + + // The reset_info adds POR and low power to TotalResetWidth. + typedef logic [pwrmgr_pkg::TotalResetWidth+2-1:0] reset_info_t; + typedef logic [pwrmgr_pkg::HwResetWidth-1:0] rstreqs_t; + + rand sw_rst_t sw_rst_regwen; + rand sw_rst_t sw_rst_ctrl_n; + + bit reset_once; + + rand cpu_crash_dump_t cpu_dump; + rand alert_crashdump_t alert_dump; + + rand rstreqs_t rstreqs; + + rand logic scan_rst_ni; + constraint scan_rst_ni_c {scan_rst_ni == 1;} + + // Various cycles for delaying stimulus. + rand int rst_to_req_cycles; + constraint rst_to_req_cycles_c {rst_to_req_cycles inside {[1 : 6]};} + + rand int release_lc_to_release_sys_cycles; + constraint release_lc_to_release_sys_cycles_c { + release_lc_to_release_sys_cycles inside {[1 : 10]}; + } + + rand int scan_rst_cycles; + constraint scan_rst_cycles_c {scan_rst_cycles inside {[0 : 4]};} + + rand int scanmode_cycles; + constraint scanmode_cycles_c {scanmode_cycles inside {[0 : 4]};} + + rand int lowpower_rst_cycles; + constraint lowpower_rst_cycles_c {lowpower_rst_cycles inside {[0 : 20]};} + + rand int sw_rst_cycles; + constraint sw_rst_cycles_c {sw_rst_cycles inside {[0 : 20]};} + + rand int hw_rst_cycles; + constraint hw_rst_cycles_c {hw_rst_cycles inside {[0 : 20]};} + + rand int reset_us; + constraint reset_us_c {reset_us inside {[1 : 4]};} + + bit do_rstmgr_init = 1'b1; + + mubi4_t scanmode; + int scanmode_on_weight = 8; + + // This is used to randomize the delays for the clocks to start and stop. + typedef struct { + bit [5:0] io_delay; + bit [5:0] io_div2_delay; + bit [5:0] io_div4_delay; + bit [5:0] main_delay; + bit [5:0] usb_delay; + } clock_delays_in_ns_t; + + // What to expect when testing resets. + string reset_name[reset_e] = '{ + ResetPOR: "POR", + ResetScan: "scan", + ResetLowPower: "low power", + ResetSw: "software", + ResetHw: "hardware" + }; + + function int get_reset_code(reset_e reset, rstreqs_t rstreqs); + case (reset) + ResetPOR, ResetScan: return 1 << ral.reset_info.por.get_lsb_pos(); + ResetLowPower: return 1 << ral.reset_info.low_power_exit.get_lsb_pos(); + ResetSw: return 1 << ral.reset_info.sw_reset.get_lsb_pos(); + ResetHw: return rstreqs << ral.reset_info.hw_req.get_lsb_pos(); + default: `uvm_error(`gfn, $sformatf("Unexpected reset code %0d", reset)) + endcase + endfunction + + function void post_randomize(); + scanmode = get_rand_mubi4_val(scanmode_on_weight, 4, 4); + endfunction + + local function void update_scanmode(prim_mubi_pkg::mubi4_t value); + cfg.rstmgr_vif.scanmode_i = value; + endfunction + + local function void update_scan_rst_n(logic value); + cfg.rstmgr_vif.scan_rst_ni = value; + endfunction + + local function void set_pwrmgr_rst_reqs(logic rst_lc_req, logic rst_sys_req); + `uvm_info(`gfn, $sformatf("Setting pwr_i lc_req=%x sys_req=%x", rst_lc_req, rst_sys_req), + UVM_MEDIUM) + cfg.rstmgr_vif.pwr_i.rst_lc_req = {rstmgr_pkg::PowerDomains{rst_lc_req}}; + cfg.rstmgr_vif.pwr_i.rst_sys_req = {rstmgr_pkg::PowerDomains{rst_sys_req}}; + endfunction + + local function void set_rstreqs(rstreqs_t rstreqs); + cfg.rstmgr_vif.pwr_i.rstreqs = rstreqs; + endfunction + + local function void add_rstreqs(rstreqs_t rstreqs); + cfg.rstmgr_vif.pwr_i.rstreqs |= rstreqs; + `uvm_info(`gfn, $sformatf("Updating rstreqs to 0x%x", cfg.rstmgr_vif.pwr_i.rstreqs), UVM_MEDIUM) + endfunction + + local function void set_reset_cause(pwrmgr_pkg::reset_cause_e reset_cause); + cfg.rstmgr_vif.pwr_i.reset_cause = reset_cause; + endfunction + + static function logic is_running_sequence(string seq_name); + string actual_sequence = "none"; + // Okay to ignore return value since the default won't match. + void'($value$plusargs("UVM_TEST_SEQ=%0s", actual_sequence)); + return actual_sequence.compare(seq_name) == 0; + endfunction + + virtual protected task check_reset_info(logic [TL_DW-1:0] expected_value, + string msg = "reset_info mismatch"); + csr_rd_check(.ptr(ral.reset_info), .compare_value(expected_value), .err_msg(msg)); + endtask + + local function void set_cpu_dump_info(cpu_crash_dump_t cpu_dump); + `uvm_info(`gfn, $sformatf("Setting cpu_dump_i to %p", cpu_dump), UVM_MEDIUM) + cfg.rstmgr_vif.cpu_dump_i = cpu_dump; + endfunction + + local task check_cpu_dump_info(cpu_crash_dump_t cpu_dump); + `uvm_info(`gfn, "Checking cpu_info", UVM_MEDIUM) + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(7)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.prev_valid), + .err_msg("checking previous_valid")); + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(6)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.prev_exception_pc), + .err_msg("checking previous exception_pc")); + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(5)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.prev_exception_addr), + .err_msg("checking previous exception_addr")); + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(4)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.current.current_pc), + .err_msg("checking current current_pc")); + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(3)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.current.next_pc), + .err_msg("checking current next_pc")); + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(2)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.current.last_data_addr), + .err_msg("checking current last_data_addr")); + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(1)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.current.exception_pc), + .err_msg("checking current exception_pc")); + csr_wr(.ptr(ral.cpu_info_ctrl.index), .value(0)); + csr_rd_check(.ptr(ral.cpu_info), .compare_value(cpu_dump.current.exception_addr), + .err_msg("checking current exception_addr")); + + endtask + + local function void set_alert_dump_info(alert_crashdump_t alert_dump); + `uvm_info(`gfn, $sformatf( + "Setting alert_dump_i to 0x%x", linearized_alert_dump_t'({>>{alert_dump}})), + UVM_MEDIUM) + cfg.rstmgr_vif.alert_dump_i = alert_dump; + endfunction + + local task check_alert_dump_info(alert_crashdump_t alert_dump); + localparam int DumpWidth = $bits(alert_dump); + localparam int WordWidth = 32; + logic [DumpWidth-1:0] linear_dump = {>>{alert_dump}}; + int i; + `uvm_info(`gfn, "Checking alert_info", UVM_MEDIUM) + for (i = 0; i + WordWidth <= DumpWidth; i += WordWidth) begin + csr_wr(.ptr(ral.alert_info_ctrl.index), .value(i / WordWidth)); + csr_rd_check(.ptr(ral.alert_info), .compare_value(linear_dump[i+:WordWidth]), + .err_msg($sformatf("checking alert_info bits %0d:%0d", i + 31, i))); + end + if (i < DumpWidth) begin + logic [(DumpWidth % 32) - 1:0] word = linear_dump >> i; + csr_wr(.ptr(ral.alert_info_ctrl.index), .value(i / WordWidth)); + csr_rd_check(.ptr(ral.alert_info), .compare_value(word), + .err_msg($sformatf("checking alert_info bits %0d:%0d", DumpWidth - 1, i))); + end + endtask + + virtual protected task set_alert_info_for_capture(alert_crashdump_t alert_dump, logic enable); + set_alert_dump_info(alert_dump); + `uvm_info(`gfn, $sformatf("%0sabling alert_info capture", (enable ? "En" : "Dis")), UVM_MEDIUM) + csr_wr(.ptr(ral.alert_info_ctrl.en), .value(enable)); + endtask + + virtual protected task set_cpu_info_for_capture(cpu_crash_dump_t cpu_dump, logic enable); + set_cpu_dump_info(cpu_dump); + `uvm_info(`gfn, $sformatf("%0sabling cpu_info capture", (enable ? "En" : "Dis")), UVM_MEDIUM) + csr_wr(.ptr(ral.cpu_info_ctrl.en), .value(enable)); + endtask + + virtual protected task set_alert_and_cpu_info_for_capture(alert_crashdump_t alert_dump, + cpu_crash_dump_t cpu_dump); + set_alert_info_for_capture(alert_dump, 1'b1); + set_cpu_info_for_capture(cpu_dump, 1'b1); + endtask + + virtual protected task check_alert_info_after_reset(alert_crashdump_t alert_dump, logic enable); + csr_rd_check(.ptr(ral.alert_info_ctrl.en), .compare_value(enable), + .err_msg($sformatf("Expected alert info capture enable %b", enable))); + csr_wr(.ptr(ral.alert_info_ctrl.en), .value(enable)); + check_alert_dump_info(alert_dump); + endtask + + virtual protected task check_cpu_info_after_reset(cpu_crash_dump_t cpu_dump, logic enable); + csr_rd_check(.ptr(ral.cpu_info_ctrl.en), .compare_value(enable), + .err_msg($sformatf("Expected cpu info capture enable %b", enable))); + csr_wr(.ptr(ral.cpu_info_ctrl.en), .value(enable)); + check_cpu_dump_info(cpu_dump); + endtask + + // Checks both alert and cpu_info_ctrl.en, and their _info contents. + // This is tricky: both ctrl.en fields don't necessarily match the mirrored value since the + // hardware may update them on most resets. This can cause the subsequent writes to the .index + // field to overwrite the .en field. To make things simpler, after checking .en's expected + // value we write it to update the mirrored value. + virtual protected task check_alert_and_cpu_info_after_reset( + alert_crashdump_t alert_dump, cpu_crash_dump_t cpu_dump, logic enable); + check_alert_info_after_reset(alert_dump, enable); + check_cpu_info_after_reset(cpu_dump, enable); + endtask + + virtual protected task clear_alert_and_cpu_info(); + set_alert_and_cpu_info_for_capture('0, '0); + send_sw_reset(); + cfg.io_div4_clk_rst_vif.wait_clks(20); // # of lc reset cycles measured from waveform + check_alert_and_cpu_info_after_reset(.alert_dump('0), .cpu_dump('0), .enable(0)); + endtask + + virtual protected task clear_sw_rst_ctrl_n(); + const sw_rst_t sw_rst_all_ones = '1; + rstmgr_csr_wr_unpack(.ptr(ral.sw_rst_ctrl_n), .value(sw_rst_all_ones)); + rstmgr_csr_rd_check_unpack(.ptr(ral.sw_rst_ctrl_n), .compare_value(sw_rst_all_ones), + .err_msg("Expected sw_rst_ctrl_n to be set")); + endtask + + virtual protected task clear_sw_rst_ctrl_n_per_entry(int entry); + csr_wr(.ptr(ral.sw_rst_ctrl_n[entry]), .value(1'b1)); + csr_rd_check(.ptr(ral.sw_rst_ctrl_n[entry]), .compare_value(1'b1), + .err_msg($sformatf("Expected sw_rst_ctrl_n[%0d] to be set", entry))); + endtask + + virtual protected task check_sw_rst_regwen(sw_rst_t expected_regwen); + rstmgr_csr_rd_check_unpack(.ptr(ral.sw_rst_regwen), .compare_value(expected_regwen), + .err_msg("Mismatching sw_rst_regwen")); + endtask + + // Stimulate and check sw_rst_ctrl_n with a given sw_rst_regwen setting. + // Exit when a reset is detected or the sequence would be invalid and may get stuck. + virtual protected task check_sw_rst_ctrl_n(sw_rst_t sw_rst_ctrl_n, sw_rst_t sw_rst_regwen, + bit erase_ctrl_n); + sw_rst_t exp_ctrl_n = ~sw_rst_regwen | sw_rst_ctrl_n; + + `uvm_info(`gfn, $sformatf( + "Setting sw_rst_ctrl_n to 0x%0x with regwen 0x%x, expect 0x%x", + sw_rst_ctrl_n, + sw_rst_regwen, + exp_ctrl_n + ), UVM_MEDIUM) + foreach (ral.sw_rst_ctrl_n[i]) begin + if (under_reset) return; + csr_wr(.ptr(ral.sw_rst_ctrl_n[i]), .value(sw_rst_ctrl_n[i])); + if (under_reset) return; + csr_rd_check(.ptr(ral.sw_rst_ctrl_n[i]), .compare_value(exp_ctrl_n[i]), + .err_msg($sformatf("Mismatch for bit %0d", i))); + end + if (erase_ctrl_n && !under_reset) clear_sw_rst_ctrl_n(); + endtask + + virtual protected task check_sw_rst_ctrl_n_per_entry( + sw_rst_t sw_rst_ctrl_n, sw_rst_t sw_rst_regwen, bit erase_ctrl_n, int entry); + sw_rst_t exp_ctrl_n; + + `uvm_info(`gfn, $sformatf("Set sw_rst_ctrl_n[%0d] to 0x%0x", entry, sw_rst_ctrl_n), UVM_MEDIUM) + csr_wr(.ptr(ral.sw_rst_ctrl_n[entry]), .value(sw_rst_ctrl_n[entry])); + // And check that the reset outputs match the actual ctrl_n settings. + // Allow for domain crossing delay. + cfg.io_div2_clk_rst_vif.wait_clks(3); + exp_ctrl_n = ~sw_rst_regwen | sw_rst_ctrl_n; + `uvm_info(`gfn, $sformatf( + "regwen=%b, ctrl_n=%b, expected=%b", sw_rst_regwen, sw_rst_ctrl_n, exp_ctrl_n), + UVM_MEDIUM) + csr_rd_check(.ptr(ral.sw_rst_ctrl_n[entry]), .compare_value(exp_ctrl_n[entry]), + .err_msg($sformatf("Expected enabled updates in sw_rst_ctrl_n[%0d]", entry))); + if (erase_ctrl_n) clear_sw_rst_ctrl_n_per_entry(entry); + endtask + + local task control_all_clocks(bit enable); + // Randomize the delays for each clock turning on or off. + clock_delays_in_ns_t delays; + `DV_CHECK_STD_RANDOMIZE_FATAL(delays) + if (enable) fork + #(delays.io_delay * 1ns) cfg.io_clk_rst_vif.start_clk(); + #(delays.io_div2_delay * 1ns) cfg.io_div2_clk_rst_vif.start_clk(); + #(delays.io_div4_delay * 1ns) cfg.io_div4_clk_rst_vif.start_clk(); + #(delays.main_delay * 1ns) cfg.main_clk_rst_vif.start_clk(); + #(delays.usb_delay * 1ns) cfg.usb_clk_rst_vif.start_clk(); + join else fork + #(delays.io_delay * 1ns) cfg.io_clk_rst_vif.stop_clk(); + #(delays.io_div2_delay * 1ns) cfg.io_div2_clk_rst_vif.stop_clk(); + #(delays.io_div4_delay * 1ns) cfg.io_div4_clk_rst_vif.stop_clk(); + #(delays.main_delay * 1ns) cfg.main_clk_rst_vif.stop_clk(); + #(delays.usb_delay * 1ns) cfg.usb_clk_rst_vif.stop_clk(); + join + endtask + + // Happens with hardware resets. + local task reset_start(pwrmgr_pkg::reset_cause_e reset_cause); + `uvm_info(`gfn, $sformatf("Starting pwrmgr inputs for %0s request", reset_cause.name()), + UVM_MEDIUM) + set_reset_cause(reset_cause); + // These lag the reset requests since they are set after the pwrmgr fast fsm has made some + // state transitions. + cfg.io_div4_clk_rst_vif.wait_clks(rst_to_req_cycles); + set_pwrmgr_rst_reqs(.rst_lc_req('1), .rst_sys_req('1)); + cfg.clk_rst_vif.stop_clk(); + if (reset_cause == pwrmgr_pkg::LowPwrEntry) begin + control_all_clocks(.enable(0)); + end + endtask + + protected task wait_till_active(); + // And wait for the main reset to be done. + `DV_WAIT(cfg.rstmgr_vif.rst_ni_inactive, "Time-out waiting for rst_ni becoming inactive"); + // And wait a few cycles for settling before allowing the sequences to start. + cfg.io_div4_clk_rst_vif.wait_clks(8); + endtask + + protected task reset_done(); + `uvm_info(`gfn, "Releasing reset", UVM_LOW) + update_scanmode(prim_mubi_pkg::MuBi4False); + update_scan_rst_n(1'b1); + if (cfg.rstmgr_vif.pwr_i.reset_cause == pwrmgr_pkg::LowPwrEntry) begin + control_all_clocks(.enable(1)); + end + cfg.clk_rst_vif.start_clk(); + cfg.io_div4_clk_rst_vif.wait_clks(10); + set_reset_cause(pwrmgr_pkg::ResetNone); + set_pwrmgr_rst_reqs(.rst_lc_req('0), .rst_sys_req('1)); + cfg.io_div4_clk_rst_vif.wait_clks(release_lc_to_release_sys_cycles); + set_pwrmgr_rst_reqs(.rst_lc_req('0), .rst_sys_req('0)); + set_rstreqs(0); + wait_till_active(); + `uvm_info(`gfn, "Reset done", UVM_MEDIUM) + endtask + + // Sends either an external hardware reset request, setting the possibly different + // rstreqs bits at different times. It optionally completes the reset. + virtual protected task send_hw_reset(rstreqs_t rstreqs, logic complete_it = 1); + `uvm_info(`gfn, $sformatf("Sending hw reset with 0b%0b", rstreqs), UVM_LOW) + reset_start(pwrmgr_pkg::HwReq); + fork + begin : isolation_fork + foreach (rstreqs[i]) begin : loop + if (rstreqs[i]) begin + fork + automatic int index = i; + automatic bit [2:0] cycles; + `DV_CHECK_STD_RANDOMIZE_FATAL(cycles) + cfg.io_div4_clk_rst_vif.wait_clks(cycles); + add_rstreqs(rstreqs & (1 << index)); + join_none + end + end : loop + wait fork; + end : isolation_fork + join + if (complete_it) reset_done(); + endtask + + virtual protected task send_lowpower_reset(bit complete_it = 1); + `uvm_info(`gfn, "Sending low power reset", UVM_LOW) + reset_start(pwrmgr_pkg::LowPwrEntry); + if (complete_it) reset_done(); + endtask + + + // Lead with scan_rst active to avoid some derived sequence changing scanmode_i in such + // a way it defeats this reset. + virtual protected task send_scan_reset(bit complete_it = 1); + `uvm_info(`gfn, "Sending scan reset", UVM_MEDIUM) + fork + begin + cfg.io_div4_clk_rst_vif.wait_clks(scan_rst_cycles); + update_scan_rst_n(1'b0); + end + begin + cfg.io_div4_clk_rst_vif.wait_clks(scanmode_cycles); + update_scanmode(prim_mubi_pkg::MuBi4True); + end + join + reset_start(pwrmgr_pkg::HwReq); + + // The clocks are turned off, so wait in time units. + #(reset_us * 1us); + if (complete_it) reset_done(); + endtask + + // Requests a sw reset. It is cleared by hardware once the reset is taken. + virtual protected task send_sw_reset(bit complete_it = 1); + `uvm_info(`gfn, "Sending sw reset", UVM_LOW) + reset_start(pwrmgr_pkg::HwReq); + #(reset_us * 1us); + if (complete_it) reset_done(); + endtask + + virtual task dut_init(string reset_kind = "HARD"); + if (do_rstmgr_init) rstmgr_init(); + super.dut_init(); + endtask + + virtual task dut_shutdown(); + // No checks seem needed. + endtask + + local task start_clocks(); + control_all_clocks(.enable(1)); + fork + cfg.aon_clk_rst_vif.apply_reset(.reset_width_clks(BOGUS_RESET_CLK_CYCLES)); + cfg.io_clk_rst_vif.apply_reset(.reset_width_clks(BOGUS_RESET_CLK_CYCLES)); + cfg.io_div2_clk_rst_vif.apply_reset(.reset_width_clks(BOGUS_RESET_CLK_CYCLES)); + cfg.io_div4_clk_rst_vif.apply_reset(.reset_width_clks(BOGUS_RESET_CLK_CYCLES)); + cfg.main_clk_rst_vif.apply_reset(.reset_width_clks(BOGUS_RESET_CLK_CYCLES)); + cfg.usb_clk_rst_vif.apply_reset(.reset_width_clks(BOGUS_RESET_CLK_CYCLES)); + join + endtask + + protected task por_reset_done(bit complete_it); + cfg.rstmgr_vif.por_n = '1; + reset_start(pwrmgr_pkg::ResetUndefined); + #(reset_us * 1us); + if (complete_it) reset_done(); + endtask + + virtual protected task por_reset(bit complete_it = 1); + `uvm_info(`gfn, "Starting POR", UVM_MEDIUM) + cfg.rstmgr_vif.por_n = '0; + control_all_clocks(.enable(0)); + #(100 * 1ns); + start_clocks(); + cfg.aon_clk_rst_vif.wait_clks(POR_CLK_CYCLES); + por_reset_done(complete_it); + endtask + + virtual task apply_reset(string kind = "HARD"); + fork + por_reset(); + super.apply_reset(kind); + join + endtask + + virtual task apply_resets_concurrently(int reset_duration_ps = 0); + fork + por_reset(); + start_clocks(); + super.apply_resets_concurrently(reset_duration_ps); + join + `uvm_info(`gfn, "Done with apply_resets_concurrently", UVM_MEDIUM) + endtask + + // Disable exclusions for RESET_REQ since they cause trouble 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("rstmgr_reg_block.reset_req"), .enable(1'b0)); + csr_excl.print_exclusions(UVM_MEDIUM); + endfunction + + task pre_start(); + if (do_rstmgr_init) rstmgr_init(); + disable_unnecessary_exclusions(); + super.pre_start(); + endtask + + // setup basic rstmgr features + virtual task rstmgr_init(); + // Must set clk_rst_vif frequency to IO_DIV4_FREQ_MHZ since they are gated + // versions of each other and have no clock domain crossings. + // Notice they may still end up out of phase due to the way they get started. + cfg.clk_rst_vif.set_freq_mhz(IO_DIV4_FREQ_MHZ); + cfg.aon_clk_rst_vif.set_freq_mhz(AON_FREQ_MHZ); + cfg.io_clk_rst_vif.set_freq_mhz(IO_FREQ_MHZ); + cfg.io_div2_clk_rst_vif.set_freq_mhz(IO_DIV2_FREQ_MHZ); + cfg.io_div4_clk_rst_vif.set_freq_mhz(IO_DIV4_FREQ_MHZ); + cfg.main_clk_rst_vif.set_freq_mhz(MAIN_FREQ_MHZ); + cfg.usb_clk_rst_vif.set_freq_mhz(USB_FREQ_MHZ); + // Initial values for some input pins. + cfg.rstmgr_vif.scanmode_i = prim_mubi_pkg::MuBi4False; + cfg.rstmgr_vif.scan_rst_ni = scan_rst_ni; + set_pwrmgr_rst_reqs(1'b0, 1'b0); + set_rstreqs('0); + set_reset_cause(pwrmgr_pkg::ResetNone); + endtask + + // csr method wrapper for unpacked array registers + virtual task rstmgr_csr_rd_check_unpack( + input uvm_object ptr[], input uvm_reg_data_t compare_value = 0, input string err_msg = ""); + foreach (ptr[i]) begin + if (cfg.under_reset) return; + csr_rd_check(.ptr(ptr[i]), .compare_value(compare_value[i]), .err_msg(err_msg)); + end + endtask : rstmgr_csr_rd_check_unpack + + virtual task rstmgr_csr_wr_unpack(input uvm_object ptr[], input uvm_reg_data_t value); + foreach (ptr[i]) begin + if (cfg.under_reset) return; + csr_wr(.ptr(ptr[i]), .value(value[i])); + end + endtask +endclass : rstmgr_base_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_common_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_common_vseq.sv new file mode 100644 index 0000000000000..3f87231dfd307 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_common_vseq.sv @@ -0,0 +1,15 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class rstmgr_common_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_common_vseq) + + constraint num_trans_c {num_trans inside {[1 : 2]};} + `uvm_object_new + + virtual task body(); + run_common_vseq_wrapper(num_trans); + endtask : body + +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_cnsty_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_cnsty_vseq.sv new file mode 100644 index 0000000000000..fdc180ea41f9f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_cnsty_vseq.sv @@ -0,0 +1,228 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This tests each leaf reset consistency checkers. +// +// For resets out of +// 1 - low power entry reset +// 2 - hw req reset +// 3 - sw reset +// Create reset consistency errors in the current leaf, and check that a +// fatal_cnsty_fault alert is generated. +class rstmgr_leaf_rst_cnsty_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_leaf_rst_cnsty_vseq) + + `uvm_object_new + + int cycles_to_check = 7; + int error_pos; + int my_pos; + rand int cycles_reset_width; + rand int cycles_child_reset_width; + rand int cycles_in_apply_resets; + rand int cycles_to_child_reset; + rand int cycles_to_child_release; + rand int cycles_to_parent_reset; + rand int cycles_to_parent_release; + rand int cycles_to_sw_reset; + rand int cycles_to_sw_release; + + constraint rstreqs_non_zero_c {rstreqs != '0;} + constraint sw_rst_regwen_non_trivial_c {sw_rst_regwen != '0 && sw_rst_regwen != '1;} + constraint sw_rst_some_reset_n_c {sw_rst_regwen & ~sw_rst_ctrl_n != '0;} + + constraint cycles_reset_width_c {cycles_reset_width inside {[2 : 10]};} + constraint cycles_child_reset_width_c {cycles_child_reset_width inside {[2 : 10]};} + constraint cycles_in_apply_resets_c {cycles_in_apply_resets inside {[5 : 25]};} + constraint cycles_to_child_reset_c {cycles_to_child_reset inside {[3 : 8]};} + constraint cycles_to_child_release_c {cycles_to_child_release inside {[3 : 6]};} + constraint cycles_to_parent_reset_c {cycles_to_parent_reset inside {[2 : 8]};} + constraint cycles_to_parent_release_c {cycles_to_parent_release inside {[3 : 6]};} + constraint cycles_to_sw_reset_c {cycles_to_sw_reset inside {[2 : 8]};} + constraint cycles_to_sw_release_c {cycles_to_sw_release inside {[3 : 6]};} + + // There is an extra POR reset when the consistency failure is triggered due to apply_reset. + int maybe_por_reset; + + task body(); + for (int i = 0; i < LIST_OF_LEAFS.size(); ++i) begin + string leaf_path = {"tb.dut.", LIST_OF_LEAFS[i], ".gen_rst_chk.u_rst_chk"}; + error_pos = $urandom_range(1, 3); + my_pos = 0; + `uvm_info(`gfn, $sformatf("Round %0d %s pos:%0d", i, leaf_path, error_pos), UVM_MEDIUM) + // Get a clean slate for reset_info. + csr_wr(.ptr(ral.reset_info), .value('1)); + + fork + unexpected_child_activity(leaf_path); + begin + int expected; + set_pos_and_wait(); + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + // Send low power entry reset. + send_lowpower_reset(); + expected = 1 << ral.reset_info.low_power_exit.get_lsb_pos(); + + check_reset_info(maybe_por_reset | expected, "expected reset_info to indicate low power"); + check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, 1'b1); + + csr_wr(.ptr(ral.reset_info), .value('1)); + cfg.io_div4_clk_rst_vif.wait_clks(10); + + // Send HwReq. + // Enable alert_info and cpu_info capture. + set_pos_and_wait(); + `DV_CHECK_RANDOMIZE_FATAL(this) + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + expected = rstreqs << ral.reset_info.hw_req.get_lsb_pos(); + send_hw_reset(rstreqs); + check_reset_info(maybe_por_reset | expected, $sformatf( + "expected reset_info to match hw_req 0x%x", expected)); + check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, 1'b0); + + csr_wr(.ptr(ral.reset_info), .value('1)); + + set_pos_and_wait(); + `DV_CHECK_RANDOMIZE_FATAL(this) + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + + // Send sw reset. + csr_wr(.ptr(ral.reset_req), .value(MuBi4True)); + send_sw_reset(); + expected = 1 << ral.reset_info.sw_reset.get_lsb_pos(); + check_reset_info(maybe_por_reset | expected, "Expected reset_info to indicate sw reset"); + check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, 0); + csr_wr(.ptr(ral.reset_info), .value('1)); + end + join + end + endtask : body + + task post_start(); + expect_fatal_alerts = 1; + super.post_start(); + endtask + + task send_unexpected_child_reset(string path); + `uvm_info(`gfn, "unexpected child reset start", UVM_MEDIUM) + // clear all + set_leaf_reset(.path({path, ".parent_rst_ni"}), .value(1), .cycles(0)); + set_leaf_reset(.path({path, ".sw_rst_req_i"}), .value(0), .cycles(0)); + set_leaf_reset(.path({path, ".child_rst_ni"}), .value(1), .cycles(0)); + + cfg.scoreboard.set_exp_alert("fatal_cnsty_fault", 1, 20); + + // assert child reset + set_leaf_reset(.path({path, ".child_rst_ni"}), .value(0), .cycles(cycles_to_child_reset)); + endtask : send_unexpected_child_reset + + task send_unexpected_child_release(string path); + `uvm_info(`gfn, "unexpected child release start", UVM_MEDIUM) + fork + set_leaf_reset(.path({path, ".parent_rst_ni"}), .value(0), .cycles(cycles_to_parent_reset)); + set_leaf_reset(.path({path, ".sw_rst_req_i"}), .value(1), .cycles(cycles_to_sw_reset)); + set_leaf_reset(.path({path, ".child_rst_ni"}), .value(0), .cycles(cycles_to_child_reset)); + join + + cfg.scoreboard.set_exp_alert("fatal_cnsty_fault", 1, 20); + + set_leaf_reset(.path({path, ".child_rst_ni"}), .value(1), .cycles(cycles_to_child_release)); + endtask : send_unexpected_child_release + + local task set_leaf_reset(string path, logic value, int cycles); + cfg.clk_rst_vif.wait_clks(cycles); + `uvm_info(`gfn, $sformatf("Force %s = %b", path, value), UVM_MEDIUM) + `DV_CHECK(uvm_hdl_force(path, value)) + endtask : set_leaf_reset + + // Create some unexpected child activity when my_pos is error_pos. The unexpected activity + // should trigger alerts, so this fails if no alert is generated. + task unexpected_child_activity(string path); + int err_value; + string lpath; + `DV_SPINWAIT(while (my_pos < error_pos) @cfg.clk_rst_vif.cb;, + "Timeout waiting for my_pos < error_pos", 1000_000) + + `DV_SPINWAIT(wait_for_cnsty_idle(path);, "Timeout waiting for cnsty_idle", 1000_000) + + `DV_SPINWAIT(wait_for_alert_sender_ready();, "Timeout waiting for alert_sender ready", 1000_000) + `DV_CHECK_RANDOMIZE_FATAL(this); + `uvm_info(`gfn, "Triggering inconsistency", UVM_MEDIUM) + randcase + 1: send_unexpected_child_reset(path); + 1: send_unexpected_child_release(path); + endcase + + cfg.clk_rst_vif.wait_clks(cycles_to_check); + `DV_SPINWAIT(wait(cfg.m_alert_agent_cfgs["fatal_cnsty_fault"].vif.alert_tx_final.alert_p);, + "Timeout waiting for alert fatal_cnsty_fault", 10_000) + + lpath = {path, ".child_rst_ni"}; + `DV_CHECK(uvm_hdl_release(lpath)) + lpath = {path, ".parent_rst_ni"}; + `DV_CHECK(uvm_hdl_release(lpath)) + lpath = {path, ".sw_rst_req_i"}; + `DV_CHECK(uvm_hdl_release(lpath)) + // And expect POR bit to be set. + maybe_por_reset = 1; + apply_reset(); + + // set error_pos to large value + // after error injection. + error_pos = 100; + endtask : unexpected_child_activity + + // wait for parent and child reset deassert. + // to make sure rstmgr_cnsty_chk state is not Reset state. + task wait_for_cnsty_idle(string path); + int value = 1; + string lpath; + + while (value == 1) begin + @cfg.clk_rst_vif.cb; + lpath = {path, ".sync_parent_rst"}; + `DV_CHECK(uvm_hdl_read(lpath, value)) + end + value = 1; + while (value == 1) begin + @cfg.clk_rst_vif.cb; + lpath = {path, ".sync_child_rst"}; + `DV_CHECK(uvm_hdl_read(lpath, value)) + end + endtask : wait_for_cnsty_idle + + // This waits until the alert_rx differential pairs are complementary, indicating the + // end of their initialization phase. This is necessary so the fault injection doesn't + // happen during initialization, which would end up delaying the outgoing alert. + task wait_for_alert_sender_ready(); + `uvm_info(`gfn, "Waiting for alert sender ready", UVM_MEDIUM) + forever @cfg.m_alert_agent_cfgs["fatal_cnsty_fault"].vif.sender_cb begin + if (cfg.m_alert_agent_cfgs["fatal_cnsty_fault"].vif.sender_cb.alert_rx.ping_p != + cfg.m_alert_agent_cfgs["fatal_cnsty_fault"].vif.sender_cb.alert_rx.ping_n && + cfg.m_alert_agent_cfgs["fatal_cnsty_fault"].vif.sender_cb.alert_rx.ack_p != + cfg.m_alert_agent_cfgs["fatal_cnsty_fault"].vif.sender_cb.alert_rx.ack_n) begin + `uvm_info(`gfn, "Alert sender is ready", UVM_MEDIUM) + return; + end + end + endtask : wait_for_alert_sender_ready + + task check_alert_and_cpu_info_after_reset(alert_crashdump_t alert_dump, cpu_crash_dump_t cpu_dump, + logic enable); + + if (error_pos != my_pos) begin + super.check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, enable); + end + endtask : check_alert_and_cpu_info_after_reset + + // Increments my_pos and if it equals error_pos this just waits to give time for the consistency + // error to be injected and side-effects to be created. Clear the expectation of a por reset + // since this is a new reset. + task set_pos_and_wait(); + maybe_por_reset = 0; + my_pos++; + `DV_SPINWAIT(while (my_pos == error_pos) @cfg.clk_rst_vif.cb;, $sformatf( + "Timeout waiting for my_pos == error_pos ends my_pos:%0d", my_pos), 1000_000) + endtask : set_pos_and_wait +endclass : rstmgr_leaf_rst_cnsty_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_shadow_attack_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_shadow_attack_vseq.sv new file mode 100644 index 0000000000000..4b88e03748fb6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_leaf_rst_shadow_attack_vseq.sv @@ -0,0 +1,84 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// Description: +// Test assert glitch to shadow leaf reset module and +// check if nomal reset module got affected or vice versa +class rstmgr_leaf_rst_shadow_attack_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_leaf_rst_shadow_attack_vseq) + + `uvm_object_new + + string leaf_path; + + task body(); + for (int i = 0; i < LIST_OF_SHADOW_LEAFS.size(); ++i) begin + leaf_path = {"tb.dut.", LIST_OF_SHADOW_LEAFS[i]}; + `uvm_info(`gfn, $sformatf("Round %0d %s ", i, leaf_path), UVM_MEDIUM) + + leaf_rst_attack(leaf_path, {leaf_path, "_shadowed"}); + leaf_rst_attack({leaf_path, "_shadowed"}, leaf_path); + end + endtask : body + + task leaf_rst_attack(string npath, string gpath); + // Wait for any bit in rst_sys_io_div4_n to become inactive. + wait(|cfg.rstmgr_vif.resets_o.rst_sys_io_div4_n); + // Disable cascading reset assertions, since forcing related signals causes failures. + cfg.rstmgr_cascading_sva_vif.disable_sva = 1'b1; + `uvm_info(`gfn, $sformatf("Starting leaf attack between %s and %s", npath, gpath), UVM_MEDIUM) + cfg.scoreboard.set_exp_alert("fatal_cnsty_fault", 1, 20); + add_glitch(gpath); + wait_and_check(npath); + remove_glitch(gpath); + cfg.rstmgr_cascading_sva_vif.disable_sva = 1'b0; + `uvm_info(`gfn, "Ending leaf attack", UVM_MEDIUM) + + cfg.clk_rst_vif.wait_clks(10); + apply_reset(); + endtask : leaf_rst_attack + + + function void add_glitch(string path); + string epath = {path, ".rst_en_o"}; + string opath = {path, ".leaf_rst_o"}; + + `DV_CHECK(uvm_hdl_force(epath, prim_mubi_pkg::MuBi4True), $sformatf( + "Path %0s has problem", epath)) + `DV_CHECK(uvm_hdl_force(opath, 0), $sformatf("Path %0s has problem", opath)) + endfunction + + task wait_and_check(string path); + logic [3:0] rst_en; + logic leaf_rst; + string epath = {path, ".rst_en_o"}; + string opath = {path, ".leaf_rst_o"}; + + // Wait enough cycles to allow the uvm_hdl_force to take effect, since it is not instantaneous, + // and for side-effects to propagate. + cfg.io_div4_clk_rst_vif.wait_clks(10); + + `uvm_info(`gfn, $sformatf("Checking rst and en for %s", path), UVM_MEDIUM) + `DV_CHECK(uvm_hdl_read(epath, rst_en), $sformatf("Path %0s has problem", epath)) + `DV_CHECK(uvm_hdl_read(opath, leaf_rst), $sformatf("Path %0s has problem", opath)) + + `DV_CHECK_EQ(prim_mubi_pkg::mubi4_t'(rst_en), prim_mubi_pkg::MuBi4False, + $sformatf("%s value mismatch", epath)) + `DV_CHECK_EQ(leaf_rst, 1, $sformatf("%s value mismatch", opath)) + endtask : wait_and_check + + function void remove_glitch(string path); + string epath = {path, ".rst_en_o"}; + string opath = {path, ".leaf_rst_o"}; + `DV_CHECK(uvm_hdl_release(epath), $sformatf("Path %0s has problem", epath)) + `DV_CHECK(uvm_hdl_release(opath), $sformatf("Path %0s has problem", opath)) + endfunction + + // clean up glitch will create reset consistency error + // in shadow leaf reset module + task post_start(); + expect_fatal_alerts = 1; + super.post_start(); + endtask + +endclass : rstmgr_leaf_rst_shadow_attack_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_por_stretcher_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_por_stretcher_vseq.sv new file mode 100644 index 0000000000000..5a68b71345311 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_por_stretcher_vseq.sv @@ -0,0 +1,43 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Tests the POR stretching functionality: it directly controls the por_n_i input at the start of +// the test, and randomly glitches it for a few cycles at intervals less than the stretch cycle +// count, which is at least 32 cycles, to make sure the internal and output resets won't be +// released until the input is held steady for a sufficient number of cycles. +class rstmgr_por_stretcher_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_por_stretcher_vseq) + + `uvm_object_new + + // Wait a few cycles for resets to propagate before we start flipping por_n_i, to avoid + // spurious SVA failures dut to missing rise transitions of leaf resets. + localparam int AON_CYCLES_BEFORE_START = 4; + + // Wait this many cycles before checking for side effects of a complete reset. + localparam int AON_CYCLES_BEFORE_RESET_CHECK = 45; + + rand int glitch_separation_cycles; + rand int glitch_duration_cycles; + + // The separation between glitches that will cause a reset to fail to propagate. + constraint glitch_separation_cycles_c {glitch_separation_cycles inside {[1 : 35]};} + // The duration cycle is not very interesting. + constraint glitch_duration_cycles_c {glitch_duration_cycles inside {[1 : 8]};} + + task body(); + cfg.aon_clk_rst_vif.wait_clks(AON_CYCLES_BEFORE_START); + for (int i = 0; i < num_trans; ++i) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + cfg.rstmgr_vif.por_n = 1'b1; + cfg.aon_clk_rst_vif.wait_clks(glitch_separation_cycles); + cfg.rstmgr_vif.por_n = 1'b0; + cfg.aon_clk_rst_vif.wait_clks(glitch_duration_cycles); + `DV_CHECK_EQ(cfg.rstmgr_vif.resets_o.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel], 1'b0) + end + por_reset_done(.complete_it(1)); + csr_rd_check(.ptr(ral.reset_info.por), .compare_value(1'b1), + .err_msg("Unexpected reset_info.por low")); + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_reset_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_reset_vseq.sv new file mode 100644 index 0000000000000..1a5071c521c2f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_reset_vseq.sv @@ -0,0 +1,189 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Tests the reset_info CSR settings, and alert and cpu dump capture for random +// resets. +// +// Notice that for rstmgr both POR and scan reset have identical side-effects. +class rstmgr_reset_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_reset_vseq) + + `uvm_object_new + + typedef bit [ResetLast-1:0] which_resets_t; + + rand bit por_rst; + rand bit scan_rst; + rand bit low_power_rst; + rand bit sw_rst; + rand bit hw_rst; + + constraint which_resets_c { + $onehot( + {por_rst, scan_rst, low_power_rst, sw_rst || hw_rst} + ); + } + + constraint num_trans_c {num_trans inside {[40 : 60]};} + + // VCS seems to have non-uniform distributions for this variable. + rand logic alert_enable; + + rand logic cpu_enable; + + rand reset_e start_reset; + constraint start_reset_c {start_reset inside {ResetPOR, ResetScan};} + + which_resets_t which_resets; + mubi4_t sw_reset_csr; + + function which_resets_t create_which_resets(); + which_resets_t which_resets; + if (por_rst) which_resets[ResetPOR] = 1; + if (scan_rst) which_resets[ResetScan] = 1; + if (low_power_rst) which_resets[ResetLowPower] = 1; + if (sw_rst) which_resets[ResetSw] = 1; + if (hw_rst) which_resets[ResetHw] = 1; + return which_resets; + endfunction + + function bit has_aon_reset(which_resets_t which_resets); + return which_resets[ResetPOR] || which_resets[ResetScan]; + endfunction + + function bit clear_capture_enable(which_resets_t which_resets); + return (which_resets & ~(1 << ResetLowPower)) ? 1 : 0; + endfunction + + function void post_randomize(); + sw_reset_csr = get_rand_mubi4_val(0, 2, 4); + endfunction + + function string resets_description(which_resets_t which_resets, rstreqs_t rstreqs); + string msg = "Resets to be sent:"; + bit some; + for (reset_e r = r.first(); r != r.last(); r = r.next()) begin + if (which_resets[r]) begin + if (some) msg = {msg, ", "}; + msg = {msg, " ", reset_name[r]}; + if (r == ResetHw) msg = {msg, $sformatf(" with 0x%x", rstreqs)}; + some = 1; + end + end + return msg; + endfunction + + function reset_info_t get_expected_reset_info(which_resets_t which_resets, rstreqs_t rstreqs); + reset_info_t reset_info; + for (reset_e r = r.first(); r != r.last(); r = r.next()) begin + if (which_resets[r]) reset_info |= get_reset_code(r, rstreqs); + end + return reset_info; + endfunction + + task body(); + reset_info_t expected_reset_info_code; + logic expected_alert_enable; + logic expected_cpu_enable; + alert_crashdump_t expected_alert_dump = '0; + cpu_crash_dump_t expected_cpu_dump = '0; + alert_crashdump_t prev_alert_dump = '0; + cpu_crash_dump_t prev_cpu_dump = '0; + + // Expect reset info to be POR when running the sequence standalone. + if (is_running_sequence("rstmgr_reset_vseq")) begin + check_reset_info(1, "expected reset_info to be POR"); + check_alert_and_cpu_info_after_reset(.alert_dump('0), .cpu_dump('0), .enable(1'b0)); + end + + `DV_CHECK_RANDOMIZE_FATAL(this) + + // Clear reset_info register, and enable cpu and alert info capture. + set_alert_info_for_capture(alert_dump, alert_enable); + set_cpu_info_for_capture(cpu_dump, cpu_enable); + csr_wr(.ptr(ral.reset_info), .value('1)); + + // We need to start with an AON reset to process non-capturing resets. + if (start_reset == ResetPOR) por_reset(); + else if (start_reset == ResetScan) send_scan_reset(); + + // On either of these resets we expect captures to be all zero and enables to be off. + expected_alert_dump = '0; + expected_cpu_dump = '0; + expected_alert_enable = 0; + expected_cpu_enable = 0; + + cfg.clk_rst_vif.wait_clks(8); + // Wait till rst_lc_n is inactive for non-aon. + `DV_WAIT(cfg.rstmgr_vif.resets_o.rst_lc_n[1]) + + check_reset_info(get_reset_code(start_reset, 0), {reset_name[start_reset], " reset"}); + check_alert_info_after_reset(expected_alert_dump, expected_alert_enable); + check_cpu_info_after_reset(expected_cpu_dump, expected_cpu_enable); + prev_alert_dump = expected_alert_dump; + prev_cpu_dump = expected_cpu_dump; + + for (int i = 0; i < num_trans; ++i) begin : trans_loop + logic clear_enables; + logic has_aon; + + `uvm_info(`gfn, $sformatf("Starting new round %0d", i), UVM_MEDIUM) + `DV_CHECK_RANDOMIZE_FATAL(this) + which_resets = create_which_resets(); + set_alert_info_for_capture(alert_dump, alert_enable); + set_cpu_info_for_capture(cpu_dump, cpu_enable); + csr_wr(.ptr(ral.reset_info), .value('1)); + if (which_resets[ResetSw]) begin + sw_reset_csr = MuBi4True; + csr_wr(.ptr(ral.reset_req), .value(sw_reset_csr)); + end + has_aon = has_aon_reset(which_resets); + clear_enables = clear_capture_enable(which_resets); + + `uvm_info(`gfn, $sformatf("Expected to %0s capture enables", clear_enables ? "clear" : "hold" + ), UVM_MEDIUM) + expected_reset_info_code = get_expected_reset_info(which_resets, rstreqs); + expected_alert_enable = alert_enable && !clear_enables; + expected_cpu_enable = cpu_enable && !clear_enables; + expected_alert_dump = has_aon ? '0 : (alert_enable ? alert_dump : prev_alert_dump); + expected_cpu_dump = has_aon ? '0 : (cpu_enable ? cpu_dump : prev_cpu_dump); + `uvm_info(`gfn, resets_description(which_resets, rstreqs), UVM_MEDIUM) + `uvm_info(`gfn, $sformatf("resets with alert_en %b, cpu_en %b", alert_enable, cpu_enable), + UVM_MEDIUM) + + fork + if (which_resets[ResetPOR]) por_reset(.complete_it(0)); + if (which_resets[ResetScan]) send_scan_reset(.complete_it(0)); + if (which_resets[ResetLowPower]) begin + cfg.io_div4_clk_rst_vif.wait_clks(lowpower_rst_cycles); + send_lowpower_reset(.complete_it(0)); + end + if (which_resets[ResetSw]) begin + cfg.io_div4_clk_rst_vif.wait_clks(sw_rst_cycles); + send_sw_reset(.complete_it(0)); + end + if (which_resets[ResetHw]) begin + cfg.io_div4_clk_rst_vif.wait_clks(hw_rst_cycles); + send_hw_reset(rstreqs, .complete_it(0)); + end + join + #(reset_us * 1us); + reset_done(); + + cfg.io_div4_clk_rst_vif.wait_clks(8); + wait(cfg.rstmgr_vif.resets_o.rst_lc_n[1]); + check_reset_info(expected_reset_info_code); + check_alert_info_after_reset(.alert_dump(expected_alert_dump), + .enable(expected_alert_enable)); + check_cpu_info_after_reset(.cpu_dump(expected_cpu_dump), .enable(expected_cpu_enable)); + if (has_aon) read_and_check_all_csrs_after_reset(); + prev_alert_dump = expected_alert_dump; + prev_cpu_dump = expected_cpu_dump; + end : trans_loop + csr_wr(.ptr(ral.reset_info), .value('1)); + // This clears the info registers to cancel side-effects into other sequences with stress tests. + clear_alert_and_cpu_info(); + endtask : body + +endclass : rstmgr_reset_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sec_cm_scan_intersig_mubi_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sec_cm_scan_intersig_mubi_vseq.sv new file mode 100644 index 0000000000000..cb4369acbb47b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sec_cm_scan_intersig_mubi_vseq.sv @@ -0,0 +1,52 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Description: +// While running smoke test, assert illegal scanmode input +class rstmgr_sec_cm_scan_intersig_mubi_vseq extends rstmgr_smoke_vseq; + + `uvm_object_utils(rstmgr_sec_cm_scan_intersig_mubi_vseq) + + `uvm_object_new + + task body(); + fork + begin : isolation_fork + fork + super.body(); + add_noise(); + join_any + disable fork; + end + join + endtask : body + + task add_noise(); + int delay; + + forever begin + // If scan_rst_ni is active we assume super is doing a scan reset, so keep scanmode_i True. + if (cfg.rstmgr_vif.scan_rst_ni == 1'b1) begin + cfg.rstmgr_vif.scanmode_i = get_rand_mubi4_val(0, 1, 4); + end else begin + cfg.rstmgr_vif.scanmode_i = prim_mubi_pkg::MuBi4True; + end + delay = $urandom_range(5, 30); + fork + // This waits for a certain number of cycles or for a change in scan_rst_ni, + // whichever is sooner, or it could end up skipping a full scan reset. + begin : isolation_fork + fork + // @(edge) is not supported by xcelium, workaround with posedge+negedge + @(posedge cfg.rstmgr_vif.scan_rst_ni or negedge cfg.rstmgr_vif.scan_rst_ni); + cfg.clk_rst_vif.wait_clks(delay); + join_any + disable fork; + end + join + // Somehow without this VCS will scan_rst_ni transitions to 0. + #0; + end + endtask : add_noise +endclass : rstmgr_sec_cm_scan_intersig_mubi_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_smoke_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_smoke_vseq.sv new file mode 100644 index 0000000000000..9d8a05495c66b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_smoke_vseq.sv @@ -0,0 +1,116 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Tests the different kinds of reset: POR, low power wakeup, hardware reset, debug_mode reset, +// and software initiated peripheral resets. +class rstmgr_smoke_vseq extends rstmgr_base_vseq; + + `uvm_object_utils(rstmgr_smoke_vseq) + + `uvm_object_new + + constraint rstreqs_non_zero_c {rstreqs != '0;} + constraint sw_rst_regwen_non_trivial_c {sw_rst_regwen != '0 && sw_rst_regwen != '1;} + constraint sw_rst_some_reset_c {sw_rst_regwen & ~sw_rst_ctrl_n != '0;} + + local task wait_between_resets(); + cfg.io_div4_clk_rst_vif.wait_clks(10); + endtask + + task body(); + uvm_reg_data_t exp_reg; + bit is_standalone = is_running_sequence("rstmgr_smoke_vseq"); + // Expect reset info to be POR when running the sequence standalone. + if (is_standalone) begin + check_reset_info(1, "expected reset_info to be POR"); + check_alert_and_cpu_info_after_reset(.alert_dump('0), .cpu_dump('0), .enable(1'b0)); + end + csr_wr(.ptr(ral.reset_info), .value('1)); + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + + send_scan_reset(); + // Scan reset triggers an AON reset (and all others). + wait(&cfg.rstmgr_vif.resets_o.rst_por_aon_n); + + check_reset_info(1, "expected reset_info to be POR for scan reset"); + // Alert and cpu info settings were reset. Check and re-enable them. + check_alert_and_cpu_info_after_reset(.alert_dump('0), .cpu_dump('0), .enable(1'b0)); + wait_between_resets(); + + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + + csr_wr(.ptr(ral.reset_info), .value('1)); + + // Send low power entry reset. + send_lowpower_reset(); + exp_reg = csr_utils_pkg::get_csr_val_with_updated_field(ral.reset_info.low_power_exit, '0, 1); + check_reset_info(exp_reg, "expected reset_info to indicate low power"); + check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, 1'b1); + wait_between_resets(); + + csr_wr(.ptr(ral.reset_info), .value('1)); + + // Send HwReq. + // Enable alert_info and cpu_info capture. + `DV_CHECK_RANDOMIZE_FATAL(this) + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + + send_hw_reset(rstreqs); + exp_reg = csr_utils_pkg::get_csr_val_with_updated_field(ral.reset_info.hw_req, '0, rstreqs); + check_reset_info(exp_reg, $sformatf("expected reset_info to match 0x%x", exp_reg)); + check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, 1'b0); + wait_between_resets(); + + csr_wr(.ptr(ral.reset_info), .value('1)); + + `DV_CHECK_RANDOMIZE_FATAL(this) + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + + `DV_CHECK_RANDOMIZE_FATAL(this) + set_alert_and_cpu_info_for_capture(alert_dump, cpu_dump); + + // Send sw reset. + csr_wr(.ptr(ral.reset_req), .value(MuBi4True)); + send_sw_reset(); + exp_reg = csr_utils_pkg::get_csr_val_with_updated_field(ral.reset_info.sw_reset, '0, 1); + check_reset_info(exp_reg, "Expected reset_info to indicate sw reset"); + check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, 0); + wait_between_resets(); + + csr_wr(.ptr(ral.reset_info), .value('1)); + + // Testing software resets: only run this when the sequence is run standalone, since + // setting sw_rst_regwen is irreversible. + if (is_standalone) begin : sw_rst + logic [NumSwResets-1:0] exp_ctrl_n; + const logic [NumSwResets-1:0] sw_rst_all_ones = '1; + alert_crashdump_t bogus_alert_dump = '1; + cpu_crash_dump_t bogus_cpu_dump = '1; + + set_alert_and_cpu_info_for_capture(bogus_alert_dump, bogus_cpu_dump); + rstmgr_csr_rd_check_unpack(.ptr(ral.sw_rst_ctrl_n), .compare_value(sw_rst_all_ones), + .err_msg("expected no reset on")); + rstmgr_csr_wr_unpack(.ptr(ral.sw_rst_regwen), .value(sw_rst_regwen)); + `uvm_info(`gfn, $sformatf("sw_rst_regwen set to 0x%0h", sw_rst_regwen), UVM_LOW) + rstmgr_csr_rd_check_unpack(.ptr(ral.sw_rst_regwen), .compare_value(sw_rst_regwen)); + + // This is probably also tested by common CSR tests. + // Check sw_rst_regwen can not be set to all ones again because it is rw0c. + rstmgr_csr_wr_unpack(.ptr(ral.sw_rst_regwen), .value({NumSwResets{1'b1}})); + rstmgr_csr_rd_check_unpack(.ptr(ral.sw_rst_regwen), .compare_value(sw_rst_regwen), + .err_msg("Expected sw_rst_regwen block raising individual bits because rw0c")); + + // Check that the regwen disabled bits block corresponding updated to ctrl_n. + rstmgr_csr_wr_unpack(.ptr(ral.sw_rst_ctrl_n), .value(sw_rst_regwen)); + rstmgr_csr_rd_check_unpack(.ptr(ral.sw_rst_ctrl_n), .compare_value(sw_rst_all_ones), + .err_msg("Expected sw_rst_ctrl_n not to change")); + + check_sw_rst_ctrl_n(sw_rst_ctrl_n, sw_rst_regwen, 1); + check_alert_and_cpu_info_after_reset(alert_dump, cpu_dump, 1'b1); + end : sw_rst + // This clears the info registers to cancel side-effects into other sequences with stress tests. + clear_alert_and_cpu_info(); + endtask : body + +endclass : rstmgr_smoke_vseq diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_stress_all_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_stress_all_vseq.sv new file mode 100644 index 0000000000000..0ab994ac1c83e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_stress_all_vseq.sv @@ -0,0 +1,37 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// combine all rstmgr seqs (except below seqs) in one seq to run sequentially +// 1. csr seq, which requires scb to be disabled +class rstmgr_stress_all_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_stress_all_vseq) + + `uvm_object_new + + task body(); + string seq_names[] = {"rstmgr_reset_vseq", "rstmgr_smoke_vseq", "rstmgr_sw_rst_vseq"}; + for (int i = 1; i <= num_trans; i++) begin + uvm_sequence seq; + rstmgr_base_vseq rstmgr_vseq; + uint seq_idx = $urandom_range(0, seq_names.size - 1); + + seq = create_seq_by_name(seq_names[seq_idx]); + `downcast(rstmgr_vseq, seq) + + // if upper seq disables do_apply_reset for this seq, then can't issue reset + // as upper seq may drive reset + if (do_apply_reset) rstmgr_vseq.do_apply_reset = $urandom_range(0, 1); + else rstmgr_vseq.do_apply_reset = 0; + rstmgr_vseq.set_sequencer(p_sequencer); + `DV_CHECK_RANDOMIZE_FATAL(rstmgr_vseq) + `uvm_info(`gfn, $sformatf("seq_idx = %0d, sequence is %0s", seq_idx, rstmgr_vseq.get_name()), + UVM_MEDIUM) + + rstmgr_vseq.start(p_sequencer); + `uvm_info(`gfn, $sformatf( + "End of sequence %0s with seq_idx = %0d", rstmgr_vseq.get_name(), seq_idx), + UVM_MEDIUM) + end + endtask : body +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_reset_race_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_reset_race_vseq.sv new file mode 100644 index 0000000000000..1e38ad100cadd --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_reset_race_vseq.sv @@ -0,0 +1,59 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Tests the software reset functionality: using `sw_rst_regen` and `sw_rst_ctrl_n` CSRs it causes +// resets for each of the bits randomly. It also triggers lc or sys resets to verify the reset +// transitions that cause rising upper resets but non-rising leafs. +// +// Then it clears specific `sw_rst_regwen` bits and attempts to cause resets to determine +// the bits with `sw_rst_regwen` cleared cannot cause a reset. +class rstmgr_sw_rst_reset_race_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_sw_rst_reset_race_vseq) + + `uvm_object_new + rand int cycles_before_sw_rst; + rand int cycles_before_reset; + + // When reset is issued the clocks will be stopped, so the sw_rst_ctrl_n writes must + // start before reset to be safe, or this could wait forever since the clock will stop. + constraint cycles_racing_c { + solve cycles_before_reset before cycles_before_sw_rst; + cycles_before_reset inside {[2 : 8]}; + cycles_before_sw_rst inside {[1 : cycles_before_reset - 1]}; + } + + constraint rstreqs_non_zero_c {rstreqs != '0;} + + task body(); + bit [NumSwResets-1:0] exp_ctrl_n; + bit [NumSwResets-1:0] sw_rst_regwen = '1; + int expected; + alert_pkg::alert_crashdump_t bogus_alert_dump = '1; + rv_core_ibex_pkg::cpu_crash_dump_t bogus_cpu_dump = '1; + set_alert_and_cpu_info_for_capture(bogus_alert_dump, bogus_cpu_dump); + + for (int i = 0; i < num_trans; ++i) begin + csr_wr(.ptr(ral.reset_info), .value('1)); + + `DV_CHECK_RANDOMIZE_FATAL(this) + fork + begin + cfg.clk_rst_vif.wait_clks(cycles_before_sw_rst); + check_sw_rst_ctrl_n(sw_rst_ctrl_n, sw_rst_regwen, 0); + `uvm_info(`gfn, "Done with sw_rst", UVM_MEDIUM) + end + begin + cfg.clk_rst_vif.wait_clks(cycles_before_reset); + send_hw_reset(rstreqs, .complete_it(0)); + `uvm_info(`gfn, "Done with send_reset", UVM_MEDIUM) + end + join + #(reset_us * 1us); + reset_done(); + clear_sw_rst_ctrl_n(); + expected = rstreqs << ral.reset_info.hw_req.get_lsb_pos(); + check_reset_info(expected, $sformatf("expected reset_info to match 0x%x", expected)); + end + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_vseq.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_vseq.sv new file mode 100644 index 0000000000000..edb0ba7d24d21 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_sw_rst_vseq.sv @@ -0,0 +1,49 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// Tests the software reset functionality: using `sw_rst_regen` and `sw_rst_ctrl_n` CSRs it causes +// resets for each of the bits randomly. It also triggers lc or sys resets to verify the reset +// transitions that cause rising upper resets but non-rising leafs. +// +// Then it clears each `sw_rst_regwen` bits and attempts to cause resets to determine +// the bits with `sw_rst_regwen` cleared cannot cause a reset. +class rstmgr_sw_rst_vseq extends rstmgr_base_vseq; + `uvm_object_utils(rstmgr_sw_rst_vseq) + + `uvm_object_new + + task body(); + bit [NumSwResets-1:0] exp_ctrl_n; + bit [NumSwResets-1:0] sw_rst_regwen = '1; + alert_crashdump_t bogus_alert_dump = '1; + cpu_crash_dump_t bogus_cpu_dump = '1; + set_alert_and_cpu_info_for_capture(bogus_alert_dump, bogus_cpu_dump); + + for (int i = 0; i < num_trans; ++i) begin + `DV_CHECK_RANDOMIZE_FATAL(this) + check_sw_rst_ctrl_n(sw_rst_ctrl_n, sw_rst_regwen, i % 2); + end + // Only run this part of the test if running standalone. Doing this in a stress test + // messes things up since setting the sw_rst_regwen CSR is irreversible. + if (is_running_sequence("rstmgr_sw_rst_vseq")) begin + // In preparation for the per-bit enable test, set sw_rst_ctrl_n to all 1. + rstmgr_csr_wr_unpack(.ptr(ral.sw_rst_ctrl_n), .value({NumSwResets{1'b1}})); + for (int i = 0; i < NumSwResets; ++i) begin + // Clear the regwen. + bit [NumSwResets-1:0] val_regwen = ~(1 << i); + bit [NumSwResets-1:0] exp_regwen = (~0) << (i + 1); + `uvm_info(`gfn, $sformatf("clearing sw_rst_regwen[%0d]", i), UVM_LOW) + csr_wr(.ptr(ral.sw_rst_regwen[i]), .value(val_regwen[i])); + check_sw_rst_regwen(exp_regwen); + check_sw_rst_ctrl_n(.sw_rst_ctrl_n('0), .sw_rst_regwen(exp_regwen), .erase_ctrl_n(1'b1)); + check_sw_rst_ctrl_n(.sw_rst_ctrl_n('1), .sw_rst_regwen(exp_regwen), .erase_ctrl_n(1'b1)); + // Check we cannot set it back. + csr_wr(.ptr(ral.sw_rst_regwen[i]), .value(1)); + csr_rd_check(.ptr(ral.sw_rst_regwen[i]), .compare_value(0), + .err_msg($sformatf("sw_rst_regwen[%0d] cannot be set back to 1", i))); + end + check_alert_and_cpu_info_after_reset(.alert_dump('0), .cpu_dump('0), .enable(1'b1)); + end + endtask +endclass diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_vseq_list.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_vseq_list.sv new file mode 100644 index 0000000000000..10d98cad9bf90 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/env/seq_lib/rstmgr_vseq_list.sv @@ -0,0 +1,15 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +`include "rstmgr_base_vseq.sv" +`include "rstmgr_por_stretcher_vseq.sv" +`include "rstmgr_reset_vseq.sv" +`include "rstmgr_smoke_vseq.sv" +`include "rstmgr_stress_all_vseq.sv" +`include "rstmgr_sw_rst_reset_race_vseq.sv" +`include "rstmgr_sw_rst_vseq.sv" +`include "rstmgr_common_vseq.sv" +`include "rstmgr_sec_cm_scan_intersig_mubi_vseq.sv" +`include "rstmgr_leaf_rst_cnsty_vseq.sv" +`include "rstmgr_leaf_rst_shadow_attack_vseq.sv" diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_manual_excl.el b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_manual_excl.el new file mode 100644 index 0000000000000..f152dfdd346ef --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_manual_excl.el @@ -0,0 +1,15 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: maturana +// Format Version: 2 +// Date: Wed Nov 16 12:45:49 2022 +// ExclMode: default +//================================================== +CHECKSUM: "3681358461" +INSTANCE: tb.dut.u_child_handshake +ANNOTATION: "[UNR] src_req_i and req_chk_i are tied to constants" +Assert SyncReqAckHoldReq "assertion" diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_unr_excl.el b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_unr_excl.el new file mode 100644 index 0000000000000..75fe8118bd0af --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/cov_unr_excl.el @@ -0,0 +1,17 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: maturana +// Format Version: 2 +// Date: Wed Nov 16 20:32:58 2022 +// ExclMode: default +//================================================== +CHECKSUM: "1154881809 722956608" +INSTANCE: tb.dut +ANNOTATION: "VC_COV_UNR" +Condition 4 "1172916134" "(sync_child_rst && ((!sync_parent_rst))) 1 -1" (2 "10") +ANNOTATION: "VC_COV_UNR" +Condition 5 "1866172979" "(sync_parent_rst && ((!sync_child_rst))) 1 -1" (2 "10") diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/data/rstmgr_cnsty_chk_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/data/rstmgr_cnsty_chk_testplan.hjson new file mode 100644 index 0000000000000..8c1d365bb0a89 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/data/rstmgr_cnsty_chk_testplan.hjson @@ -0,0 +1,43 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "rstmgr_cnsty_chk" + testpoints: [ + { + name: unexpected_child_reset_activity + desc: '''Verify unexpected child_reset activity flags an error. + ''' + stage: V2S + tests: ["rstmgr_cnsty_chk_smoke"] + } + { + name: child_reset_asserts_late + desc: '''Verify error triggered if child reset asserts late. + ''' + stage: V2S + tests: [] + } + { + name: child_reset_releases_late + desc: '''Verify error triggered if child reset releases late. + ''' + stage: V2S + tests: [] + } + { + name: parent_reset_asserts_late + desc: '''Verify error triggered if parent reset asserts late. + ''' + stage: V2S + tests: [] + } + { + name: parent_reset_releases_late + desc: '''Verify error triggered if parent reset releases late. + ''' + stage: V2S + tests: [] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim.core new file mode 100644 index 0000000000000..d6fa3b19a7431 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim.core @@ -0,0 +1,32 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_cnsty_chk_sim:0.1 +description: "Rstmgr_cnsty_chk DV sim target" +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_rstmgr_cnsty_chk:0.1 + - lowrisc:dv:sec_cm + file_type: systemVerilogSource + + files_dv: + depend: + - lowrisc:dv:dv_utils + - lowrisc:dv:dv_test_status + - lowrisc:dv:common_ifs + files: + - tb.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/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim_cfg.hjson new file mode 100644 index 0000000000000..108a3c2055d75 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/rstmgr_cnsty_chk_sim_cfg.hjson @@ -0,0 +1,57 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: rstmgr_cnsty_chk + + // Top level dut name (sv module). + dut: rstmgr_cnsty_chk + + // 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:opentitan:top_englishbreakfast_rstmgr_cnsty_chk_sim:0.1 + + // Testplan hjson file. + testplan: "{self_dir}/data/rstmgr_cnsty_chk_testplan.hjson" + + // Import additional common sim cfg files. + import_cfgs: ["{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson"] + + + // Specific exclusion files. + vcs_cov_excl_files: ["{self_dir}/cov_manual_excl.el", + "{self_dir}/cov_unr_excl.el"] + + // Default iterations for all tests - each test entry can override this. + reseed: 10 + + // Enable cdc instrumentation. + run_opts: ["+cdc_instrumentation_enabled=1"] + + // List of test specifications. + tests: [ + { + name: rstmgr_cnsty_chk_test + } + ] + // List of regressions. + regressions: [ + { + name: smoke + tests: ["rstmgr_cnsty_chk_test"] + } + ] + overrides: [ + // This override is in order to pick the autogen rstmgr packages. + { + name: design_level + value: "top" + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/tb.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/tb.sv new file mode 100644 index 0000000000000..560e7c57ae4a7 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_cnsty_chk/tb.sv @@ -0,0 +1,471 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Testbench module for rstmgr_cnsty_chk. +// +// The test runs pairs of events separated by a variable number of cycles in order to determine +// when errors are triggered. +// +// Consider events E1 and E2: it can send E1 from N cycles before E2 up to M cycles after it and +// any number of cycles in between. +// +// The event pairs considered are: +// - Parent reset active, child reset active +// - Sw reset active, child reset active +// - Parent reset inactive, child reset inactive +// - Sw reset inactive, child reset inactive +// +// There are two clocks involved, and it tests either one running faster then the other. +// +// In order to improve coverage it also injects sparse fsm errors. + +// Interface driving the dut. +interface rstmgr_cnsty_chk_if; + logic child_rst_ni; + logic parent_rst_ni; + logic sw_rst_req_i; + logic sw_rst_req_clr_o; + logic err_o; + logic fsm_err_o; +endinterface + +// Class generating stimulus. +class reset_class; + parameter time ClkPeriod = 10_000; + parameter time ChildFastClkPeriod = 6_543; + parameter time ChildSlowClkPeriod = 25_678; + + parameter int ScanSweepBeforeCycles = 50; + parameter int ScanSweepAfterCycles = 10; + parameter int ScanSweepCycles = ScanSweepBeforeCycles + ScanSweepAfterCycles; + + parameter int IterationsPerDelta = 16; + + import uvm_pkg::*; + + typedef enum int { + OrderChildLags, + OrderChildLeads + } order_e; + + typedef enum int { + TimingOkay, + TimingSlow + } timing_e; + + typedef enum int { + ChildClkFaster, + ChildClkSlower + } child_clk_e; + + typedef struct packed { + order_e order; + timing_e timing; + } reset_op_t; + + virtual clk_rst_if clk_rst_vif; + virtual clk_rst_if child_clk_rst_vif; + virtual rstmgr_cnsty_chk_if reset_vif; + + logic error = 0; + int cycles_to_check = 8; + + bit parent_rst_n; + bit sw_reset; + + int cycles_to_child_reset; + int cycles_to_child_release; + int cycles_to_parent_reset; + int cycles_to_parent_release; + int cycles_to_sw_reset; + int cycles_to_sw_release; + + rand int cycles_reset_width; + rand int cycles_child_reset_width; + rand int cycles_in_apply_resets; + + constraint cycles_reset_width_c {cycles_reset_width inside {[2 : 10]};} + constraint cycles_child_reset_width_c {cycles_child_reset_width inside {[2 : 10]};} + constraint cycles_in_apply_resets_c {cycles_in_apply_resets inside {[5 : 25]};} + + function new(virtual clk_rst_if clk_vif, virtual clk_rst_if child_clk_vif, + virtual rstmgr_cnsty_chk_if rst_vif); + clk_rst_vif = clk_vif; + child_clk_rst_vif = child_clk_vif; + reset_vif = rst_vif; + endfunction + + function string get_full_name(); + return "reset_class"; + endfunction + + task set_child_period(child_clk_e child_clk); + if (child_clk == ChildClkFaster) begin + `uvm_info(`gfn, $sformatf( + "Setting child clk (%0d ps) faster than reference (%0d ps)", + ChildFastClkPeriod, + ClkPeriod + ), UVM_LOW) + child_clk_rst_vif.set_period_ps(ChildFastClkPeriod); + end else begin + `uvm_info(`gfn, $sformatf( + "Setting child clk (%0d ps) slower than reference (%0d ps)", + ChildSlowClkPeriod, + ClkPeriod + ), UVM_LOW) + child_clk_rst_vif.set_period_ps(ChildSlowClkPeriod); + end + endtask + + task apply_resets(); + `uvm_info(`gfn, "Start apply_resets", UVM_MEDIUM) + fork + clk_rst_vif.apply_reset(.reset_width_clks(cycles_reset_width)); + child_clk_rst_vif.apply_reset(.reset_width_clks(cycles_child_reset_width)); + begin + reset_vif.parent_rst_ni = 1'b0; + clk_rst_vif.wait_clks(cycles_in_apply_resets); + reset_vif.parent_rst_ni = 1'b1; + end + begin + reset_vif.child_rst_ni = 1'b0; + child_clk_rst_vif.wait_clks(cycles_in_apply_resets); + reset_vif.child_rst_ni = 1'b1; + end + join + clk_rst_vif.wait_clks(20); + `uvm_info(`gfn, "End apply_resets", UVM_MEDIUM) + endtask + + task set_quiescent(); + `uvm_info(`gfn, "Setting quiescent inputs", UVM_MEDIUM) + reset_vif.parent_rst_ni = 1'b1; + reset_vif.sw_rst_req_i = 1'b0; + reset_vif.child_rst_ni = 1'b1; + endtask + + task set_parent_reset(logic value, int cycles); + if (reset_vif.parent_rst_ni == value) return; + `uvm_info(`gfn, $sformatf("Setting parent_rst_ni=%b after %0d cycles", value, cycles), UVM_HIGH) + clk_rst_vif.wait_clks(cycles); + reset_vif.parent_rst_ni = value; + endtask + + task set_sw_reset(logic value, int cycles); + if (reset_vif.sw_rst_req_i == value) return; + `uvm_info(`gfn, $sformatf("Setting sw_rst_req_i=%b after %0d cycles", value, cycles), UVM_HIGH) + clk_rst_vif.wait_clks(cycles); + reset_vif.sw_rst_req_i = value; + endtask + + task set_child_reset(logic value, int cycles); + if (reset_vif.child_rst_ni == value) return; + `uvm_info(`gfn, $sformatf("Setting child_rst_ni=%b after %0d cycles", value, cycles), UVM_HIGH) + clk_rst_vif.wait_clks(cycles); + reset_vif.child_rst_ni = value; + endtask + + task reset_start(); + fork + set_parent_reset(.value(parent_rst_n), .cycles(cycles_to_parent_reset)); + set_sw_reset(.value(sw_reset), .cycles(cycles_to_sw_reset)); + set_child_reset(.value(0), .cycles(cycles_to_child_reset)); + join + endtask + + task reset_end(); + fork + set_parent_reset(.value(1), .cycles(cycles_to_parent_release)); + set_sw_reset(.value(0), .cycles(cycles_to_sw_release)); + set_child_reset(.value(1), .cycles(cycles_to_child_release)); + join + endtask + + // Run a number of reset scenarios with some given cycle delays to allow CDC cycle fluctuations. + task run_iterations(input string description, input int delta_cycles, output int error_count); + error_count = 0; + for (int i = 0; i < IterationsPerDelta; ++i) begin + set_quiescent(); + reset_start(); + clk_rst_vif.wait_clks(20); + reset_end(); + clk_rst_vif.wait_clks(cycles_to_check); + if (reset_vif.err_o) begin + ++error_count; + end + `uvm_info(`gfn, $sformatf( + "Scan %0s with cycles delta %0d error %b", + description, + delta_cycles, + reset_vif.err_o + ), UVM_HIGH) + // May get error, so reset. + set_quiescent(); + apply_resets(); + end + endtask + + // Run a parent reset to child reset. + task scan_parent_rst(); + `uvm_info(`gfn, "scanning parent resets", UVM_LOW) + sw_reset = 0; + parent_rst_n = 0; + cycles_to_parent_release = 4; + cycles_to_child_release = 5; + cycles_to_child_reset = ScanSweepBeforeCycles; + for ( + cycles_to_parent_reset = 0; + cycles_to_parent_reset < ScanSweepCycles; + ++cycles_to_parent_reset + ) begin + int error_count = 0; + int delta_cycles = cycles_to_parent_reset - cycles_to_child_reset; + `uvm_info(`gfn, $sformatf("Sending parent reset %0d cycles from child", delta_cycles), + UVM_MEDIUM) + run_iterations("parent reset", delta_cycles, error_count); + `uvm_info(`gfn, $sformatf( + "Scan parent reset with cycles delta %0d total errors %0d / %0d", + delta_cycles, + error_count, + IterationsPerDelta + ), UVM_LOW) + `DV_CHECK(((delta_cycles <= -4) || (delta_cycles >= 4)) || (error_count == 0)) + `DV_CHECK(((delta_cycles >= -5) && (delta_cycles <= 5)) || + (error_count == IterationsPerDelta)) + end + endtask + + task scan_parent_release(); + `uvm_info(`gfn, "scanning parent release", UVM_LOW) + sw_reset = 0; + parent_rst_n = 0; + cycles_to_parent_reset = 5; + cycles_to_child_reset = 5; + cycles_to_child_release = ScanSweepBeforeCycles; + for ( + cycles_to_parent_release = 0; + cycles_to_parent_release < ScanSweepCycles; + ++cycles_to_parent_release + ) begin + int error_count = 0; + int delta_cycles = cycles_to_parent_release - cycles_to_child_release; + `uvm_info(`gfn, $sformatf("Sending parent release %0d cycles from child", delta_cycles), + UVM_MEDIUM) + run_iterations("parent release", delta_cycles, error_count); + `uvm_info(`gfn, $sformatf( + "Scan parent release with cycles delta %0d total errors %0d / %0d", + delta_cycles, + error_count, + IterationsPerDelta + ), UVM_LOW) + `DV_CHECK((delta_cycles < -12) || (delta_cycles > -1) || (error_count == 0)) + `DV_CHECK(((delta_cycles > -42) && (delta_cycles < 2)) || (error_count == IterationsPerDelta)) + end + endtask + + task scan_sw_rst(); + `uvm_info(`gfn, "scanning sw resets", UVM_LOW) + sw_reset = 1; + parent_rst_n = 1; + cycles_to_sw_release = 4; + cycles_to_child_release = 5; + cycles_to_child_reset = ScanSweepBeforeCycles; + for (cycles_to_sw_reset = 0; cycles_to_sw_reset < ScanSweepCycles; ++cycles_to_sw_reset) begin + int error_count = 0; + int delta_cycles = cycles_to_sw_reset - cycles_to_child_reset; + `uvm_info(`gfn, $sformatf("Sending sw reset %0d cycles from child", delta_cycles), UVM_HIGH) + run_iterations("sw reset", delta_cycles, error_count); + `uvm_info(`gfn, $sformatf( + "Scan sw reset with cycles delta %0d total errors %0d / %0d", + delta_cycles, + error_count, + IterationsPerDelta + ), UVM_LOW) + `DV_CHECK((delta_cycles >= 3) || (error_count == 0)) + `DV_CHECK((delta_cycles <= 3) || (error_count == IterationsPerDelta)) + end + endtask + + task scan_sw_release(); + `uvm_info(`gfn, "scanning sw releases", UVM_LOW) + sw_reset = 1; + parent_rst_n = 1; + cycles_to_sw_reset = 4; + cycles_to_child_reset = 5; + cycles_to_child_release = ScanSweepBeforeCycles; + for ( + cycles_to_sw_release = 0; cycles_to_sw_release < ScanSweepCycles; ++cycles_to_sw_release + ) begin + int error_count = 0; + int delta_cycles = cycles_to_sw_release - cycles_to_child_release; + `uvm_info(`gfn, $sformatf("Sending sw release %0d cycles from child", delta_cycles), UVM_HIGH) + run_iterations("sw release", delta_cycles, error_count); + `uvm_info(`gfn, $sformatf( + "Scan sw release with cycles delta %0d total errors %0d / %0d", + delta_cycles, + error_count, + IterationsPerDelta + ), UVM_LOW) + `DV_CHECK((delta_cycles < -8) || (delta_cycles > 3) || (error_count == 0)) + `DV_CHECK(((delta_cycles > -38) && (delta_cycles < 5)) || (error_count == IterationsPerDelta)) + end + endtask + + task inject_fsm_errors(); + sec_cm_pkg::sec_cm_base_if_proxy if_proxy = sec_cm_pkg::find_sec_cm_if_proxy( + "tb.dut.u_state_regs", 0 + ); + `DV_CHECK(!reset_vif.fsm_err_o) + repeat (10) begin + clk_rst_vif.wait_clks(5); + if_proxy.inject_fault(); + clk_rst_vif.wait_clks(5); + if_proxy.restore_fault(); + `DV_CHECK(reset_vif.fsm_err_o) + apply_resets(); + `DV_CHECK(!reset_vif.fsm_err_o) + end + clk_rst_vif.wait_clks(5); + endtask + + task body(); + foreach (sec_cm_pkg::sec_cm_if_proxy_q[i]) begin + `uvm_info(`gfn, $sformatf("Path of proxy: %0s", sec_cm_pkg::sec_cm_if_proxy_q[i].path), + UVM_MEDIUM) + end + clk_rst_vif.set_period_ps(ClkPeriod); + clk_rst_vif.set_active(); + child_clk_rst_vif.set_period_ps(ChildFastClkPeriod); + child_clk_rst_vif.set_active(); + `DV_CHECK_RANDOMIZE_FATAL(this); + + `uvm_info(`gfn, "Past set active", UVM_MEDIUM) + set_quiescent(); + apply_resets(); + + // Run with child clock faster than reference. + set_child_period(ChildClkFaster); + clk_rst_vif.wait_clks(20); + + set_quiescent(); + apply_resets(); + scan_parent_rst(); + + set_quiescent(); + apply_resets(); + scan_parent_release(); + + set_quiescent(); + apply_resets(); + scan_sw_rst(); + + set_quiescent(); + apply_resets(); + scan_sw_release(); + + set_quiescent(); + apply_resets(); + + // Run with child clock slower than reference. + set_child_period(ChildClkSlower); + clk_rst_vif.wait_clks(20); + + set_quiescent(); + apply_resets(); + scan_parent_rst(); + + set_quiescent(); + apply_resets(); + scan_parent_release(); + + set_quiescent(); + apply_resets(); + scan_sw_rst(); + + set_quiescent(); + apply_resets(); + scan_sw_release(); + + // And inject sparse fsm errors. + set_quiescent(); + apply_resets(); + inject_fsm_errors(); + endtask +endclass + +module tb; + + import uvm_pkg::*; + + reset_class reset_cl; + + wire clk_i; + wire rst_ni; + wire child_clk_i; + wire unused_child_rst_ni; + + bind prim_sparse_fsm_flop prim_sparse_fsm_flop_if #( + .Width(Width), + .CustomForceName(CustomForceName) + ) prim_sparse_fsm_flop_if (.*); + + clk_rst_if clk_rst_if ( + .clk (clk_i), + .rst_n(rst_ni) + ); + clk_rst_if child_clk_rst_if ( + .clk (child_clk_i), + .rst_n(child_rst_ni) + ); + rstmgr_cnsty_chk_if rstmgr_cnsty_chk_if (); + + logic sw_rst_req_q; + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + sw_rst_req_q <= '0; + end else if (sw_rst_req_q && rstmgr_cnsty_chk_if.sw_rst_req_clr_o) begin + sw_rst_req_q <= '0; + end else if (!sw_rst_req_q && rstmgr_cnsty_chk_if.sw_rst_req_i && + !rstmgr_cnsty_chk_if.sw_rst_req_clr_o) begin + sw_rst_req_q <= 1'b1; + end + end + + logic leaf_chk_rst_n; + prim_rst_sync u_prim_rst_sync ( + .clk_i (child_clk_i), + .d_i (rst_ni), + .q_o (leaf_chk_rst_n), + .scan_rst_ni(1'b1), + .scanmode_i(prim_mubi_pkg::MuBi4False) + ); + + rstmgr_cnsty_chk dut ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .child_clk_i(child_clk_i), + .child_rst_ni(rstmgr_cnsty_chk_if.child_rst_ni), + .child_chk_rst_ni(leaf_chk_rst_n), + .parent_rst_ni(rstmgr_cnsty_chk_if.parent_rst_ni), + .sw_rst_req_i(rstmgr_cnsty_chk_if.sw_rst_req_i | sw_rst_req_q), + .sw_rst_req_clr_o(rstmgr_cnsty_chk_if.sw_rst_req_clr_o), + .err_o(rstmgr_cnsty_chk_if.err_o), + .fsm_err_o(rstmgr_cnsty_chk_if.fsm_err_o) + ); + + // set this to one to avoid a SVA error + // This SVA is to ensure we have a fatal alert check attached to the FSM error, but this is unit + // level testbench, no alert will occur. + assign dut.u_state_regs.unused_assert_connected = 1; + initial begin + automatic dv_utils_pkg::dv_report_server dv_report_server = new(); + $timeformat(-12, 0, " ps", 12); + uvm_report_server::set_server(dv_report_server); + reset_cl = new(clk_rst_if, child_clk_rst_if, rstmgr_cnsty_chk_if); + reset_cl.body(); + dv_report_server.report_summarize(); + $finish(); + end + +endmodule : tb diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim.core new file mode 100644 index 0000000000000..9edbcbd955fde --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim.core @@ -0,0 +1,30 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_sim:0.1 +description: "RSTMGR DV sim target" +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_rstmgr + + files_dv: + depend: + - lowrisc:opentitan:top_englishbreakfast_rstmgr_test:0.1 + - lowrisc:opentitan:top_englishbreakfast_rstmgr_sva:0.1 + files: + - tb.sv + - cov/rstmgr_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/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim_cfg.hjson b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim_cfg.hjson new file mode 100644 index 0000000000000..7865f569bd99e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/rstmgr_sim_cfg.hjson @@ -0,0 +1,113 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: rstmgr + + // Top level dut name (sv module). + dut: rstmgr + + // 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:opentitan:top_englishbreakfast_rstmgr_sim:0.1 + + // Testplan hjson file. + testplan: "{self_dir}/../data/rstmgr_testplan.hjson" + + // RAL spec - used to generate the RAL model. + ral_spec: "{self_dir}/../data/rstmgr.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/alert_test.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/tl_access_tests.hjson", + "{proj_root}/hw/dv/tools/dvsim/tests/sec_cm_tests.hjson", + // Just run the stress_all sequence, and don't inject random + // resets since we may get overlapping resets due to sequences + // that inject them. + "{proj_root}/hw/dv/tools/dvsim/tests/stress_all_test.hjson" + ] + + // Specific exclusion files. + vcs_cov_excl_files: ["{self_dir}/cov/rstmgr_unr_excl.el"] + + // Overrides + overrides: [ + { + name: design_level + value: "top" + } + { + name: default_vcs_cov_cfg_file + value: "-cm_hier {proj_root}/hw/dv/tools/vcs/cover.cfg+{proj_root}/hw/dv/tools/vcs/common_cov_excl.cfg+{self_dir}/cov/rstmgr_cover.cfg+{self_dir}/cov/rstmgr_tgl_excl.cfg" + } + ] + + // Add additional tops for simulation. + sim_tops: ["rstmgr_bind", "rstmgr_cov_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: rstmgr_base_test + uvm_test_seq: rstmgr_base_vseq + + // Enable cdc instrumentation. + run_opts: ["+cdc_instrumentation_enabled=1"] + + // List of test specifications. + tests: [ + { + name: rstmgr_smoke + uvm_test_seq: rstmgr_smoke_vseq + } + { + name: rstmgr_por_stretcher + uvm_test_seq: rstmgr_por_stretcher_vseq + } + { + name: rstmgr_reset + uvm_test_seq: rstmgr_reset_vseq + } + { + name: rstmgr_sw_rst_reset_race + uvm_test_seq: rstmgr_sw_rst_reset_race_vseq + } + { + name: rstmgr_sw_rst + uvm_test_seq: rstmgr_sw_rst_vseq + } + { + name: rstmgr_sec_cm_scan_intersig_mubi + uvm_test_seq: rstmgr_sec_cm_scan_intersig_mubi_vseq + } + { + name: rstmgr_leaf_rst_cnsty + uvm_test_seq: rstmgr_leaf_rst_cnsty_vseq + } + { + name: rstmgr_leaf_rst_shadow_attack + uvm_test_seq: rstmgr_leaf_rst_shadow_attack_vseq + } + ] + + // List of regressions. + regressions: [ + { + name: smoke + tests: ["rstmgr_smoke"] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_attrs_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_attrs_sva_if.sv new file mode 100644 index 0000000000000..e3467c7d72867 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_attrs_sva_if.sv @@ -0,0 +1,19 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This has assertions that check the read-only value of the alert and cpu_info_attr. +interface rstmgr_attrs_sva_if ( + input logic rst_ni, + input int actual_alert_info_attr, + input int actual_cpu_info_attr, + input int expected_alert_info_attr, + input int expected_cpu_info_attr +); + + initial + @(posedge rst_ni) begin + `ASSERT_I(AlertInfoAttr_A, actual_alert_info_attr == expected_alert_info_attr) + `ASSERT_I(CpuInfoAttr_A, actual_cpu_info_attr == expected_cpu_info_attr) + end +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_bind.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_bind.sv new file mode 100644 index 0000000000000..43ff3eb0ca10d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_bind.sv @@ -0,0 +1,106 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module rstmgr_bind; +`ifndef GATE_LEVEL + bind rstmgr 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 rstmgr rstmgr_csr_assert_fpv rstmgr_csr_assert (.clk_i, .rst_ni, .h2d(tl_i), .d2h(tl_o)); +`endif + + bind rstmgr rstmgr_cascading_sva_if rstmgr_cascading_sva_if ( + .clk_i, + .clk_aon_i, + .clk_io_div4_i, + .clk_io_div2_i, + .clk_io_i, + .clk_main_i, + .clk_usb_i, + .por_n_i, + .scan_rst_ni, + .scanmode_i, + .resets_o, + .rst_lc_req(pwr_i.rst_lc_req), + .rst_sys_req(pwr_i.rst_sys_req), + .rst_lc_src_n(pwr_o.rst_lc_src_n), + .rst_sys_src_n(pwr_o.rst_sys_src_n) + ); + + bind rstmgr rstmgr_attrs_sva_if rstmgr_attrs_sva_if ( + .rst_ni, + .actual_alert_info_attr(int'(hw2reg.alert_info_attr)), + .actual_cpu_info_attr(int'(hw2reg.cpu_info_attr)), + .expected_alert_info_attr(($bits(alert_dump_i) + 31) / 32), + .expected_cpu_info_attr(($bits(cpu_dump_i) + 31) / 32) + ); + + bind rstmgr pwrmgr_rstmgr_sva_if #( + .PowerDomains(rstmgr_pkg::PowerDomains) + ) pwrmgr_rstmgr_sva_if ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .clk_slow_i(clk_aon_i), + .rst_slow_ni(&rst_por_aon_n), + // These are actually used for checks. + .rst_lc_req(pwr_i.rst_lc_req), + .rst_sys_req(pwr_i.rst_sys_req), + // The inputs from rstmgr. + .rst_lc_src_n(pwr_o.rst_lc_src_n), + .rst_sys_src_n(pwr_o.rst_sys_src_n) + ); + + bind rstmgr rstmgr_sw_rst_sva_if rstmgr_sw_rst_sva_if ( + .clk_i({ + clk_io_div4_i, + clk_io_div4_i, + clk_io_div4_i, + clk_aon_i, + clk_usb_i, + clk_io_div2_i, + clk_io_i, + clk_io_div4_i + }), + .rst_ni, + .parent_rst_n(rst_sys_src_n[1]), + .ctrl_ns(reg2hw.sw_rst_ctrl_n), + .rst_ens({ + rst_en_o.i2c2[1] == prim_mubi_pkg::MuBi4True, + rst_en_o.i2c1[1] == prim_mubi_pkg::MuBi4True, + rst_en_o.i2c0[1] == prim_mubi_pkg::MuBi4True, + rst_en_o.usb_aon[1] == prim_mubi_pkg::MuBi4True, + rst_en_o.usb[1] == prim_mubi_pkg::MuBi4True, + rst_en_o.spi_host1[1] == prim_mubi_pkg::MuBi4True, + rst_en_o.spi_host0[1] == prim_mubi_pkg::MuBi4True, + rst_en_o.spi_device[1] == prim_mubi_pkg::MuBi4True + }), + .rst_ns({ + resets_o.rst_i2c2_n[1], + resets_o.rst_i2c1_n[1], + resets_o.rst_i2c0_n[1], + resets_o.rst_usb_aon_n[1], + resets_o.rst_usb_n[1], + resets_o.rst_spi_host1_n[1], + resets_o.rst_spi_host0_n[1], + resets_o.rst_spi_device_n[1] + }) + ); + + bind rstmgr rstmgr_rst_en_track_sva_if rstmgr_rst_en_track_sva_if ( + .resets_i(resets_o), + .reset_en_i(rst_en_o), + .clk_aon_i(clk_aon_i), + .clk_io_div4_i(clk_io_div4_i), + .clk_main_i(clk_main_i), + .clk_io_i(clk_io_i), + .clk_io_div2_i(clk_io_div2_i), + .clk_usb_i(clk_usb_i), + .rst_por_ni(rst_por_ni) + ); + +`endif +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv new file mode 100644 index 0000000000000..9c138af8a396a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_cascading_sva_if.sv @@ -0,0 +1,188 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This has assertions that check the reset outputs of rstmgr cascade properly. +// This means higher level resets always cause the lower level ones to assert. +// The hierarchy is +// por > lc > sys > specific peripherals +// In addition, a scan reset is at the same level as por. +// +// Local terminology: A cascading relationship is between an "above" and a "below" reset. +// +// Some individual reset outputs will always be off. Allowing for this in general would +// weaken the property that some resets MUST rise following other rise. +// +// Peripheral resets cascade from sys, and are checked in rstmgr_sw_rst_sva_if since they +// require additional inputs. +interface rstmgr_cascading_sva_if ( + input logic clk_i, + input logic clk_aon_i, + input logic clk_io_div2_i, + input logic clk_io_div4_i, + input logic clk_io_i, + input logic clk_main_i, + input logic clk_usb_i, + input [rstmgr_pkg::PowerDomains-1:0] por_n_i, + input rstmgr_pkg::rstmgr_out_t resets_o, + input [rstmgr_pkg::PowerDomains-1:0] rst_lc_req, + input [rstmgr_pkg::PowerDomains-1:0] rst_sys_req, + input [rstmgr_pkg::PowerDomains-1:0] rst_lc_src_n, + input [rstmgr_pkg::PowerDomains-1:0] rst_sys_src_n, + input logic scan_rst_ni, + input prim_mubi_pkg::mubi4_t scanmode_i +); + + // The min and max bounds on the number of cycles for an edge to occur. + typedef struct { + int min; + int max; + } bounds_t; + + // The bounds for a fall and rise edge to occur. + typedef struct { + bounds_t fall; + bounds_t rise; + } edge_bounds_t; + + // This is used to check por_n_i active high leads to a rising edge of rst_por_aon_n[0]. + // The number of cycles with por_n_i stable is 32 plus synchronizers and some filter stages. + localparam edge_bounds_t PorCycles = '{fall: '{min: 0, max: 4}, rise: '{min: 35, max: 40}}; + + // This is used to check for regular synchronizing delay. Reset falls asynchronously so the + // fall min cycles is zero. + localparam edge_bounds_t SyncCycles = '{fall: '{min: 0, max: 3}, rise: '{min: 1, max: 3}}; + + // Cycles are counted from the output rst_por_aon_n or scan reset edges. The rise times can be + // higher since in the chip the aon reset goes through the pwrmgr slow fsm where it causes an + // lc rise request and there may be multiple synchronizers in the path. + localparam edge_bounds_t LcCycles = '{fall: '{min: 0, max: 4}, rise: '{min: 1, max: 4}}; + + // In the real system the rise of rst_lc_src_n is triggered by the pwr_i.rst_lc_req input, + // which can take a few cycles since it comes from the pwrmgr after it gets reset, + // is generated with the aon clock, and gets synchronized before it triggers + // a rise in rst_lc_src_n. There is an SVA for the rise in pwrmgr_rstmgr_sva_if. + + // The cycles are counted from Lc edges. + localparam edge_bounds_t SysCycles = '{fall: '{min: 0, max: 3}, rise: '{min: 1, max: 5}}; + + // The different peripheral edges are synchronized to their respective clocks, + // so these counts assume synchronization and are triggered on the correct clock. + localparam edge_bounds_t PeriCycles = '{fall: '{min: 0, max: 4}, rise: '{min: 2, max: 8}}; + + bit disable_sva; + + // Macros to avoid excessive boiler-plate code below. + `define FALL_ASSERT(_name, _from, _to, _cycles, _clk) \ + `ASSERT(_name``AboveFall_A, \ + $fell(_from) |-> ##[_cycles.fall.min:_cycles.fall.max] _from || !_to, _clk, \ + disable_sva) + + `define RISE_ASSERTS(_name, _from, _to, _cycles, _clk) \ + `ASSERT(_name``AboveRise_A, \ + $rose(_from) ##1 _from [* _cycles.rise.min] |=> ##[0:_cycles.rise.max-_cycles.rise.min] (!_from || _to), _clk, \ + disable_sva) \ + + `define CASCADED_ASSERTS(_name, _from, _to, _cycles, _clk) \ + `FALL_ASSERT(_name, _from, _to, _cycles, _clk) \ + `RISE_ASSERTS(_name, _from, _to, _cycles, _clk) + + // A fall in por_n_i leads to a fall in rst_por_aon_n[0]. + `FALL_ASSERT(CascadePorToAon, por_n_i[rstmgr_pkg::DomainAonSel], + resets_o.rst_por_aon_n[rstmgr_pkg::DomainAonSel], PorCycles, clk_aon_i) + + // A number of consecutive cycles with por_n_i inactive (high) should cause the aon resets to + // become inactive. This checks POR stretching. + + // The antecedent: por_n_i rising and being active for enough cycles. + + logic scanmode; + always_comb scanmode = prim_mubi_pkg::mubi4_test_true_strict(scanmode_i); + + logic scan_reset_n; + always_comb scan_reset_n = !scanmode || scan_rst_ni; + + // In scanmode only scan_rst_ni controls reset, so por_n_i is ignored. + logic aon_por_n_i; + always_comb aon_por_n_i = por_n_i[rstmgr_pkg::DomainAonSel] && !scanmode; + + sequence PorStable_S; + $rose( + aon_por_n_i + ) ##1 aon_por_n_i [* PorCycles.rise.min]; + endsequence + + // The reset stretching assertion. + `ASSERT(StablePorToAonRise_A, + PorStable_S |-> ##[0:(PorCycles.rise.max-PorCycles.rise.min)] + !aon_por_n_i || resets_o.rst_por_aon_n[0], + clk_aon_i, disable_sva) + + // The scan reset to Por. + `ASSERT(ScanRstToAonRise_A, scan_reset_n && scanmode |-> resets_o.rst_por_aon_n[0], clk_aon_i, + disable_sva) + + logic [rstmgr_pkg::PowerDomains-1:0] effective_aon_rst_n; + always_comb + effective_aon_rst_n = resets_o.rst_por_aon_n & {rstmgr_pkg::PowerDomains{scan_reset_n}}; + + // The AON reset triggers the various POR reset for the different clock domains through + // synchronizers. + // The current system doesn't have any consumers of domain 1 por_io_div4, and thus only domain 0 + // cascading is checked here. + `CASCADED_ASSERTS(CascadeEffAonToRstPorIoDiv4, effective_aon_rst_n[0], + resets_o.rst_por_io_div4_n[0], SyncCycles, clk_io_div4_i) + + // The internal reset is triggered by one of synchronized por. + logic [rstmgr_pkg::PowerDomains-1:0] por_rst_n; + always_comb por_rst_n = resets_o.rst_por_aon_n; + + logic [rstmgr_pkg::PowerDomains-1:0] local_rst_or_lc_req_n; + always_comb local_rst_or_lc_req_n = por_rst_n & ~rst_lc_req; + + logic [rstmgr_pkg::PowerDomains-1:0] lc_rst_or_sys_req_n; + always_comb lc_rst_or_sys_req_n = por_rst_n & ~rst_sys_req; + + for (genvar pd = 0; pd < rstmgr_pkg::PowerDomains; ++pd) begin : g_power_domains + // The root lc reset is triggered either by the internal reset, or by the pwr_i.rst_lc_req + // input. The latter is checked independently in pwrmgr_rstmgr_sva_if. + `CASCADED_ASSERTS(CascadeLocalRstToLc, local_rst_or_lc_req_n[pd], rst_lc_src_n[pd], LcCycles, + clk_i) + + // The root sys reset is triggered by the lc reset, or independently by external requests. + // The latter is checked independently in pwrmgr_rstmgr_sva_if. + `CASCADED_ASSERTS(CascadeLcToSys, lc_rst_or_sys_req_n[pd], rst_sys_src_n[pd], SysCycles, clk_i) + + // Controlled by rst_sys_src_n. + if (pd == rstmgr_pkg::DomainAonSel) begin : gen_sys_io_div4_chk + `CASCADED_ASSERTS(CascadeSysToSysIoDiv4, rst_sys_src_n[pd], resets_o.rst_sys_io_div4_n[pd], + SysCycles, clk_io_div4_i) + end + end + + // Aon to POR + `CASCADED_ASSERTS(CascadeEffAonToRstPor, effective_aon_rst_n[rstmgr_pkg::DomainAonSel], + resets_o.rst_por_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_main_i) + `CASCADED_ASSERTS(CascadeEffAonToRstPorIo, effective_aon_rst_n[rstmgr_pkg::DomainAonSel], + resets_o.rst_por_io_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_io_i) + `CASCADED_ASSERTS(CascadeEffAonToRstPorIoDiv2, effective_aon_rst_n[rstmgr_pkg::DomainAonSel], + resets_o.rst_por_io_div2_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_io_div2_i) + `CASCADED_ASSERTS(CascadeEffAonToRstPorUcb, effective_aon_rst_n[rstmgr_pkg::DomainAonSel], + resets_o.rst_por_usb_n[rstmgr_pkg::DomainAonSel], SyncCycles, clk_usb_i) + + // Controlled by rst_lc_src_n. + `CASCADED_ASSERTS(CascadeLcToLcAon, rst_lc_src_n[rstmgr_pkg::DomainAonSel], + resets_o.rst_lc_aon_n[rstmgr_pkg::DomainAonSel], SysCycles, clk_aon_i) + `CASCADED_ASSERTS(CascadeLcToLc, rst_lc_src_n[rstmgr_pkg::Domain0Sel], + resets_o.rst_lc_n[rstmgr_pkg::Domain0Sel], SysCycles, clk_main_i) + + // Controlled by rst_sys_src_n. + `CASCADED_ASSERTS(CascadeSysToSys, rst_sys_src_n[rstmgr_pkg::Domain0Sel], + resets_o.rst_sys_n[rstmgr_pkg::Domain0Sel], PeriCycles, clk_main_i) + `CASCADED_ASSERTS(CascadeLcToLcShadowed, rst_lc_src_n[rstmgr_pkg::Domain0Sel], + resets_o.rst_lc_shadowed_n[rstmgr_pkg::Domain0Sel], SysCycles, clk_main_i) + + `undef FALL_ASSERT + `undef RISE_ASSERTS + `undef CASCADED_ASSERTS +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_rst_en_track_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_rst_en_track_sva_if.sv new file mode 100644 index 0000000000000..ab82c3743560a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_rst_en_track_sva_if.sv @@ -0,0 +1,243 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This checks that the outgoing resets and the corresponding reset enable going to alert handler +// are shifted by a single clock cycle. +interface rstmgr_rst_en_track_sva_if ( + input rstmgr_pkg::rstmgr_out_t resets_i, + input rstmgr_pkg::rstmgr_rst_en_t reset_en_i, + input logic clk_aon_i, + input logic clk_io_div4_i, + input logic clk_main_i, + input logic clk_io_i, + input logic clk_io_div2_i, + input logic clk_usb_i, + input logic rst_por_ni +); + import rstmgr_pkg::DomainAonSel; + import rstmgr_pkg::Domain0Sel; + localparam int DELAY = 1; + + `ASSERT(DAonRstPorAonEnTracksRstPorAonActive_A, + $fell(resets_i.rst_por_aon_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.por_aon[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_aon_i, + !rst_por_ni) + + `ASSERT(DAonRstPorAonEnTracksRstPorAonInactive_A, + $rose(resets_i.rst_por_aon_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_por_aon_n[DomainAonSel] || + reset_en_i.por_aon[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_aon_i, + !rst_por_ni) + + `ASSERT(DAonRstPorEnTracksRstPorActive_A, + $fell(resets_i.rst_por_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.por[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_main_i, + !rst_por_ni) + + `ASSERT(DAonRstPorEnTracksRstPorInactive_A, + $rose(resets_i.rst_por_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_por_n[DomainAonSel] || + reset_en_i.por[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_main_i, + !rst_por_ni) + + `ASSERT(DAonRstPorIoEnTracksRstPorIoActive_A, + $fell(resets_i.rst_por_io_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.por_io[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_io_i, + !rst_por_ni) + + `ASSERT(DAonRstPorIoEnTracksRstPorIoInactive_A, + $rose(resets_i.rst_por_io_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_por_io_n[DomainAonSel] || + reset_en_i.por_io[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_io_i, + !rst_por_ni) + + `ASSERT(DAonRstPorIoDiv2EnTracksRstPorIoDiv2Active_A, + $fell(resets_i.rst_por_io_div2_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.por_io_div2[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_io_div2_i, + !rst_por_ni) + + `ASSERT(DAonRstPorIoDiv2EnTracksRstPorIoDiv2Inactive_A, + $rose(resets_i.rst_por_io_div2_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_por_io_div2_n[DomainAonSel] || + reset_en_i.por_io_div2[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_io_div2_i, + !rst_por_ni) + + `ASSERT(DAonRstPorIoDiv4ShadowedEnTracksRstPorIoDiv4ShadowedActive_A, + $fell(resets_i.rst_por_io_div4_shadowed_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.por_io_div4_shadowed[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(DAonRstPorIoDiv4ShadowedEnTracksRstPorIoDiv4ShadowedInactive_A, + $rose(resets_i.rst_por_io_div4_shadowed_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_por_io_div4_shadowed_n[DomainAonSel] || + reset_en_i.por_io_div4_shadowed[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(DAonRstPorUsbEnTracksRstPorUsbActive_A, + $fell(resets_i.rst_por_usb_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.por_usb[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_usb_i, + !rst_por_ni) + + `ASSERT(DAonRstPorUsbEnTracksRstPorUsbInactive_A, + $rose(resets_i.rst_por_usb_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_por_usb_n[DomainAonSel] || + reset_en_i.por_usb[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_usb_i, + !rst_por_ni) + + `ASSERT(D0RstLcShadowedEnTracksRstLcShadowedActive_A, + $fell(resets_i.rst_lc_shadowed_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.lc_shadowed[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_main_i, + !rst_por_ni) + + `ASSERT(D0RstLcShadowedEnTracksRstLcShadowedInactive_A, + $rose(resets_i.rst_lc_shadowed_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_lc_shadowed_n[Domain0Sel] || + reset_en_i.lc_shadowed[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_main_i, + !rst_por_ni) + + `ASSERT(D0RstLcIoDiv4EnTracksRstLcIoDiv4Active_A, + $fell(resets_i.rst_lc_io_div4_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.lc_io_div4[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(D0RstLcIoDiv4EnTracksRstLcIoDiv4Inactive_A, + $rose(resets_i.rst_lc_io_div4_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_lc_io_div4_n[Domain0Sel] || + reset_en_i.lc_io_div4[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(DAonRstLcIoDiv4EnTracksRstLcIoDiv4Active_A, + $fell(resets_i.rst_lc_io_div4_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.lc_io_div4[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(DAonRstLcIoDiv4EnTracksRstLcIoDiv4Inactive_A, + $rose(resets_i.rst_lc_io_div4_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_lc_io_div4_n[DomainAonSel] || + reset_en_i.lc_io_div4[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(D0RstSysShadowedEnTracksRstSysShadowedActive_A, + $fell(resets_i.rst_sys_shadowed_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.sys_shadowed[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_main_i, + !rst_por_ni) + + `ASSERT(D0RstSysShadowedEnTracksRstSysShadowedInactive_A, + $rose(resets_i.rst_sys_shadowed_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_sys_shadowed_n[Domain0Sel] || + reset_en_i.sys_shadowed[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_main_i, + !rst_por_ni) + + `ASSERT(D0RstSysIoDiv4EnTracksRstSysIoDiv4Active_A, + $fell(resets_i.rst_sys_io_div4_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.sys_io_div4[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(D0RstSysIoDiv4EnTracksRstSysIoDiv4Inactive_A, + $rose(resets_i.rst_sys_io_div4_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_sys_io_div4_n[Domain0Sel] || + reset_en_i.sys_io_div4[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(DAonRstSysIoDiv4EnTracksRstSysIoDiv4Active_A, + $fell(resets_i.rst_sys_io_div4_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.sys_io_div4[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(DAonRstSysIoDiv4EnTracksRstSysIoDiv4Inactive_A, + $rose(resets_i.rst_sys_io_div4_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_sys_io_div4_n[DomainAonSel] || + reset_en_i.sys_io_div4[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_io_div4_i, + !rst_por_ni) + + `ASSERT(D0RstSysAonEnTracksRstSysAonActive_A, + $fell(resets_i.rst_sys_aon_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.sys_aon[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_aon_i, + !rst_por_ni) + + `ASSERT(D0RstSysAonEnTracksRstSysAonInactive_A, + $rose(resets_i.rst_sys_aon_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_sys_aon_n[Domain0Sel] || + reset_en_i.sys_aon[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_aon_i, + !rst_por_ni) + + `ASSERT(DAonRstSysAonEnTracksRstSysAonActive_A, + $fell(resets_i.rst_sys_aon_n[DomainAonSel]) |-> ##[0:DELAY] + reset_en_i.sys_aon[DomainAonSel] == prim_mubi_pkg::MuBi4True, + clk_aon_i, + !rst_por_ni) + + `ASSERT(DAonRstSysAonEnTracksRstSysAonInactive_A, + $rose(resets_i.rst_sys_aon_n[DomainAonSel]) |-> ##DELAY + !resets_i.rst_sys_aon_n[DomainAonSel] || + reset_en_i.sys_aon[DomainAonSel] == prim_mubi_pkg::MuBi4False, + clk_aon_i, + !rst_por_ni) + + `ASSERT(D0RstSpiDeviceEnTracksRstSpiDeviceActive_A, + $fell(resets_i.rst_spi_device_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.spi_device[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_io_div2_i, + !rst_por_ni) + + `ASSERT(D0RstSpiDeviceEnTracksRstSpiDeviceInactive_A, + $rose(resets_i.rst_spi_device_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_spi_device_n[Domain0Sel] || + reset_en_i.spi_device[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_io_div2_i, + !rst_por_ni) + + `ASSERT(D0RstSpiHost0EnTracksRstSpiHost0Active_A, + $fell(resets_i.rst_spi_host0_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.spi_host0[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_io_i, + !rst_por_ni) + + `ASSERT(D0RstSpiHost0EnTracksRstSpiHost0Inactive_A, + $rose(resets_i.rst_spi_host0_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_spi_host0_n[Domain0Sel] || + reset_en_i.spi_host0[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_io_i, + !rst_por_ni) + + `ASSERT(D0RstUsbEnTracksRstUsbActive_A, + $fell(resets_i.rst_usb_n[Domain0Sel]) |-> ##[0:DELAY] + reset_en_i.usb[Domain0Sel] == prim_mubi_pkg::MuBi4True, + clk_usb_i, + !rst_por_ni) + + `ASSERT(D0RstUsbEnTracksRstUsbInactive_A, + $rose(resets_i.rst_usb_n[Domain0Sel]) |-> ##DELAY + !resets_i.rst_usb_n[Domain0Sel] || + reset_en_i.usb[Domain0Sel] == prim_mubi_pkg::MuBi4False, + clk_usb_i, + !rst_por_ni) + +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva.core new file mode 100644 index 0000000000000..3658315be88f0 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva.core @@ -0,0 +1,35 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_sva:0.1 +description: "RSTMGR assertion modules and bind file." +filesets: + files_dv: + depend: + - lowrisc:prim:mubi + - lowrisc:opentitan:top_englishbreakfast_rstmgr_pkg:0.1 + - lowrisc:fpv:csr_assert_gen + - lowrisc:opentitan:top_englishbreakfast_rstmgr_sva_ifs:0.1 + + files: + - rstmgr_bind.sv + file_type: systemVerilogSource + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../../data/rstmgr.hjson + +targets: + default: &default_target + filesets: + - files_dv + generate: + - csr_assert_gen + formal: + <<: *default_target + filesets: + - files_dv + toplevel: rstmgr diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva_ifs.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva_ifs.core new file mode 100644 index 0000000000000..070c91154c995 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sva_ifs.core @@ -0,0 +1,25 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_sva_ifs:0.1 +description: "RSTMGR cascading resets assertion interface." +filesets: + files_dv: + depend: + - lowrisc:ip:lc_ctrl_pkg + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + - lowrisc:dv:pwrmgr_rstmgr_sva_if + - lowrisc:opentitan:top_englishbreakfast_rstmgr + + files: + - rstmgr_attrs_sva_if.sv + - rstmgr_cascading_sva_if.sv + - rstmgr_rst_en_track_sva_if.sv + - rstmgr_sw_rst_sva_if.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv new file mode 100644 index 0000000000000..7be1e05940778 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/sva/rstmgr_sw_rst_sva_if.sv @@ -0,0 +1,44 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This has assertions that check the output resets read-only value of the alert and cpu_info_attr. +interface rstmgr_sw_rst_sva_if ( + input logic [rstmgr_reg_pkg::NumSwResets-1:0] clk_i, + input logic rst_ni, + input logic parent_rst_n, + input logic [rstmgr_reg_pkg::NumSwResets-1:0] ctrl_ns, + input logic [rstmgr_reg_pkg::NumSwResets-1:0] rst_ens, + input logic [rstmgr_reg_pkg::NumSwResets-1:0] rst_ns +); + parameter int RiseMin = 2; + parameter int RiseMax = 12; + + bit disable_sva; + + for (genvar i = 0; i < rstmgr_reg_pkg::NumSwResets; ++i) begin : gen_assertions + logic rst_cause; + always_comb rst_cause = !parent_rst_n || !ctrl_ns[i]; + + sequence CauseReadyOn_S; + $rose( + rst_cause + ) ##1 rst_cause [* RiseMin]; + endsequence + + sequence CauseReadyOff_S; + $fell( + rst_cause + ) ##1 !rst_cause [* RiseMin]; + endsequence + + `ASSERT(RstNOn_A, CauseReadyOn_S |=> ##[0:RiseMax-RiseMin] !rst_cause || !rst_ns[i], clk_i[i], + !rst_ni || disable_sva) + `ASSERT(RstNOff_A, CauseReadyOff_S |=> ##[0:RiseMax-RiseMin] rst_cause || rst_ns[i], clk_i[i], + !rst_ni || disable_sva) + `ASSERT(RstEnOn_A, CauseReadyOn_S |=> ##[0:RiseMax-RiseMin] !rst_cause || rst_ens[i], clk_i[i], + !rst_ni || disable_sva) + `ASSERT(RstEnOff_A, CauseReadyOff_S |=> ##[0:RiseMax-RiseMin] rst_cause || !rst_ens[i], + clk_i[i], !rst_ni || disable_sva) + end +endinterface diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tb.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tb.sv new file mode 100644 index 0000000000000..7dd5cdbab44e4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tb.sv @@ -0,0 +1,145 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 rstmgr_env_pkg::*; + import rstmgr_test_pkg::*; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + wire clk, rst_n; + wire clk_aon; + wire clk_io_div4_i; + wire clk_main_i; + wire clk_io_i; + wire clk_io_div2_i; + wire clk_usb_i; + + // interfaces + clk_rst_if clk_rst_if ( + .clk, + .rst_n + ); + clk_rst_if aon_clk_rst_if ( + .clk (clk_aon), + .rst_n() + ); + clk_rst_if io_clk_rst_if ( + .clk (clk_io), + .rst_n() + ); + clk_rst_if io_div2_clk_rst_if ( + .clk (clk_io_div2), + .rst_n() + ); + clk_rst_if io_div4_clk_rst_if ( + .clk (clk_io_div4), + .rst_n() + ); + clk_rst_if main_clk_rst_if ( + .clk (clk_main), + .rst_n() + ); + clk_rst_if usb_clk_rst_if ( + .clk (clk_usb), + .rst_n() + ); + + tl_if tl_if ( + .clk, + .rst_n(rstmgr_if.resets_o.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + + rstmgr_if rstmgr_if ( + .clk_aon, + .clk, + .rst_n + ); + + initial begin + clk_rst_if.set_active(); + aon_clk_rst_if.set_active(); + io_clk_rst_if.set_active(); + io_div2_clk_rst_if.set_active(); + io_div4_clk_rst_if.set_active(); + main_clk_rst_if.set_active(); + usb_clk_rst_if.set_active(); + end + + `DV_ALERT_IF_CONNECT() + + // dut + // IMPORTANT: Notice the rst_ni input is connected to one of dut's outputs. + // This is consistent with rstmgr being the only source of resets. + rstmgr dut ( + .clk_i (clk), + .rst_ni (rstmgr_if.resets_o.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]), + .clk_aon_i (clk_aon), + .clk_io_div4_i(clk_io_div4), + .clk_main_i (clk_main), + .clk_io_i (clk_io), + .clk_io_div2_i(clk_io_div2), + .clk_usb_i (clk_usb), + .clk_por_i (clk_io_div4), + .rst_por_ni (rstmgr_if.resets_o.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]), + + .tl_i (tl_if.h2d), + .tl_o (tl_if.d2h), + .alert_rx_i(alert_rx), + .alert_tx_o(alert_tx), + + .por_n_i(rstmgr_if.por_n), + + .pwr_i(rstmgr_if.pwr_i), + .pwr_o(rstmgr_if.pwr_o), + + .sw_rst_req_o (rstmgr_if.sw_rst_req_o), + + .alert_dump_i(rstmgr_if.alert_dump_i), + .cpu_dump_i (rstmgr_if.cpu_dump_i), + + .scan_rst_ni(rstmgr_if.scan_rst_ni), + .scanmode_i (rstmgr_if.scanmode_i), + + .rst_en_o(rstmgr_if.rst_en_o), + .resets_o(rstmgr_if.resets_o) + ); + + initial begin + // drive clk and rst_n from clk_rst_if + 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", "aon_clk_rst_vif", aon_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "io_clk_rst_vif", io_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "io_div2_clk_rst_vif", + io_div2_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "io_div4_clk_rst_vif", + io_div4_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "main_clk_rst_vif", main_clk_rst_if); + uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "usb_clk_rst_vif", usb_clk_rst_if); + uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if); + + uvm_config_db#(virtual pwrmgr_rstmgr_sva_if)::set(null, "*.env", "pwrmgr_rstmgr_sva_vif", + dut.pwrmgr_rstmgr_sva_if); + uvm_config_db#(virtual rstmgr_cascading_sva_if)::set(null, "*.env", "rstmgr_cascading_sva_vif", + dut.rstmgr_cascading_sva_if); + uvm_config_db#(virtual rstmgr_if)::set(null, "*.env", "rstmgr_vif", rstmgr_if); + + $timeformat(-12, 0, " ps", 12); + run_test(); + end + + initial begin + // This may help any code that depends on clk_rst_vif.rst_n in the infrastructure: they won't + // be able to change but at least the reset value will be true to the environment. + clk_rst_if.drive_rst_n = 1'b0; + force clk_rst_if.rst_n = rstmgr_if.resets_o.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]; + end + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_base_test.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_base_test.sv new file mode 100644 index 0000000000000..a3eaf46e04f0a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_base_test.sv @@ -0,0 +1,20 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +class rstmgr_base_test extends cip_base_test #( + .CFG_T(rstmgr_env_cfg), + .ENV_T(rstmgr_env) +); + + `uvm_component_utils(rstmgr_base_test) + `uvm_component_new + + // the base class dv_base_test creates the following instances: + // rstmgr_env_cfg: cfg + // rstmgr_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 : rstmgr_base_test diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test.core new file mode 100644 index 0000000000000..94e6f3932d1b4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test.core @@ -0,0 +1,19 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_test:0.1 +description: "RSTMGR DV UVM test" +filesets: + files_dv: + depend: + - lowrisc:opentitan:top_englishbreakfast_rstmgr_env:0.1 + files: + - rstmgr_test_pkg.sv + - rstmgr_base_test.sv: {is_include_file: true} + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_dv diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test_pkg.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test_pkg.sv new file mode 100644 index 0000000000000..6bc66f09e85d6 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/dv/tests/rstmgr_test_pkg.sv @@ -0,0 +1,22 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +package rstmgr_test_pkg; + // dep packages + import uvm_pkg::*; + import cip_base_pkg::*; + import rstmgr_env_pkg::*; + + // macro includes + `include "uvm_macros.svh" + `include "dv_macros.svh" + + // local types + + // functions + + // package sources + `include "rstmgr_base_test.sv" + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.vlt b/hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.vlt new file mode 100644 index 0000000000000..a345f0dcdf9fe --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.vlt @@ -0,0 +1,5 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// waiver file for rstmgr diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.waiver b/hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.waiver new file mode 100644 index 0000000000000..4958290fba509 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/lint/rstmgr.waiver @@ -0,0 +1,37 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# waiver file for rstmgr + +# dedicated reset drivers / muxes +set_reset_drivers prim_clock_mux2 prim_flop_2sync prim_flop +set_clock_drivers prim_clock_buf + +waive -rules TERMINAL_STATE -location {rstmgr_cnsty_chk.sv} -regexp {Terminal state 'Error' is detected} \ + -comment "Intentional terminal state" + +# All leaf resets have a reset multiplexer for scan reset +waive -rules RESET_MUX -location {rstmgr.sv rstmgr_por.sv rstmgr_ctrl.sv} -regexp {Asynchronous reset '(resets_o\.)?rst_[A-Za-z_0-9]+_n(\[[0-9:]+\])?' is driven by a multiplexer} \ + -comment "This is dedicated reset infrastructure, and hence permissible" + +waive -rules RESET_MUX -location {rstmgr_leaf_rst.sv} -regexp {Asynchronous reset 'leaf_rst_o' is driven by a multiplexer} \ + -comment "This is dedicated reset infrastructure, and hence permissible" + +waive -rules RESET_MUX -location {rstmgr_leaf_rst.sv} -regexp {Asynchronous reset 'gen_rst_chk.leaf_chk_rst_n' is driven by a multiplexer here, used as a reset 'rst_dst_ni' at} \ + -comment "This is dedicated reset infrastructure, and hence permissible" + +waive -rules RESET_USE -location {rstmgr.sv} -regexp {'rst_(por_aon_)?n\[1\]' is connected to 'rstmgr_ctrl' port 'rst_.*ni*} \ + -comment "Parent Non always on resets are combined with the always on reset first before being used as resets" + +waive -rules RESET_USE -location {rstmgr.sv} -regexp {rst_lc_src_n.* is connected to 'rstmgr_ctrl' port 'rst_parent_ni.*} \ + -comment "Parent resets are used synchronously instead of directly as async resets" + +waive -rules CONST_FF -location {rstmgr_crash_info.sv} -regexp {Flip-flop \'slots_q\[.*\]\[.*\]\' is driven by constant zeros in module \'rstmgr_crash_info\'} \ + -comment "Some bits int the last slot are tied off to zero." + +waive -rules CONST_FF -location {rstmgr_cnsty_chk.sv} -regexp {Flip-flop '(parent|child)_rst_asserted' is driven by constant zero} \ + -comment "These flipflop inputs are driven by zero." + +waive -rules CONST_FF -location {rstmgr_por.sv} -msg {Flip-flop 'rst_filter_n[0]' is driven by constant one} \ + -comment "This flipflops is a reset filter, and the first index is driven by a constant one." diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr.core new file mode 100644 index 0000000000000..88118c7b4e88a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr.core @@ -0,0 +1,69 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr:0.1 +description: "Reset manager RTL" + +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_earlgrey_alert_handler_pkg + - lowrisc:ip:rv_core_ibex_pkg + - lowrisc:ip:tlul + - lowrisc:prim:clock_mux2 + - lowrisc:prim:esc + - lowrisc:prim:lc_sync + - lowrisc:prim:mubi + - lowrisc:prim:clock_buf + - lowrisc:prim:sparse_fsm + - lowrisc:opentitan:top_englishbreakfast_rstmgr_pkg:0.1 + - lowrisc:opentitan:top_englishbreakfast_rstmgr_reg:0.1 + - lowrisc:opentitan:top_englishbreakfast_rstmgr_cnsty_chk:0.1 + files: + - rtl/rstmgr_ctrl.sv + - rtl/rstmgr_por.sv + - rtl/rstmgr_crash_info.sv + - rtl/rstmgr_leaf_rst.sv + - rtl/rstmgr.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/rstmgr.waiver + file_type: waiver + +parameters: + SYNTHESIS: + datatype: bool + paramtype: vlogdefine + + +targets: + default: &default_target + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - files_rtl + toplevel: rstmgr + + lint: + <<: *default_target + default_tool: verilator + parameters: + - SYNTHESIS=true + tools: + verilator: + mode: lint-only + verilator_options: + - "-Wall" diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_cnsty_chk.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_cnsty_chk.core new file mode 100644 index 0000000000000..3d16d11a955f9 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_cnsty_chk.core @@ -0,0 +1,40 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_cnsty_chk:0.1 +description: "Rstmgr consistency checker" +filesets: + files_rtl: + depend: + - lowrisc:prim:all + - lowrisc:prim:sparse_fsm + - lowrisc:ip:rv_core_ibex_pkg + - lowrisc:opentitan:top_englishbreakfast_rstmgr_pkg + files: + - rtl/rstmgr_cnsty_chk.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_pkg.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_pkg.core new file mode 100644 index 0000000000000..2c072b4fe0bcc --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_pkg.core @@ -0,0 +1,22 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_pkg:0.1 +description: "Reset manager package" +virtual: + - lowrisc:ip_interfaces:rstmgr_pkg + +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + files: + - rtl/rstmgr_reg_pkg.sv + - rtl/rstmgr_pkg.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_reg.core b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_reg.core new file mode 100644 index 0000000000000..e7895c2179f85 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rstmgr_reg.core @@ -0,0 +1,21 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rstmgr_reg:0.1 +description: "Reset manager registers" + +filesets: + files_rtl: + depend: + - lowrisc:tlul:headers + - lowrisc:prim:subreg + - lowrisc:opentitan:top_englishbreakfast_rstmgr_pkg + files: + - rtl/rstmgr_reg_top.sv + file_type: systemVerilogSource + +targets: + default: + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr.sv new file mode 100644 index 0000000000000..7bbae7959de38 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr.sv @@ -0,0 +1,969 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module is the overall reset manager wrapper + +`include "prim_assert.sv" + + +// This top level controller is fairly hardcoded right now, but will be switched to a template +module rstmgr + import rstmgr_pkg::*; + import rstmgr_reg_pkg::*; + import prim_mubi_pkg::mubi4_t; +#( + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + parameter bit SecCheck = 1, + parameter int SecMaxSyncDelay = 2 +) ( + // Primary module clocks + input clk_i, + input rst_ni, + input clk_aon_i, + input clk_io_div4_i, + input clk_main_i, + input clk_io_i, + input clk_io_div2_i, + input clk_usb_i, + input clk_por_i, + input rst_por_ni, + + // POR input + input [PowerDomains-1:0] por_n_i, + + // 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, + + // pwrmgr interface + input pwrmgr_pkg::pwr_rst_req_t pwr_i, + output pwrmgr_pkg::pwr_rst_rsp_t pwr_o, + + // software initiated reset request + output mubi4_t sw_rst_req_o, + + // Interface to alert handler + input alert_pkg::alert_crashdump_t alert_dump_i, + + // Interface to cpu crash dump + input rv_core_ibex_pkg::cpu_crash_dump_t cpu_dump_i, + + // dft bypass + input scan_rst_ni, + // SEC_CM: SCAN.INTERSIG.MUBI + input prim_mubi_pkg::mubi4_t scanmode_i, + + // Reset asserted indications going to alert handler + output rstmgr_rst_en_t rst_en_o, + + // reset outputs + output rstmgr_out_t resets_o + +); + + import prim_mubi_pkg::MuBi4False; + import prim_mubi_pkg::MuBi4True; + + // receive POR and stretch + // The por is at first stretched and synced on clk_aon + // The rst_ni and pok_i input will be changed once AST is integrated + logic [PowerDomains-1:0] rst_por_aon_n; + + for (genvar i = 0; i < PowerDomains; i++) begin : gen_rst_por_aon + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] por_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_por_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o(por_scanmode) + ); + + if (i == DomainAonSel) begin : gen_rst_por_aon_normal + rstmgr_por u_rst_por_aon ( + .clk_i(clk_aon_i), + .rst_ni(por_n_i[i]), + .scan_rst_ni, + .scanmode_i(prim_mubi_pkg::mubi4_test_true_strict(por_scanmode[0])), + .rst_no(rst_por_aon_n[i]) + ); + + // reset asserted indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender ( + .clk_i(clk_aon_i), + .rst_ni(rst_por_aon_n[i]), + .mubi_i(MuBi4False), + .mubi_o(rst_en_o.por_aon[i]) + ); + end else begin : gen_rst_por_domain + logic rst_por_aon_premux; + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_por_domain_sync ( + .clk_i(clk_aon_i), + // do not release from reset if aon has not + .rst_ni(rst_por_aon_n[DomainAonSel] & por_n_i[i]), + .d_i(1'b1), + .q_o(rst_por_aon_premux) + ); + + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_por_domain_mux ( + .clk0_i(rst_por_aon_premux), + .clk1_i(scan_rst_ni), + .sel_i(prim_mubi_pkg::mubi4_test_true_strict(por_scanmode[0])), + .clk_o(rst_por_aon_n[i]) + ); + + // reset asserted indication for alert handler + prim_mubi4_sender #( + .ResetValue(MuBi4True) + ) u_prim_mubi4_sender ( + .clk_i(clk_aon_i), + .rst_ni(rst_por_aon_n[i]), + .mubi_i(MuBi4False), + .mubi_o(rst_en_o.por_aon[i]) + ); + end + end + assign resets_o.rst_por_aon_n = rst_por_aon_n; + + logic clk_por; + logic rst_por_n; + prim_clock_buf #( + .NoFpgaBuf(1'b1) + ) u_por_clk_buf ( + .clk_i(clk_por_i), + .clk_o(clk_por) + ); + + prim_clock_buf #( + .NoFpgaBuf(1'b1) + ) u_por_rst_buf ( + .clk_i(rst_por_ni), + .clk_o(rst_por_n) + ); + + //////////////////////////////////////////////////// + // Register Interface // + //////////////////////////////////////////////////// + + rstmgr_reg_pkg::rstmgr_reg2hw_t reg2hw; + rstmgr_reg_pkg::rstmgr_hw2reg_t hw2reg; + + logic reg_intg_err; + // SEC_CM: BUS.INTEGRITY + // SEC_CM: SW_RST.CONFIG.REGWEN, DUMP_CTRL.CONFIG.REGWEN + rstmgr_reg_top u_reg ( + .clk_i, + .rst_ni, + .clk_por_i (clk_por), + .rst_por_ni (rst_por_n), + .tl_i, + .tl_o, + .reg2hw, + .hw2reg, + .intg_err_o(reg_intg_err) + ); + + + //////////////////////////////////////////////////// + // Errors // + //////////////////////////////////////////////////// + + // consistency check errors + logic [12:0][PowerDomains-1:0] cnsty_chk_errs; + logic [12:0][PowerDomains-1:0] shadow_cnsty_chk_errs; + + // consistency sparse fsm errors + logic [12:0][PowerDomains-1:0] fsm_errs; + logic [12:0][PowerDomains-1:0] shadow_fsm_errs; + + assign hw2reg.err_code.reg_intg_err.d = 1'b1; + assign hw2reg.err_code.reg_intg_err.de = reg_intg_err; + assign hw2reg.err_code.reset_consistency_err.d = 1'b1; + assign hw2reg.err_code.reset_consistency_err.de = |cnsty_chk_errs || + |shadow_cnsty_chk_errs; + assign hw2reg.err_code.fsm_err.d = 1'b1; + assign hw2reg.err_code.fsm_err.de = |fsm_errs || |shadow_fsm_errs; + //////////////////////////////////////////////////// + // Alerts // + //////////////////////////////////////////////////// + logic [NumAlerts-1:0] alert_test, alerts; + + // All of these are fatal alerts + assign alerts[0] = reg2hw.err_code.reg_intg_err.q | + (|reg2hw.err_code.fsm_err.q); + + assign alerts[1] = reg2hw.err_code.reset_consistency_err.q; + + assign alert_test = { + reg2hw.alert_test.fatal_cnsty_fault.q & reg2hw.alert_test.fatal_cnsty_fault.qe, + reg2hw.alert_test.fatal_fault.q & reg2hw.alert_test.fatal_fault.qe + }; + + 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, + .rst_ni, + .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 + + //////////////////////////////////////////////////// + // Source resets in the system // + // These are hardcoded and not directly used. // + // Instead they act as async reset roots. // + //////////////////////////////////////////////////// + + // The two source reset modules are chained together. The output of one is fed into the + // the second. This ensures that if upstream resets for any reason, the associated downstream + // reset will also reset. + + logic [PowerDomains-1:0] rst_lc_src_n; + logic [PowerDomains-1:0] rst_sys_src_n; + + // Declared as size 1 packed array to avoid FPV warning. + prim_mubi_pkg::mubi4_t [0:0] rst_ctrl_scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_ctrl_scanmode_sync ( + .clk_i (clk_por), + .rst_ni (rst_por_n), + .mubi_i(scanmode_i), + .mubi_o(rst_ctrl_scanmode) + ); + + // lc reset sources + rstmgr_ctrl u_lc_src ( + .clk_i (clk_por), + .scanmode_i(prim_mubi_pkg::mubi4_test_true_strict(rst_ctrl_scanmode[0])), + .scan_rst_ni, + .rst_req_i(pwr_i.rst_lc_req), + .rst_parent_ni(rst_por_aon_n), + .rst_no(rst_lc_src_n) + ); + + // sys reset sources + rstmgr_ctrl u_sys_src ( + .clk_i (clk_por), + .scanmode_i(prim_mubi_pkg::mubi4_test_true_strict(rst_ctrl_scanmode[0])), + .scan_rst_ni, + .rst_req_i(pwr_i.rst_sys_req), + .rst_parent_ni(rst_por_aon_n), + .rst_no(rst_sys_src_n) + ); + + assign pwr_o.rst_lc_src_n = rst_lc_src_n; + assign pwr_o.rst_sys_src_n = rst_sys_src_n; + + + //////////////////////////////////////////////////// + // leaf reset in the system // + // These should all be generated // + //////////////////////////////////////////////////// + // To simplify generation, each reset generates all associated power domain outputs. + // If a reset does not support a particular power domain, that reset is always hard-wired to 0. + + // Generating resets for por + // Power Domains: ['Aon'] + // Shadowed: False + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_por ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_main_i), + .parent_rst_ni(rst_por_aon_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.por[DomainAonSel]), + .leaf_rst_o(resets_o.rst_por_n[DomainAonSel]), + .err_o(cnsty_chk_errs[0][DomainAonSel]), + .fsm_err_o(fsm_errs[0][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_por_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonPorFsmCheck_A, + u_daon_por.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_por_n[Domain0Sel] = '0; + assign cnsty_chk_errs[0][Domain0Sel] = '0; + assign fsm_errs[0][Domain0Sel] = '0; + assign rst_en_o.por[Domain0Sel] = MuBi4True; + assign shadow_cnsty_chk_errs[0] = '0; + assign shadow_fsm_errs[0] = '0; + + // Generating resets for por_io + // Power Domains: ['Aon'] + // Shadowed: False + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_por_io ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_i), + .parent_rst_ni(rst_por_aon_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.por_io[DomainAonSel]), + .leaf_rst_o(resets_o.rst_por_io_n[DomainAonSel]), + .err_o(cnsty_chk_errs[1][DomainAonSel]), + .fsm_err_o(fsm_errs[1][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_por_io_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonPorIoFsmCheck_A, + u_daon_por_io.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_por_io_n[Domain0Sel] = '0; + assign cnsty_chk_errs[1][Domain0Sel] = '0; + assign fsm_errs[1][Domain0Sel] = '0; + assign rst_en_o.por_io[Domain0Sel] = MuBi4True; + assign shadow_cnsty_chk_errs[1] = '0; + assign shadow_fsm_errs[1] = '0; + + // Generating resets for por_io_div2 + // Power Domains: ['Aon'] + // Shadowed: False + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_por_io_div2 ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div2_i), + .parent_rst_ni(rst_por_aon_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.por_io_div2[DomainAonSel]), + .leaf_rst_o(resets_o.rst_por_io_div2_n[DomainAonSel]), + .err_o(cnsty_chk_errs[2][DomainAonSel]), + .fsm_err_o(fsm_errs[2][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_por_io_div2_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonPorIoDiv2FsmCheck_A, + u_daon_por_io_div2.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_por_io_div2_n[Domain0Sel] = '0; + assign cnsty_chk_errs[2][Domain0Sel] = '0; + assign fsm_errs[2][Domain0Sel] = '0; + assign rst_en_o.por_io_div2[Domain0Sel] = MuBi4True; + assign shadow_cnsty_chk_errs[2] = '0; + assign shadow_fsm_errs[2] = '0; + + // Generating resets for por_io_div4 + // Power Domains: ['Aon'] + // Shadowed: True + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_por_io_div4 ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div4_i), + .parent_rst_ni(rst_por_aon_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.por_io_div4[DomainAonSel]), + .leaf_rst_o(resets_o.rst_por_io_div4_n[DomainAonSel]), + .err_o(cnsty_chk_errs[3][DomainAonSel]), + .fsm_err_o(fsm_errs[3][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_por_io_div4_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonPorIoDiv4FsmCheck_A, + u_daon_por_io_div4.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_por_io_div4_n[Domain0Sel] = '0; + assign cnsty_chk_errs[3][Domain0Sel] = '0; + assign fsm_errs[3][Domain0Sel] = '0; + assign rst_en_o.por_io_div4[Domain0Sel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_por_io_div4_shadowed ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div4_i), + .parent_rst_ni(rst_por_aon_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.por_io_div4_shadowed[DomainAonSel]), + .leaf_rst_o(resets_o.rst_por_io_div4_shadowed_n[DomainAonSel]), + .err_o(shadow_cnsty_chk_errs[3][DomainAonSel]), + .fsm_err_o(shadow_fsm_errs[3][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_por_io_div4_shadowed_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonPorIoDiv4ShadowedFsmCheck_A, + u_daon_por_io_div4_shadowed.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_por_io_div4_shadowed_n[Domain0Sel] = '0; + assign shadow_cnsty_chk_errs[3][Domain0Sel] = '0; + assign shadow_fsm_errs[3][Domain0Sel] = '0; + assign rst_en_o.por_io_div4_shadowed[Domain0Sel] = MuBi4True; + + // Generating resets for por_usb + // Power Domains: ['Aon'] + // Shadowed: False + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_por_usb ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_usb_i), + .parent_rst_ni(rst_por_aon_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.por_usb[DomainAonSel]), + .leaf_rst_o(resets_o.rst_por_usb_n[DomainAonSel]), + .err_o(cnsty_chk_errs[4][DomainAonSel]), + .fsm_err_o(fsm_errs[4][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_por_usb_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonPorUsbFsmCheck_A, + u_daon_por_usb.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_por_usb_n[Domain0Sel] = '0; + assign cnsty_chk_errs[4][Domain0Sel] = '0; + assign fsm_errs[4][Domain0Sel] = '0; + assign rst_en_o.por_usb[Domain0Sel] = MuBi4True; + assign shadow_cnsty_chk_errs[4] = '0; + assign shadow_fsm_errs[4] = '0; + + // Generating resets for lc + // Power Domains: ['0'] + // Shadowed: True + assign resets_o.rst_lc_n[DomainAonSel] = '0; + assign cnsty_chk_errs[5][DomainAonSel] = '0; + assign fsm_errs[5][DomainAonSel] = '0; + assign rst_en_o.lc[DomainAonSel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_d0_lc ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_main_i), + .parent_rst_ni(rst_lc_src_n[Domain0Sel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.lc[Domain0Sel]), + .leaf_rst_o(resets_o.rst_lc_n[Domain0Sel]), + .err_o(cnsty_chk_errs[5][Domain0Sel]), + .fsm_err_o(fsm_errs[5][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_lc_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0LcFsmCheck_A, + u_d0_lc.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_lc_shadowed_n[DomainAonSel] = '0; + assign shadow_cnsty_chk_errs[5][DomainAonSel] = '0; + assign shadow_fsm_errs[5][DomainAonSel] = '0; + assign rst_en_o.lc_shadowed[DomainAonSel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_d0_lc_shadowed ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_main_i), + .parent_rst_ni(rst_lc_src_n[Domain0Sel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.lc_shadowed[Domain0Sel]), + .leaf_rst_o(resets_o.rst_lc_shadowed_n[Domain0Sel]), + .err_o(shadow_cnsty_chk_errs[5][Domain0Sel]), + .fsm_err_o(shadow_fsm_errs[5][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_lc_shadowed_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0LcShadowedFsmCheck_A, + u_d0_lc_shadowed.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + + // Generating resets for lc_io_div4 + // Power Domains: ['0', 'Aon'] + // Shadowed: False + rstmgr_leaf_rst #( + .SecCheck(0), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_lc_io_div4 ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div4_i), + .parent_rst_ni(rst_lc_src_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.lc_io_div4[DomainAonSel]), + .leaf_rst_o(resets_o.rst_lc_io_div4_n[DomainAonSel]), + .err_o(cnsty_chk_errs[6][DomainAonSel]), + .fsm_err_o(fsm_errs[6][DomainAonSel]) + ); + + rstmgr_leaf_rst #( + .SecCheck(0), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_d0_lc_io_div4 ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div4_i), + .parent_rst_ni(rst_lc_src_n[Domain0Sel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.lc_io_div4[Domain0Sel]), + .leaf_rst_o(resets_o.rst_lc_io_div4_n[Domain0Sel]), + .err_o(cnsty_chk_errs[6][Domain0Sel]), + .fsm_err_o(fsm_errs[6][Domain0Sel]) + ); + + assign shadow_cnsty_chk_errs[6] = '0; + assign shadow_fsm_errs[6] = '0; + + // Generating resets for sys + // Power Domains: ['0'] + // Shadowed: True + assign resets_o.rst_sys_n[DomainAonSel] = '0; + assign cnsty_chk_errs[7][DomainAonSel] = '0; + assign fsm_errs[7][DomainAonSel] = '0; + assign rst_en_o.sys[DomainAonSel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_d0_sys ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_main_i), + .parent_rst_ni(rst_sys_src_n[Domain0Sel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.sys[Domain0Sel]), + .leaf_rst_o(resets_o.rst_sys_n[Domain0Sel]), + .err_o(cnsty_chk_errs[7][Domain0Sel]), + .fsm_err_o(fsm_errs[7][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_sys_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0SysFsmCheck_A, + u_d0_sys.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign resets_o.rst_sys_shadowed_n[DomainAonSel] = '0; + assign shadow_cnsty_chk_errs[7][DomainAonSel] = '0; + assign shadow_fsm_errs[7][DomainAonSel] = '0; + assign rst_en_o.sys_shadowed[DomainAonSel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_d0_sys_shadowed ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_main_i), + .parent_rst_ni(rst_sys_src_n[Domain0Sel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.sys_shadowed[Domain0Sel]), + .leaf_rst_o(resets_o.rst_sys_shadowed_n[Domain0Sel]), + .err_o(shadow_cnsty_chk_errs[7][Domain0Sel]), + .fsm_err_o(shadow_fsm_errs[7][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_sys_shadowed_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0SysShadowedFsmCheck_A, + u_d0_sys_shadowed.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + + // Generating resets for sys_io_div4 + // Power Domains: ['0', 'Aon'] + // Shadowed: False + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_sys_io_div4 ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div4_i), + .parent_rst_ni(rst_sys_src_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.sys_io_div4[DomainAonSel]), + .leaf_rst_o(resets_o.rst_sys_io_div4_n[DomainAonSel]), + .err_o(cnsty_chk_errs[8][DomainAonSel]), + .fsm_err_o(fsm_errs[8][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_sys_io_div4_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonSysIoDiv4FsmCheck_A, + u_daon_sys_io_div4.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_d0_sys_io_div4 ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div4_i), + .parent_rst_ni(rst_sys_src_n[Domain0Sel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.sys_io_div4[Domain0Sel]), + .leaf_rst_o(resets_o.rst_sys_io_div4_n[Domain0Sel]), + .err_o(cnsty_chk_errs[8][Domain0Sel]), + .fsm_err_o(fsm_errs[8][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_sys_io_div4_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0SysIoDiv4FsmCheck_A, + u_d0_sys_io_div4.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign shadow_cnsty_chk_errs[8] = '0; + assign shadow_fsm_errs[8] = '0; + + // Generating resets for sys_aon + // Power Domains: ['0', 'Aon'] + // Shadowed: False + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_daon_sys_aon ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_aon_i), + .parent_rst_ni(rst_sys_src_n[DomainAonSel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.sys_aon[DomainAonSel]), + .leaf_rst_o(resets_o.rst_sys_aon_n[DomainAonSel]), + .err_o(cnsty_chk_errs[9][DomainAonSel]), + .fsm_err_o(fsm_errs[9][DomainAonSel]) + ); + + if (SecCheck) begin : gen_daon_sys_aon_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + DAonSysAonFsmCheck_A, + u_daon_sys_aon.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b0) + ) u_d0_sys_aon ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_aon_i), + .parent_rst_ni(rst_sys_src_n[Domain0Sel]), + .sw_rst_req_ni(1'b1), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.sys_aon[Domain0Sel]), + .leaf_rst_o(resets_o.rst_sys_aon_n[Domain0Sel]), + .err_o(cnsty_chk_errs[9][Domain0Sel]), + .fsm_err_o(fsm_errs[9][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_sys_aon_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0SysAonFsmCheck_A, + u_d0_sys_aon.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign shadow_cnsty_chk_errs[9] = '0; + assign shadow_fsm_errs[9] = '0; + + // Generating resets for spi_device + // Power Domains: ['0'] + // Shadowed: False + assign resets_o.rst_spi_device_n[DomainAonSel] = '0; + assign cnsty_chk_errs[10][DomainAonSel] = '0; + assign fsm_errs[10][DomainAonSel] = '0; + assign rst_en_o.spi_device[DomainAonSel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b1) + ) u_d0_spi_device ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_div2_i), + .parent_rst_ni(rst_sys_src_n[Domain0Sel]), + .sw_rst_req_ni(reg2hw.sw_rst_ctrl_n[SPI_DEVICE].q), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.spi_device[Domain0Sel]), + .leaf_rst_o(resets_o.rst_spi_device_n[Domain0Sel]), + .err_o(cnsty_chk_errs[10][Domain0Sel]), + .fsm_err_o(fsm_errs[10][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_spi_device_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0SpiDeviceFsmCheck_A, + u_d0_spi_device.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign shadow_cnsty_chk_errs[10] = '0; + assign shadow_fsm_errs[10] = '0; + + // Generating resets for spi_host0 + // Power Domains: ['0'] + // Shadowed: False + assign resets_o.rst_spi_host0_n[DomainAonSel] = '0; + assign cnsty_chk_errs[11][DomainAonSel] = '0; + assign fsm_errs[11][DomainAonSel] = '0; + assign rst_en_o.spi_host0[DomainAonSel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b1) + ) u_d0_spi_host0 ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_io_i), + .parent_rst_ni(rst_sys_src_n[Domain0Sel]), + .sw_rst_req_ni(reg2hw.sw_rst_ctrl_n[SPI_HOST0].q), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.spi_host0[Domain0Sel]), + .leaf_rst_o(resets_o.rst_spi_host0_n[Domain0Sel]), + .err_o(cnsty_chk_errs[11][Domain0Sel]), + .fsm_err_o(fsm_errs[11][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_spi_host0_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0SpiHost0FsmCheck_A, + u_d0_spi_host0.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign shadow_cnsty_chk_errs[11] = '0; + assign shadow_fsm_errs[11] = '0; + + // Generating resets for usb + // Power Domains: ['0'] + // Shadowed: False + assign resets_o.rst_usb_n[DomainAonSel] = '0; + assign cnsty_chk_errs[12][DomainAonSel] = '0; + assign fsm_errs[12][DomainAonSel] = '0; + assign rst_en_o.usb[DomainAonSel] = MuBi4True; + rstmgr_leaf_rst #( + .SecCheck(SecCheck), + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(1'b1) + ) u_d0_usb ( + .clk_i, + .rst_ni, + .leaf_clk_i(clk_usb_i), + .parent_rst_ni(rst_sys_src_n[Domain0Sel]), + .sw_rst_req_ni(reg2hw.sw_rst_ctrl_n[USB].q), + .scan_rst_ni, + .scanmode_i, + .rst_en_o(rst_en_o.usb[Domain0Sel]), + .leaf_rst_o(resets_o.rst_usb_n[Domain0Sel]), + .err_o(cnsty_chk_errs[12][Domain0Sel]), + .fsm_err_o(fsm_errs[12][Domain0Sel]) + ); + + if (SecCheck) begin : gen_d0_usb_assert + `ASSERT_PRIM_FSM_ERROR_TRIGGER_ALERT( + D0UsbFsmCheck_A, + u_d0_usb.gen_rst_chk.u_rst_chk.u_state_regs, + alert_tx_o[0]) + end + assign shadow_cnsty_chk_errs[12] = '0; + assign shadow_fsm_errs[12] = '0; + + + //////////////////////////////////////////////////// + // Reset info construction // + //////////////////////////////////////////////////// + + logic rst_hw_req; + logic rst_low_power; + logic pwrmgr_rst_req; + + // there is a valid reset request from pwrmgr + assign pwrmgr_rst_req = |pwr_i.rst_lc_req || |pwr_i.rst_sys_req; + + // a reset reason is only valid if the related processing element is also reset. + // In the future, if ever there are multiple processing elements, this code here + // must be updated to account for each individual core. + assign rst_hw_req = pwrmgr_rst_req & + (pwr_i.reset_cause == pwrmgr_pkg::HwReq); + assign rst_low_power = pwrmgr_rst_req & + (pwr_i.reset_cause == pwrmgr_pkg::LowPwrEntry); + + // software initiated reset request + assign sw_rst_req_o = prim_mubi_pkg::mubi4_t'(reg2hw.reset_req.q); + + // when pwrmgr reset request is received (reset is imminent), clear software + // request so we are not in an infinite reset loop. + assign hw2reg.reset_req.de = pwrmgr_rst_req; + assign hw2reg.reset_req.d = prim_mubi_pkg::MuBi4False; + + // Only sw is allowed to clear a reset reason, hw is only allowed to set it. + assign hw2reg.reset_info.low_power_exit.d = 1'b1; + assign hw2reg.reset_info.low_power_exit.de = rst_low_power; + + // software issued request triggers the same response as hardware, although it is + // accounted for differently. + assign hw2reg.reset_info.sw_reset.d = prim_mubi_pkg::mubi4_test_true_strict(sw_rst_req_o) | + reg2hw.reset_info.sw_reset.q; + assign hw2reg.reset_info.sw_reset.de = rst_hw_req; + + // HW reset requests most likely will be multi-bit, so OR in whatever reasons + // that are already set. + assign hw2reg.reset_info.hw_req.d = pwr_i.rstreqs | + reg2hw.reset_info.hw_req.q; + assign hw2reg.reset_info.hw_req.de = rst_hw_req; + + //////////////////////////////////////////////////// + // Crash info capture // + //////////////////////////////////////////////////// + + logic dump_capture; + assign dump_capture = rst_hw_req | rst_low_power; + + // halt dump capture once we hit particular conditions + logic dump_capture_halt; + assign dump_capture_halt = rst_hw_req; + + rstmgr_crash_info #( + .CrashDumpWidth($bits(alert_pkg::alert_crashdump_t)) + ) u_alert_info ( + .clk_i(clk_por_i), + .rst_ni(rst_por_ni), + .dump_i(alert_dump_i), + .dump_capture_i(dump_capture & reg2hw.alert_info_ctrl.en.q), + .slot_sel_i(reg2hw.alert_info_ctrl.index.q), + .slots_cnt_o(hw2reg.alert_info_attr.d), + .slot_o(hw2reg.alert_info.d) + ); + + rstmgr_crash_info #( + .CrashDumpWidth($bits(rv_core_ibex_pkg::cpu_crash_dump_t)) + ) u_cpu_info ( + .clk_i(clk_por_i), + .rst_ni(rst_por_ni), + .dump_i(cpu_dump_i), + .dump_capture_i(dump_capture & reg2hw.cpu_info_ctrl.en.q), + .slot_sel_i(reg2hw.cpu_info_ctrl.index.q), + .slots_cnt_o(hw2reg.cpu_info_attr.d), + .slot_o(hw2reg.cpu_info.d) + ); + + // once dump is captured, no more information is captured until + // re-enabled by software. + assign hw2reg.alert_info_ctrl.en.d = 1'b0; + assign hw2reg.alert_info_ctrl.en.de = dump_capture_halt; + assign hw2reg.cpu_info_ctrl.en.d = 1'b0; + assign hw2reg.cpu_info_ctrl.en.de = dump_capture_halt; + + //////////////////////////////////////////////////// + // Exported resets // + //////////////////////////////////////////////////// + + + + + //////////////////////////////////////////////////// + // Assertions // + //////////////////////////////////////////////////// + + `ASSERT_INIT(ParameterMatch_A, NumHwResets == pwrmgr_pkg::HwResetWidth) + + // when upstream resets, downstream must also reset + + // output known asserts + `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(PwrKnownO_A, pwr_o ) + `ASSERT_KNOWN(ResetsKnownO_A, resets_o ) + `ASSERT_KNOWN(RstEnKnownO_A, rst_en_o ) + + // Alert assertions for reg_we onehot check + `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[0]) +endmodule // rstmgr diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_cnsty_chk.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_cnsty_chk.sv new file mode 100644 index 0000000000000..d70ab3be41c0b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_cnsty_chk.sv @@ -0,0 +1,273 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module implements reset consistency checks +// The main goal is to check whether conditions allow for a reset to be asserted +// For example, if a child reset asserts, it must be the case that its parent +// reset or software controls (if available) have asserted. +// If a child reset asserts and neither of the above case is true, it is considered +// a fatal error. + +`include "prim_assert.sv" + +module rstmgr_cnsty_chk + import rstmgr_pkg::*; + import rstmgr_reg_pkg::*; +#( + parameter int SecMaxSyncDelay = 2, + parameter bit SwRstReq = 1 +) ( + input clk_i, + input rst_ni, + input child_clk_i, + input child_rst_ni, + input child_chk_rst_ni, // rst_ni synchronized to child_clk_i domain. + input parent_rst_ni, + input sw_rst_req_i, + output logic sw_rst_req_clr_o, + output logic err_o, + output logic fsm_err_o +); + + // The "+ 2" here is because the cnt counter that uses this width needs to be able to count up to + // SecMaxSyncDelay + 1. + localparam int CntWidth = $clog2(SecMaxSyncDelay + 2); + + // These two flops below are completely async. + // The value from these flops are always fed through synchronizers before use. + logic parent_rst_asserted; + always_ff @(posedge clk_i or negedge parent_rst_ni) begin + if (!parent_rst_ni) begin + parent_rst_asserted <= 1'b1; + end else begin + parent_rst_asserted <= '0; + end + end + + logic child_rst_asserted; + always_ff @(posedge clk_i or negedge child_rst_ni) begin + if (!child_rst_ni) begin + child_rst_asserted <= 1'b1; + end else begin + child_rst_asserted <= '0; + end + end + + logic sync_parent_rst; + prim_flop_2sync #( + .Width(1), + .ResetValue(1) + ) u_parent_sync ( + .clk_i, + .rst_ni, + .d_i(parent_rst_asserted), + .q_o(sync_parent_rst) + ); + + logic sync_child_rst; + prim_flop_2sync #( + .Width(1), + .ResetValue(1) + ) u_child_sync ( + .clk_i, + .rst_ni, + .d_i(child_rst_asserted), + .q_o(sync_child_rst) + ); + + // Encoding generated with: + // $ ./util/design/sparse-fsm-encode.py -d 3 -m 7 -n 6 \ + // -s 90402488 --language=sv + // + // Hamming distance histogram: + // + // 0: -- + // 1: -- + // 2: -- + // 3: |||||||||||||||||||| (57.14%) + // 4: ||||||||||||||| (42.86%) + // 5: -- + // 6: -- + // + // Minimum Hamming distance: 3 + // Maximum Hamming distance: 4 + // Minimum Hamming weight: 1 + // Maximum Hamming weight: 5 + // + localparam int StateWidth = 6; + typedef enum logic [StateWidth-1:0] { + Reset = 6'b010001, + Idle = 6'b100011, + WaitForParent = 6'b111101, + WaitForChild = 6'b001111, + WaitForSrcRelease = 6'b100100, + WaitForChildRelease = 6'b111010, + Error = 6'b010110, + FsmError = 6'b001000 + } state_e; + + state_e state_q, state_d; + + // SEC_CM: LEAF.FSM.SPARSE + `PRIM_FLOP_SPARSE_FSM(u_state_regs, state_d, state_q, state_e, Reset, clk_i, rst_ni) + + logic timeout; + logic cnt_inc; + logic cnt_clr; + logic [CntWidth-1:0] cnt; + + // the timeout count is on clk_i because the synchronizers are + // also operating on clk_i. We are mainly trying to wait out the reset assertion delays. + // parent resets are asynchronous assertion so there is at most a one cycle separation. + // if needed we can make this timeout bigger. + assign timeout = int'(cnt) > SecMaxSyncDelay; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + cnt <= '0; + end else if (cnt_clr) begin + cnt <= '0; + end else if (cnt_inc && !timeout) begin + cnt <= cnt + 1'b1; + end + end + + logic src_valid; + // The following code makes it easier for tools such as UNR, + // it is not functionally required. + if (SwRstReq) begin : gen_sw_rst_req + assign src_valid = sync_parent_rst || sw_rst_req_i; + end else begin : gen_no_sw_rst_req + assign src_valid = sync_parent_rst; + + logic unused_sw_rst_req; + assign unused_sw_rst_req = sw_rst_req_i; + end + + logic sync_child_ack; + + always_comb begin + state_d = state_q; + err_o = '0; + fsm_err_o = '0; + cnt_inc = '0; + cnt_clr = '0; + sw_rst_req_clr_o = '0; + + unique case (state_q) + Reset: begin + // when the checker itself comes out of reset, conditions + // may be ambiguous, wait for things to stabilize + if (!sync_child_rst && !sync_parent_rst) begin + state_d = Idle; + end + end + + Idle: begin + // If a child reset asserts, one of the conditions must be true. + // It is possible for the child to assert but parent to remain de-asserted + // due to CDC latency (or vice versa), wait for the other corresponding reset + // when this occurs. + if (sync_child_rst && src_valid) begin + state_d = WaitForSrcRelease; + end else if (sync_child_rst && !sync_parent_rst) begin + state_d = WaitForParent; + end else if (sync_parent_rst && !sync_child_rst) begin + state_d = WaitForChild; + end + end + + // parent reset must show up within timeout region + WaitForParent: begin + cnt_inc = 1'b1; + + if (timeout && !sync_parent_rst) begin + state_d = Error; + end else if (sync_parent_rst) begin + state_d = WaitForSrcRelease; + cnt_clr = 1'b1; + end + end + + // child reset must show up within timeout region + WaitForChild: begin + cnt_inc = 1'b1; + + if (timeout && !sync_child_rst) begin + state_d = Error; + end else if (sync_child_rst) begin + state_d = WaitForSrcRelease; + cnt_clr = 1'b1; + end + end + + // waiting for parent reset to release + WaitForSrcRelease: begin + // if arrived here due to software requested reset, it is now + // okay to clear the original request. + sw_rst_req_clr_o = 1'b1; + + // it is not possible for the child reset to release + // ahead of the parent reset + if (!sync_child_rst && src_valid) begin + state_d = Error; + end else if (!src_valid) begin + cnt_clr = 1'b1; + state_d = WaitForChildRelease; + end + end + + // waiting for child reset to release + WaitForChildRelease: begin + // operate only on child ack to keep things in sync + // This is needed because the reset releases are synchronous to the child clock. + // So if we have a situation where the child clock is way slower than the local + // clock used to increment the count, we may timeout incorrectly. + // By using sync_child_ack, we ensure that the count is advanced only when a + // child clock edge is seen. This usage is conservative, because by the time + // sync_child_ack is seen, there may have been more than one child clock, yet the + // count is only incremented by 1. + cnt_inc = sync_child_ack; + if (sync_child_rst && src_valid) begin + // This condition covers the case if for whatever reason the parent reset re-asserts + // in a valid way. + state_d = WaitForSrcRelease; + cnt_clr = 1'b1; + end else if (sync_child_rst && timeout) begin + state_d = Error; + end else if (!sync_child_rst) begin + state_d = Idle; + cnt_clr = 1'b1; + end + end + + Error: begin + err_o = 1'b1; + end + + FsmError: begin + fsm_err_o = 1'b1; + end + + default: begin + state_d = FsmError; + fsm_err_o = 1'b1; + end + endcase // unique case (state_q) + end // always_comb + + logic child_ack; + prim_sync_reqack u_child_handshake ( + .clk_src_i(clk_i), + .rst_src_ni(rst_ni), + .clk_dst_i(child_clk_i), + .rst_dst_ni(child_chk_rst_ni), + .req_chk_i('0), + .src_req_i(1'b1), + .src_ack_o(sync_child_ack), + .dst_req_o(child_ack), + .dst_ack_i(child_ack) + ); + +endmodule // rstmgr_cnsty_chk diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_crash_info.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_crash_info.sv new file mode 100644 index 0000000000000..e252c43fd6d63 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_crash_info.sv @@ -0,0 +1,60 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// This module implements the crash dump functionality + +`include "prim_assert.sv" + +module rstmgr_crash_info + import rstmgr_pkg::*; + import rstmgr_reg_pkg::IdxWidth; + import rstmgr_reg_pkg::RdWidth; +#( + parameter int CrashDumpWidth = 32, + localparam int CrashRemainder = CrashDumpWidth % RdWidth > 0 ? 1 : 0, + localparam int unsigned CrashStoreSlot = CrashDumpWidth / RdWidth + CrashRemainder, + localparam int SlotCntWidth = $clog2(CrashStoreSlot) +) ( + input clk_i, + input rst_ni, + input [CrashDumpWidth-1:0] dump_i, + input dump_capture_i, + input [IdxWidth-1:0] slot_sel_i, + output logic [IdxWidth-1:0] slots_cnt_o, + output logic [RdWidth-1:0] slot_o +); + + localparam int TotalWidth = CrashStoreSlot * RdWidth; + logic [2**SlotCntWidth-1:0][RdWidth-1:0] slots; + logic [ CrashStoreSlot-1:0][RdWidth-1:0] slots_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + slots_q <= '0; + end else if (dump_capture_i) begin + slots_q <= TotalWidth'(dump_i); + end + end + + always_comb begin + slots = '0; + slots[CrashStoreSlot-1:0] = slots_q; + end + + assign slots_cnt_o = CrashStoreSlot[IdxWidth-1:0]; + assign slot_o = slots[slot_sel_i[SlotCntWidth-1:0]]; + + if (SlotCntWidth < IdxWidth) begin : gen_tieoffs + //VCS coverage off + // pragma coverage off + logic [IdxWidth-SlotCntWidth-1:0] unused_idx; + assign unused_idx = slot_sel_i[IdxWidth-1:SlotCntWidth]; + //VCS coverage on + // pragma coverage on + end + + // Make sure the crash dump isn't excessively large + `ASSERT_INIT(CntStoreSlot_A, CrashStoreSlot < (1 << IdxWidth)) + `ASSERT_INIT(CntWidth_A, SlotCntWidth <= IdxWidth) + +endmodule // rstmgr_crash_info diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_ctrl.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_ctrl.sv new file mode 100644 index 0000000000000..a762ec8281b9e --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_ctrl.sv @@ -0,0 +1,77 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module implements generic reset controls +// + +`include "prim_assert.sv" + +module rstmgr_ctrl + import rstmgr_pkg::*; + import rstmgr_reg_pkg::*; +( + input clk_i, + input [PowerDomains-1:0] rst_req_i, + input [PowerDomains-1:0] rst_parent_ni, // parent reset + output logic [PowerDomains-1:0] rst_no, + input scanmode_i, + input scan_rst_ni +); + + // the always on root reset + logic rst_aon_n_premux, rst_aon_n; + + // the remaining resets + logic [OffDomains-1:0] rst_pd_nd, rst_pd_nq; + + // always on handling + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_aon_rst ( + .clk_i, + .rst_ni(rst_parent_ni[DomainAonSel]), + .d_i(~rst_req_i[DomainAonSel]), + .q_o(rst_aon_n_premux) + ); + + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_rst_aon_mux ( + .clk0_i(rst_aon_n_premux), + .clk1_i(scan_rst_ni), + .sel_i(scanmode_i), + .clk_o(rst_aon_n) + ); + assign rst_no[DomainAonSel] = rst_aon_n; + + // the non-always-on domains + // These reset whenever the always on domain reset, to ensure power definition consistency. + // By extension, they also reset whenever the root (rst_ni) resets + assign rst_pd_nd = ~rst_req_i[Domain0Sel +: OffDomains]; + + localparam int DomainPdStartIdx = DomainAonSel + 1; + for(genvar i = 0; i < OffDomains; i++) begin : gen_rst_pd_n + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_pd_rst ( + .clk_i, + // when the always on portion resets, always reset the non-always-on portion as well. + .rst_ni(rst_aon_n & rst_parent_ni[DomainPdStartIdx + i]), + .d_i(rst_pd_nd[i]), + .q_o(rst_pd_nq[i]) + ); + + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_rst_pd_mux ( + .clk0_i(rst_pd_nq[i]), + .clk1_i(scan_rst_ni), + .sel_i(scanmode_i), + .clk_o(rst_no[DomainPdStartIdx + i]) + ); + end + +endmodule // rstmgr_ctrl diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_leaf_rst.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_leaf_rst.sv new file mode 100644 index 0000000000000..ca1ab02a1c7e3 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_leaf_rst.sv @@ -0,0 +1,134 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module generates the leaf resets and instantiates the associated reset +// checks. + +`include "prim_assert.sv" + +module rstmgr_leaf_rst + import rstmgr_pkg::*; + import rstmgr_reg_pkg::*; + import prim_mubi_pkg::mubi4_t; #( + parameter bit SecCheck = 1, + parameter int SecMaxSyncDelay = 2, + parameter bit SwRstReq = 1 +) ( + input clk_i, + input rst_ni, + input leaf_clk_i, + input parent_rst_ni, + input sw_rst_req_ni, + input prim_mubi_pkg::mubi4_t scanmode_i, + input scan_rst_ni, + output mubi4_t rst_en_o, + output logic leaf_rst_o, + output logic err_o, + output logic fsm_err_o +); + + prim_mubi_pkg::mubi4_t scanmode; + prim_mubi4_sync #( + .NumCopies(1), + .AsyncOn(0) + ) u_scanmode_sync ( + .clk_i, + .rst_ni, + .mubi_i(scanmode_i), + .mubi_o({scanmode}) + ); + + logic leaf_rst_sync; + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_rst_sync ( + .clk_i(leaf_clk_i), + .rst_ni(parent_rst_ni), + .d_i(sw_rst_req_ni), + .q_o(leaf_rst_sync) + ); + + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_rst_mux ( + .clk0_i(leaf_rst_sync), + .clk1_i(scan_rst_ni), + .sel_i(prim_mubi_pkg::mubi4_test_true_strict(scanmode)), + .clk_o(leaf_rst_o) + ); + + logic sw_rst_req_q; + logic clr_sw_rst_req; + if (SwRstReq && SecCheck) begin : gen_sw_rst_req + // once software requests a reset, hold on to the request until the consistency + // checker passes the assertion check point + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + sw_rst_req_q <= '0; + end else if (sw_rst_req_q && clr_sw_rst_req) begin + sw_rst_req_q <= '0; + end else if (!sw_rst_req_q && !sw_rst_req_ni && !clr_sw_rst_req) begin + sw_rst_req_q <= 1'b1; + end + end + end else begin : gen_no_sw_rst_req + //VCS coverage off + // pragma coverage off + logic unused_sig; + assign unused_sig = clr_sw_rst_req; + //VCS coverage on + // pragma coverage on + assign sw_rst_req_q = '0; + end + + if (SecCheck) begin : gen_rst_chk + + // We have to create a separately synced reset for the child handshakes below, since keeping the + // child side of the prim_sync_reqack synchronizer under reset would defeat the reset checker's + // purpose, as it would never count any clock ticks in the WaitForChildRelease state above. + logic leaf_chk_rst_n; + prim_rst_sync u_prim_rst_sync ( + .clk_i (leaf_clk_i), + .d_i (rst_ni), + .q_o (leaf_chk_rst_n), + .scan_rst_ni, + .scanmode_i + ); + + // SEC_CM: LEAF.RST.BKGN_CHK + rstmgr_cnsty_chk #( + .SecMaxSyncDelay(SecMaxSyncDelay), + .SwRstReq(SwRstReq) + ) u_rst_chk ( + .clk_i, + .rst_ni, + .child_clk_i(leaf_clk_i), + .child_rst_ni(leaf_rst_o), + .child_chk_rst_ni(leaf_chk_rst_n), + .parent_rst_ni, + .sw_rst_req_i(sw_rst_req_q | ~sw_rst_req_ni), + .sw_rst_req_clr_o(clr_sw_rst_req), + .err_o, + .fsm_err_o + ); + end else begin : gen_no_rst_chk + logic unused_sig; + assign unused_sig = sw_rst_req_q; + assign clr_sw_rst_req = '0; + assign err_o = '0; + assign fsm_err_o = '0; + end + + // reset asserted indication for alert handler + prim_mubi4_sender #( + .ResetValue(prim_mubi_pkg::MuBi4True) + ) u_prim_mubi4_sender ( + .clk_i(leaf_clk_i), + .rst_ni(leaf_rst_o), + .mubi_i(prim_mubi_pkg::MuBi4False), + .mubi_o(rst_en_o) + ); + +endmodule // rstmgr_leaf_rst diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_pkg.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_pkg.sv new file mode 100644 index 0000000000000..f29bff68b1923 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_pkg.sv @@ -0,0 +1,99 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// + +package rstmgr_pkg; + + // Power domain parameters + parameter int PowerDomains = 2; + parameter int DomainAonSel = 0; + parameter int Domain0Sel = 1; + + // Number of non-always-on domains + parameter int OffDomains = PowerDomains-1; + + // positions of software controllable reset bits + parameter int SPI_DEVICE = 0; + parameter int SPI_HOST0 = 1; + parameter int USB = 2; + + // resets generated and broadcast + // SEC_CM: LEAF.RST.SHADOW + typedef struct packed { + logic [PowerDomains-1:0] rst_por_aon_n; + logic [PowerDomains-1:0] rst_por_n; + logic [PowerDomains-1:0] rst_por_io_n; + logic [PowerDomains-1:0] rst_por_io_div2_n; + logic [PowerDomains-1:0] rst_por_io_div4_shadowed_n; + logic [PowerDomains-1:0] rst_por_io_div4_n; + logic [PowerDomains-1:0] rst_por_usb_n; + logic [PowerDomains-1:0] rst_lc_shadowed_n; + logic [PowerDomains-1:0] rst_lc_n; + logic [PowerDomains-1:0] rst_lc_io_div4_n; + logic [PowerDomains-1:0] rst_sys_shadowed_n; + logic [PowerDomains-1:0] rst_sys_n; + logic [PowerDomains-1:0] rst_sys_io_div4_n; + logic [PowerDomains-1:0] rst_sys_aon_n; + logic [PowerDomains-1:0] rst_spi_device_n; + logic [PowerDomains-1:0] rst_spi_host0_n; + logic [PowerDomains-1:0] rst_usb_n; + } rstmgr_out_t; + + // reset indication for alert handler + typedef struct packed { + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] por_aon; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] por; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] por_io; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] por_io_div2; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] por_io_div4_shadowed; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] por_io_div4; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] por_usb; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] lc_shadowed; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] lc; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] lc_io_div4; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] sys_shadowed; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] sys; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] sys_io_div4; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] sys_aon; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] spi_device; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] spi_host0; + prim_mubi_pkg::mubi4_t [PowerDomains-1:0] usb; + } rstmgr_rst_en_t; + + parameter int NumOutputRst = 17 * PowerDomains; + + // cpu reset requests and status + typedef struct packed { + logic ndmreset_req; + } rstmgr_cpu_t; + + // exported resets + + // default value for rstmgr_ast_rsp_t (for dangling ports) + parameter rstmgr_cpu_t RSTMGR_CPU_DEFAULT = '{ + ndmreset_req: '0 + }; + + // Enumeration for pwrmgr hw reset inputs + localparam int ResetWidths = $clog2(rstmgr_reg_pkg::NumTotalResets); + typedef enum logic [ResetWidths-1:0] { + ReqPeriResetIdx[0:0], + ReqMainPwrResetIdx, + ReqEscResetIdx, + ReqNdmResetIdx + } reset_req_idx_e; + + // Enumeration for reset info bit idx + typedef enum logic [ResetWidths-1:0] { + InfoPorIdx, + InfoLowPowerExitIdx, + InfoSwResetIdx, + InfoPeriResetIdx[0:0], + InfoMainPwrResetIdx, + InfoEscResetIdx, + InfoNdmResetIdx + } reset_info_idx_e; + + +endpackage // rstmgr_pkg diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_por.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_por.sv new file mode 100644 index 0000000000000..0ac7e14becb72 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_por.sv @@ -0,0 +1,106 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// This module stretches the POR +// + +module rstmgr_por #( + parameter int FilterStages = 3, + parameter int unsigned StretchCount = 32 +) ( + input clk_i, + input rst_ni, + input scan_rst_ni, + input scanmode_i, + output logic rst_no +); + localparam int CtrWidth = $clog2(StretchCount+1); + + logic rst_root_n_pre_mux, rst_root_n; + logic [FilterStages-1:0] rst_filter_n; + logic rst_stable; + logic rst_clean_n; + logic [CtrWidth-1:0] cnt; + logic cnt_en; + + // sync the POR + prim_flop_2sync #( + .Width(1), + .ResetValue('0) + ) u_rst_sync ( + .clk_i(clk_i), + .rst_ni(rst_ni), + .d_i(1'b1), + .q_o(rst_root_n_pre_mux) + ); + + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_rst_root_mux ( + .clk0_i(rst_root_n_pre_mux), + .clk1_i(scan_rst_ni), + .sel_i(scanmode_i), + .clk_o(rst_root_n) + ); + + // filter the POR + always_ff @(posedge clk_i or negedge rst_root_n) begin + if (!rst_root_n) begin + rst_filter_n <= '0; + end else begin + rst_filter_n <= {rst_filter_n[0 +: FilterStages-1], 1'b1}; + end + end + + // The stable is a vote of all filter stages. + // Only when all the stages agree is the reset considered stable and count allowed. + + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_rst_clean_mux ( + .clk0_i(rst_filter_n[FilterStages-1]), + .clk1_i(scan_rst_ni), + .sel_i(scanmode_i), + .clk_o(rst_clean_n) + ); + + assign rst_stable = &rst_filter_n; + assign cnt_en = rst_stable & !rst_no; + + // stretch the POR + logic rst_nd, rst_nq; + + assign rst_nd = ~rst_stable ? 1'b0 : + cnt_en & (cnt == StretchCount[CtrWidth-1:0]) ? 1'b1 : rst_nq; + + always_ff @(posedge clk_i or negedge rst_clean_n) begin + if (!rst_clean_n) begin + cnt <= '0; + end else if (!rst_stable) begin + cnt <= '0; + end else if (cnt_en) begin + cnt <= cnt + 1'b1; + end + end + + prim_flop #( + .Width(1), + .ResetValue('0) + ) u_rst_flop ( + .clk_i, + .rst_ni(rst_clean_n), + .d_i(rst_nd), + .q_o(rst_nq) + ); + + prim_clock_mux2 #( + .NoFpgaBufG(1'b1) + ) u_rst_out_mux ( + .clk0_i(rst_nq), + .clk1_i(scan_rst_ni), + .sel_i(scanmode_i), + .clk_o(rst_no) + ); + +endmodule // rstmgr_por diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_pkg.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_pkg.sv new file mode 100644 index 0000000000000..26ac4f745ce8d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_pkg.sv @@ -0,0 +1,248 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 rstmgr_reg_pkg; + + // Param list + parameter int RdWidth = 32; + parameter int IdxWidth = 4; + parameter int NumHwResets = 4; + parameter int NumSwResets = 3; + parameter int NumTotalResets = 7; + parameter int NumAlerts = 2; + + // Address widths within the block + parameter int BlockAw = 7; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + struct packed { + logic q; + logic qe; + } fatal_cnsty_fault; + struct packed { + logic q; + logic qe; + } fatal_fault; + } rstmgr_reg2hw_alert_test_reg_t; + + typedef struct packed { + logic [3:0] q; + } rstmgr_reg2hw_reset_req_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } hw_req; + struct packed { + logic q; + } sw_reset; + } rstmgr_reg2hw_reset_info_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } index; + struct packed { + logic q; + } en; + } rstmgr_reg2hw_alert_info_ctrl_reg_t; + + typedef struct packed { + struct packed { + logic [3:0] q; + } index; + struct packed { + logic q; + } en; + } rstmgr_reg2hw_cpu_info_ctrl_reg_t; + + typedef struct packed { + logic q; + } rstmgr_reg2hw_sw_rst_ctrl_n_mreg_t; + + typedef struct packed { + struct packed { + logic q; + } fsm_err; + struct packed { + logic q; + } reset_consistency_err; + struct packed { + logic q; + } reg_intg_err; + } rstmgr_reg2hw_err_code_reg_t; + + typedef struct packed { + logic [3:0] d; + logic de; + } rstmgr_hw2reg_reset_req_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } low_power_exit; + struct packed { + logic d; + logic de; + } sw_reset; + struct packed { + logic [3:0] d; + logic de; + } hw_req; + } rstmgr_hw2reg_reset_info_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } en; + } rstmgr_hw2reg_alert_info_ctrl_reg_t; + + typedef struct packed { + logic [3:0] d; + } rstmgr_hw2reg_alert_info_attr_reg_t; + + typedef struct packed { + logic [31:0] d; + } rstmgr_hw2reg_alert_info_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } en; + } rstmgr_hw2reg_cpu_info_ctrl_reg_t; + + typedef struct packed { + logic [3:0] d; + } rstmgr_hw2reg_cpu_info_attr_reg_t; + + typedef struct packed { + logic [31:0] d; + } rstmgr_hw2reg_cpu_info_reg_t; + + typedef struct packed { + struct packed { + logic d; + logic de; + } reg_intg_err; + struct packed { + logic d; + logic de; + } reset_consistency_err; + struct packed { + logic d; + logic de; + } fsm_err; + } rstmgr_hw2reg_err_code_reg_t; + + // Register -> HW type + typedef struct packed { + rstmgr_reg2hw_alert_test_reg_t alert_test; // [28:25] + rstmgr_reg2hw_reset_req_reg_t reset_req; // [24:21] + rstmgr_reg2hw_reset_info_reg_t reset_info; // [20:16] + rstmgr_reg2hw_alert_info_ctrl_reg_t alert_info_ctrl; // [15:11] + rstmgr_reg2hw_cpu_info_ctrl_reg_t cpu_info_ctrl; // [10:6] + rstmgr_reg2hw_sw_rst_ctrl_n_mreg_t [2:0] sw_rst_ctrl_n; // [5:3] + rstmgr_reg2hw_err_code_reg_t err_code; // [2:0] + } rstmgr_reg2hw_t; + + // HW -> register type + typedef struct packed { + rstmgr_hw2reg_reset_req_reg_t reset_req; // [95:91] + rstmgr_hw2reg_reset_info_reg_t reset_info; // [90:82] + rstmgr_hw2reg_alert_info_ctrl_reg_t alert_info_ctrl; // [81:80] + rstmgr_hw2reg_alert_info_attr_reg_t alert_info_attr; // [79:76] + rstmgr_hw2reg_alert_info_reg_t alert_info; // [75:44] + rstmgr_hw2reg_cpu_info_ctrl_reg_t cpu_info_ctrl; // [43:42] + rstmgr_hw2reg_cpu_info_attr_reg_t cpu_info_attr; // [41:38] + rstmgr_hw2reg_cpu_info_reg_t cpu_info; // [37:6] + rstmgr_hw2reg_err_code_reg_t err_code; // [5:0] + } rstmgr_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] RSTMGR_ALERT_TEST_OFFSET = 7'h 0; + parameter logic [BlockAw-1:0] RSTMGR_RESET_REQ_OFFSET = 7'h 4; + parameter logic [BlockAw-1:0] RSTMGR_RESET_INFO_OFFSET = 7'h 8; + parameter logic [BlockAw-1:0] RSTMGR_ALERT_REGWEN_OFFSET = 7'h c; + parameter logic [BlockAw-1:0] RSTMGR_ALERT_INFO_CTRL_OFFSET = 7'h 10; + parameter logic [BlockAw-1:0] RSTMGR_ALERT_INFO_ATTR_OFFSET = 7'h 14; + parameter logic [BlockAw-1:0] RSTMGR_ALERT_INFO_OFFSET = 7'h 18; + parameter logic [BlockAw-1:0] RSTMGR_CPU_REGWEN_OFFSET = 7'h 1c; + parameter logic [BlockAw-1:0] RSTMGR_CPU_INFO_CTRL_OFFSET = 7'h 20; + parameter logic [BlockAw-1:0] RSTMGR_CPU_INFO_ATTR_OFFSET = 7'h 24; + parameter logic [BlockAw-1:0] RSTMGR_CPU_INFO_OFFSET = 7'h 28; + parameter logic [BlockAw-1:0] RSTMGR_SW_RST_REGWEN_0_OFFSET = 7'h 2c; + parameter logic [BlockAw-1:0] RSTMGR_SW_RST_REGWEN_1_OFFSET = 7'h 30; + parameter logic [BlockAw-1:0] RSTMGR_SW_RST_REGWEN_2_OFFSET = 7'h 34; + parameter logic [BlockAw-1:0] RSTMGR_SW_RST_CTRL_N_0_OFFSET = 7'h 38; + parameter logic [BlockAw-1:0] RSTMGR_SW_RST_CTRL_N_1_OFFSET = 7'h 3c; + parameter logic [BlockAw-1:0] RSTMGR_SW_RST_CTRL_N_2_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] RSTMGR_ERR_CODE_OFFSET = 7'h 44; + + // Reset values for hwext registers and their fields + parameter logic [1:0] RSTMGR_ALERT_TEST_RESVAL = 2'h 0; + parameter logic [0:0] RSTMGR_ALERT_TEST_FATAL_FAULT_RESVAL = 1'h 0; + parameter logic [0:0] RSTMGR_ALERT_TEST_FATAL_CNSTY_FAULT_RESVAL = 1'h 0; + parameter logic [3:0] RSTMGR_ALERT_INFO_ATTR_RESVAL = 4'h 0; + parameter logic [3:0] RSTMGR_ALERT_INFO_ATTR_CNT_AVAIL_RESVAL = 4'h 0; + parameter logic [31:0] RSTMGR_ALERT_INFO_RESVAL = 32'h 0; + parameter logic [31:0] RSTMGR_ALERT_INFO_VALUE_RESVAL = 32'h 0; + parameter logic [3:0] RSTMGR_CPU_INFO_ATTR_RESVAL = 4'h 0; + parameter logic [3:0] RSTMGR_CPU_INFO_ATTR_CNT_AVAIL_RESVAL = 4'h 0; + parameter logic [31:0] RSTMGR_CPU_INFO_RESVAL = 32'h 0; + parameter logic [31:0] RSTMGR_CPU_INFO_VALUE_RESVAL = 32'h 0; + + // Register index + typedef enum int { + RSTMGR_ALERT_TEST, + RSTMGR_RESET_REQ, + RSTMGR_RESET_INFO, + RSTMGR_ALERT_REGWEN, + RSTMGR_ALERT_INFO_CTRL, + RSTMGR_ALERT_INFO_ATTR, + RSTMGR_ALERT_INFO, + RSTMGR_CPU_REGWEN, + RSTMGR_CPU_INFO_CTRL, + RSTMGR_CPU_INFO_ATTR, + RSTMGR_CPU_INFO, + RSTMGR_SW_RST_REGWEN_0, + RSTMGR_SW_RST_REGWEN_1, + RSTMGR_SW_RST_REGWEN_2, + RSTMGR_SW_RST_CTRL_N_0, + RSTMGR_SW_RST_CTRL_N_1, + RSTMGR_SW_RST_CTRL_N_2, + RSTMGR_ERR_CODE + } rstmgr_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] RSTMGR_PERMIT [18] = '{ + 4'b 0001, // index[ 0] RSTMGR_ALERT_TEST + 4'b 0001, // index[ 1] RSTMGR_RESET_REQ + 4'b 0001, // index[ 2] RSTMGR_RESET_INFO + 4'b 0001, // index[ 3] RSTMGR_ALERT_REGWEN + 4'b 0001, // index[ 4] RSTMGR_ALERT_INFO_CTRL + 4'b 0001, // index[ 5] RSTMGR_ALERT_INFO_ATTR + 4'b 1111, // index[ 6] RSTMGR_ALERT_INFO + 4'b 0001, // index[ 7] RSTMGR_CPU_REGWEN + 4'b 0001, // index[ 8] RSTMGR_CPU_INFO_CTRL + 4'b 0001, // index[ 9] RSTMGR_CPU_INFO_ATTR + 4'b 1111, // index[10] RSTMGR_CPU_INFO + 4'b 0001, // index[11] RSTMGR_SW_RST_REGWEN_0 + 4'b 0001, // index[12] RSTMGR_SW_RST_REGWEN_1 + 4'b 0001, // index[13] RSTMGR_SW_RST_REGWEN_2 + 4'b 0001, // index[14] RSTMGR_SW_RST_CTRL_N_0 + 4'b 0001, // index[15] RSTMGR_SW_RST_CTRL_N_1 + 4'b 0001, // index[16] RSTMGR_SW_RST_CTRL_N_2 + 4'b 0001 // index[17] RSTMGR_ERR_CODE + }; + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_top.sv new file mode 100644 index 0000000000000..b972baf972c11 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rstmgr/rtl/rstmgr_reg_top.sv @@ -0,0 +1,1124 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 rstmgr_reg_top ( + input clk_i, + input rst_ni, + input clk_por_i, + input rst_por_ni, + input tlul_pkg::tl_h2d_t tl_i, + output tlul_pkg::tl_d2h_t tl_o, + // To HW + output rstmgr_reg_pkg::rstmgr_reg2hw_t reg2hw, // Write + input rstmgr_reg_pkg::rstmgr_hw2reg_t hw2reg, // Read + + // Integrity check errors + output logic intg_err_o +); + + import rstmgr_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 [17:0] reg_we_check; + prim_reg_we_check #( + .OneHotWidth(18) + ) 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 = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic alert_test_we; + logic alert_test_fatal_fault_wd; + logic alert_test_fatal_cnsty_fault_wd; + logic reset_req_we; + logic [3:0] reset_req_qs; + logic [3:0] reset_req_wd; + logic reset_info_we; + logic reset_info_por_qs; + logic reset_info_por_wd; + logic reset_info_low_power_exit_qs; + logic reset_info_low_power_exit_wd; + logic reset_info_sw_reset_qs; + logic reset_info_sw_reset_wd; + logic [3:0] reset_info_hw_req_qs; + logic [3:0] reset_info_hw_req_wd; + logic alert_regwen_we; + logic alert_regwen_qs; + logic alert_regwen_wd; + logic alert_info_ctrl_we; + logic alert_info_ctrl_en_qs; + logic alert_info_ctrl_en_wd; + logic [3:0] alert_info_ctrl_index_qs; + logic [3:0] alert_info_ctrl_index_wd; + logic alert_info_attr_re; + logic [3:0] alert_info_attr_qs; + logic alert_info_re; + logic [31:0] alert_info_qs; + logic cpu_regwen_we; + logic cpu_regwen_qs; + logic cpu_regwen_wd; + logic cpu_info_ctrl_we; + logic cpu_info_ctrl_en_qs; + logic cpu_info_ctrl_en_wd; + logic [3:0] cpu_info_ctrl_index_qs; + logic [3:0] cpu_info_ctrl_index_wd; + logic cpu_info_attr_re; + logic [3:0] cpu_info_attr_qs; + logic cpu_info_re; + logic [31:0] cpu_info_qs; + logic sw_rst_regwen_0_we; + logic sw_rst_regwen_0_qs; + logic sw_rst_regwen_0_wd; + logic sw_rst_regwen_1_we; + logic sw_rst_regwen_1_qs; + logic sw_rst_regwen_1_wd; + logic sw_rst_regwen_2_we; + logic sw_rst_regwen_2_qs; + logic sw_rst_regwen_2_wd; + logic sw_rst_ctrl_n_0_we; + logic sw_rst_ctrl_n_0_qs; + logic sw_rst_ctrl_n_0_wd; + logic sw_rst_ctrl_n_1_we; + logic sw_rst_ctrl_n_1_qs; + logic sw_rst_ctrl_n_1_wd; + logic sw_rst_ctrl_n_2_we; + logic sw_rst_ctrl_n_2_qs; + logic sw_rst_ctrl_n_2_wd; + logic err_code_reg_intg_err_qs; + logic err_code_reset_consistency_err_qs; + logic err_code_fsm_err_qs; + // Define register CDC handling. + // CDC handling is done on a per-reg instead of per-field boundary. + + // Register instances + // R[alert_test]: V(True) + logic alert_test_qe; + logic [1:0] alert_test_flds_we; + assign alert_test_qe = &alert_test_flds_we; + // F[fatal_fault]: 0:0 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_fault ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_fault_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[0]), + .q (reg2hw.alert_test.fatal_fault.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_fault.qe = alert_test_qe; + + // F[fatal_cnsty_fault]: 1:1 + prim_subreg_ext #( + .DW (1) + ) u_alert_test_fatal_cnsty_fault ( + .re (1'b0), + .we (alert_test_we), + .wd (alert_test_fatal_cnsty_fault_wd), + .d ('0), + .qre (), + .qe (alert_test_flds_we[1]), + .q (reg2hw.alert_test.fatal_cnsty_fault.q), + .ds (), + .qs () + ); + assign reg2hw.alert_test.fatal_cnsty_fault.qe = alert_test_qe; + + + // R[reset_req]: V(False) + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h9), + .Mubi (1'b1) + ) u_reset_req ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (reset_req_we), + .wd (reset_req_wd), + + // from internal hardware + .de (hw2reg.reset_req.de), + .d (hw2reg.reset_req.d), + + // to internal hardware + .qe (), + .q (reg2hw.reset_req.q), + .ds (), + + // to register interface (read) + .qs (reset_req_qs) + ); + + + // R[reset_info]: V(False) + // F[por]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_reset_info_por ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (reset_info_we), + .wd (reset_info_por_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (reset_info_por_qs) + ); + + // F[low_power_exit]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_reset_info_low_power_exit ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (reset_info_we), + .wd (reset_info_low_power_exit_wd), + + // from internal hardware + .de (hw2reg.reset_info.low_power_exit.de), + .d (hw2reg.reset_info.low_power_exit.d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (reset_info_low_power_exit_qs) + ); + + // F[sw_reset]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_reset_info_sw_reset ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (reset_info_we), + .wd (reset_info_sw_reset_wd), + + // from internal hardware + .de (hw2reg.reset_info.sw_reset.de), + .d (hw2reg.reset_info.sw_reset.d), + + // to internal hardware + .qe (), + .q (reg2hw.reset_info.sw_reset.q), + .ds (), + + // to register interface (read) + .qs (reset_info_sw_reset_qs) + ); + + // F[hw_req]: 6:3 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessW1C), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_reset_info_hw_req ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (reset_info_we), + .wd (reset_info_hw_req_wd), + + // from internal hardware + .de (hw2reg.reset_info.hw_req.de), + .d (hw2reg.reset_info.hw_req.d), + + // to internal hardware + .qe (), + .q (reg2hw.reset_info.hw_req.q), + .ds (), + + // to register interface (read) + .qs (reset_info_hw_req_qs) + ); + + + // R[alert_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_alert_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (alert_regwen_we), + .wd (alert_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (alert_regwen_qs) + ); + + + // R[alert_info_ctrl]: V(False) + // Create REGWEN-gated WE signal + logic alert_info_ctrl_gated_we; + assign alert_info_ctrl_gated_we = alert_info_ctrl_we & alert_regwen_qs; + // F[en]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_alert_info_ctrl_en ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (alert_info_ctrl_gated_we), + .wd (alert_info_ctrl_en_wd), + + // from internal hardware + .de (hw2reg.alert_info_ctrl.en.de), + .d (hw2reg.alert_info_ctrl.en.d), + + // to internal hardware + .qe (), + .q (reg2hw.alert_info_ctrl.en.q), + .ds (), + + // to register interface (read) + .qs (alert_info_ctrl_en_qs) + ); + + // F[index]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_alert_info_ctrl_index ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (alert_info_ctrl_gated_we), + .wd (alert_info_ctrl_index_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.alert_info_ctrl.index.q), + .ds (), + + // to register interface (read) + .qs (alert_info_ctrl_index_qs) + ); + + + // R[alert_info_attr]: V(True) + prim_subreg_ext #( + .DW (4) + ) u_alert_info_attr ( + .re (alert_info_attr_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_info_attr.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_info_attr_qs) + ); + + + // R[alert_info]: V(True) + prim_subreg_ext #( + .DW (32) + ) u_alert_info ( + .re (alert_info_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.alert_info.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (alert_info_qs) + ); + + + // R[cpu_regwen]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_cpu_regwen ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (cpu_regwen_we), + .wd (cpu_regwen_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (cpu_regwen_qs) + ); + + + // R[cpu_info_ctrl]: V(False) + // Create REGWEN-gated WE signal + logic cpu_info_ctrl_gated_we; + assign cpu_info_ctrl_gated_we = cpu_info_ctrl_we & cpu_regwen_qs; + // F[en]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_cpu_info_ctrl_en ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (cpu_info_ctrl_gated_we), + .wd (cpu_info_ctrl_en_wd), + + // from internal hardware + .de (hw2reg.cpu_info_ctrl.en.de), + .d (hw2reg.cpu_info_ctrl.en.d), + + // to internal hardware + .qe (), + .q (reg2hw.cpu_info_ctrl.en.q), + .ds (), + + // to register interface (read) + .qs (cpu_info_ctrl_en_qs) + ); + + // F[index]: 7:4 + prim_subreg #( + .DW (4), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (4'h0), + .Mubi (1'b0) + ) u_cpu_info_ctrl_index ( + // sync clock and reset required for this register + .clk_i (clk_por_i), + .rst_ni (rst_por_ni), + + // from register interface + .we (cpu_info_ctrl_gated_we), + .wd (cpu_info_ctrl_index_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.cpu_info_ctrl.index.q), + .ds (), + + // to register interface (read) + .qs (cpu_info_ctrl_index_qs) + ); + + + // R[cpu_info_attr]: V(True) + prim_subreg_ext #( + .DW (4) + ) u_cpu_info_attr ( + .re (cpu_info_attr_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.cpu_info_attr.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (cpu_info_attr_qs) + ); + + + // R[cpu_info]: V(True) + prim_subreg_ext #( + .DW (32) + ) u_cpu_info ( + .re (cpu_info_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.cpu_info.d), + .qre (), + .qe (), + .q (), + .ds (), + .qs (cpu_info_qs) + ); + + + // Subregister 0 of Multireg sw_rst_regwen + // R[sw_rst_regwen_0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_sw_rst_regwen_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (sw_rst_regwen_0_we), + .wd (sw_rst_regwen_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (sw_rst_regwen_0_qs) + ); + + + // Subregister 1 of Multireg sw_rst_regwen + // R[sw_rst_regwen_1]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_sw_rst_regwen_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (sw_rst_regwen_1_we), + .wd (sw_rst_regwen_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (sw_rst_regwen_1_qs) + ); + + + // Subregister 2 of Multireg sw_rst_regwen + // R[sw_rst_regwen_2]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessW0C), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_sw_rst_regwen_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (sw_rst_regwen_2_we), + .wd (sw_rst_regwen_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (sw_rst_regwen_2_qs) + ); + + + // Subregister 0 of Multireg sw_rst_ctrl_n + // R[sw_rst_ctrl_n_0]: V(False) + // Create REGWEN-gated WE signal + logic sw_rst_ctrl_n_0_gated_we; + assign sw_rst_ctrl_n_0_gated_we = sw_rst_ctrl_n_0_we & sw_rst_regwen_0_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_sw_rst_ctrl_n_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (sw_rst_ctrl_n_0_gated_we), + .wd (sw_rst_ctrl_n_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.sw_rst_ctrl_n[0].q), + .ds (), + + // to register interface (read) + .qs (sw_rst_ctrl_n_0_qs) + ); + + + // Subregister 1 of Multireg sw_rst_ctrl_n + // R[sw_rst_ctrl_n_1]: V(False) + // Create REGWEN-gated WE signal + logic sw_rst_ctrl_n_1_gated_we; + assign sw_rst_ctrl_n_1_gated_we = sw_rst_ctrl_n_1_we & sw_rst_regwen_1_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_sw_rst_ctrl_n_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (sw_rst_ctrl_n_1_gated_we), + .wd (sw_rst_ctrl_n_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.sw_rst_ctrl_n[1].q), + .ds (), + + // to register interface (read) + .qs (sw_rst_ctrl_n_1_qs) + ); + + + // Subregister 2 of Multireg sw_rst_ctrl_n + // R[sw_rst_ctrl_n_2]: V(False) + // Create REGWEN-gated WE signal + logic sw_rst_ctrl_n_2_gated_we; + assign sw_rst_ctrl_n_2_gated_we = sw_rst_ctrl_n_2_we & sw_rst_regwen_2_qs; + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h1), + .Mubi (1'b0) + ) u_sw_rst_ctrl_n_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (sw_rst_ctrl_n_2_gated_we), + .wd (sw_rst_ctrl_n_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.sw_rst_ctrl_n[2].q), + .ds (), + + // to register interface (read) + .qs (sw_rst_ctrl_n_2_qs) + ); + + + // R[err_code]: V(False) + // F[reg_intg_err]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_reg_intg_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.reg_intg_err.de), + .d (hw2reg.err_code.reg_intg_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.err_code.reg_intg_err.q), + .ds (), + + // to register interface (read) + .qs (err_code_reg_intg_err_qs) + ); + + // F[reset_consistency_err]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_reset_consistency_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.reset_consistency_err.de), + .d (hw2reg.err_code.reset_consistency_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.err_code.reset_consistency_err.q), + .ds (), + + // to register interface (read) + .qs (err_code_reset_consistency_err_qs) + ); + + // F[fsm_err]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_err_code_fsm_err ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.err_code.fsm_err.de), + .d (hw2reg.err_code.fsm_err.d), + + // to internal hardware + .qe (), + .q (reg2hw.err_code.fsm_err.q), + .ds (), + + // to register interface (read) + .qs (err_code_fsm_err_qs) + ); + + + + logic [17:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == RSTMGR_ALERT_TEST_OFFSET); + addr_hit[ 1] = (reg_addr == RSTMGR_RESET_REQ_OFFSET); + addr_hit[ 2] = (reg_addr == RSTMGR_RESET_INFO_OFFSET); + addr_hit[ 3] = (reg_addr == RSTMGR_ALERT_REGWEN_OFFSET); + addr_hit[ 4] = (reg_addr == RSTMGR_ALERT_INFO_CTRL_OFFSET); + addr_hit[ 5] = (reg_addr == RSTMGR_ALERT_INFO_ATTR_OFFSET); + addr_hit[ 6] = (reg_addr == RSTMGR_ALERT_INFO_OFFSET); + addr_hit[ 7] = (reg_addr == RSTMGR_CPU_REGWEN_OFFSET); + addr_hit[ 8] = (reg_addr == RSTMGR_CPU_INFO_CTRL_OFFSET); + addr_hit[ 9] = (reg_addr == RSTMGR_CPU_INFO_ATTR_OFFSET); + addr_hit[10] = (reg_addr == RSTMGR_CPU_INFO_OFFSET); + addr_hit[11] = (reg_addr == RSTMGR_SW_RST_REGWEN_0_OFFSET); + addr_hit[12] = (reg_addr == RSTMGR_SW_RST_REGWEN_1_OFFSET); + addr_hit[13] = (reg_addr == RSTMGR_SW_RST_REGWEN_2_OFFSET); + addr_hit[14] = (reg_addr == RSTMGR_SW_RST_CTRL_N_0_OFFSET); + addr_hit[15] = (reg_addr == RSTMGR_SW_RST_CTRL_N_1_OFFSET); + addr_hit[16] = (reg_addr == RSTMGR_SW_RST_CTRL_N_2_OFFSET); + addr_hit[17] = (reg_addr == RSTMGR_ERR_CODE_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] & (|(RSTMGR_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(RSTMGR_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(RSTMGR_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(RSTMGR_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(RSTMGR_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(RSTMGR_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(RSTMGR_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(RSTMGR_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(RSTMGR_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(RSTMGR_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(RSTMGR_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(RSTMGR_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(RSTMGR_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(RSTMGR_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(RSTMGR_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(RSTMGR_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(RSTMGR_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(RSTMGR_PERMIT[17] & ~reg_be))))); + end + + // Generate write-enables + assign alert_test_we = addr_hit[0] & reg_we & !reg_error; + + assign alert_test_fatal_fault_wd = reg_wdata[0]; + + assign alert_test_fatal_cnsty_fault_wd = reg_wdata[1]; + assign reset_req_we = addr_hit[1] & reg_we & !reg_error; + + assign reset_req_wd = reg_wdata[3:0]; + assign reset_info_we = addr_hit[2] & reg_we & !reg_error; + + assign reset_info_por_wd = reg_wdata[0]; + + assign reset_info_low_power_exit_wd = reg_wdata[1]; + + assign reset_info_sw_reset_wd = reg_wdata[2]; + + assign reset_info_hw_req_wd = reg_wdata[6:3]; + assign alert_regwen_we = addr_hit[3] & reg_we & !reg_error; + + assign alert_regwen_wd = reg_wdata[0]; + assign alert_info_ctrl_we = addr_hit[4] & reg_we & !reg_error; + + assign alert_info_ctrl_en_wd = reg_wdata[0]; + + assign alert_info_ctrl_index_wd = reg_wdata[7:4]; + assign alert_info_attr_re = addr_hit[5] & reg_re & !reg_error; + assign alert_info_re = addr_hit[6] & reg_re & !reg_error; + assign cpu_regwen_we = addr_hit[7] & reg_we & !reg_error; + + assign cpu_regwen_wd = reg_wdata[0]; + assign cpu_info_ctrl_we = addr_hit[8] & reg_we & !reg_error; + + assign cpu_info_ctrl_en_wd = reg_wdata[0]; + + assign cpu_info_ctrl_index_wd = reg_wdata[7:4]; + assign cpu_info_attr_re = addr_hit[9] & reg_re & !reg_error; + assign cpu_info_re = addr_hit[10] & reg_re & !reg_error; + assign sw_rst_regwen_0_we = addr_hit[11] & reg_we & !reg_error; + + assign sw_rst_regwen_0_wd = reg_wdata[0]; + assign sw_rst_regwen_1_we = addr_hit[12] & reg_we & !reg_error; + + assign sw_rst_regwen_1_wd = reg_wdata[0]; + assign sw_rst_regwen_2_we = addr_hit[13] & reg_we & !reg_error; + + assign sw_rst_regwen_2_wd = reg_wdata[0]; + assign sw_rst_ctrl_n_0_we = addr_hit[14] & reg_we & !reg_error; + + assign sw_rst_ctrl_n_0_wd = reg_wdata[0]; + assign sw_rst_ctrl_n_1_we = addr_hit[15] & reg_we & !reg_error; + + assign sw_rst_ctrl_n_1_wd = reg_wdata[0]; + assign sw_rst_ctrl_n_2_we = addr_hit[16] & reg_we & !reg_error; + + assign sw_rst_ctrl_n_2_wd = reg_wdata[0]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = alert_test_we; + reg_we_check[1] = reset_req_we; + reg_we_check[2] = reset_info_we; + reg_we_check[3] = alert_regwen_we; + reg_we_check[4] = alert_info_ctrl_gated_we; + reg_we_check[5] = 1'b0; + reg_we_check[6] = 1'b0; + reg_we_check[7] = cpu_regwen_we; + reg_we_check[8] = cpu_info_ctrl_gated_we; + reg_we_check[9] = 1'b0; + reg_we_check[10] = 1'b0; + reg_we_check[11] = sw_rst_regwen_0_we; + reg_we_check[12] = sw_rst_regwen_1_we; + reg_we_check[13] = sw_rst_regwen_2_we; + reg_we_check[14] = sw_rst_ctrl_n_0_gated_we; + reg_we_check[15] = sw_rst_ctrl_n_1_gated_we; + reg_we_check[16] = sw_rst_ctrl_n_2_gated_we; + reg_we_check[17] = 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] = '0; + reg_rdata_next[1] = '0; + end + + addr_hit[1]: begin + reg_rdata_next[3:0] = reset_req_qs; + end + + addr_hit[2]: begin + reg_rdata_next[0] = reset_info_por_qs; + reg_rdata_next[1] = reset_info_low_power_exit_qs; + reg_rdata_next[2] = reset_info_sw_reset_qs; + reg_rdata_next[6:3] = reset_info_hw_req_qs; + end + + addr_hit[3]: begin + reg_rdata_next[0] = alert_regwen_qs; + end + + addr_hit[4]: begin + reg_rdata_next[0] = alert_info_ctrl_en_qs; + reg_rdata_next[7:4] = alert_info_ctrl_index_qs; + end + + addr_hit[5]: begin + reg_rdata_next[3:0] = alert_info_attr_qs; + end + + addr_hit[6]: begin + reg_rdata_next[31:0] = alert_info_qs; + end + + addr_hit[7]: begin + reg_rdata_next[0] = cpu_regwen_qs; + end + + addr_hit[8]: begin + reg_rdata_next[0] = cpu_info_ctrl_en_qs; + reg_rdata_next[7:4] = cpu_info_ctrl_index_qs; + end + + addr_hit[9]: begin + reg_rdata_next[3:0] = cpu_info_attr_qs; + end + + addr_hit[10]: begin + reg_rdata_next[31:0] = cpu_info_qs; + end + + addr_hit[11]: begin + reg_rdata_next[0] = sw_rst_regwen_0_qs; + end + + addr_hit[12]: begin + reg_rdata_next[0] = sw_rst_regwen_1_qs; + end + + addr_hit[13]: begin + reg_rdata_next[0] = sw_rst_regwen_2_qs; + end + + addr_hit[14]: begin + reg_rdata_next[0] = sw_rst_ctrl_n_0_qs; + end + + addr_hit[15]: begin + reg_rdata_next[0] = sw_rst_ctrl_n_1_qs; + end + + addr_hit[16]: begin + reg_rdata_next[0] = sw_rst_ctrl_n_2_qs; + end + + addr_hit[17]: begin + reg_rdata_next[0] = err_code_reg_intg_err_qs; + reg_rdata_next[1] = err_code_reset_consistency_err_qs; + reg_rdata_next[2] = err_code_fsm_err_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_englishbreakfast/ip_autogen/rv_plic/BUILD b/hw/top_englishbreakfast/ip_autogen/rv_plic/BUILD new file mode 100644 index 0000000000000..dda56de039e27 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/BUILD @@ -0,0 +1,10 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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/top_englishbreakfast/ip_autogen/rv_plic/README.md b/hw/top_englishbreakfast/ip_autogen/rv_plic/README.md new file mode 100644 index 0000000000000..1436784f7a380 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/README.md @@ -0,0 +1,26 @@ +# Interrupt Controller Technical Specification + +# Overview + +This document specifies the Interrupt Controller (RV_PLIC) functionality. This +module conforms to the +[Comportable guideline for peripheral functionality](../../../../doc/contributing/hw/comportability/README.md). +See that document for integration overview within the broader top level system. + + +## Features + +- RISC-V Platform-Level Interrupt Controller (PLIC) compliant interrupt controller +- Support arbitrary number of interrupt vectors (up to 255) and targets +- Support interrupt enable, interrupt status registers +- Memory-mapped MSIP register per HART for software interrupt control. + +## Description + +The RV_PLIC module is designed to manage various interrupt sources from the +peripherals. It receives interrupt events as either edge or level of the +incoming interrupt signals (``intr_src_i``) and can notify multiple targets. + +## Compatibility + +The RV_PLIC is compatible with any RISC-V core implementing the RISC-V privilege specification. diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson new file mode 100644 index 0000000000000..140cc915810f2 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic.hjson @@ -0,0 +1,901 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +# RV_PLIC register template +# +# Parameter (given by Python tool) +# - src: Number of Interrupt Sources +# - target: Number of Targets that handle interrupt requests +# - prio: Max value of interrupt priorities +# - module_instance_name: Module instance name. +{ + name: "rv_plic", + human_name: "RISC-V platform level interrupt controller", + one_line_desc: "Interrupt controller, adhering to RISC-V PLIC specification", + one_paragraph_desc: ''' + rv_plic is an interrupt controller which handles multiple interrupt sources. Each interrupt + source can be enabled or disabled, and can be given a priority. rv_plic generates an output + that identifies the source with the highest priority amongst those that are currently asserted. + ''' + // Unique comportable IP identifier defined under KNOWN_CIP_IDS in the regtool. + cip_id: "33", + design_spec: "../doc", + dv_doc: "../doc/dv", + hw_checklist: "../doc/checklist", + sw_checklist: "/sw/device/lib/dif/dif_rv_plic", + revisions: [ + { + version: "2.0.0", + life_stage: "L1", + design_stage: "D3", + verification_stage: "V2", + dif_stage: "S2", + commit_id: "", + notes: "Use FPV to perform block level verification.", + } + ], + clocking: [{clock: "clk_i", reset: "rst_ni"}], + bus_interfaces: [ + { protocol: "tlul", direction: "device" } + ], + + param_list: [ + { name: "NumSrc", + desc: "Number of interrupt sources", + type: "int", + default: "88", + local: "true" + }, + { name: "NumTarget", + desc: "Number of Targets (Harts)", + type: "int", + default: "1", + local: "true", + }, + { name: "PrioWidth", + desc: "Width of priority signals", + type: "int", + default: "2", + local: "true", + }, + ], + + // In order to not disturb the PLIC address map, we place the alert test + // register manually at a safe offset after the main CSRs. + no_auto_alert_regs: "True", + alert_list: [ + { name: "fatal_fault", + desc: ''' + This fatal alert is triggered when a fatal TL-UL bus integrity fault is detected. + ''' + } + ], + + inter_signal_list: [ + { struct: "logic", + type: "uni", + name: "irq", + act: "req", + package: "", + width: "1" + }, + + { struct: "logic", + type: "uni", + name: "irq_id", + act: "req", + package: "", + }, + + { struct: "logic", + type: "uni", + name: "msip", + act: "req", + package: "", + width: "1" + }, + ] + + countermeasures: [ + { name: "BUS.INTEGRITY", + desc: "End-to-end bus integrity scheme." + } + ] + + features: [ + { name: "RV_PLIC.PRIORITY", + desc: '''Each interrupt source can be given a configurable priority.''' + } + { name: "RV_PLIC.ENABLE", + desc: '''Each target has an associated set of interrupt enable bits. Configuring these + controls whether a target will be notified when the interrupt is triggered. + ''' + } + ] + + regwidth: "32", + registers: [ + { name: "PRIO0", + desc: "Interrupt Source 0 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO1", + desc: "Interrupt Source 1 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO2", + desc: "Interrupt Source 2 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO3", + desc: "Interrupt Source 3 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO4", + desc: "Interrupt Source 4 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO5", + desc: "Interrupt Source 5 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO6", + desc: "Interrupt Source 6 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO7", + desc: "Interrupt Source 7 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO8", + desc: "Interrupt Source 8 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO9", + desc: "Interrupt Source 9 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO10", + desc: "Interrupt Source 10 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO11", + desc: "Interrupt Source 11 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO12", + desc: "Interrupt Source 12 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO13", + desc: "Interrupt Source 13 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO14", + desc: "Interrupt Source 14 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO15", + desc: "Interrupt Source 15 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO16", + desc: "Interrupt Source 16 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO17", + desc: "Interrupt Source 17 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO18", + desc: "Interrupt Source 18 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO19", + desc: "Interrupt Source 19 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO20", + desc: "Interrupt Source 20 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO21", + desc: "Interrupt Source 21 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO22", + desc: "Interrupt Source 22 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO23", + desc: "Interrupt Source 23 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO24", + desc: "Interrupt Source 24 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO25", + desc: "Interrupt Source 25 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO26", + desc: "Interrupt Source 26 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO27", + desc: "Interrupt Source 27 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO28", + desc: "Interrupt Source 28 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO29", + desc: "Interrupt Source 29 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO30", + desc: "Interrupt Source 30 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO31", + desc: "Interrupt Source 31 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO32", + desc: "Interrupt Source 32 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO33", + desc: "Interrupt Source 33 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO34", + desc: "Interrupt Source 34 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO35", + desc: "Interrupt Source 35 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO36", + desc: "Interrupt Source 36 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO37", + desc: "Interrupt Source 37 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO38", + desc: "Interrupt Source 38 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO39", + desc: "Interrupt Source 39 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO40", + desc: "Interrupt Source 40 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO41", + desc: "Interrupt Source 41 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO42", + desc: "Interrupt Source 42 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO43", + desc: "Interrupt Source 43 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO44", + desc: "Interrupt Source 44 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO45", + desc: "Interrupt Source 45 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO46", + desc: "Interrupt Source 46 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO47", + desc: "Interrupt Source 47 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO48", + desc: "Interrupt Source 48 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO49", + desc: "Interrupt Source 49 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO50", + desc: "Interrupt Source 50 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO51", + desc: "Interrupt Source 51 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO52", + desc: "Interrupt Source 52 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO53", + desc: "Interrupt Source 53 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO54", + desc: "Interrupt Source 54 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO55", + desc: "Interrupt Source 55 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO56", + desc: "Interrupt Source 56 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO57", + desc: "Interrupt Source 57 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO58", + desc: "Interrupt Source 58 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO59", + desc: "Interrupt Source 59 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO60", + desc: "Interrupt Source 60 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO61", + desc: "Interrupt Source 61 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO62", + desc: "Interrupt Source 62 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO63", + desc: "Interrupt Source 63 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO64", + desc: "Interrupt Source 64 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO65", + desc: "Interrupt Source 65 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO66", + desc: "Interrupt Source 66 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO67", + desc: "Interrupt Source 67 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO68", + desc: "Interrupt Source 68 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO69", + desc: "Interrupt Source 69 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO70", + desc: "Interrupt Source 70 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO71", + desc: "Interrupt Source 71 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO72", + desc: "Interrupt Source 72 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO73", + desc: "Interrupt Source 73 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO74", + desc: "Interrupt Source 74 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO75", + desc: "Interrupt Source 75 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO76", + desc: "Interrupt Source 76 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO77", + desc: "Interrupt Source 77 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO78", + desc: "Interrupt Source 78 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO79", + desc: "Interrupt Source 79 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO80", + desc: "Interrupt Source 80 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO81", + desc: "Interrupt Source 81 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO82", + desc: "Interrupt Source 82 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO83", + desc: "Interrupt Source 83 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO84", + desc: "Interrupt Source 84 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO85", + desc: "Interrupt Source 85 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO86", + desc: "Interrupt Source 86 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "PRIO87", + desc: "Interrupt Source 87 Priority", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { skipto: "0x00001000" } + { multireg: { + name: "IP", + desc: "Interrupt Pending", + count: "NumSrc", + cname: "RV_PLIC", + swaccess: "ro", + hwaccess: "hwo", + fields: [ + { bits: "0", name: "P", desc: "Interrupt Pending of Source" } + ], + tags: [// IP is driven by intr_src, cannot auto-predict + "excl:CsrNonInitTests:CsrExclCheck"], + } + }, + { skipto: "0x2000" } + { multireg: { + name: "IE0", + desc: "Interrupt Enable for Target 0", + count: "NumSrc", + cname: "RV_PLIC", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "0", name: "E", desc: "Interrupt Enable of Source" } + ], + } + } + { skipto: "0x200000" } + { name: "THRESHOLD0", + desc: "Threshold of priority for Target 0", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "1:0" } + ], + } + { name: "CC0", + desc: '''Claim interrupt by read, complete interrupt by write for Target 0. + Value read/written is interrupt ID. Reading a value of 0 means no pending interrupts.''', + swaccess: "rw", + hwaccess: "hrw", + hwext: "true", + hwqe: "true", + hwre: "true", + fields: [ + { bits: "6:0" } + ], + tags: [// CC register value is related to IP + "excl:CsrNonInitTests:CsrExclCheck"], + } + { skipto: "0x4000000" } + { name: "MSIP0", + desc: '''msip for Hart 0. + Write 1 to here asserts software interrupt for Hart msip_o[0], write 0 to clear.''', + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "0", + desc: "Software Interrupt Pending register", + } + ], + } + { skipto: "0x4004000" } + { name: "ALERT_TEST", + desc: '''Alert Test Register.''', + swaccess: "wo", + hwaccess: "hro", + hwqe: "True", + hwext: "True", + fields: [ + { bits: "0", + name: "fatal_fault", + desc: "'Write 1 to trigger one alert event of this kind.'", + } + ], + } + ], +} diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_fpv_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_fpv_testplan.hjson new file mode 100644 index 0000000000000..ea0956eff732b --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_fpv_testplan.hjson @@ -0,0 +1,73 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + name: "rv_plic" + import_testplans: ["hw/dv/tools/dvsim/testplans/fpv_csr_testplan.hjson"] + testpoints: [ + { + name: LevelTriggeredIp_A + desc: '''If interrupt pending (`ip`) is triggered, and the level indicator is set to + level triggered (`le=0`), then in the prvious clock cycle, the interrupt source + (`intr_src_i) should be set to 1.''' + stage: V2 + tests: ["rv_plic_assert"] + } + { + name: LevelTriggeredIpWithClaim_A + desc: '''If `intr_src_i` is set to 1, level indicator is set to level triggered, and claim + signal is not set, then at the next clock cycle `ip` will be triggered.''' + stage: V2 + tests: ["rv_plic_assert"] + } + { + name: IpStableAfterTriggered_A + desc: "Once `ip` is set, it stays stable until is being claimed." + stage: V2 + tests: ["rv_plic_assert"] + } + { + name: IpClearAfterClaim_A + desc: "Once `ip` is set and being claimed, its value is cleared to 0." + stage: V2 + tests: ["rv_plic_assert"] + } + { + name: IpStableAfterClaimed_A + desc: '''Once `ip` is cleared to 0, it stays stable until completed and being triggered + again.''' + stage: V2 + tests: ["rv_plic_assert"] + } + { + name: TriggerIrqForwardCheck_A + desc: '''If interrupt is enabled (`ie=1`), interrupt pending is set (`ip=1`), interrupt + input has the highest priority among the rest of the inputs, and its priority is + above the threshold. Then in the next clock clcye, the `irq_o` should be triggered, + and the `irq_id_o` will reflect the input ID.''' + stage: V2 + tests: ["rv_plic_assert"] + } + { + name: TriggerIrqBackwardCheck_A + desc: '''If `irq_o` is set to 1, then in the previous clock cycle, the corresponding + `ip` should be set, `ie` should be enabled, and the interrupt source should above the + threshold and have the highest priority.''' + stage: V2 + tests: ["rv_plic_assert"] + + } + { + name: IdChangeWithIrq_A + desc: '''If `irq_id_o` signal is changed and the signal does not change to 0 (value 0 does + not represent any interrupt source ID). Then either of the two condition should have + happened: + - `irq_o` is triggered + - No interrupt triggered, `ip` is set and `ie` is enabled, interrupt source priority is the + largest among the rest of the interrupt, but the interrupt source + priority is smaller than the threshold''' + stage: V2 + tests: ["rv_plic_assert"] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_sec_cm_testplan.hjson b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_sec_cm_testplan.hjson new file mode 100644 index 0000000000000..d7aac02a08d24 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/rv_plic_sec_cm_testplan.hjson @@ -0,0 +1,33 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// .../rv_plic/data/rv_plic.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: +// .../rv_plic/data/rv_plic_testplan.hjson +{ + testpoints: [ + { + name: sec_cm_bus_integrity + desc: "Verify the countermeasure(s) BUS.INTEGRITY." + stage: V2S + tests: [] + } + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/data/top_englishbreakfast_rv_plic.ipconfig.hjson b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/top_englishbreakfast_rv_plic.ipconfig.hjson new file mode 100644 index 0000000000000..98e41fca2ed07 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/data/top_englishbreakfast_rv_plic.ipconfig.hjson @@ -0,0 +1,13 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +{ + instance_name: top_englishbreakfast_rv_plic + param_values: + { + src: 88 + target: 1 + prio: 3 + topname: englishbreakfast + } +} diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/defs.bzl b/hw/top_englishbreakfast/ip_autogen/rv_plic/defs.bzl new file mode 100644 index 0000000000000..605456fbd3be2 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/defs.bzl @@ -0,0 +1,9 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +load("//rules/opentitan:hw.bzl", "opentitan_ip") + +RV_PLIC = opentitan_ip( + name = "rv_plic", + hjson = "//hw/top_englishbreakfast/ip_autogen/rv_plic:data/rv_plic.hjson", +) diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/block_diagram.svg b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/block_diagram.svg new file mode 100644 index 0000000000000..ac02b678fa6d7 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/block_diagram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/checklist.md b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/checklist.md new file mode 100644 index 0000000000000..9177f98cdeefa --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/checklist.md @@ -0,0 +1,264 @@ +# RV_PLIC Checklist + +This checklist is for [Hardware Stage](../../../../../doc/project_governance/development_stages.md) transitions for the [RV_PLIC 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 | [RV_PLIC Spec][] +Documentation | [CSR_DEFINED][] | Done | +RTL | [CLKRST_CONNECTED][] | Done | +RTL | [IP_TOP][] | Done | +RTL | [IP_INSTANTIABLE][] | Done | +RTL | [PHYSICAL_MACROS_DEFINED_80][] | Done | +RTL | [FUNC_IMPLEMENTED][] | Done | +RTL | [ASSERT_KNOWN_ADDED][] | Done | +Code Quality | [LINT_SETUP][] | Done | + +[RV_PLIC Spec]: ../README.md + +[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][] | N/A | +Documentation | [BLOCK_DIAGRAM][] | Done | +Documentation | [DOC_INTERFACE][] | Done | +Documentation | [MISSING_FUNC][] | N/A | +Documentation | [FEATURE_FROZEN][] | Done | +RTL | [FEATURE_COMPLETE][] | Done | +RTL | [AREA_CHECK][] | Done | +RTL | [PORT_FROZEN][] | Done | +RTL | [ARCHITECTURE_FROZEN][] | Done | +RTL | [REVIEW_TODO][] | Done | One TODO about Vivado Issue +RTL | [STYLE_X][] | Done | +Code Quality | [LINT_PASS][] | Done | +Code Quality | [CDC_SETUP][] | N/A | +Code Quality | [TIMING_CHECK][] | Done | Fmax @ 50MHz on NexysVideo +Code Quality | [CDC_SYNCMACRO][] | N/A | +Security | [SEC_CM_DOCUMENTED][] | N/A | + +[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 +[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 +[AREA_CHECK]: ../../../../../doc/project_governance/checklist/README.md#area_check +[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 +[LINT_PASS]: ../../../../../doc/project_governance/checklist/README.md#lint_pass +[CDC_SETUP]: ../../../../../doc/project_governance/checklist/README.md#cdc_setup +[TIMING_CHECK]: ../../../../../doc/project_governance/checklist/README.md#timing_check +[CDC_SYNCMACRO]: ../../../../../doc/project_governance/checklist/README.md#cdc_syncmacro +[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][] | N/A | +Security | [SEC_CM_SHADOW_REGS][] | N/A | +Security | [SEC_CM_RTL_REVIEWED][] | N/A | +Security | [SEC_CM_COUNCIL_REVIEWED][] | N/A | This block only contains the bus-integrity CM. + +[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][] | Done | +RTL | [TODO_COMPLETE][] | Done | +Code Quality | [LINT_COMPLETE][] | Done | +Code Quality | [CDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Code Quality | [RDC_COMPLETE][] | Waived | No block-level flow available - waived to top-level signoff. +Review | [REVIEW_RTL][] | Done | +Review | [REVIEW_DELETED_FF][] | Waived | No block-level flow available - waived to top-level signoff. +Review | [REVIEW_SW_CHANGE][] | Done | +Review | [REVIEW_SW_ERRATA][] | Done | +Review | Reviewer(s) | Done | eunchan@ gac@ chencindy@ ttrippel@ +Review | Signoff date | Done | 2022-07-25 + +[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 | [rv_plic_fpv_plan](./dv/README.md) +Documentation | [TESTPLAN_COMPLETED][] | Done | +Testbench | [TB_TOP_CREATED][] | Done | +Testbench | [PRELIMINARY_ASSERTION_CHECKS_ADDED][]| Done | +Testbench | [SIM_TB_ENV_CREATED][] | N/A | +Testbench | [SIM_RAL_MODEL_GEN_AUTOMATED][] | N/A | +Testbench | [CSR_CHECK_GEN_AUTOMATED][] | Done | +Testbench | [TB_GEN_AUTOMATED][] | N/A | +Tests | [SIM_SMOKE_TEST_PASSING][] | N/A | +Tests | [SIM_CSR_MEM_TEST_SUITE_PASSING][] | N/A | +Tests | [FPV_MAIN_ASSERTIONS_PROVEN][] | Done | +Tool Setup | [SIM_ALT_TOOL_SETUP][] | N/A | +Regression | [SIM_SMOKE_REGRESSION_SETUP][] | N/A | +Regression | [SIM_NIGHTLY_REGRESSION_SETUP][] | N/A | +Regression | [FPV_REGRESSION_SETUP][] | Done | +Coverage | [SIM_COVERAGE_MODEL_ADDED][] | N/A | +Code Quality | [TB_LINT_SETUP][] | Done | +Integration | [PRE_VERIFIED_SUB_MODULES_V1][] | N/A | +Review | [DESIGN_SPEC_REVIEWED][] | Done | +Review | [TESTPLAN_REVIEWED][] | Done | +Review | [STD_TEST_CATEGORIES_PLANNED][] | N/A | +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][] | N/A | +Documentation | [DV_DOC_COMPLETED][] | Done | +Testbench | [FUNCTIONAL_COVERAGE_IMPLEMENTED][] | N/A | +Testbench | [ALL_INTERFACES_EXERCISED][] | Done | +Testbench | [ALL_ASSERTION_CHECKS_ADDED][] | Done | +Testbench | [SIM_TB_ENV_COMPLETED][] | N/A | +Tests | [SIM_ALL_TESTS_PASSING][] | N/A | +Tests | [FPV_ALL_ASSERTIONS_WRITTEN][] | Done | +Tests | [FPV_ALL_ASSUMPTIONS_REVIEWED][] | Done | +Tests | [SIM_FW_SIMULATED][] | N/A | +Regression | [SIM_NIGHTLY_REGRESSION_V2][] | N/A | +Coverage | [SIM_CODE_COVERAGE_V2][] | N/A | +Coverage | [SIM_FUNCTIONAL_COVERAGE_V2][] | N/A | +Coverage | [FPV_CODE_COVERAGE_V2][] | Done | +Coverage | [FPV_COI_COVERAGE_V2][] | Done | +Integration | [PRE_VERIFIED_SUB_MODULES_V2][] | N/A | +Issues | [NO_HIGH_PRIORITY_ISSUES_PENDING][] | Done | +Issues | [ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED][] | Done | +Review | [DV_DOC_TESTPLAN_REVIEWED][] | Not Started | +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][] | Waived | Waived since only 1 standard sec_cm - bus integrity. +Tests | [FPV_SEC_CM_PROVEN][] | Done | The bus integrity cm has been proven formally. +Tests | [SIM_SEC_CM_VERIFIED][] | N/A | This module only has an FPV testbench. +Coverage | [SIM_COVERAGE_REVIEWED][] | N/A | This module only has an FPV testbench. +Review | [SEC_CM_DV_REVIEWED][] | Waived | Waived since only 1 standard sec_cm - bus integrity. + +[SEC_CM_TESTPLAN_COMPLETED]: ../../../../../doc/project_governance/checklist/README.md#sec_cm_testplan_completed +[FPV_SEC_CM_PROVEN]: ../../../../../doc/project_governance/checklist/README.md#fpv_sec_cm_proven +[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/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/README.md b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/README.md new file mode 100644 index 0000000000000..18130a9ce6c30 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/README.md @@ -0,0 +1,48 @@ +# RV_PLIC DV document + +## Goals +* DV: + * RV_PLIC is decided to verify in FPV only + +* FPV: + * Verify all the RV_PLIC outputs by writing assumptions and assertions with a + FPV based testbench + * Verify TileLink device protocol compliance with a FPV based testbench + +## Current status +* [Design & verification stage](../../../../README.md) + * [HW development stages](../../../../../../doc/project_governance/development_stages.md) +* FPV dashboard (link TBD) + +## Design features +For detailed information on RV_PLIC design features, please see the +[RV_PLIC design specification](../../README.md). + +## Testbench architecture +RV_PLIC FPV testbench has been constructed based on the [formal +architecture](../../../../../formal/README.md). + +### Block diagram +![Block diagram](fpv.svg) + +#### TLUL assertions +* The file `rv_plic_bind.sv` binds the `tlul_assert` [assertions](../../../../../ip/tlul/doc/TlulProtocolChecker.md) + to rv_plic to ensure TileLink interface protocol compliance. +* The `hw/rv_plic/fpv/tb/rv_plic_bind.sv` also binds the `rv_plic_csr_assert_fpv` + under `fpv/vip/` to check if TileLink writes and reads correct + CSRs. + +#### RV_PLIC assertions +The file `rv_plic_bind.sv` binds the `rv_plic_assert` under `rv_plic_assert.sv`. +The assertion file ensures RV_PLIC's outputs (`irq_o` and `irq_id_o`) and important signals (`ip`) are being asserted. + +##### Symbolic variables +Due to there are large number of input interrupt sources, the symbolic variable +is used to reduce the number of repeated assertions code. In RV_PLIC, we +declared two symbolic variables `src_sel` and `tgt_sel` to represent the index for +interrupt source and interrupt target. +Detailed explanation is listed in the +[Symbolic Variables](../../../../../formal/README.md#symbolic-variables) section. + +## Testplan +[Testplan](../../data/rv_plic_fpv_testplan.hjson) diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/fpv.svg b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/fpv.svg new file mode 100644 index 0000000000000..2f4cfe0798530 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/dv/fpv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/programmers_guide.md b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/programmers_guide.md new file mode 100644 index 0000000000000..cdbd8f2c62a3a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/programmers_guide.md @@ -0,0 +1,100 @@ +# Programmer's Guide + +## Initialization + +After reset, RV_PLIC doesn't generate any interrupts to any targets even if +interrupt sources are set, as all priorities and thresholds are 0 by default and +all ``IE`` values are 0. Software should configure the above three registers. + +[`PRIO0`](../data/rv_plic.hjson#prio0) .. [`PRIO31`](../data/rv_plic.hjson#prio1) registers are unique. So, only one of the targets +shall configure them. + +```c +// Pseudo-code below +void plic_init() { + // Configure priority + // Note that PRIO0 register doesn't affect as intr_src_i[0] is tied to 0. + for (int i = 0; i < N_SOURCE; ++i) { + *(PRIO + i) = value(i); + } +} + +void plic_threshold(tid, threshold) { + *(THRESHOLD + tid) = threshold; +} + +void plic_enable(tid, iid) { + // iid: 0-based ID + int offset = ceil(N_SOURCE / 32) * tid + (iid >> 5); + + *(IE + offset) = *(IE + offset) | (1 << (iid % 32)); +} +``` + +## Handling Interrupt Request Events + +If software receives an interrupt request, it is recommended to follow the steps +shown below (assuming target 0 which uses [`CC0`](../data/rv_plic.hjson#cc0) for claim/complete). + +1. Claim the interrupts right after entering to the interrupt service routine + by reading the [`CC0`](../data/rv_plic.hjson#cc0) register. +2. Determine which interrupt should be serviced based on the values read from + the [`CC0`](../data/rv_plic.hjson#cc0) register. +3. Execute ISR, clearing the originating peripheral interrupt. +4. Write Interrupt ID to [`CC0`](../data/rv_plic.hjson#cc0) +5. Repeat as necessary for other pending interrupts. + +It is possible to have multiple interrupt events claimed. If software claims one +interrupt request, then the process module advertises any pending interrupts +with lower priority unless new higher priority interrupt events occur. If a +higher interrupt event occurs after previous interrupt is claimed, the RV_PLIC +IP advertises the higher priority interrupt. Software may utilize an event +manager inside a loop so that interrupt claiming and completion can be +separated. + +~~~~c +void interrupt_service() { + uint32_t tid = /* ... */; + uint32_t iid = *(CC + tid); + if (iid == 0) { + // Interrupt is claimed by one of other targets. + return; + } + + do { + // Process interrupts... + // ... + + // Finish. + *(CC + tid) = iid; + iid = *(CC + tid); + } while (iid != 0); +} +~~~~ + +As a reference, default interrupt service routines are auto-generated for each +IP, and are documented [here](/sw/apis/isr__testutils_8h.html). + +## Device Interface Functions (DIFs) + +- [Device Interface Functions](../../../../../sw/device/lib/dif/dif_rv_plic.h) + +## Registers + +The RV_PLIC in the top level is generated by topgen tool so that the number of +interrupt sources may be different. + +- IE: CEILING(N_SOURCE / DW) X N_TARGET + Each bit enables corresponding interrupt source. Each target has IE set. +- PRIO: N_SOURCE + Universal set across all targets. Lower n bits are valid. n is determined by + MAX_PRIO parameter +- THRESHOLD: N_TARGET + Priority threshold per target. Only priority of the interrupt greater than + threshold can raise interrupt notification to the target. +- IP: CEILING(N_SOURCE / DW) + Pending bits right after the gateways. Read-only +- CC: N_TARGET + Claim by read, complete by write + +* [Register Table](../data/rv_plic.hjson#interfaces) diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/theory_of_operation.md b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/theory_of_operation.md new file mode 100644 index 0000000000000..161a7979787cd --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/doc/theory_of_operation.md @@ -0,0 +1,118 @@ +# Theory of Operation + +## Block Diagram + +![RV_PLIC Block Diagram](block_diagram.svg) + +## Hardware Interfaces + +* [Interface Tables](../data/rv_plic.hjson#interfaces) + +## Design Details + +### Identifier + +Each interrupt source has a unique ID assigned based upon its bit position +within the input `intr_src_i`. ID ranges from 0 to N, the number of interrupt +sources. ID 0 is reserved and represents no interrupt. The bit 0 of +`intr_src_i` shall be tied to 0 from the outside of RV_PLIC. The +`intr_src_i[i]` bit has an ID of `i`. This ID is used when targets "claim" the +interrupt and to "complete" the interrupt event. + +### Priority and Threshold + +Interrupt sources have configurable priority values. The maximum value of the +priority is configurable through the localparam `MAX_PRIO` in the rv_plic +top-level module. For each target there is a threshold value ([`THRESHOLD0`](../data/rv_plic.hjson#threshold0) for +target 0). RV_PLIC notifies a target of an interrupt only if it's priority is +strictly greater than the target's threshold. Note this means an interrupt with +a priority is 0 is effectively prevented from causing an interrupt at any target +and a target can suppress all interrupts by setting it's threshold to the max +priority value. + +`MAX_PRIO` parameter is most area contributing option in RV_PLIC. If `MAX_PRIO` +is big, then finding the highest priority in Process module may consume a lot of +logic gates. + +### Interrupt Gateways + +The Gateway observes incoming interrupt sources and converts them to a common +interrupt format used internally by RV_PLIC. It can be parameterized to detect +interrupts events on an edge (when the signal changes from **0** to **1**) or +level basis (where the signal remains at **1**). +The choice is a system-integration decision and can be configured via the design parameter `LevelEdgeTrig` for each interrupt request. + +When the gateway detects an interrupt event it raises the interrupt pending bit +([`IP`](../data/rv_plic.hjson#ip)) for that interrupt source. When an interrupt is claimed by a target the +relevant bit of [`IP`](../data/rv_plic.hjson#ip) is cleared. A bit in [`IP`](../data/rv_plic.hjson#ip) will not be reasserted until the +target signals completion of the interrupt. Any new interrupt event between a +bit in [`IP`](../data/rv_plic.hjson#ip) asserting and completing that interrupt is ignored. In particular +this means that for edge triggered interrupts if a new edge is seen after the +source's [`IP`](../data/rv_plic.hjson#ip) bit is asserted but before completion, that edge will be ignored +(counting missed edges as discussed in the RISC-V PLIC specification is not +supported). + +Note that there is no ability for a level triggered interrupt to be cancelled. +If the interrupt drops after the gateway has set a bit in [`IP`](../data/rv_plic.hjson#ip), the bit will +remain set until the interrupt is completed. The SW handler should be conscious +of this and check the interrupt still requires handling in the handler if this +behaviour is possible. + +### Interrupt Enables + +Each target has a set of Interrupt Enable ([`IE0`](../data/rv_plic.hjson#ie0) for target 0) registers. Each +bit in the [`IE0`](../data/rv_plic.hjson#ie0) registers controls the corresponding interrupt source. If an +interrupt source is disabled for a target, then interrupt events from that +source won't trigger an interrupt at the target. RV_PLIC doesn't have a global +interrupt disable feature. + +### Interrupt Claims + +"Claiming" an interrupt is done by a target reading the associated +Claim/Completion register for the target ([`CC0`](../data/rv_plic.hjson#cc0) for target 0). The return value +of the [`CC0`](../data/rv_plic.hjson#cc0) read represents the ID of the pending interrupt that has the +highest priority. If two or more pending interrupts have the same priority, +RV_PLIC chooses the one with lowest ID. Only interrupts that are enabled +for the target can be claimed. The target priority threshold doesn't matter +(this only factors into whether an interrupt is signalled to the target) so +lower priority interrupt IDs can be returned on a read from [`CC0`](../data/rv_plic.hjson#cc0). If no +interrupt is pending (or all pending interrupts are disabled for the target) a +read of [`CC0`](../data/rv_plic.hjson#cc0) returns an ID of 0. + +### Interrupt Completion + +After an interrupt is claimed, the relevant bit of interrupt pending ([`IP`](../data/rv_plic.hjson#ip)) is +cleared, regardless of the status of the `intr_src_i` input value. Until a +target "completes" the interrupt, it won't be re-asserted if a new event for the +interrupt occurs. A target completes the interrupt by writing the ID of the +interrupt to the Claim/Complete register ([`CC0`](../data/rv_plic.hjson#cc0) for target 0). The write event +is forwarded to the Gateway logic, which resets the interrupt status to accept a +new interrupt event. The assumption is that the processor has cleaned up the +originating interrupt event during the time between claim and complete such that +`intr_src_i[ID]` will have de-asserted (unless a new interrupt has occurred). + +```wavejson +{ signal: [ + { name: 'clk', wave: 'p...........' }, + { name: 'intr_src_i[i]', wave: '01....0.1...', node:'.a....e.f...'}, + { name: 'irq_o', wave: '0.1.0......1', node:'..b.d......h'}, + { name: 'irq_id_o', wave: '=.=.=......=', + data: ["0","i","0","i"] }, + { name: 'claim', wave: '0..10.......', node:'...c........'}, + { name: 'complete', wave: '0.........10', node:'..........g.'}, + ], + head:{ + text: 'Interrupt Flow', + tick: 0, + }, +} +``` + +In the example above an interrupt for source ID `i` is configured as a level +interrupt and is raised at a, this results in the target being notified of the +interrupt at b. The target claims the interrupt at c (reading `i` from it's +Claim/Complete register) so `irq_o` deasserts though `intr_src_i[i]` remains +raised. The SW handles the interrupt and it drops at e. However a new interrupt +quickly occurs at f. As complete hasn't been signaled yet `irq_o` isn't +asserted. At g the interrupt is completed (by writing `i` to it's +Claim/Complete register) so at h `irq_o` is asserted due to the new interrupt. diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_expected_failure.hjson b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_expected_failure.hjson new file mode 100644 index 0000000000000..e77d6989e7b07 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_expected_failure.hjson @@ -0,0 +1,12 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +{ + unreachable: + [ + rv_plic_tb.dut.FpvSecCmRegWeOnehotCheck_A:precondition1 + rv_plic_tb.dut.u_reg.u_prim_reg_we_check.u_prim_onehot_check.Onehot0Check_A:precondition1 + rv_plic_tb.dut.u_reg.u_prim_reg_we_check.u_prim_onehot_check.gen_enable_check.gen_not_strict.EnableCheck_A:precondition1 + ] +} diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_fpv.core b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_fpv.core new file mode 100644 index 0000000000000..18a7980c0e6da --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/rv_plic_fpv.core @@ -0,0 +1,44 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rv_plic_fpv:0.1 +description: "FPV for RISC-V PLIC" + +filesets: + files_formal: + depend: + - lowrisc:ip:tlul + - lowrisc:prim:all + - lowrisc:opentitan:top_englishbreakfast_rv_plic + - lowrisc:fpv:csr_assert_gen + files: + - tb/rv_plic_bind_fpv.sv + - tb/rv_plic_tb.sv + - vip/rv_plic_assert_fpv.sv + file_type: systemVerilogSource + + +generate: + csr_assert_gen: + generator: csr_assert_gen + parameters: + spec: ../data/rv_plic.hjson + depend: lowrisc:opentitan:top_englishbreakfast_rv_plic + +targets: + default: &default_target + # note, this setting is just used + # to generate a file list for jg + default_tool: icarus + filesets: + - files_formal + generate: + - csr_assert_gen + toplevel: rv_plic_tb + + formal: + <<: *default_target + + lint: + <<: *default_target diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_bind_fpv.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_bind_fpv.sv new file mode 100644 index 0000000000000..cfe6c847bda16 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_bind_fpv.sv @@ -0,0 +1,47 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +module rv_plic_bind_fpv; + + import rv_plic_reg_pkg::*; + + bind rv_plic rv_plic_assert_fpv #( + .NumSrc(rv_plic_reg_pkg::NumSrc), + .NumTarget(rv_plic_reg_pkg::NumTarget), + .NumAlerts(rv_plic_reg_pkg::NumAlerts), + .PRIOW(rv_plic_reg_pkg::PrioWidth) + ) rv_plic_assert_fpv( + .clk_i, + .rst_ni, + .intr_src_i, + .alert_rx_i, + .alert_tx_o, + .irq_o, + .irq_id_o, + .msip_o, + .ip, + .ie, + .claim, + .complete, + .prio, + .threshold + ); + + bind rv_plic tlul_assert #( + .EndpointType("Device") + ) tlul_assert_device ( + .clk_i, + .rst_ni, + .h2d (tl_i), + .d2h (tl_o) + ); + + bind rv_plic rv_plic_csr_assert_fpv rv_plic_csr_assert_fpv ( + .clk_i, + .rst_ni, + .h2d (tl_i), + .d2h (tl_o) + ); + +endmodule : rv_plic_bind_fpv diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv new file mode 100644 index 0000000000000..8a64257766d71 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/tb/rv_plic_tb.sv @@ -0,0 +1,40 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Testbench module for rv_plic. Intended to use with a formal tool. + +module rv_plic_tb import rv_plic_reg_pkg::*; #( + // test all implementations + localparam int unsigned NumInstances = 1 +) ( + input clk_i, + input rst_ni, + input tlul_pkg::tl_h2d_t [NumInstances-1:0] tl_i, + output tlul_pkg::tl_d2h_t [NumInstances-1:0] tl_o, + input [NumInstances-1:0][NumSrc-1:0] intr_src_i, + input prim_alert_pkg::alert_rx_t [NumInstances-1:0][NumAlerts-1:0] alert_rx_i, + output prim_alert_pkg::alert_tx_t [NumInstances-1:0][NumAlerts-1:0] alert_tx_o, + output [NumInstances-1:0][NumTarget-1:0] irq_o, + output [$clog2(NumSrc)-1:0] irq_id_o [NumInstances][NumTarget], + output logic [NumInstances-1:0][NumTarget-1:0] msip_o +); + + // TODO: once the PLIC is fully parameterizable in RTL, generate + // several instances with different NumSrc and NumTarget configs here + // (in a similar way as this has been done in prim_lfsr_fpv) + // for (genvar k = 0; k < NumInstances; k++) begin : geNumInstances + rv_plic dut ( + .clk_i , + .rst_ni , + .tl_i (tl_i[0]), + .tl_o (tl_o[0]), + .intr_src_i (intr_src_i[0]), + .alert_rx_i (alert_rx_i[0]), + .alert_tx_o (alert_tx_o[0]), + .irq_o (irq_o[0]), + .irq_id_o (irq_id_o[0]), + .msip_o (msip_o[0]) + ); + +endmodule : rv_plic_tb diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/vip/rv_plic_assert_fpv.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/vip/rv_plic_assert_fpv.sv new file mode 100644 index 0000000000000..fb09709fe0bcf --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/fpv/vip/rv_plic_assert_fpv.sv @@ -0,0 +1,107 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// Testbench module for rv_plic. Intended to use with a formal tool. + +`include "prim_assert.sv" + +module rv_plic_assert_fpv #(parameter int NumSrc = 1, + parameter int NumTarget = 1, + parameter int NumAlerts = 1, + parameter int PRIOW = $clog2(7+1) +) ( + input clk_i, + input rst_ni, + input [NumSrc-1:0] intr_src_i, + input prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i, + input prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o, + input [NumTarget-1:0] irq_o, + input [$clog2(NumSrc)-1:0] irq_id_o [NumTarget], + input [NumTarget-1:0] msip_o, + // probe design signals + input [NumSrc-1:0] ip, + input [NumSrc-1:0] ie [NumTarget], + input [NumSrc-1:0] claim, + input [NumSrc-1:0] complete, + input [NumSrc-1:0][PRIOW-1:0] prio, + input [PRIOW-1:0] threshold [NumTarget] +); + + localparam int SrcIdxWidth = NumSrc > 1 ? $clog2(NumSrc - 1) : 1; + localparam int TgtIdxWidth = NumTarget > 1 ? $clog2(NumTarget - 1) : 1; + + logic claim_reg, claimed; + logic max_priority; + logic irq; + logic [$clog2(NumSrc)-1:0] i_high_prio; + + // symbolic variables + bit [SrcIdxWidth-1:0] src_sel; + bit [TgtIdxWidth-1:0] tgt_sel; + + `ASSUME_FPV(IsrcRange_M, src_sel > 0 && src_sel < NumSrc, clk_i, !rst_ni) + `ASSUME_FPV(ItgtRange_M, tgt_sel >= 0 && tgt_sel < NumTarget, clk_i, !rst_ni) + `ASSUME_FPV(IsrcStable_M, ##1 $stable(src_sel), clk_i, !rst_ni) + `ASSUME_FPV(ItgtStable_M, ##1 $stable(tgt_sel), clk_i, !rst_ni) + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + claim_reg <= 1'b0; + end else if (claim[src_sel]) begin + claim_reg <= 1'b1; + end else if (complete[src_sel]) begin + claim_reg <= 1'b0; + end + end + + assign claimed = claim_reg || claim[src_sel]; + + always_comb begin + max_priority = 1'b1; + for (int i = 0; i < NumSrc; i++) begin + // conditions that if src_sel has the highest priority with the lowest ID + if (i != src_sel && ip[i] && ie[tgt_sel][i] && + (prio[i] > prio[src_sel] || (prio[i] == prio[src_sel] && i < src_sel))) begin + max_priority = 1'b0; + break; + end + end + end + + always_comb begin + automatic logic [31:0] max_prio = 0; + for (int i = NumSrc-1; i >= 0; i--) begin + if (ip[i] && ie[tgt_sel][i] && prio[i] >= max_prio) begin + max_prio = prio[i]; + i_high_prio = i; // i is the smallest id if have IPs with the same priority + end + end + if (max_prio > threshold[tgt_sel]) irq = 1'b1; + else irq = 1'b0; + end + + // when IP is set, previous cycle should follow edge or level triggered criteria + `ASSERT(LevelTriggeredIp_A, ##3 $rose(ip[src_sel]) |-> $past(intr_src_i[src_sel], 3)) + + // when interrupt is trigger, and nothing claimed yet, then next cycle should assert IP. + `ASSERT(LevelTriggeredIpWithClaim_A, ##2 $past(intr_src_i[src_sel], 2) && + !claimed |=> ip[src_sel]) + + // ip stays stable until claimed, reset to 0 after claimed, and stays 0 until complete + `ASSERT(IpStableAfterTriggered_A, ip[src_sel] && !claimed |=> ip[src_sel]) + `ASSERT(IpClearAfterClaim_A, ip[src_sel] && claim[src_sel] |=> !ip[src_sel]) + `ASSERT(IpStableAfterClaimed_A, claimed |=> !ip[src_sel]) + + // when ip is set and priority is the largest and above threshold, and interrupt enable is set, + // assertion irq_o at next cycle + `ASSERT(TriggerIrqForwardCheck_A, ip[src_sel] && prio[src_sel] > threshold[tgt_sel] && + max_priority && ie[tgt_sel][src_sel] |=> irq_o[tgt_sel]) + + `ASSERT(TriggerIrqBackwardCheck_A, $rose(irq_o[tgt_sel]) |-> + $past(irq) && (irq_id_o[tgt_sel] == $past(i_high_prio))) + + // when irq ID changed, but not to ID=0, irq_o should be high, or irq represents the largest prio + // but smaller than the threshold + `ASSERT(IdChangeWithIrq_A, !$stable(irq_id_o[tgt_sel]) && irq_id_o[tgt_sel] != 0 |-> + irq_o[tgt_sel] || ((irq_id_o[tgt_sel]) == $past(i_high_prio) && !$past(irq))) +endmodule : rv_plic_assert_fpv diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.vlt b/hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.vlt new file mode 100644 index 0000000000000..f9318e609c6c4 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.vlt @@ -0,0 +1,7 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// waiver file for rv_plic + +`verilator_config diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.waiver b/hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.waiver new file mode 100644 index 0000000000000..9e84bd9021205 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/lint/rv_plic.waiver @@ -0,0 +1,22 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +# +# waiver file for Platform-Level Interrupt Controller + +waive -rules ONE_BIT_MEM_WIDTH -location {rv_plic.sv} -regexp {Memory '(claim_re|complete_we)' has} \ + -comment "N_TARGET can be 1." + +waive -rules VAR_INDEX_RANGE -location {rv_plic.sv} -regexp {(claim_id|complete_id).* (maximum|minimum) value} \ + -comment "Claim ID is guarded inside target module, complete ID has undeterministic behavior if FW writes OOR value" + +waive -rules HIER_NET_NOT_READ -location {rv_plic.sv} -regexp {[Nn]et 'tl_[io]\.[ad]_(address|param|user)} \ + -comment "Register interface doesn't use upper address and param, user filed" + +waive -rules EXPLICIT_BITLEN -location {rv_plic_target.sv} -regexp {Bit length .* '1'} \ + -comment "i + 1 is assumed as constant and guarded by SRCW" +waive -rules INTEGER -location {rv_plic_target.sv} -regexp {'i' of type int used as} \ + -comment "int i is static and only assigned to irq_id_next when it hits condition" + +waive -rules TWOS_COMP -location {rv_plic_target.sv} -regexp {Explicit two's complement with terms} \ + -comment "This is permissible in this context" diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv new file mode 100644 index 0000000000000..56079bfa0a27f --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic.sv @@ -0,0 +1,362 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// RISC-V Platform-Level Interrupt Controller compliant INTC +// +// Current version doesn't support MSI interrupt but it is easy to add +// the feature. Create one external register and connect qe signal to the +// gateway module (as edge-triggered) +// +// Consider to set MAX_PRIO as small number as possible. It is main factor +// of area increase if edge-triggered counter isn't implemented. +// +// Verilog parameter +// MAX_PRIO: Maximum value of interrupt priority + +`include "prim_assert.sv" + +module rv_plic import rv_plic_reg_pkg::*; #( + parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}, + // OpenTitan IP standardizes on level triggered interrupts, + // hence LevelEdgeTrig is set to all-zeroes by default. + // Note that in case of edge-triggered interrupts, CDC handling is not + // fully implemented yet (this would require instantiating pulse syncs + // and routing the source clocks / resets to the PLIC). + parameter logic [NumSrc-1:0] LevelEdgeTrig = '0, // 0: level, 1: edge + // derived parameter + localparam int SRCW = $clog2(NumSrc) +) ( + input clk_i, + input rst_ni, + + // Bus Interface (device) + input tlul_pkg::tl_h2d_t tl_i, + output tlul_pkg::tl_d2h_t tl_o, + + // Interrupt Sources + input [NumSrc-1:0] intr_src_i, + + // 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, + + // Interrupt notification to targets + output [NumTarget-1:0] irq_o, + output [SRCW-1:0] irq_id_o [NumTarget], + + output logic [NumTarget-1:0] msip_o +); + + rv_plic_reg2hw_t reg2hw; + rv_plic_hw2reg_t hw2reg; + + localparam int MAX_PRIO = 3; + localparam int PRIOW = $clog2(MAX_PRIO+1); + + logic [NumSrc-1:0] ip; + + logic [NumSrc-1:0] ie [NumTarget]; + + logic [NumTarget-1:0] claim_re; // Target read indicator + logic [SRCW-1:0] claim_id [NumTarget]; + logic [NumSrc-1:0] claim; // Converted from claim_re/claim_id + + logic [NumTarget-1:0] complete_we; // Target write indicator + logic [SRCW-1:0] complete_id [NumTarget]; + logic [NumSrc-1:0] complete; // Converted from complete_re/complete_id + + logic [SRCW-1:0] cc_id [NumTarget]; // Write ID + + logic [NumSrc-1:0][PRIOW-1:0] prio; + + logic [PRIOW-1:0] threshold [NumTarget]; + + // Glue logic between rv_plic_reg_top and others + assign cc_id = irq_id_o; + + always_comb begin + claim = '0; + for (int i = 0 ; i < NumTarget ; i++) begin + if (claim_re[i]) claim[claim_id[i]] = 1'b1; + end + end + always_comb begin + complete = '0; + for (int i = 0 ; i < NumTarget ; i++) begin + if (complete_we[i]) complete[complete_id[i]] = 1'b1; + end + end + + //`ASSERT_PULSE(claimPulse, claim_re[i]) + //`ASSERT_PULSE(completePulse, complete_we[i]) + + `ASSERT(onehot0Claim, $onehot0(claim_re)) + + `ASSERT(onehot0Complete, $onehot0(complete_we)) + + ////////////// + // Priority // + ////////////// + assign prio[0] = reg2hw.prio0.q; + assign prio[1] = reg2hw.prio1.q; + assign prio[2] = reg2hw.prio2.q; + assign prio[3] = reg2hw.prio3.q; + assign prio[4] = reg2hw.prio4.q; + assign prio[5] = reg2hw.prio5.q; + assign prio[6] = reg2hw.prio6.q; + assign prio[7] = reg2hw.prio7.q; + assign prio[8] = reg2hw.prio8.q; + assign prio[9] = reg2hw.prio9.q; + assign prio[10] = reg2hw.prio10.q; + assign prio[11] = reg2hw.prio11.q; + assign prio[12] = reg2hw.prio12.q; + assign prio[13] = reg2hw.prio13.q; + assign prio[14] = reg2hw.prio14.q; + assign prio[15] = reg2hw.prio15.q; + assign prio[16] = reg2hw.prio16.q; + assign prio[17] = reg2hw.prio17.q; + assign prio[18] = reg2hw.prio18.q; + assign prio[19] = reg2hw.prio19.q; + assign prio[20] = reg2hw.prio20.q; + assign prio[21] = reg2hw.prio21.q; + assign prio[22] = reg2hw.prio22.q; + assign prio[23] = reg2hw.prio23.q; + assign prio[24] = reg2hw.prio24.q; + assign prio[25] = reg2hw.prio25.q; + assign prio[26] = reg2hw.prio26.q; + assign prio[27] = reg2hw.prio27.q; + assign prio[28] = reg2hw.prio28.q; + assign prio[29] = reg2hw.prio29.q; + assign prio[30] = reg2hw.prio30.q; + assign prio[31] = reg2hw.prio31.q; + assign prio[32] = reg2hw.prio32.q; + assign prio[33] = reg2hw.prio33.q; + assign prio[34] = reg2hw.prio34.q; + assign prio[35] = reg2hw.prio35.q; + assign prio[36] = reg2hw.prio36.q; + assign prio[37] = reg2hw.prio37.q; + assign prio[38] = reg2hw.prio38.q; + assign prio[39] = reg2hw.prio39.q; + assign prio[40] = reg2hw.prio40.q; + assign prio[41] = reg2hw.prio41.q; + assign prio[42] = reg2hw.prio42.q; + assign prio[43] = reg2hw.prio43.q; + assign prio[44] = reg2hw.prio44.q; + assign prio[45] = reg2hw.prio45.q; + assign prio[46] = reg2hw.prio46.q; + assign prio[47] = reg2hw.prio47.q; + assign prio[48] = reg2hw.prio48.q; + assign prio[49] = reg2hw.prio49.q; + assign prio[50] = reg2hw.prio50.q; + assign prio[51] = reg2hw.prio51.q; + assign prio[52] = reg2hw.prio52.q; + assign prio[53] = reg2hw.prio53.q; + assign prio[54] = reg2hw.prio54.q; + assign prio[55] = reg2hw.prio55.q; + assign prio[56] = reg2hw.prio56.q; + assign prio[57] = reg2hw.prio57.q; + assign prio[58] = reg2hw.prio58.q; + assign prio[59] = reg2hw.prio59.q; + assign prio[60] = reg2hw.prio60.q; + assign prio[61] = reg2hw.prio61.q; + assign prio[62] = reg2hw.prio62.q; + assign prio[63] = reg2hw.prio63.q; + assign prio[64] = reg2hw.prio64.q; + assign prio[65] = reg2hw.prio65.q; + assign prio[66] = reg2hw.prio66.q; + assign prio[67] = reg2hw.prio67.q; + assign prio[68] = reg2hw.prio68.q; + assign prio[69] = reg2hw.prio69.q; + assign prio[70] = reg2hw.prio70.q; + assign prio[71] = reg2hw.prio71.q; + assign prio[72] = reg2hw.prio72.q; + assign prio[73] = reg2hw.prio73.q; + assign prio[74] = reg2hw.prio74.q; + assign prio[75] = reg2hw.prio75.q; + assign prio[76] = reg2hw.prio76.q; + assign prio[77] = reg2hw.prio77.q; + assign prio[78] = reg2hw.prio78.q; + assign prio[79] = reg2hw.prio79.q; + assign prio[80] = reg2hw.prio80.q; + assign prio[81] = reg2hw.prio81.q; + assign prio[82] = reg2hw.prio82.q; + assign prio[83] = reg2hw.prio83.q; + assign prio[84] = reg2hw.prio84.q; + assign prio[85] = reg2hw.prio85.q; + assign prio[86] = reg2hw.prio86.q; + assign prio[87] = reg2hw.prio87.q; + + ////////////////////// + // Interrupt Enable // + ////////////////////// + for (genvar s = 0; s < 88; s++) begin : gen_ie0 + assign ie[0][s] = reg2hw.ie0[s].q; + end + + //////////////////////// + // THRESHOLD register // + //////////////////////// + assign threshold[0] = reg2hw.threshold0.q; + + ///////////////// + // CC register // + ///////////////// + assign claim_re[0] = reg2hw.cc0.re; + assign claim_id[0] = irq_id_o[0]; + assign complete_we[0] = reg2hw.cc0.qe; + assign complete_id[0] = reg2hw.cc0.q; + assign hw2reg.cc0.d = cc_id[0]; + + /////////////////// + // MSIP register // + /////////////////// + assign msip_o[0] = reg2hw.msip0.q; + + //////// + // IP // + //////// + for (genvar s = 0; s < 88; s++) begin : gen_ip + assign hw2reg.ip[s].de = 1'b1; // Always write + assign hw2reg.ip[s].d = ip[s]; + end + + ////////////// + // Gateways // + ////////////// + + // Synchronize all incoming interrupt requests. + logic [NumSrc-1:0] intr_src_synced; + prim_flop_2sync #( + .Width(NumSrc) + ) u_prim_flop_2sync ( + .clk_i, + .rst_ni, + .d_i(intr_src_i), + .q_o(intr_src_synced) + ); + + rv_plic_gateway #( + .N_SOURCE (NumSrc) + ) u_gateway ( + .clk_i, + .rst_ni, + + .src_i (intr_src_synced), + .le_i (LevelEdgeTrig), + + .claim_i (claim), + .complete_i (complete), + + .ip_o (ip) + ); + + /////////////////////////////////// + // Target interrupt notification // + /////////////////////////////////// + for (genvar i = 0 ; i < NumTarget ; i++) begin : gen_target + rv_plic_target #( + .N_SOURCE (NumSrc), + .MAX_PRIO (MAX_PRIO) + ) u_target ( + .clk_i, + .rst_ni, + + .ip_i (ip), + .ie_i (ie[i]), + + .prio_i (prio), + .threshold_i (threshold[i]), + + .irq_o (irq_o[i]), + .irq_id_o (irq_id_o[i]) + + ); + end + + //////////// + // Alerts // + //////////// + + logic [NumAlerts-1:0] alert_test, alerts; + + assign alert_test = { + reg2hw.alert_test.q & + reg2hw.alert_test.qe + }; + + 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, + .rst_ni, + .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 + + //////////////////////// + // Register interface // + //////////////////////// + // Limitation of register tool prevents the module from having flexibility to parameters + // So, signals are manually tied at the top. + rv_plic_reg_top u_reg ( + .clk_i, + .rst_ni, + + .tl_i, + .tl_o, + + .reg2hw, + .hw2reg, + + // SEC_CM: BUS.INTEGRITY + .intg_err_o(alerts[0]) + ); + + // Assertions + `ASSERT_KNOWN(TlDValidKnownO_A, tl_o.d_valid) + `ASSERT_KNOWN(TlAReadyKnownO_A, tl_o.a_ready) + `ASSERT_KNOWN(IrqKnownO_A, irq_o) + `ASSERT_KNOWN(MsipKnownO_A, msip_o) + for (genvar k = 0; k < NumTarget; k++) begin : gen_irq_id_known + `ASSERT_KNOWN(IrqIdKnownO_A, irq_id_o[k]) + end + + // Assume + `ASSUME(Irq0Tied_A, intr_src_i[0] == 1'b0) + + // This assertion should be provable in FPV because we don't have a block-level DV environment. It + // is trying to say that any integrity error detected inside the register block (u_reg) will cause + // an alert to be asserted within at most _SEC_CM_ALERT_MAX_CYC cycles. + // + // This isn't *quite* true because there are two extra requirements for prim_alert_sender to send + // an alert with alert_p high: + // + // - The multi-phase alert handshake might not be in the expected phase. Rather than adding an + // assumption that says alert_rx_i acks a signal when it is raised, we cheat and add a + // precondition about the initial state of the prim_alert_sender FSM, guaranteeing that we're + // not waiting for an ack. + // + // - The prim_alert_sender musn't detect a signal integrity issue on the alert signal coming in + // (alert_rx_i). Normally FpvSecCm tests get analysed with an FPV_ALERT_NO_SIGINT_ERR define, + // but we don't have that defined here. To avoid this happening, we want an assertion of the + // form "If no integrity error is detected for _SEC_CM_ALERT_MAX_CYC cycles, the alert_p signal + // must go high". To encode this cleanly in SVA, we actually say "We can't have neither an + // integrity error nor an alert signal for too many cycles". + `ASSERT(FpvSecCmBusIntegrity_A, + ($rose(u_reg.intg_err) && + gen_alert_tx[0].u_prim_alert_sender.state_q == gen_alert_tx[0].u_prim_alert_sender.Idle) + |-> + not ((!gen_alert_tx[0].u_prim_alert_sender.sigint_detected && !alert_tx_o[0].alert_p) + [*`_SEC_CM_ALERT_MAX_CYC])) + + // Alert assertions for reg_we onehot check + `ASSERT_PRIM_REG_WE_ONEHOT_ERROR_TRIGGER_ALERT(RegWeOnehotCheck_A, u_reg, alert_tx_o[0]) +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_gateway.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_gateway.sv new file mode 100644 index 0000000000000..aed8d4c9ad2ff --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_gateway.sv @@ -0,0 +1,62 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// RISC-V Platform-Level Interrupt Gateways module + +module rv_plic_gateway #( + parameter int N_SOURCE = 32 +) ( + input clk_i, + input rst_ni, + + input [N_SOURCE-1:0] src_i, + input [N_SOURCE-1:0] le_i, // Level0 Edge1 + + input [N_SOURCE-1:0] claim_i, // $onehot0(claim_i) + input [N_SOURCE-1:0] complete_i, // $onehot0(complete_i) + + output logic [N_SOURCE-1:0] ip_o +); + + logic [N_SOURCE-1:0] ia; // Interrupt Active + + logic [N_SOURCE-1:0] set; // Set: (le_i) ? src_i & ~src_q : src_i ; + logic [N_SOURCE-1:0] src_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) src_q <= '0; + else src_q <= src_i; + end + + always_comb begin + for (int i = 0 ; i < N_SOURCE; i++) begin + set[i] = (le_i[i]) ? src_i[i] & ~src_q[i] : src_i[i] ; + end + end + + // Interrupt pending is set by source (depends on le_i), cleared by claim_i. + // Until interrupt is claimed, set doesn't affect ip_o. + // RISC-V PLIC spec mentioned it can have counter for edge triggered + // But skipped the feature as counter consumes substantial logic size. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + ip_o <= '0; + end else begin + ip_o <= (ip_o | (set & ~ia & ~ip_o)) & (~(ip_o & claim_i)); + end + end + + // Interrupt active is to control ip_o. If ip_o is set then until completed + // by target, ip_o shouldn't be set by source even claim_i can clear ip_o. + // ia can be cleared only when ia was set. If `set` and `complete_i` happen + // at the same time, always `set` wins. + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + ia <= '0; + end else begin + ia <= (ia | (set & ~ia)) & (~(ia & complete_i & ~ip_o)); + end + end + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv new file mode 100644 index 0000000000000..f8d485d35f7af --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_pkg.sv @@ -0,0 +1,817 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 rv_plic_reg_pkg; + + // Param list + parameter int NumSrc = 88; + parameter int NumTarget = 1; + parameter int PrioWidth = 2; + parameter int NumAlerts = 1; + + // Address widths within the block + parameter int BlockAw = 27; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio0_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio1_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio2_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio3_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio4_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio5_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio6_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio7_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio8_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio9_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio10_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio11_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio12_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio13_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio14_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio15_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio16_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio17_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio18_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio19_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio20_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio21_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio22_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio23_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio24_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio25_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio26_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio27_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio28_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio29_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio30_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio31_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio32_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio33_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio34_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio35_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio36_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio37_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio38_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio39_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio40_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio41_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio42_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio43_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio44_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio45_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio46_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio47_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio48_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio49_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio50_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio51_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio52_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio53_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio54_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio55_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio56_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio57_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio58_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio59_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio60_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio61_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio62_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio63_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio64_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio65_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio66_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio67_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio68_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio69_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio70_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio71_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio72_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio73_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio74_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio75_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio76_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio77_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio78_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio79_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio80_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio81_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio82_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio83_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio84_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio85_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio86_reg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_prio87_reg_t; + + typedef struct packed { + logic q; + } rv_plic_reg2hw_ie0_mreg_t; + + typedef struct packed { + logic [1:0] q; + } rv_plic_reg2hw_threshold0_reg_t; + + typedef struct packed { + logic [6:0] q; + logic qe; + logic re; + } rv_plic_reg2hw_cc0_reg_t; + + typedef struct packed { + logic q; + } rv_plic_reg2hw_msip0_reg_t; + + typedef struct packed { + logic q; + logic qe; + } rv_plic_reg2hw_alert_test_reg_t; + + typedef struct packed { + logic d; + logic de; + } rv_plic_hw2reg_ip_mreg_t; + + typedef struct packed { + logic [6:0] d; + } rv_plic_hw2reg_cc0_reg_t; + + // Register -> HW type + typedef struct packed { + rv_plic_reg2hw_prio0_reg_t prio0; // [277:276] + rv_plic_reg2hw_prio1_reg_t prio1; // [275:274] + rv_plic_reg2hw_prio2_reg_t prio2; // [273:272] + rv_plic_reg2hw_prio3_reg_t prio3; // [271:270] + rv_plic_reg2hw_prio4_reg_t prio4; // [269:268] + rv_plic_reg2hw_prio5_reg_t prio5; // [267:266] + rv_plic_reg2hw_prio6_reg_t prio6; // [265:264] + rv_plic_reg2hw_prio7_reg_t prio7; // [263:262] + rv_plic_reg2hw_prio8_reg_t prio8; // [261:260] + rv_plic_reg2hw_prio9_reg_t prio9; // [259:258] + rv_plic_reg2hw_prio10_reg_t prio10; // [257:256] + rv_plic_reg2hw_prio11_reg_t prio11; // [255:254] + rv_plic_reg2hw_prio12_reg_t prio12; // [253:252] + rv_plic_reg2hw_prio13_reg_t prio13; // [251:250] + rv_plic_reg2hw_prio14_reg_t prio14; // [249:248] + rv_plic_reg2hw_prio15_reg_t prio15; // [247:246] + rv_plic_reg2hw_prio16_reg_t prio16; // [245:244] + rv_plic_reg2hw_prio17_reg_t prio17; // [243:242] + rv_plic_reg2hw_prio18_reg_t prio18; // [241:240] + rv_plic_reg2hw_prio19_reg_t prio19; // [239:238] + rv_plic_reg2hw_prio20_reg_t prio20; // [237:236] + rv_plic_reg2hw_prio21_reg_t prio21; // [235:234] + rv_plic_reg2hw_prio22_reg_t prio22; // [233:232] + rv_plic_reg2hw_prio23_reg_t prio23; // [231:230] + rv_plic_reg2hw_prio24_reg_t prio24; // [229:228] + rv_plic_reg2hw_prio25_reg_t prio25; // [227:226] + rv_plic_reg2hw_prio26_reg_t prio26; // [225:224] + rv_plic_reg2hw_prio27_reg_t prio27; // [223:222] + rv_plic_reg2hw_prio28_reg_t prio28; // [221:220] + rv_plic_reg2hw_prio29_reg_t prio29; // [219:218] + rv_plic_reg2hw_prio30_reg_t prio30; // [217:216] + rv_plic_reg2hw_prio31_reg_t prio31; // [215:214] + rv_plic_reg2hw_prio32_reg_t prio32; // [213:212] + rv_plic_reg2hw_prio33_reg_t prio33; // [211:210] + rv_plic_reg2hw_prio34_reg_t prio34; // [209:208] + rv_plic_reg2hw_prio35_reg_t prio35; // [207:206] + rv_plic_reg2hw_prio36_reg_t prio36; // [205:204] + rv_plic_reg2hw_prio37_reg_t prio37; // [203:202] + rv_plic_reg2hw_prio38_reg_t prio38; // [201:200] + rv_plic_reg2hw_prio39_reg_t prio39; // [199:198] + rv_plic_reg2hw_prio40_reg_t prio40; // [197:196] + rv_plic_reg2hw_prio41_reg_t prio41; // [195:194] + rv_plic_reg2hw_prio42_reg_t prio42; // [193:192] + rv_plic_reg2hw_prio43_reg_t prio43; // [191:190] + rv_plic_reg2hw_prio44_reg_t prio44; // [189:188] + rv_plic_reg2hw_prio45_reg_t prio45; // [187:186] + rv_plic_reg2hw_prio46_reg_t prio46; // [185:184] + rv_plic_reg2hw_prio47_reg_t prio47; // [183:182] + rv_plic_reg2hw_prio48_reg_t prio48; // [181:180] + rv_plic_reg2hw_prio49_reg_t prio49; // [179:178] + rv_plic_reg2hw_prio50_reg_t prio50; // [177:176] + rv_plic_reg2hw_prio51_reg_t prio51; // [175:174] + rv_plic_reg2hw_prio52_reg_t prio52; // [173:172] + rv_plic_reg2hw_prio53_reg_t prio53; // [171:170] + rv_plic_reg2hw_prio54_reg_t prio54; // [169:168] + rv_plic_reg2hw_prio55_reg_t prio55; // [167:166] + rv_plic_reg2hw_prio56_reg_t prio56; // [165:164] + rv_plic_reg2hw_prio57_reg_t prio57; // [163:162] + rv_plic_reg2hw_prio58_reg_t prio58; // [161:160] + rv_plic_reg2hw_prio59_reg_t prio59; // [159:158] + rv_plic_reg2hw_prio60_reg_t prio60; // [157:156] + rv_plic_reg2hw_prio61_reg_t prio61; // [155:154] + rv_plic_reg2hw_prio62_reg_t prio62; // [153:152] + rv_plic_reg2hw_prio63_reg_t prio63; // [151:150] + rv_plic_reg2hw_prio64_reg_t prio64; // [149:148] + rv_plic_reg2hw_prio65_reg_t prio65; // [147:146] + rv_plic_reg2hw_prio66_reg_t prio66; // [145:144] + rv_plic_reg2hw_prio67_reg_t prio67; // [143:142] + rv_plic_reg2hw_prio68_reg_t prio68; // [141:140] + rv_plic_reg2hw_prio69_reg_t prio69; // [139:138] + rv_plic_reg2hw_prio70_reg_t prio70; // [137:136] + rv_plic_reg2hw_prio71_reg_t prio71; // [135:134] + rv_plic_reg2hw_prio72_reg_t prio72; // [133:132] + rv_plic_reg2hw_prio73_reg_t prio73; // [131:130] + rv_plic_reg2hw_prio74_reg_t prio74; // [129:128] + rv_plic_reg2hw_prio75_reg_t prio75; // [127:126] + rv_plic_reg2hw_prio76_reg_t prio76; // [125:124] + rv_plic_reg2hw_prio77_reg_t prio77; // [123:122] + rv_plic_reg2hw_prio78_reg_t prio78; // [121:120] + rv_plic_reg2hw_prio79_reg_t prio79; // [119:118] + rv_plic_reg2hw_prio80_reg_t prio80; // [117:116] + rv_plic_reg2hw_prio81_reg_t prio81; // [115:114] + rv_plic_reg2hw_prio82_reg_t prio82; // [113:112] + rv_plic_reg2hw_prio83_reg_t prio83; // [111:110] + rv_plic_reg2hw_prio84_reg_t prio84; // [109:108] + rv_plic_reg2hw_prio85_reg_t prio85; // [107:106] + rv_plic_reg2hw_prio86_reg_t prio86; // [105:104] + rv_plic_reg2hw_prio87_reg_t prio87; // [103:102] + rv_plic_reg2hw_ie0_mreg_t [87:0] ie0; // [101:14] + rv_plic_reg2hw_threshold0_reg_t threshold0; // [13:12] + rv_plic_reg2hw_cc0_reg_t cc0; // [11:3] + rv_plic_reg2hw_msip0_reg_t msip0; // [2:2] + rv_plic_reg2hw_alert_test_reg_t alert_test; // [1:0] + } rv_plic_reg2hw_t; + + // HW -> register type + typedef struct packed { + rv_plic_hw2reg_ip_mreg_t [87:0] ip; // [182:7] + rv_plic_hw2reg_cc0_reg_t cc0; // [6:0] + } rv_plic_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] RV_PLIC_PRIO0_OFFSET = 27'h 0; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO1_OFFSET = 27'h 4; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO2_OFFSET = 27'h 8; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO3_OFFSET = 27'h c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO4_OFFSET = 27'h 10; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO5_OFFSET = 27'h 14; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO6_OFFSET = 27'h 18; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO7_OFFSET = 27'h 1c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO8_OFFSET = 27'h 20; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO9_OFFSET = 27'h 24; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO10_OFFSET = 27'h 28; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO11_OFFSET = 27'h 2c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO12_OFFSET = 27'h 30; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO13_OFFSET = 27'h 34; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO14_OFFSET = 27'h 38; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO15_OFFSET = 27'h 3c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO16_OFFSET = 27'h 40; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO17_OFFSET = 27'h 44; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO18_OFFSET = 27'h 48; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO19_OFFSET = 27'h 4c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO20_OFFSET = 27'h 50; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO21_OFFSET = 27'h 54; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO22_OFFSET = 27'h 58; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO23_OFFSET = 27'h 5c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO24_OFFSET = 27'h 60; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO25_OFFSET = 27'h 64; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO26_OFFSET = 27'h 68; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO27_OFFSET = 27'h 6c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO28_OFFSET = 27'h 70; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO29_OFFSET = 27'h 74; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO30_OFFSET = 27'h 78; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO31_OFFSET = 27'h 7c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO32_OFFSET = 27'h 80; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO33_OFFSET = 27'h 84; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO34_OFFSET = 27'h 88; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO35_OFFSET = 27'h 8c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO36_OFFSET = 27'h 90; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO37_OFFSET = 27'h 94; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO38_OFFSET = 27'h 98; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO39_OFFSET = 27'h 9c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO40_OFFSET = 27'h a0; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO41_OFFSET = 27'h a4; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO42_OFFSET = 27'h a8; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO43_OFFSET = 27'h ac; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO44_OFFSET = 27'h b0; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO45_OFFSET = 27'h b4; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO46_OFFSET = 27'h b8; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO47_OFFSET = 27'h bc; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO48_OFFSET = 27'h c0; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO49_OFFSET = 27'h c4; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO50_OFFSET = 27'h c8; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO51_OFFSET = 27'h cc; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO52_OFFSET = 27'h d0; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO53_OFFSET = 27'h d4; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO54_OFFSET = 27'h d8; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO55_OFFSET = 27'h dc; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO56_OFFSET = 27'h e0; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO57_OFFSET = 27'h e4; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO58_OFFSET = 27'h e8; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO59_OFFSET = 27'h ec; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO60_OFFSET = 27'h f0; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO61_OFFSET = 27'h f4; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO62_OFFSET = 27'h f8; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO63_OFFSET = 27'h fc; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO64_OFFSET = 27'h 100; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO65_OFFSET = 27'h 104; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO66_OFFSET = 27'h 108; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO67_OFFSET = 27'h 10c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO68_OFFSET = 27'h 110; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO69_OFFSET = 27'h 114; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO70_OFFSET = 27'h 118; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO71_OFFSET = 27'h 11c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO72_OFFSET = 27'h 120; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO73_OFFSET = 27'h 124; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO74_OFFSET = 27'h 128; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO75_OFFSET = 27'h 12c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO76_OFFSET = 27'h 130; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO77_OFFSET = 27'h 134; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO78_OFFSET = 27'h 138; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO79_OFFSET = 27'h 13c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO80_OFFSET = 27'h 140; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO81_OFFSET = 27'h 144; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO82_OFFSET = 27'h 148; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO83_OFFSET = 27'h 14c; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO84_OFFSET = 27'h 150; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO85_OFFSET = 27'h 154; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO86_OFFSET = 27'h 158; + parameter logic [BlockAw-1:0] RV_PLIC_PRIO87_OFFSET = 27'h 15c; + parameter logic [BlockAw-1:0] RV_PLIC_IP_0_OFFSET = 27'h 1000; + parameter logic [BlockAw-1:0] RV_PLIC_IP_1_OFFSET = 27'h 1004; + parameter logic [BlockAw-1:0] RV_PLIC_IP_2_OFFSET = 27'h 1008; + parameter logic [BlockAw-1:0] RV_PLIC_IE0_0_OFFSET = 27'h 2000; + parameter logic [BlockAw-1:0] RV_PLIC_IE0_1_OFFSET = 27'h 2004; + parameter logic [BlockAw-1:0] RV_PLIC_IE0_2_OFFSET = 27'h 2008; + parameter logic [BlockAw-1:0] RV_PLIC_THRESHOLD0_OFFSET = 27'h 200000; + parameter logic [BlockAw-1:0] RV_PLIC_CC0_OFFSET = 27'h 200004; + parameter logic [BlockAw-1:0] RV_PLIC_MSIP0_OFFSET = 27'h 4000000; + parameter logic [BlockAw-1:0] RV_PLIC_ALERT_TEST_OFFSET = 27'h 4004000; + + // Reset values for hwext registers and their fields + parameter logic [6:0] RV_PLIC_CC0_RESVAL = 7'h 0; + parameter logic [0:0] RV_PLIC_ALERT_TEST_RESVAL = 1'h 0; + + // Register index + typedef enum int { + RV_PLIC_PRIO0, + RV_PLIC_PRIO1, + RV_PLIC_PRIO2, + RV_PLIC_PRIO3, + RV_PLIC_PRIO4, + RV_PLIC_PRIO5, + RV_PLIC_PRIO6, + RV_PLIC_PRIO7, + RV_PLIC_PRIO8, + RV_PLIC_PRIO9, + RV_PLIC_PRIO10, + RV_PLIC_PRIO11, + RV_PLIC_PRIO12, + RV_PLIC_PRIO13, + RV_PLIC_PRIO14, + RV_PLIC_PRIO15, + RV_PLIC_PRIO16, + RV_PLIC_PRIO17, + RV_PLIC_PRIO18, + RV_PLIC_PRIO19, + RV_PLIC_PRIO20, + RV_PLIC_PRIO21, + RV_PLIC_PRIO22, + RV_PLIC_PRIO23, + RV_PLIC_PRIO24, + RV_PLIC_PRIO25, + RV_PLIC_PRIO26, + RV_PLIC_PRIO27, + RV_PLIC_PRIO28, + RV_PLIC_PRIO29, + RV_PLIC_PRIO30, + RV_PLIC_PRIO31, + RV_PLIC_PRIO32, + RV_PLIC_PRIO33, + RV_PLIC_PRIO34, + RV_PLIC_PRIO35, + RV_PLIC_PRIO36, + RV_PLIC_PRIO37, + RV_PLIC_PRIO38, + RV_PLIC_PRIO39, + RV_PLIC_PRIO40, + RV_PLIC_PRIO41, + RV_PLIC_PRIO42, + RV_PLIC_PRIO43, + RV_PLIC_PRIO44, + RV_PLIC_PRIO45, + RV_PLIC_PRIO46, + RV_PLIC_PRIO47, + RV_PLIC_PRIO48, + RV_PLIC_PRIO49, + RV_PLIC_PRIO50, + RV_PLIC_PRIO51, + RV_PLIC_PRIO52, + RV_PLIC_PRIO53, + RV_PLIC_PRIO54, + RV_PLIC_PRIO55, + RV_PLIC_PRIO56, + RV_PLIC_PRIO57, + RV_PLIC_PRIO58, + RV_PLIC_PRIO59, + RV_PLIC_PRIO60, + RV_PLIC_PRIO61, + RV_PLIC_PRIO62, + RV_PLIC_PRIO63, + RV_PLIC_PRIO64, + RV_PLIC_PRIO65, + RV_PLIC_PRIO66, + RV_PLIC_PRIO67, + RV_PLIC_PRIO68, + RV_PLIC_PRIO69, + RV_PLIC_PRIO70, + RV_PLIC_PRIO71, + RV_PLIC_PRIO72, + RV_PLIC_PRIO73, + RV_PLIC_PRIO74, + RV_PLIC_PRIO75, + RV_PLIC_PRIO76, + RV_PLIC_PRIO77, + RV_PLIC_PRIO78, + RV_PLIC_PRIO79, + RV_PLIC_PRIO80, + RV_PLIC_PRIO81, + RV_PLIC_PRIO82, + RV_PLIC_PRIO83, + RV_PLIC_PRIO84, + RV_PLIC_PRIO85, + RV_PLIC_PRIO86, + RV_PLIC_PRIO87, + RV_PLIC_IP_0, + RV_PLIC_IP_1, + RV_PLIC_IP_2, + RV_PLIC_IE0_0, + RV_PLIC_IE0_1, + RV_PLIC_IE0_2, + RV_PLIC_THRESHOLD0, + RV_PLIC_CC0, + RV_PLIC_MSIP0, + RV_PLIC_ALERT_TEST + } rv_plic_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] RV_PLIC_PERMIT [98] = '{ + 4'b 0001, // index[ 0] RV_PLIC_PRIO0 + 4'b 0001, // index[ 1] RV_PLIC_PRIO1 + 4'b 0001, // index[ 2] RV_PLIC_PRIO2 + 4'b 0001, // index[ 3] RV_PLIC_PRIO3 + 4'b 0001, // index[ 4] RV_PLIC_PRIO4 + 4'b 0001, // index[ 5] RV_PLIC_PRIO5 + 4'b 0001, // index[ 6] RV_PLIC_PRIO6 + 4'b 0001, // index[ 7] RV_PLIC_PRIO7 + 4'b 0001, // index[ 8] RV_PLIC_PRIO8 + 4'b 0001, // index[ 9] RV_PLIC_PRIO9 + 4'b 0001, // index[10] RV_PLIC_PRIO10 + 4'b 0001, // index[11] RV_PLIC_PRIO11 + 4'b 0001, // index[12] RV_PLIC_PRIO12 + 4'b 0001, // index[13] RV_PLIC_PRIO13 + 4'b 0001, // index[14] RV_PLIC_PRIO14 + 4'b 0001, // index[15] RV_PLIC_PRIO15 + 4'b 0001, // index[16] RV_PLIC_PRIO16 + 4'b 0001, // index[17] RV_PLIC_PRIO17 + 4'b 0001, // index[18] RV_PLIC_PRIO18 + 4'b 0001, // index[19] RV_PLIC_PRIO19 + 4'b 0001, // index[20] RV_PLIC_PRIO20 + 4'b 0001, // index[21] RV_PLIC_PRIO21 + 4'b 0001, // index[22] RV_PLIC_PRIO22 + 4'b 0001, // index[23] RV_PLIC_PRIO23 + 4'b 0001, // index[24] RV_PLIC_PRIO24 + 4'b 0001, // index[25] RV_PLIC_PRIO25 + 4'b 0001, // index[26] RV_PLIC_PRIO26 + 4'b 0001, // index[27] RV_PLIC_PRIO27 + 4'b 0001, // index[28] RV_PLIC_PRIO28 + 4'b 0001, // index[29] RV_PLIC_PRIO29 + 4'b 0001, // index[30] RV_PLIC_PRIO30 + 4'b 0001, // index[31] RV_PLIC_PRIO31 + 4'b 0001, // index[32] RV_PLIC_PRIO32 + 4'b 0001, // index[33] RV_PLIC_PRIO33 + 4'b 0001, // index[34] RV_PLIC_PRIO34 + 4'b 0001, // index[35] RV_PLIC_PRIO35 + 4'b 0001, // index[36] RV_PLIC_PRIO36 + 4'b 0001, // index[37] RV_PLIC_PRIO37 + 4'b 0001, // index[38] RV_PLIC_PRIO38 + 4'b 0001, // index[39] RV_PLIC_PRIO39 + 4'b 0001, // index[40] RV_PLIC_PRIO40 + 4'b 0001, // index[41] RV_PLIC_PRIO41 + 4'b 0001, // index[42] RV_PLIC_PRIO42 + 4'b 0001, // index[43] RV_PLIC_PRIO43 + 4'b 0001, // index[44] RV_PLIC_PRIO44 + 4'b 0001, // index[45] RV_PLIC_PRIO45 + 4'b 0001, // index[46] RV_PLIC_PRIO46 + 4'b 0001, // index[47] RV_PLIC_PRIO47 + 4'b 0001, // index[48] RV_PLIC_PRIO48 + 4'b 0001, // index[49] RV_PLIC_PRIO49 + 4'b 0001, // index[50] RV_PLIC_PRIO50 + 4'b 0001, // index[51] RV_PLIC_PRIO51 + 4'b 0001, // index[52] RV_PLIC_PRIO52 + 4'b 0001, // index[53] RV_PLIC_PRIO53 + 4'b 0001, // index[54] RV_PLIC_PRIO54 + 4'b 0001, // index[55] RV_PLIC_PRIO55 + 4'b 0001, // index[56] RV_PLIC_PRIO56 + 4'b 0001, // index[57] RV_PLIC_PRIO57 + 4'b 0001, // index[58] RV_PLIC_PRIO58 + 4'b 0001, // index[59] RV_PLIC_PRIO59 + 4'b 0001, // index[60] RV_PLIC_PRIO60 + 4'b 0001, // index[61] RV_PLIC_PRIO61 + 4'b 0001, // index[62] RV_PLIC_PRIO62 + 4'b 0001, // index[63] RV_PLIC_PRIO63 + 4'b 0001, // index[64] RV_PLIC_PRIO64 + 4'b 0001, // index[65] RV_PLIC_PRIO65 + 4'b 0001, // index[66] RV_PLIC_PRIO66 + 4'b 0001, // index[67] RV_PLIC_PRIO67 + 4'b 0001, // index[68] RV_PLIC_PRIO68 + 4'b 0001, // index[69] RV_PLIC_PRIO69 + 4'b 0001, // index[70] RV_PLIC_PRIO70 + 4'b 0001, // index[71] RV_PLIC_PRIO71 + 4'b 0001, // index[72] RV_PLIC_PRIO72 + 4'b 0001, // index[73] RV_PLIC_PRIO73 + 4'b 0001, // index[74] RV_PLIC_PRIO74 + 4'b 0001, // index[75] RV_PLIC_PRIO75 + 4'b 0001, // index[76] RV_PLIC_PRIO76 + 4'b 0001, // index[77] RV_PLIC_PRIO77 + 4'b 0001, // index[78] RV_PLIC_PRIO78 + 4'b 0001, // index[79] RV_PLIC_PRIO79 + 4'b 0001, // index[80] RV_PLIC_PRIO80 + 4'b 0001, // index[81] RV_PLIC_PRIO81 + 4'b 0001, // index[82] RV_PLIC_PRIO82 + 4'b 0001, // index[83] RV_PLIC_PRIO83 + 4'b 0001, // index[84] RV_PLIC_PRIO84 + 4'b 0001, // index[85] RV_PLIC_PRIO85 + 4'b 0001, // index[86] RV_PLIC_PRIO86 + 4'b 0001, // index[87] RV_PLIC_PRIO87 + 4'b 1111, // index[88] RV_PLIC_IP_0 + 4'b 1111, // index[89] RV_PLIC_IP_1 + 4'b 0111, // index[90] RV_PLIC_IP_2 + 4'b 1111, // index[91] RV_PLIC_IE0_0 + 4'b 1111, // index[92] RV_PLIC_IE0_1 + 4'b 0111, // index[93] RV_PLIC_IE0_2 + 4'b 0001, // index[94] RV_PLIC_THRESHOLD0 + 4'b 0001, // index[95] RV_PLIC_CC0 + 4'b 0001, // index[96] RV_PLIC_MSIP0 + 4'b 0001 // index[97] RV_PLIC_ALERT_TEST + }; + +endpackage diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv new file mode 100644 index 0000000000000..b66600ac15619 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_reg_top.sv @@ -0,0 +1,9369 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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 rv_plic_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 rv_plic_reg_pkg::rv_plic_reg2hw_t reg2hw, // Write + input rv_plic_reg_pkg::rv_plic_hw2reg_t hw2reg, // Read + + // Integrity check errors + output logic intg_err_o +); + + import rv_plic_reg_pkg::* ; + + localparam int AW = 27; + 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 [97:0] reg_we_check; + prim_reg_we_check #( + .OneHotWidth(98) + ) 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 = addrmiss | wr_err | intg_err; + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic prio0_we; + logic [1:0] prio0_qs; + logic [1:0] prio0_wd; + logic prio1_we; + logic [1:0] prio1_qs; + logic [1:0] prio1_wd; + logic prio2_we; + logic [1:0] prio2_qs; + logic [1:0] prio2_wd; + logic prio3_we; + logic [1:0] prio3_qs; + logic [1:0] prio3_wd; + logic prio4_we; + logic [1:0] prio4_qs; + logic [1:0] prio4_wd; + logic prio5_we; + logic [1:0] prio5_qs; + logic [1:0] prio5_wd; + logic prio6_we; + logic [1:0] prio6_qs; + logic [1:0] prio6_wd; + logic prio7_we; + logic [1:0] prio7_qs; + logic [1:0] prio7_wd; + logic prio8_we; + logic [1:0] prio8_qs; + logic [1:0] prio8_wd; + logic prio9_we; + logic [1:0] prio9_qs; + logic [1:0] prio9_wd; + logic prio10_we; + logic [1:0] prio10_qs; + logic [1:0] prio10_wd; + logic prio11_we; + logic [1:0] prio11_qs; + logic [1:0] prio11_wd; + logic prio12_we; + logic [1:0] prio12_qs; + logic [1:0] prio12_wd; + logic prio13_we; + logic [1:0] prio13_qs; + logic [1:0] prio13_wd; + logic prio14_we; + logic [1:0] prio14_qs; + logic [1:0] prio14_wd; + logic prio15_we; + logic [1:0] prio15_qs; + logic [1:0] prio15_wd; + logic prio16_we; + logic [1:0] prio16_qs; + logic [1:0] prio16_wd; + logic prio17_we; + logic [1:0] prio17_qs; + logic [1:0] prio17_wd; + logic prio18_we; + logic [1:0] prio18_qs; + logic [1:0] prio18_wd; + logic prio19_we; + logic [1:0] prio19_qs; + logic [1:0] prio19_wd; + logic prio20_we; + logic [1:0] prio20_qs; + logic [1:0] prio20_wd; + logic prio21_we; + logic [1:0] prio21_qs; + logic [1:0] prio21_wd; + logic prio22_we; + logic [1:0] prio22_qs; + logic [1:0] prio22_wd; + logic prio23_we; + logic [1:0] prio23_qs; + logic [1:0] prio23_wd; + logic prio24_we; + logic [1:0] prio24_qs; + logic [1:0] prio24_wd; + logic prio25_we; + logic [1:0] prio25_qs; + logic [1:0] prio25_wd; + logic prio26_we; + logic [1:0] prio26_qs; + logic [1:0] prio26_wd; + logic prio27_we; + logic [1:0] prio27_qs; + logic [1:0] prio27_wd; + logic prio28_we; + logic [1:0] prio28_qs; + logic [1:0] prio28_wd; + logic prio29_we; + logic [1:0] prio29_qs; + logic [1:0] prio29_wd; + logic prio30_we; + logic [1:0] prio30_qs; + logic [1:0] prio30_wd; + logic prio31_we; + logic [1:0] prio31_qs; + logic [1:0] prio31_wd; + logic prio32_we; + logic [1:0] prio32_qs; + logic [1:0] prio32_wd; + logic prio33_we; + logic [1:0] prio33_qs; + logic [1:0] prio33_wd; + logic prio34_we; + logic [1:0] prio34_qs; + logic [1:0] prio34_wd; + logic prio35_we; + logic [1:0] prio35_qs; + logic [1:0] prio35_wd; + logic prio36_we; + logic [1:0] prio36_qs; + logic [1:0] prio36_wd; + logic prio37_we; + logic [1:0] prio37_qs; + logic [1:0] prio37_wd; + logic prio38_we; + logic [1:0] prio38_qs; + logic [1:0] prio38_wd; + logic prio39_we; + logic [1:0] prio39_qs; + logic [1:0] prio39_wd; + logic prio40_we; + logic [1:0] prio40_qs; + logic [1:0] prio40_wd; + logic prio41_we; + logic [1:0] prio41_qs; + logic [1:0] prio41_wd; + logic prio42_we; + logic [1:0] prio42_qs; + logic [1:0] prio42_wd; + logic prio43_we; + logic [1:0] prio43_qs; + logic [1:0] prio43_wd; + logic prio44_we; + logic [1:0] prio44_qs; + logic [1:0] prio44_wd; + logic prio45_we; + logic [1:0] prio45_qs; + logic [1:0] prio45_wd; + logic prio46_we; + logic [1:0] prio46_qs; + logic [1:0] prio46_wd; + logic prio47_we; + logic [1:0] prio47_qs; + logic [1:0] prio47_wd; + logic prio48_we; + logic [1:0] prio48_qs; + logic [1:0] prio48_wd; + logic prio49_we; + logic [1:0] prio49_qs; + logic [1:0] prio49_wd; + logic prio50_we; + logic [1:0] prio50_qs; + logic [1:0] prio50_wd; + logic prio51_we; + logic [1:0] prio51_qs; + logic [1:0] prio51_wd; + logic prio52_we; + logic [1:0] prio52_qs; + logic [1:0] prio52_wd; + logic prio53_we; + logic [1:0] prio53_qs; + logic [1:0] prio53_wd; + logic prio54_we; + logic [1:0] prio54_qs; + logic [1:0] prio54_wd; + logic prio55_we; + logic [1:0] prio55_qs; + logic [1:0] prio55_wd; + logic prio56_we; + logic [1:0] prio56_qs; + logic [1:0] prio56_wd; + logic prio57_we; + logic [1:0] prio57_qs; + logic [1:0] prio57_wd; + logic prio58_we; + logic [1:0] prio58_qs; + logic [1:0] prio58_wd; + logic prio59_we; + logic [1:0] prio59_qs; + logic [1:0] prio59_wd; + logic prio60_we; + logic [1:0] prio60_qs; + logic [1:0] prio60_wd; + logic prio61_we; + logic [1:0] prio61_qs; + logic [1:0] prio61_wd; + logic prio62_we; + logic [1:0] prio62_qs; + logic [1:0] prio62_wd; + logic prio63_we; + logic [1:0] prio63_qs; + logic [1:0] prio63_wd; + logic prio64_we; + logic [1:0] prio64_qs; + logic [1:0] prio64_wd; + logic prio65_we; + logic [1:0] prio65_qs; + logic [1:0] prio65_wd; + logic prio66_we; + logic [1:0] prio66_qs; + logic [1:0] prio66_wd; + logic prio67_we; + logic [1:0] prio67_qs; + logic [1:0] prio67_wd; + logic prio68_we; + logic [1:0] prio68_qs; + logic [1:0] prio68_wd; + logic prio69_we; + logic [1:0] prio69_qs; + logic [1:0] prio69_wd; + logic prio70_we; + logic [1:0] prio70_qs; + logic [1:0] prio70_wd; + logic prio71_we; + logic [1:0] prio71_qs; + logic [1:0] prio71_wd; + logic prio72_we; + logic [1:0] prio72_qs; + logic [1:0] prio72_wd; + logic prio73_we; + logic [1:0] prio73_qs; + logic [1:0] prio73_wd; + logic prio74_we; + logic [1:0] prio74_qs; + logic [1:0] prio74_wd; + logic prio75_we; + logic [1:0] prio75_qs; + logic [1:0] prio75_wd; + logic prio76_we; + logic [1:0] prio76_qs; + logic [1:0] prio76_wd; + logic prio77_we; + logic [1:0] prio77_qs; + logic [1:0] prio77_wd; + logic prio78_we; + logic [1:0] prio78_qs; + logic [1:0] prio78_wd; + logic prio79_we; + logic [1:0] prio79_qs; + logic [1:0] prio79_wd; + logic prio80_we; + logic [1:0] prio80_qs; + logic [1:0] prio80_wd; + logic prio81_we; + logic [1:0] prio81_qs; + logic [1:0] prio81_wd; + logic prio82_we; + logic [1:0] prio82_qs; + logic [1:0] prio82_wd; + logic prio83_we; + logic [1:0] prio83_qs; + logic [1:0] prio83_wd; + logic prio84_we; + logic [1:0] prio84_qs; + logic [1:0] prio84_wd; + logic prio85_we; + logic [1:0] prio85_qs; + logic [1:0] prio85_wd; + logic prio86_we; + logic [1:0] prio86_qs; + logic [1:0] prio86_wd; + logic prio87_we; + logic [1:0] prio87_qs; + logic [1:0] prio87_wd; + logic ip_0_p_0_qs; + logic ip_0_p_1_qs; + logic ip_0_p_2_qs; + logic ip_0_p_3_qs; + logic ip_0_p_4_qs; + logic ip_0_p_5_qs; + logic ip_0_p_6_qs; + logic ip_0_p_7_qs; + logic ip_0_p_8_qs; + logic ip_0_p_9_qs; + logic ip_0_p_10_qs; + logic ip_0_p_11_qs; + logic ip_0_p_12_qs; + logic ip_0_p_13_qs; + logic ip_0_p_14_qs; + logic ip_0_p_15_qs; + logic ip_0_p_16_qs; + logic ip_0_p_17_qs; + logic ip_0_p_18_qs; + logic ip_0_p_19_qs; + logic ip_0_p_20_qs; + logic ip_0_p_21_qs; + logic ip_0_p_22_qs; + logic ip_0_p_23_qs; + logic ip_0_p_24_qs; + logic ip_0_p_25_qs; + logic ip_0_p_26_qs; + logic ip_0_p_27_qs; + logic ip_0_p_28_qs; + logic ip_0_p_29_qs; + logic ip_0_p_30_qs; + logic ip_0_p_31_qs; + logic ip_1_p_32_qs; + logic ip_1_p_33_qs; + logic ip_1_p_34_qs; + logic ip_1_p_35_qs; + logic ip_1_p_36_qs; + logic ip_1_p_37_qs; + logic ip_1_p_38_qs; + logic ip_1_p_39_qs; + logic ip_1_p_40_qs; + logic ip_1_p_41_qs; + logic ip_1_p_42_qs; + logic ip_1_p_43_qs; + logic ip_1_p_44_qs; + logic ip_1_p_45_qs; + logic ip_1_p_46_qs; + logic ip_1_p_47_qs; + logic ip_1_p_48_qs; + logic ip_1_p_49_qs; + logic ip_1_p_50_qs; + logic ip_1_p_51_qs; + logic ip_1_p_52_qs; + logic ip_1_p_53_qs; + logic ip_1_p_54_qs; + logic ip_1_p_55_qs; + logic ip_1_p_56_qs; + logic ip_1_p_57_qs; + logic ip_1_p_58_qs; + logic ip_1_p_59_qs; + logic ip_1_p_60_qs; + logic ip_1_p_61_qs; + logic ip_1_p_62_qs; + logic ip_1_p_63_qs; + logic ip_2_p_64_qs; + logic ip_2_p_65_qs; + logic ip_2_p_66_qs; + logic ip_2_p_67_qs; + logic ip_2_p_68_qs; + logic ip_2_p_69_qs; + logic ip_2_p_70_qs; + logic ip_2_p_71_qs; + logic ip_2_p_72_qs; + logic ip_2_p_73_qs; + logic ip_2_p_74_qs; + logic ip_2_p_75_qs; + logic ip_2_p_76_qs; + logic ip_2_p_77_qs; + logic ip_2_p_78_qs; + logic ip_2_p_79_qs; + logic ip_2_p_80_qs; + logic ip_2_p_81_qs; + logic ip_2_p_82_qs; + logic ip_2_p_83_qs; + logic ip_2_p_84_qs; + logic ip_2_p_85_qs; + logic ip_2_p_86_qs; + logic ip_2_p_87_qs; + logic ie0_0_we; + logic ie0_0_e_0_qs; + logic ie0_0_e_0_wd; + logic ie0_0_e_1_qs; + logic ie0_0_e_1_wd; + logic ie0_0_e_2_qs; + logic ie0_0_e_2_wd; + logic ie0_0_e_3_qs; + logic ie0_0_e_3_wd; + logic ie0_0_e_4_qs; + logic ie0_0_e_4_wd; + logic ie0_0_e_5_qs; + logic ie0_0_e_5_wd; + logic ie0_0_e_6_qs; + logic ie0_0_e_6_wd; + logic ie0_0_e_7_qs; + logic ie0_0_e_7_wd; + logic ie0_0_e_8_qs; + logic ie0_0_e_8_wd; + logic ie0_0_e_9_qs; + logic ie0_0_e_9_wd; + logic ie0_0_e_10_qs; + logic ie0_0_e_10_wd; + logic ie0_0_e_11_qs; + logic ie0_0_e_11_wd; + logic ie0_0_e_12_qs; + logic ie0_0_e_12_wd; + logic ie0_0_e_13_qs; + logic ie0_0_e_13_wd; + logic ie0_0_e_14_qs; + logic ie0_0_e_14_wd; + logic ie0_0_e_15_qs; + logic ie0_0_e_15_wd; + logic ie0_0_e_16_qs; + logic ie0_0_e_16_wd; + logic ie0_0_e_17_qs; + logic ie0_0_e_17_wd; + logic ie0_0_e_18_qs; + logic ie0_0_e_18_wd; + logic ie0_0_e_19_qs; + logic ie0_0_e_19_wd; + logic ie0_0_e_20_qs; + logic ie0_0_e_20_wd; + logic ie0_0_e_21_qs; + logic ie0_0_e_21_wd; + logic ie0_0_e_22_qs; + logic ie0_0_e_22_wd; + logic ie0_0_e_23_qs; + logic ie0_0_e_23_wd; + logic ie0_0_e_24_qs; + logic ie0_0_e_24_wd; + logic ie0_0_e_25_qs; + logic ie0_0_e_25_wd; + logic ie0_0_e_26_qs; + logic ie0_0_e_26_wd; + logic ie0_0_e_27_qs; + logic ie0_0_e_27_wd; + logic ie0_0_e_28_qs; + logic ie0_0_e_28_wd; + logic ie0_0_e_29_qs; + logic ie0_0_e_29_wd; + logic ie0_0_e_30_qs; + logic ie0_0_e_30_wd; + logic ie0_0_e_31_qs; + logic ie0_0_e_31_wd; + logic ie0_1_we; + logic ie0_1_e_32_qs; + logic ie0_1_e_32_wd; + logic ie0_1_e_33_qs; + logic ie0_1_e_33_wd; + logic ie0_1_e_34_qs; + logic ie0_1_e_34_wd; + logic ie0_1_e_35_qs; + logic ie0_1_e_35_wd; + logic ie0_1_e_36_qs; + logic ie0_1_e_36_wd; + logic ie0_1_e_37_qs; + logic ie0_1_e_37_wd; + logic ie0_1_e_38_qs; + logic ie0_1_e_38_wd; + logic ie0_1_e_39_qs; + logic ie0_1_e_39_wd; + logic ie0_1_e_40_qs; + logic ie0_1_e_40_wd; + logic ie0_1_e_41_qs; + logic ie0_1_e_41_wd; + logic ie0_1_e_42_qs; + logic ie0_1_e_42_wd; + logic ie0_1_e_43_qs; + logic ie0_1_e_43_wd; + logic ie0_1_e_44_qs; + logic ie0_1_e_44_wd; + logic ie0_1_e_45_qs; + logic ie0_1_e_45_wd; + logic ie0_1_e_46_qs; + logic ie0_1_e_46_wd; + logic ie0_1_e_47_qs; + logic ie0_1_e_47_wd; + logic ie0_1_e_48_qs; + logic ie0_1_e_48_wd; + logic ie0_1_e_49_qs; + logic ie0_1_e_49_wd; + logic ie0_1_e_50_qs; + logic ie0_1_e_50_wd; + logic ie0_1_e_51_qs; + logic ie0_1_e_51_wd; + logic ie0_1_e_52_qs; + logic ie0_1_e_52_wd; + logic ie0_1_e_53_qs; + logic ie0_1_e_53_wd; + logic ie0_1_e_54_qs; + logic ie0_1_e_54_wd; + logic ie0_1_e_55_qs; + logic ie0_1_e_55_wd; + logic ie0_1_e_56_qs; + logic ie0_1_e_56_wd; + logic ie0_1_e_57_qs; + logic ie0_1_e_57_wd; + logic ie0_1_e_58_qs; + logic ie0_1_e_58_wd; + logic ie0_1_e_59_qs; + logic ie0_1_e_59_wd; + logic ie0_1_e_60_qs; + logic ie0_1_e_60_wd; + logic ie0_1_e_61_qs; + logic ie0_1_e_61_wd; + logic ie0_1_e_62_qs; + logic ie0_1_e_62_wd; + logic ie0_1_e_63_qs; + logic ie0_1_e_63_wd; + logic ie0_2_we; + logic ie0_2_e_64_qs; + logic ie0_2_e_64_wd; + logic ie0_2_e_65_qs; + logic ie0_2_e_65_wd; + logic ie0_2_e_66_qs; + logic ie0_2_e_66_wd; + logic ie0_2_e_67_qs; + logic ie0_2_e_67_wd; + logic ie0_2_e_68_qs; + logic ie0_2_e_68_wd; + logic ie0_2_e_69_qs; + logic ie0_2_e_69_wd; + logic ie0_2_e_70_qs; + logic ie0_2_e_70_wd; + logic ie0_2_e_71_qs; + logic ie0_2_e_71_wd; + logic ie0_2_e_72_qs; + logic ie0_2_e_72_wd; + logic ie0_2_e_73_qs; + logic ie0_2_e_73_wd; + logic ie0_2_e_74_qs; + logic ie0_2_e_74_wd; + logic ie0_2_e_75_qs; + logic ie0_2_e_75_wd; + logic ie0_2_e_76_qs; + logic ie0_2_e_76_wd; + logic ie0_2_e_77_qs; + logic ie0_2_e_77_wd; + logic ie0_2_e_78_qs; + logic ie0_2_e_78_wd; + logic ie0_2_e_79_qs; + logic ie0_2_e_79_wd; + logic ie0_2_e_80_qs; + logic ie0_2_e_80_wd; + logic ie0_2_e_81_qs; + logic ie0_2_e_81_wd; + logic ie0_2_e_82_qs; + logic ie0_2_e_82_wd; + logic ie0_2_e_83_qs; + logic ie0_2_e_83_wd; + logic ie0_2_e_84_qs; + logic ie0_2_e_84_wd; + logic ie0_2_e_85_qs; + logic ie0_2_e_85_wd; + logic ie0_2_e_86_qs; + logic ie0_2_e_86_wd; + logic ie0_2_e_87_qs; + logic ie0_2_e_87_wd; + logic threshold0_we; + logic [1:0] threshold0_qs; + logic [1:0] threshold0_wd; + logic cc0_re; + logic cc0_we; + logic [6:0] cc0_qs; + logic [6:0] cc0_wd; + logic msip0_we; + logic msip0_qs; + logic msip0_wd; + logic alert_test_we; + logic alert_test_wd; + + // Register instances + // R[prio0]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio0_we), + .wd (prio0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio0.q), + .ds (), + + // to register interface (read) + .qs (prio0_qs) + ); + + + // R[prio1]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio1_we), + .wd (prio1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio1.q), + .ds (), + + // to register interface (read) + .qs (prio1_qs) + ); + + + // R[prio2]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio2_we), + .wd (prio2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio2.q), + .ds (), + + // to register interface (read) + .qs (prio2_qs) + ); + + + // R[prio3]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio3_we), + .wd (prio3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio3.q), + .ds (), + + // to register interface (read) + .qs (prio3_qs) + ); + + + // R[prio4]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio4_we), + .wd (prio4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio4.q), + .ds (), + + // to register interface (read) + .qs (prio4_qs) + ); + + + // R[prio5]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio5_we), + .wd (prio5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio5.q), + .ds (), + + // to register interface (read) + .qs (prio5_qs) + ); + + + // R[prio6]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio6_we), + .wd (prio6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio6.q), + .ds (), + + // to register interface (read) + .qs (prio6_qs) + ); + + + // R[prio7]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio7_we), + .wd (prio7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio7.q), + .ds (), + + // to register interface (read) + .qs (prio7_qs) + ); + + + // R[prio8]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio8_we), + .wd (prio8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio8.q), + .ds (), + + // to register interface (read) + .qs (prio8_qs) + ); + + + // R[prio9]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio9_we), + .wd (prio9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio9.q), + .ds (), + + // to register interface (read) + .qs (prio9_qs) + ); + + + // R[prio10]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio10_we), + .wd (prio10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio10.q), + .ds (), + + // to register interface (read) + .qs (prio10_qs) + ); + + + // R[prio11]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio11_we), + .wd (prio11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio11.q), + .ds (), + + // to register interface (read) + .qs (prio11_qs) + ); + + + // R[prio12]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio12_we), + .wd (prio12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio12.q), + .ds (), + + // to register interface (read) + .qs (prio12_qs) + ); + + + // R[prio13]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio13_we), + .wd (prio13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio13.q), + .ds (), + + // to register interface (read) + .qs (prio13_qs) + ); + + + // R[prio14]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio14_we), + .wd (prio14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio14.q), + .ds (), + + // to register interface (read) + .qs (prio14_qs) + ); + + + // R[prio15]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio15_we), + .wd (prio15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio15.q), + .ds (), + + // to register interface (read) + .qs (prio15_qs) + ); + + + // R[prio16]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio16_we), + .wd (prio16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio16.q), + .ds (), + + // to register interface (read) + .qs (prio16_qs) + ); + + + // R[prio17]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio17_we), + .wd (prio17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio17.q), + .ds (), + + // to register interface (read) + .qs (prio17_qs) + ); + + + // R[prio18]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio18_we), + .wd (prio18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio18.q), + .ds (), + + // to register interface (read) + .qs (prio18_qs) + ); + + + // R[prio19]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio19_we), + .wd (prio19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio19.q), + .ds (), + + // to register interface (read) + .qs (prio19_qs) + ); + + + // R[prio20]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio20_we), + .wd (prio20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio20.q), + .ds (), + + // to register interface (read) + .qs (prio20_qs) + ); + + + // R[prio21]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio21_we), + .wd (prio21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio21.q), + .ds (), + + // to register interface (read) + .qs (prio21_qs) + ); + + + // R[prio22]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio22_we), + .wd (prio22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio22.q), + .ds (), + + // to register interface (read) + .qs (prio22_qs) + ); + + + // R[prio23]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio23_we), + .wd (prio23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio23.q), + .ds (), + + // to register interface (read) + .qs (prio23_qs) + ); + + + // R[prio24]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio24_we), + .wd (prio24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio24.q), + .ds (), + + // to register interface (read) + .qs (prio24_qs) + ); + + + // R[prio25]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio25_we), + .wd (prio25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio25.q), + .ds (), + + // to register interface (read) + .qs (prio25_qs) + ); + + + // R[prio26]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio26_we), + .wd (prio26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio26.q), + .ds (), + + // to register interface (read) + .qs (prio26_qs) + ); + + + // R[prio27]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio27_we), + .wd (prio27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio27.q), + .ds (), + + // to register interface (read) + .qs (prio27_qs) + ); + + + // R[prio28]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio28_we), + .wd (prio28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio28.q), + .ds (), + + // to register interface (read) + .qs (prio28_qs) + ); + + + // R[prio29]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio29_we), + .wd (prio29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio29.q), + .ds (), + + // to register interface (read) + .qs (prio29_qs) + ); + + + // R[prio30]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio30_we), + .wd (prio30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio30.q), + .ds (), + + // to register interface (read) + .qs (prio30_qs) + ); + + + // R[prio31]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio31_we), + .wd (prio31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio31.q), + .ds (), + + // to register interface (read) + .qs (prio31_qs) + ); + + + // R[prio32]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio32_we), + .wd (prio32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio32.q), + .ds (), + + // to register interface (read) + .qs (prio32_qs) + ); + + + // R[prio33]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio33_we), + .wd (prio33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio33.q), + .ds (), + + // to register interface (read) + .qs (prio33_qs) + ); + + + // R[prio34]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio34_we), + .wd (prio34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio34.q), + .ds (), + + // to register interface (read) + .qs (prio34_qs) + ); + + + // R[prio35]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio35_we), + .wd (prio35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio35.q), + .ds (), + + // to register interface (read) + .qs (prio35_qs) + ); + + + // R[prio36]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio36_we), + .wd (prio36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio36.q), + .ds (), + + // to register interface (read) + .qs (prio36_qs) + ); + + + // R[prio37]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio37_we), + .wd (prio37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio37.q), + .ds (), + + // to register interface (read) + .qs (prio37_qs) + ); + + + // R[prio38]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio38_we), + .wd (prio38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio38.q), + .ds (), + + // to register interface (read) + .qs (prio38_qs) + ); + + + // R[prio39]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio39_we), + .wd (prio39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio39.q), + .ds (), + + // to register interface (read) + .qs (prio39_qs) + ); + + + // R[prio40]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio40_we), + .wd (prio40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio40.q), + .ds (), + + // to register interface (read) + .qs (prio40_qs) + ); + + + // R[prio41]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio41_we), + .wd (prio41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio41.q), + .ds (), + + // to register interface (read) + .qs (prio41_qs) + ); + + + // R[prio42]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio42_we), + .wd (prio42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio42.q), + .ds (), + + // to register interface (read) + .qs (prio42_qs) + ); + + + // R[prio43]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio43_we), + .wd (prio43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio43.q), + .ds (), + + // to register interface (read) + .qs (prio43_qs) + ); + + + // R[prio44]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio44_we), + .wd (prio44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio44.q), + .ds (), + + // to register interface (read) + .qs (prio44_qs) + ); + + + // R[prio45]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio45_we), + .wd (prio45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio45.q), + .ds (), + + // to register interface (read) + .qs (prio45_qs) + ); + + + // R[prio46]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio46_we), + .wd (prio46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio46.q), + .ds (), + + // to register interface (read) + .qs (prio46_qs) + ); + + + // R[prio47]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio47 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio47_we), + .wd (prio47_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio47.q), + .ds (), + + // to register interface (read) + .qs (prio47_qs) + ); + + + // R[prio48]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio48 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio48_we), + .wd (prio48_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio48.q), + .ds (), + + // to register interface (read) + .qs (prio48_qs) + ); + + + // R[prio49]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio49 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio49_we), + .wd (prio49_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio49.q), + .ds (), + + // to register interface (read) + .qs (prio49_qs) + ); + + + // R[prio50]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio50 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio50_we), + .wd (prio50_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio50.q), + .ds (), + + // to register interface (read) + .qs (prio50_qs) + ); + + + // R[prio51]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio51 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio51_we), + .wd (prio51_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio51.q), + .ds (), + + // to register interface (read) + .qs (prio51_qs) + ); + + + // R[prio52]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio52 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio52_we), + .wd (prio52_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio52.q), + .ds (), + + // to register interface (read) + .qs (prio52_qs) + ); + + + // R[prio53]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio53 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio53_we), + .wd (prio53_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio53.q), + .ds (), + + // to register interface (read) + .qs (prio53_qs) + ); + + + // R[prio54]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio54 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio54_we), + .wd (prio54_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio54.q), + .ds (), + + // to register interface (read) + .qs (prio54_qs) + ); + + + // R[prio55]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio55 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio55_we), + .wd (prio55_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio55.q), + .ds (), + + // to register interface (read) + .qs (prio55_qs) + ); + + + // R[prio56]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio56 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio56_we), + .wd (prio56_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio56.q), + .ds (), + + // to register interface (read) + .qs (prio56_qs) + ); + + + // R[prio57]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio57 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio57_we), + .wd (prio57_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio57.q), + .ds (), + + // to register interface (read) + .qs (prio57_qs) + ); + + + // R[prio58]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio58 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio58_we), + .wd (prio58_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio58.q), + .ds (), + + // to register interface (read) + .qs (prio58_qs) + ); + + + // R[prio59]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio59 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio59_we), + .wd (prio59_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio59.q), + .ds (), + + // to register interface (read) + .qs (prio59_qs) + ); + + + // R[prio60]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio60 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio60_we), + .wd (prio60_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio60.q), + .ds (), + + // to register interface (read) + .qs (prio60_qs) + ); + + + // R[prio61]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio61 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio61_we), + .wd (prio61_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio61.q), + .ds (), + + // to register interface (read) + .qs (prio61_qs) + ); + + + // R[prio62]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio62 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio62_we), + .wd (prio62_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio62.q), + .ds (), + + // to register interface (read) + .qs (prio62_qs) + ); + + + // R[prio63]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio63 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio63_we), + .wd (prio63_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio63.q), + .ds (), + + // to register interface (read) + .qs (prio63_qs) + ); + + + // R[prio64]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio64 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio64_we), + .wd (prio64_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio64.q), + .ds (), + + // to register interface (read) + .qs (prio64_qs) + ); + + + // R[prio65]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio65 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio65_we), + .wd (prio65_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio65.q), + .ds (), + + // to register interface (read) + .qs (prio65_qs) + ); + + + // R[prio66]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio66 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio66_we), + .wd (prio66_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio66.q), + .ds (), + + // to register interface (read) + .qs (prio66_qs) + ); + + + // R[prio67]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio67 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio67_we), + .wd (prio67_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio67.q), + .ds (), + + // to register interface (read) + .qs (prio67_qs) + ); + + + // R[prio68]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio68 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio68_we), + .wd (prio68_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio68.q), + .ds (), + + // to register interface (read) + .qs (prio68_qs) + ); + + + // R[prio69]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio69 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio69_we), + .wd (prio69_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio69.q), + .ds (), + + // to register interface (read) + .qs (prio69_qs) + ); + + + // R[prio70]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio70 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio70_we), + .wd (prio70_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio70.q), + .ds (), + + // to register interface (read) + .qs (prio70_qs) + ); + + + // R[prio71]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio71 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio71_we), + .wd (prio71_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio71.q), + .ds (), + + // to register interface (read) + .qs (prio71_qs) + ); + + + // R[prio72]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio72 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio72_we), + .wd (prio72_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio72.q), + .ds (), + + // to register interface (read) + .qs (prio72_qs) + ); + + + // R[prio73]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio73 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio73_we), + .wd (prio73_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio73.q), + .ds (), + + // to register interface (read) + .qs (prio73_qs) + ); + + + // R[prio74]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio74 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio74_we), + .wd (prio74_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio74.q), + .ds (), + + // to register interface (read) + .qs (prio74_qs) + ); + + + // R[prio75]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio75 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio75_we), + .wd (prio75_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio75.q), + .ds (), + + // to register interface (read) + .qs (prio75_qs) + ); + + + // R[prio76]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio76 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio76_we), + .wd (prio76_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio76.q), + .ds (), + + // to register interface (read) + .qs (prio76_qs) + ); + + + // R[prio77]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio77 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio77_we), + .wd (prio77_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio77.q), + .ds (), + + // to register interface (read) + .qs (prio77_qs) + ); + + + // R[prio78]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio78 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio78_we), + .wd (prio78_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio78.q), + .ds (), + + // to register interface (read) + .qs (prio78_qs) + ); + + + // R[prio79]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio79 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio79_we), + .wd (prio79_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio79.q), + .ds (), + + // to register interface (read) + .qs (prio79_qs) + ); + + + // R[prio80]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio80 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio80_we), + .wd (prio80_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio80.q), + .ds (), + + // to register interface (read) + .qs (prio80_qs) + ); + + + // R[prio81]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio81 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio81_we), + .wd (prio81_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio81.q), + .ds (), + + // to register interface (read) + .qs (prio81_qs) + ); + + + // R[prio82]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio82 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio82_we), + .wd (prio82_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio82.q), + .ds (), + + // to register interface (read) + .qs (prio82_qs) + ); + + + // R[prio83]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio83 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio83_we), + .wd (prio83_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio83.q), + .ds (), + + // to register interface (read) + .qs (prio83_qs) + ); + + + // R[prio84]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio84 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio84_we), + .wd (prio84_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio84.q), + .ds (), + + // to register interface (read) + .qs (prio84_qs) + ); + + + // R[prio85]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio85 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio85_we), + .wd (prio85_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio85.q), + .ds (), + + // to register interface (read) + .qs (prio85_qs) + ); + + + // R[prio86]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio86 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio86_we), + .wd (prio86_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio86.q), + .ds (), + + // to register interface (read) + .qs (prio86_qs) + ); + + + // R[prio87]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_prio87 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (prio87_we), + .wd (prio87_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.prio87.q), + .ds (), + + // to register interface (read) + .qs (prio87_qs) + ); + + + // Subregister 0 of Multireg ip + // R[ip_0]: V(False) + // F[p_0]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[0].de), + .d (hw2reg.ip[0].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_0_qs) + ); + + // F[p_1]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[1].de), + .d (hw2reg.ip[1].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_1_qs) + ); + + // F[p_2]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[2].de), + .d (hw2reg.ip[2].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_2_qs) + ); + + // F[p_3]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[3].de), + .d (hw2reg.ip[3].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_3_qs) + ); + + // F[p_4]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[4].de), + .d (hw2reg.ip[4].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_4_qs) + ); + + // F[p_5]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[5].de), + .d (hw2reg.ip[5].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_5_qs) + ); + + // F[p_6]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[6].de), + .d (hw2reg.ip[6].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_6_qs) + ); + + // F[p_7]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[7].de), + .d (hw2reg.ip[7].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_7_qs) + ); + + // F[p_8]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[8].de), + .d (hw2reg.ip[8].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_8_qs) + ); + + // F[p_9]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[9].de), + .d (hw2reg.ip[9].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_9_qs) + ); + + // F[p_10]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[10].de), + .d (hw2reg.ip[10].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_10_qs) + ); + + // F[p_11]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[11].de), + .d (hw2reg.ip[11].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_11_qs) + ); + + // F[p_12]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[12].de), + .d (hw2reg.ip[12].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_12_qs) + ); + + // F[p_13]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[13].de), + .d (hw2reg.ip[13].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_13_qs) + ); + + // F[p_14]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[14].de), + .d (hw2reg.ip[14].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_14_qs) + ); + + // F[p_15]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[15].de), + .d (hw2reg.ip[15].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_15_qs) + ); + + // F[p_16]: 16:16 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[16].de), + .d (hw2reg.ip[16].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_16_qs) + ); + + // F[p_17]: 17:17 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[17].de), + .d (hw2reg.ip[17].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_17_qs) + ); + + // F[p_18]: 18:18 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[18].de), + .d (hw2reg.ip[18].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_18_qs) + ); + + // F[p_19]: 19:19 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[19].de), + .d (hw2reg.ip[19].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_19_qs) + ); + + // F[p_20]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[20].de), + .d (hw2reg.ip[20].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_20_qs) + ); + + // F[p_21]: 21:21 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[21].de), + .d (hw2reg.ip[21].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_21_qs) + ); + + // F[p_22]: 22:22 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[22].de), + .d (hw2reg.ip[22].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_22_qs) + ); + + // F[p_23]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[23].de), + .d (hw2reg.ip[23].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_23_qs) + ); + + // F[p_24]: 24:24 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[24].de), + .d (hw2reg.ip[24].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_24_qs) + ); + + // F[p_25]: 25:25 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[25].de), + .d (hw2reg.ip[25].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_25_qs) + ); + + // F[p_26]: 26:26 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[26].de), + .d (hw2reg.ip[26].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_26_qs) + ); + + // F[p_27]: 27:27 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[27].de), + .d (hw2reg.ip[27].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_27_qs) + ); + + // F[p_28]: 28:28 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[28].de), + .d (hw2reg.ip[28].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_28_qs) + ); + + // F[p_29]: 29:29 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[29].de), + .d (hw2reg.ip[29].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_29_qs) + ); + + // F[p_30]: 30:30 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[30].de), + .d (hw2reg.ip[30].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_30_qs) + ); + + // F[p_31]: 31:31 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_0_p_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[31].de), + .d (hw2reg.ip[31].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_0_p_31_qs) + ); + + + // Subregister 1 of Multireg ip + // R[ip_1]: V(False) + // F[p_32]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[32].de), + .d (hw2reg.ip[32].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_32_qs) + ); + + // F[p_33]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[33].de), + .d (hw2reg.ip[33].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_33_qs) + ); + + // F[p_34]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[34].de), + .d (hw2reg.ip[34].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_34_qs) + ); + + // F[p_35]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[35].de), + .d (hw2reg.ip[35].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_35_qs) + ); + + // F[p_36]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[36].de), + .d (hw2reg.ip[36].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_36_qs) + ); + + // F[p_37]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[37].de), + .d (hw2reg.ip[37].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_37_qs) + ); + + // F[p_38]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[38].de), + .d (hw2reg.ip[38].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_38_qs) + ); + + // F[p_39]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[39].de), + .d (hw2reg.ip[39].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_39_qs) + ); + + // F[p_40]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[40].de), + .d (hw2reg.ip[40].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_40_qs) + ); + + // F[p_41]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[41].de), + .d (hw2reg.ip[41].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_41_qs) + ); + + // F[p_42]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[42].de), + .d (hw2reg.ip[42].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_42_qs) + ); + + // F[p_43]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[43].de), + .d (hw2reg.ip[43].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_43_qs) + ); + + // F[p_44]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[44].de), + .d (hw2reg.ip[44].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_44_qs) + ); + + // F[p_45]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[45].de), + .d (hw2reg.ip[45].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_45_qs) + ); + + // F[p_46]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[46].de), + .d (hw2reg.ip[46].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_46_qs) + ); + + // F[p_47]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_47 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[47].de), + .d (hw2reg.ip[47].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_47_qs) + ); + + // F[p_48]: 16:16 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_48 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[48].de), + .d (hw2reg.ip[48].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_48_qs) + ); + + // F[p_49]: 17:17 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_49 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[49].de), + .d (hw2reg.ip[49].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_49_qs) + ); + + // F[p_50]: 18:18 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_50 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[50].de), + .d (hw2reg.ip[50].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_50_qs) + ); + + // F[p_51]: 19:19 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_51 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[51].de), + .d (hw2reg.ip[51].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_51_qs) + ); + + // F[p_52]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_52 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[52].de), + .d (hw2reg.ip[52].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_52_qs) + ); + + // F[p_53]: 21:21 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_53 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[53].de), + .d (hw2reg.ip[53].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_53_qs) + ); + + // F[p_54]: 22:22 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_54 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[54].de), + .d (hw2reg.ip[54].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_54_qs) + ); + + // F[p_55]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_55 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[55].de), + .d (hw2reg.ip[55].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_55_qs) + ); + + // F[p_56]: 24:24 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_56 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[56].de), + .d (hw2reg.ip[56].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_56_qs) + ); + + // F[p_57]: 25:25 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_57 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[57].de), + .d (hw2reg.ip[57].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_57_qs) + ); + + // F[p_58]: 26:26 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_58 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[58].de), + .d (hw2reg.ip[58].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_58_qs) + ); + + // F[p_59]: 27:27 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_59 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[59].de), + .d (hw2reg.ip[59].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_59_qs) + ); + + // F[p_60]: 28:28 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_60 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[60].de), + .d (hw2reg.ip[60].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_60_qs) + ); + + // F[p_61]: 29:29 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_61 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[61].de), + .d (hw2reg.ip[61].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_61_qs) + ); + + // F[p_62]: 30:30 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_62 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[62].de), + .d (hw2reg.ip[62].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_62_qs) + ); + + // F[p_63]: 31:31 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_1_p_63 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[63].de), + .d (hw2reg.ip[63].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_1_p_63_qs) + ); + + + // Subregister 2 of Multireg ip + // R[ip_2]: V(False) + // F[p_64]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_64 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[64].de), + .d (hw2reg.ip[64].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_64_qs) + ); + + // F[p_65]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_65 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[65].de), + .d (hw2reg.ip[65].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_65_qs) + ); + + // F[p_66]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_66 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[66].de), + .d (hw2reg.ip[66].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_66_qs) + ); + + // F[p_67]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_67 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[67].de), + .d (hw2reg.ip[67].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_67_qs) + ); + + // F[p_68]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_68 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[68].de), + .d (hw2reg.ip[68].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_68_qs) + ); + + // F[p_69]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_69 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[69].de), + .d (hw2reg.ip[69].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_69_qs) + ); + + // F[p_70]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_70 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[70].de), + .d (hw2reg.ip[70].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_70_qs) + ); + + // F[p_71]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_71 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[71].de), + .d (hw2reg.ip[71].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_71_qs) + ); + + // F[p_72]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_72 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[72].de), + .d (hw2reg.ip[72].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_72_qs) + ); + + // F[p_73]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_73 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[73].de), + .d (hw2reg.ip[73].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_73_qs) + ); + + // F[p_74]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_74 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[74].de), + .d (hw2reg.ip[74].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_74_qs) + ); + + // F[p_75]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_75 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[75].de), + .d (hw2reg.ip[75].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_75_qs) + ); + + // F[p_76]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_76 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[76].de), + .d (hw2reg.ip[76].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_76_qs) + ); + + // F[p_77]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_77 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[77].de), + .d (hw2reg.ip[77].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_77_qs) + ); + + // F[p_78]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_78 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[78].de), + .d (hw2reg.ip[78].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_78_qs) + ); + + // F[p_79]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_79 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[79].de), + .d (hw2reg.ip[79].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_79_qs) + ); + + // F[p_80]: 16:16 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_80 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[80].de), + .d (hw2reg.ip[80].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_80_qs) + ); + + // F[p_81]: 17:17 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_81 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[81].de), + .d (hw2reg.ip[81].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_81_qs) + ); + + // F[p_82]: 18:18 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_82 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[82].de), + .d (hw2reg.ip[82].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_82_qs) + ); + + // F[p_83]: 19:19 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_83 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[83].de), + .d (hw2reg.ip[83].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_83_qs) + ); + + // F[p_84]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_84 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[84].de), + .d (hw2reg.ip[84].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_84_qs) + ); + + // F[p_85]: 21:21 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_85 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[85].de), + .d (hw2reg.ip[85].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_85_qs) + ); + + // F[p_86]: 22:22 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_86 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[86].de), + .d (hw2reg.ip[86].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_86_qs) + ); + + // F[p_87]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRO), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ip_2_p_87 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (1'b0), + .wd ('0), + + // from internal hardware + .de (hw2reg.ip[87].de), + .d (hw2reg.ip[87].d), + + // to internal hardware + .qe (), + .q (), + .ds (), + + // to register interface (read) + .qs (ip_2_p_87_qs) + ); + + + // Subregister 0 of Multireg ie0 + // R[ie0_0]: V(False) + // F[e_0]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[0].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_0_qs) + ); + + // F[e_1]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_1 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_1_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[1].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_1_qs) + ); + + // F[e_2]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_2 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_2_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[2].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_2_qs) + ); + + // F[e_3]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_3 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_3_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[3].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_3_qs) + ); + + // F[e_4]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_4 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_4_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[4].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_4_qs) + ); + + // F[e_5]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_5 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_5_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[5].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_5_qs) + ); + + // F[e_6]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_6 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_6_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[6].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_6_qs) + ); + + // F[e_7]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_7 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_7_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[7].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_7_qs) + ); + + // F[e_8]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_8 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_8_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[8].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_8_qs) + ); + + // F[e_9]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_9 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_9_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[9].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_9_qs) + ); + + // F[e_10]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_10 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_10_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[10].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_10_qs) + ); + + // F[e_11]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_11 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_11_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[11].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_11_qs) + ); + + // F[e_12]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_12 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_12_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[12].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_12_qs) + ); + + // F[e_13]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_13 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_13_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[13].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_13_qs) + ); + + // F[e_14]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_14 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_14_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[14].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_14_qs) + ); + + // F[e_15]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_15 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_15_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[15].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_15_qs) + ); + + // F[e_16]: 16:16 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_16 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_16_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[16].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_16_qs) + ); + + // F[e_17]: 17:17 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_17 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_17_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[17].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_17_qs) + ); + + // F[e_18]: 18:18 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_18 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_18_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[18].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_18_qs) + ); + + // F[e_19]: 19:19 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_19 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_19_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[19].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_19_qs) + ); + + // F[e_20]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_20 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_20_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[20].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_20_qs) + ); + + // F[e_21]: 21:21 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_21 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_21_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[21].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_21_qs) + ); + + // F[e_22]: 22:22 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_22 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_22_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[22].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_22_qs) + ); + + // F[e_23]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_23 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_23_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[23].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_23_qs) + ); + + // F[e_24]: 24:24 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_24 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_24_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[24].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_24_qs) + ); + + // F[e_25]: 25:25 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_25 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_25_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[25].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_25_qs) + ); + + // F[e_26]: 26:26 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_26 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_26_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[26].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_26_qs) + ); + + // F[e_27]: 27:27 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_27 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_27_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[27].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_27_qs) + ); + + // F[e_28]: 28:28 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_28 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_28_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[28].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_28_qs) + ); + + // F[e_29]: 29:29 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_29 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_29_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[29].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_29_qs) + ); + + // F[e_30]: 30:30 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_30 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_30_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[30].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_30_qs) + ); + + // F[e_31]: 31:31 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_0_e_31 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_0_we), + .wd (ie0_0_e_31_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[31].q), + .ds (), + + // to register interface (read) + .qs (ie0_0_e_31_qs) + ); + + + // Subregister 1 of Multireg ie0 + // R[ie0_1]: V(False) + // F[e_32]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_32 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_32_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[32].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_32_qs) + ); + + // F[e_33]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_33 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_33_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[33].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_33_qs) + ); + + // F[e_34]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_34 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_34_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[34].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_34_qs) + ); + + // F[e_35]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_35 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_35_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[35].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_35_qs) + ); + + // F[e_36]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_36 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_36_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[36].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_36_qs) + ); + + // F[e_37]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_37 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_37_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[37].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_37_qs) + ); + + // F[e_38]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_38 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_38_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[38].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_38_qs) + ); + + // F[e_39]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_39 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_39_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[39].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_39_qs) + ); + + // F[e_40]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_40 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_40_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[40].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_40_qs) + ); + + // F[e_41]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_41 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_41_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[41].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_41_qs) + ); + + // F[e_42]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_42 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_42_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[42].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_42_qs) + ); + + // F[e_43]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_43 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_43_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[43].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_43_qs) + ); + + // F[e_44]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_44 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_44_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[44].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_44_qs) + ); + + // F[e_45]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_45 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_45_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[45].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_45_qs) + ); + + // F[e_46]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_46 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_46_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[46].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_46_qs) + ); + + // F[e_47]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_47 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_47_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[47].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_47_qs) + ); + + // F[e_48]: 16:16 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_48 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_48_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[48].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_48_qs) + ); + + // F[e_49]: 17:17 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_49 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_49_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[49].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_49_qs) + ); + + // F[e_50]: 18:18 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_50 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_50_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[50].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_50_qs) + ); + + // F[e_51]: 19:19 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_51 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_51_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[51].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_51_qs) + ); + + // F[e_52]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_52 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_52_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[52].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_52_qs) + ); + + // F[e_53]: 21:21 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_53 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_53_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[53].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_53_qs) + ); + + // F[e_54]: 22:22 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_54 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_54_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[54].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_54_qs) + ); + + // F[e_55]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_55 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_55_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[55].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_55_qs) + ); + + // F[e_56]: 24:24 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_56 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_56_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[56].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_56_qs) + ); + + // F[e_57]: 25:25 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_57 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_57_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[57].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_57_qs) + ); + + // F[e_58]: 26:26 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_58 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_58_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[58].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_58_qs) + ); + + // F[e_59]: 27:27 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_59 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_59_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[59].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_59_qs) + ); + + // F[e_60]: 28:28 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_60 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_60_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[60].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_60_qs) + ); + + // F[e_61]: 29:29 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_61 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_61_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[61].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_61_qs) + ); + + // F[e_62]: 30:30 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_62 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_62_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[62].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_62_qs) + ); + + // F[e_63]: 31:31 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_1_e_63 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_1_we), + .wd (ie0_1_e_63_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[63].q), + .ds (), + + // to register interface (read) + .qs (ie0_1_e_63_qs) + ); + + + // Subregister 2 of Multireg ie0 + // R[ie0_2]: V(False) + // F[e_64]: 0:0 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_64 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_64_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[64].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_64_qs) + ); + + // F[e_65]: 1:1 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_65 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_65_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[65].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_65_qs) + ); + + // F[e_66]: 2:2 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_66 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_66_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[66].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_66_qs) + ); + + // F[e_67]: 3:3 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_67 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_67_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[67].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_67_qs) + ); + + // F[e_68]: 4:4 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_68 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_68_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[68].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_68_qs) + ); + + // F[e_69]: 5:5 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_69 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_69_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[69].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_69_qs) + ); + + // F[e_70]: 6:6 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_70 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_70_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[70].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_70_qs) + ); + + // F[e_71]: 7:7 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_71 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_71_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[71].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_71_qs) + ); + + // F[e_72]: 8:8 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_72 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_72_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[72].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_72_qs) + ); + + // F[e_73]: 9:9 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_73 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_73_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[73].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_73_qs) + ); + + // F[e_74]: 10:10 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_74 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_74_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[74].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_74_qs) + ); + + // F[e_75]: 11:11 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_75 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_75_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[75].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_75_qs) + ); + + // F[e_76]: 12:12 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_76 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_76_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[76].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_76_qs) + ); + + // F[e_77]: 13:13 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_77 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_77_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[77].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_77_qs) + ); + + // F[e_78]: 14:14 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_78 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_78_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[78].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_78_qs) + ); + + // F[e_79]: 15:15 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_79 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_79_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[79].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_79_qs) + ); + + // F[e_80]: 16:16 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_80 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_80_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[80].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_80_qs) + ); + + // F[e_81]: 17:17 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_81 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_81_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[81].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_81_qs) + ); + + // F[e_82]: 18:18 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_82 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_82_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[82].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_82_qs) + ); + + // F[e_83]: 19:19 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_83 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_83_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[83].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_83_qs) + ); + + // F[e_84]: 20:20 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_84 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_84_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[84].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_84_qs) + ); + + // F[e_85]: 21:21 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_85 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_85_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[85].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_85_qs) + ); + + // F[e_86]: 22:22 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_86 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_86_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[86].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_86_qs) + ); + + // F[e_87]: 23:23 + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_ie0_2_e_87 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (ie0_2_we), + .wd (ie0_2_e_87_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.ie0[87].q), + .ds (), + + // to register interface (read) + .qs (ie0_2_e_87_qs) + ); + + + // R[threshold0]: V(False) + prim_subreg #( + .DW (2), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (2'h0), + .Mubi (1'b0) + ) u_threshold0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (threshold0_we), + .wd (threshold0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.threshold0.q), + .ds (), + + // to register interface (read) + .qs (threshold0_qs) + ); + + + // R[cc0]: V(True) + logic cc0_qe; + logic [0:0] cc0_flds_we; + assign cc0_qe = &cc0_flds_we; + prim_subreg_ext #( + .DW (7) + ) u_cc0 ( + .re (cc0_re), + .we (cc0_we), + .wd (cc0_wd), + .d (hw2reg.cc0.d), + .qre (reg2hw.cc0.re), + .qe (cc0_flds_we[0]), + .q (reg2hw.cc0.q), + .ds (), + .qs (cc0_qs) + ); + assign reg2hw.cc0.qe = cc0_qe; + + + // R[msip0]: V(False) + prim_subreg #( + .DW (1), + .SwAccess(prim_subreg_pkg::SwAccessRW), + .RESVAL (1'h0), + .Mubi (1'b0) + ) u_msip0 ( + .clk_i (clk_i), + .rst_ni (rst_ni), + + // from register interface + .we (msip0_we), + .wd (msip0_wd), + + // from internal hardware + .de (1'b0), + .d ('0), + + // to internal hardware + .qe (), + .q (reg2hw.msip0.q), + .ds (), + + // to register interface (read) + .qs (msip0_qs) + ); + + + // 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; + + + + logic [97:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[ 0] = (reg_addr == RV_PLIC_PRIO0_OFFSET); + addr_hit[ 1] = (reg_addr == RV_PLIC_PRIO1_OFFSET); + addr_hit[ 2] = (reg_addr == RV_PLIC_PRIO2_OFFSET); + addr_hit[ 3] = (reg_addr == RV_PLIC_PRIO3_OFFSET); + addr_hit[ 4] = (reg_addr == RV_PLIC_PRIO4_OFFSET); + addr_hit[ 5] = (reg_addr == RV_PLIC_PRIO5_OFFSET); + addr_hit[ 6] = (reg_addr == RV_PLIC_PRIO6_OFFSET); + addr_hit[ 7] = (reg_addr == RV_PLIC_PRIO7_OFFSET); + addr_hit[ 8] = (reg_addr == RV_PLIC_PRIO8_OFFSET); + addr_hit[ 9] = (reg_addr == RV_PLIC_PRIO9_OFFSET); + addr_hit[10] = (reg_addr == RV_PLIC_PRIO10_OFFSET); + addr_hit[11] = (reg_addr == RV_PLIC_PRIO11_OFFSET); + addr_hit[12] = (reg_addr == RV_PLIC_PRIO12_OFFSET); + addr_hit[13] = (reg_addr == RV_PLIC_PRIO13_OFFSET); + addr_hit[14] = (reg_addr == RV_PLIC_PRIO14_OFFSET); + addr_hit[15] = (reg_addr == RV_PLIC_PRIO15_OFFSET); + addr_hit[16] = (reg_addr == RV_PLIC_PRIO16_OFFSET); + addr_hit[17] = (reg_addr == RV_PLIC_PRIO17_OFFSET); + addr_hit[18] = (reg_addr == RV_PLIC_PRIO18_OFFSET); + addr_hit[19] = (reg_addr == RV_PLIC_PRIO19_OFFSET); + addr_hit[20] = (reg_addr == RV_PLIC_PRIO20_OFFSET); + addr_hit[21] = (reg_addr == RV_PLIC_PRIO21_OFFSET); + addr_hit[22] = (reg_addr == RV_PLIC_PRIO22_OFFSET); + addr_hit[23] = (reg_addr == RV_PLIC_PRIO23_OFFSET); + addr_hit[24] = (reg_addr == RV_PLIC_PRIO24_OFFSET); + addr_hit[25] = (reg_addr == RV_PLIC_PRIO25_OFFSET); + addr_hit[26] = (reg_addr == RV_PLIC_PRIO26_OFFSET); + addr_hit[27] = (reg_addr == RV_PLIC_PRIO27_OFFSET); + addr_hit[28] = (reg_addr == RV_PLIC_PRIO28_OFFSET); + addr_hit[29] = (reg_addr == RV_PLIC_PRIO29_OFFSET); + addr_hit[30] = (reg_addr == RV_PLIC_PRIO30_OFFSET); + addr_hit[31] = (reg_addr == RV_PLIC_PRIO31_OFFSET); + addr_hit[32] = (reg_addr == RV_PLIC_PRIO32_OFFSET); + addr_hit[33] = (reg_addr == RV_PLIC_PRIO33_OFFSET); + addr_hit[34] = (reg_addr == RV_PLIC_PRIO34_OFFSET); + addr_hit[35] = (reg_addr == RV_PLIC_PRIO35_OFFSET); + addr_hit[36] = (reg_addr == RV_PLIC_PRIO36_OFFSET); + addr_hit[37] = (reg_addr == RV_PLIC_PRIO37_OFFSET); + addr_hit[38] = (reg_addr == RV_PLIC_PRIO38_OFFSET); + addr_hit[39] = (reg_addr == RV_PLIC_PRIO39_OFFSET); + addr_hit[40] = (reg_addr == RV_PLIC_PRIO40_OFFSET); + addr_hit[41] = (reg_addr == RV_PLIC_PRIO41_OFFSET); + addr_hit[42] = (reg_addr == RV_PLIC_PRIO42_OFFSET); + addr_hit[43] = (reg_addr == RV_PLIC_PRIO43_OFFSET); + addr_hit[44] = (reg_addr == RV_PLIC_PRIO44_OFFSET); + addr_hit[45] = (reg_addr == RV_PLIC_PRIO45_OFFSET); + addr_hit[46] = (reg_addr == RV_PLIC_PRIO46_OFFSET); + addr_hit[47] = (reg_addr == RV_PLIC_PRIO47_OFFSET); + addr_hit[48] = (reg_addr == RV_PLIC_PRIO48_OFFSET); + addr_hit[49] = (reg_addr == RV_PLIC_PRIO49_OFFSET); + addr_hit[50] = (reg_addr == RV_PLIC_PRIO50_OFFSET); + addr_hit[51] = (reg_addr == RV_PLIC_PRIO51_OFFSET); + addr_hit[52] = (reg_addr == RV_PLIC_PRIO52_OFFSET); + addr_hit[53] = (reg_addr == RV_PLIC_PRIO53_OFFSET); + addr_hit[54] = (reg_addr == RV_PLIC_PRIO54_OFFSET); + addr_hit[55] = (reg_addr == RV_PLIC_PRIO55_OFFSET); + addr_hit[56] = (reg_addr == RV_PLIC_PRIO56_OFFSET); + addr_hit[57] = (reg_addr == RV_PLIC_PRIO57_OFFSET); + addr_hit[58] = (reg_addr == RV_PLIC_PRIO58_OFFSET); + addr_hit[59] = (reg_addr == RV_PLIC_PRIO59_OFFSET); + addr_hit[60] = (reg_addr == RV_PLIC_PRIO60_OFFSET); + addr_hit[61] = (reg_addr == RV_PLIC_PRIO61_OFFSET); + addr_hit[62] = (reg_addr == RV_PLIC_PRIO62_OFFSET); + addr_hit[63] = (reg_addr == RV_PLIC_PRIO63_OFFSET); + addr_hit[64] = (reg_addr == RV_PLIC_PRIO64_OFFSET); + addr_hit[65] = (reg_addr == RV_PLIC_PRIO65_OFFSET); + addr_hit[66] = (reg_addr == RV_PLIC_PRIO66_OFFSET); + addr_hit[67] = (reg_addr == RV_PLIC_PRIO67_OFFSET); + addr_hit[68] = (reg_addr == RV_PLIC_PRIO68_OFFSET); + addr_hit[69] = (reg_addr == RV_PLIC_PRIO69_OFFSET); + addr_hit[70] = (reg_addr == RV_PLIC_PRIO70_OFFSET); + addr_hit[71] = (reg_addr == RV_PLIC_PRIO71_OFFSET); + addr_hit[72] = (reg_addr == RV_PLIC_PRIO72_OFFSET); + addr_hit[73] = (reg_addr == RV_PLIC_PRIO73_OFFSET); + addr_hit[74] = (reg_addr == RV_PLIC_PRIO74_OFFSET); + addr_hit[75] = (reg_addr == RV_PLIC_PRIO75_OFFSET); + addr_hit[76] = (reg_addr == RV_PLIC_PRIO76_OFFSET); + addr_hit[77] = (reg_addr == RV_PLIC_PRIO77_OFFSET); + addr_hit[78] = (reg_addr == RV_PLIC_PRIO78_OFFSET); + addr_hit[79] = (reg_addr == RV_PLIC_PRIO79_OFFSET); + addr_hit[80] = (reg_addr == RV_PLIC_PRIO80_OFFSET); + addr_hit[81] = (reg_addr == RV_PLIC_PRIO81_OFFSET); + addr_hit[82] = (reg_addr == RV_PLIC_PRIO82_OFFSET); + addr_hit[83] = (reg_addr == RV_PLIC_PRIO83_OFFSET); + addr_hit[84] = (reg_addr == RV_PLIC_PRIO84_OFFSET); + addr_hit[85] = (reg_addr == RV_PLIC_PRIO85_OFFSET); + addr_hit[86] = (reg_addr == RV_PLIC_PRIO86_OFFSET); + addr_hit[87] = (reg_addr == RV_PLIC_PRIO87_OFFSET); + addr_hit[88] = (reg_addr == RV_PLIC_IP_0_OFFSET); + addr_hit[89] = (reg_addr == RV_PLIC_IP_1_OFFSET); + addr_hit[90] = (reg_addr == RV_PLIC_IP_2_OFFSET); + addr_hit[91] = (reg_addr == RV_PLIC_IE0_0_OFFSET); + addr_hit[92] = (reg_addr == RV_PLIC_IE0_1_OFFSET); + addr_hit[93] = (reg_addr == RV_PLIC_IE0_2_OFFSET); + addr_hit[94] = (reg_addr == RV_PLIC_THRESHOLD0_OFFSET); + addr_hit[95] = (reg_addr == RV_PLIC_CC0_OFFSET); + addr_hit[96] = (reg_addr == RV_PLIC_MSIP0_OFFSET); + addr_hit[97] = (reg_addr == RV_PLIC_ALERT_TEST_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] & (|(RV_PLIC_PERMIT[ 0] & ~reg_be))) | + (addr_hit[ 1] & (|(RV_PLIC_PERMIT[ 1] & ~reg_be))) | + (addr_hit[ 2] & (|(RV_PLIC_PERMIT[ 2] & ~reg_be))) | + (addr_hit[ 3] & (|(RV_PLIC_PERMIT[ 3] & ~reg_be))) | + (addr_hit[ 4] & (|(RV_PLIC_PERMIT[ 4] & ~reg_be))) | + (addr_hit[ 5] & (|(RV_PLIC_PERMIT[ 5] & ~reg_be))) | + (addr_hit[ 6] & (|(RV_PLIC_PERMIT[ 6] & ~reg_be))) | + (addr_hit[ 7] & (|(RV_PLIC_PERMIT[ 7] & ~reg_be))) | + (addr_hit[ 8] & (|(RV_PLIC_PERMIT[ 8] & ~reg_be))) | + (addr_hit[ 9] & (|(RV_PLIC_PERMIT[ 9] & ~reg_be))) | + (addr_hit[10] & (|(RV_PLIC_PERMIT[10] & ~reg_be))) | + (addr_hit[11] & (|(RV_PLIC_PERMIT[11] & ~reg_be))) | + (addr_hit[12] & (|(RV_PLIC_PERMIT[12] & ~reg_be))) | + (addr_hit[13] & (|(RV_PLIC_PERMIT[13] & ~reg_be))) | + (addr_hit[14] & (|(RV_PLIC_PERMIT[14] & ~reg_be))) | + (addr_hit[15] & (|(RV_PLIC_PERMIT[15] & ~reg_be))) | + (addr_hit[16] & (|(RV_PLIC_PERMIT[16] & ~reg_be))) | + (addr_hit[17] & (|(RV_PLIC_PERMIT[17] & ~reg_be))) | + (addr_hit[18] & (|(RV_PLIC_PERMIT[18] & ~reg_be))) | + (addr_hit[19] & (|(RV_PLIC_PERMIT[19] & ~reg_be))) | + (addr_hit[20] & (|(RV_PLIC_PERMIT[20] & ~reg_be))) | + (addr_hit[21] & (|(RV_PLIC_PERMIT[21] & ~reg_be))) | + (addr_hit[22] & (|(RV_PLIC_PERMIT[22] & ~reg_be))) | + (addr_hit[23] & (|(RV_PLIC_PERMIT[23] & ~reg_be))) | + (addr_hit[24] & (|(RV_PLIC_PERMIT[24] & ~reg_be))) | + (addr_hit[25] & (|(RV_PLIC_PERMIT[25] & ~reg_be))) | + (addr_hit[26] & (|(RV_PLIC_PERMIT[26] & ~reg_be))) | + (addr_hit[27] & (|(RV_PLIC_PERMIT[27] & ~reg_be))) | + (addr_hit[28] & (|(RV_PLIC_PERMIT[28] & ~reg_be))) | + (addr_hit[29] & (|(RV_PLIC_PERMIT[29] & ~reg_be))) | + (addr_hit[30] & (|(RV_PLIC_PERMIT[30] & ~reg_be))) | + (addr_hit[31] & (|(RV_PLIC_PERMIT[31] & ~reg_be))) | + (addr_hit[32] & (|(RV_PLIC_PERMIT[32] & ~reg_be))) | + (addr_hit[33] & (|(RV_PLIC_PERMIT[33] & ~reg_be))) | + (addr_hit[34] & (|(RV_PLIC_PERMIT[34] & ~reg_be))) | + (addr_hit[35] & (|(RV_PLIC_PERMIT[35] & ~reg_be))) | + (addr_hit[36] & (|(RV_PLIC_PERMIT[36] & ~reg_be))) | + (addr_hit[37] & (|(RV_PLIC_PERMIT[37] & ~reg_be))) | + (addr_hit[38] & (|(RV_PLIC_PERMIT[38] & ~reg_be))) | + (addr_hit[39] & (|(RV_PLIC_PERMIT[39] & ~reg_be))) | + (addr_hit[40] & (|(RV_PLIC_PERMIT[40] & ~reg_be))) | + (addr_hit[41] & (|(RV_PLIC_PERMIT[41] & ~reg_be))) | + (addr_hit[42] & (|(RV_PLIC_PERMIT[42] & ~reg_be))) | + (addr_hit[43] & (|(RV_PLIC_PERMIT[43] & ~reg_be))) | + (addr_hit[44] & (|(RV_PLIC_PERMIT[44] & ~reg_be))) | + (addr_hit[45] & (|(RV_PLIC_PERMIT[45] & ~reg_be))) | + (addr_hit[46] & (|(RV_PLIC_PERMIT[46] & ~reg_be))) | + (addr_hit[47] & (|(RV_PLIC_PERMIT[47] & ~reg_be))) | + (addr_hit[48] & (|(RV_PLIC_PERMIT[48] & ~reg_be))) | + (addr_hit[49] & (|(RV_PLIC_PERMIT[49] & ~reg_be))) | + (addr_hit[50] & (|(RV_PLIC_PERMIT[50] & ~reg_be))) | + (addr_hit[51] & (|(RV_PLIC_PERMIT[51] & ~reg_be))) | + (addr_hit[52] & (|(RV_PLIC_PERMIT[52] & ~reg_be))) | + (addr_hit[53] & (|(RV_PLIC_PERMIT[53] & ~reg_be))) | + (addr_hit[54] & (|(RV_PLIC_PERMIT[54] & ~reg_be))) | + (addr_hit[55] & (|(RV_PLIC_PERMIT[55] & ~reg_be))) | + (addr_hit[56] & (|(RV_PLIC_PERMIT[56] & ~reg_be))) | + (addr_hit[57] & (|(RV_PLIC_PERMIT[57] & ~reg_be))) | + (addr_hit[58] & (|(RV_PLIC_PERMIT[58] & ~reg_be))) | + (addr_hit[59] & (|(RV_PLIC_PERMIT[59] & ~reg_be))) | + (addr_hit[60] & (|(RV_PLIC_PERMIT[60] & ~reg_be))) | + (addr_hit[61] & (|(RV_PLIC_PERMIT[61] & ~reg_be))) | + (addr_hit[62] & (|(RV_PLIC_PERMIT[62] & ~reg_be))) | + (addr_hit[63] & (|(RV_PLIC_PERMIT[63] & ~reg_be))) | + (addr_hit[64] & (|(RV_PLIC_PERMIT[64] & ~reg_be))) | + (addr_hit[65] & (|(RV_PLIC_PERMIT[65] & ~reg_be))) | + (addr_hit[66] & (|(RV_PLIC_PERMIT[66] & ~reg_be))) | + (addr_hit[67] & (|(RV_PLIC_PERMIT[67] & ~reg_be))) | + (addr_hit[68] & (|(RV_PLIC_PERMIT[68] & ~reg_be))) | + (addr_hit[69] & (|(RV_PLIC_PERMIT[69] & ~reg_be))) | + (addr_hit[70] & (|(RV_PLIC_PERMIT[70] & ~reg_be))) | + (addr_hit[71] & (|(RV_PLIC_PERMIT[71] & ~reg_be))) | + (addr_hit[72] & (|(RV_PLIC_PERMIT[72] & ~reg_be))) | + (addr_hit[73] & (|(RV_PLIC_PERMIT[73] & ~reg_be))) | + (addr_hit[74] & (|(RV_PLIC_PERMIT[74] & ~reg_be))) | + (addr_hit[75] & (|(RV_PLIC_PERMIT[75] & ~reg_be))) | + (addr_hit[76] & (|(RV_PLIC_PERMIT[76] & ~reg_be))) | + (addr_hit[77] & (|(RV_PLIC_PERMIT[77] & ~reg_be))) | + (addr_hit[78] & (|(RV_PLIC_PERMIT[78] & ~reg_be))) | + (addr_hit[79] & (|(RV_PLIC_PERMIT[79] & ~reg_be))) | + (addr_hit[80] & (|(RV_PLIC_PERMIT[80] & ~reg_be))) | + (addr_hit[81] & (|(RV_PLIC_PERMIT[81] & ~reg_be))) | + (addr_hit[82] & (|(RV_PLIC_PERMIT[82] & ~reg_be))) | + (addr_hit[83] & (|(RV_PLIC_PERMIT[83] & ~reg_be))) | + (addr_hit[84] & (|(RV_PLIC_PERMIT[84] & ~reg_be))) | + (addr_hit[85] & (|(RV_PLIC_PERMIT[85] & ~reg_be))) | + (addr_hit[86] & (|(RV_PLIC_PERMIT[86] & ~reg_be))) | + (addr_hit[87] & (|(RV_PLIC_PERMIT[87] & ~reg_be))) | + (addr_hit[88] & (|(RV_PLIC_PERMIT[88] & ~reg_be))) | + (addr_hit[89] & (|(RV_PLIC_PERMIT[89] & ~reg_be))) | + (addr_hit[90] & (|(RV_PLIC_PERMIT[90] & ~reg_be))) | + (addr_hit[91] & (|(RV_PLIC_PERMIT[91] & ~reg_be))) | + (addr_hit[92] & (|(RV_PLIC_PERMIT[92] & ~reg_be))) | + (addr_hit[93] & (|(RV_PLIC_PERMIT[93] & ~reg_be))) | + (addr_hit[94] & (|(RV_PLIC_PERMIT[94] & ~reg_be))) | + (addr_hit[95] & (|(RV_PLIC_PERMIT[95] & ~reg_be))) | + (addr_hit[96] & (|(RV_PLIC_PERMIT[96] & ~reg_be))) | + (addr_hit[97] & (|(RV_PLIC_PERMIT[97] & ~reg_be))))); + end + + // Generate write-enables + assign prio0_we = addr_hit[0] & reg_we & !reg_error; + + assign prio0_wd = reg_wdata[1:0]; + assign prio1_we = addr_hit[1] & reg_we & !reg_error; + + assign prio1_wd = reg_wdata[1:0]; + assign prio2_we = addr_hit[2] & reg_we & !reg_error; + + assign prio2_wd = reg_wdata[1:0]; + assign prio3_we = addr_hit[3] & reg_we & !reg_error; + + assign prio3_wd = reg_wdata[1:0]; + assign prio4_we = addr_hit[4] & reg_we & !reg_error; + + assign prio4_wd = reg_wdata[1:0]; + assign prio5_we = addr_hit[5] & reg_we & !reg_error; + + assign prio5_wd = reg_wdata[1:0]; + assign prio6_we = addr_hit[6] & reg_we & !reg_error; + + assign prio6_wd = reg_wdata[1:0]; + assign prio7_we = addr_hit[7] & reg_we & !reg_error; + + assign prio7_wd = reg_wdata[1:0]; + assign prio8_we = addr_hit[8] & reg_we & !reg_error; + + assign prio8_wd = reg_wdata[1:0]; + assign prio9_we = addr_hit[9] & reg_we & !reg_error; + + assign prio9_wd = reg_wdata[1:0]; + assign prio10_we = addr_hit[10] & reg_we & !reg_error; + + assign prio10_wd = reg_wdata[1:0]; + assign prio11_we = addr_hit[11] & reg_we & !reg_error; + + assign prio11_wd = reg_wdata[1:0]; + assign prio12_we = addr_hit[12] & reg_we & !reg_error; + + assign prio12_wd = reg_wdata[1:0]; + assign prio13_we = addr_hit[13] & reg_we & !reg_error; + + assign prio13_wd = reg_wdata[1:0]; + assign prio14_we = addr_hit[14] & reg_we & !reg_error; + + assign prio14_wd = reg_wdata[1:0]; + assign prio15_we = addr_hit[15] & reg_we & !reg_error; + + assign prio15_wd = reg_wdata[1:0]; + assign prio16_we = addr_hit[16] & reg_we & !reg_error; + + assign prio16_wd = reg_wdata[1:0]; + assign prio17_we = addr_hit[17] & reg_we & !reg_error; + + assign prio17_wd = reg_wdata[1:0]; + assign prio18_we = addr_hit[18] & reg_we & !reg_error; + + assign prio18_wd = reg_wdata[1:0]; + assign prio19_we = addr_hit[19] & reg_we & !reg_error; + + assign prio19_wd = reg_wdata[1:0]; + assign prio20_we = addr_hit[20] & reg_we & !reg_error; + + assign prio20_wd = reg_wdata[1:0]; + assign prio21_we = addr_hit[21] & reg_we & !reg_error; + + assign prio21_wd = reg_wdata[1:0]; + assign prio22_we = addr_hit[22] & reg_we & !reg_error; + + assign prio22_wd = reg_wdata[1:0]; + assign prio23_we = addr_hit[23] & reg_we & !reg_error; + + assign prio23_wd = reg_wdata[1:0]; + assign prio24_we = addr_hit[24] & reg_we & !reg_error; + + assign prio24_wd = reg_wdata[1:0]; + assign prio25_we = addr_hit[25] & reg_we & !reg_error; + + assign prio25_wd = reg_wdata[1:0]; + assign prio26_we = addr_hit[26] & reg_we & !reg_error; + + assign prio26_wd = reg_wdata[1:0]; + assign prio27_we = addr_hit[27] & reg_we & !reg_error; + + assign prio27_wd = reg_wdata[1:0]; + assign prio28_we = addr_hit[28] & reg_we & !reg_error; + + assign prio28_wd = reg_wdata[1:0]; + assign prio29_we = addr_hit[29] & reg_we & !reg_error; + + assign prio29_wd = reg_wdata[1:0]; + assign prio30_we = addr_hit[30] & reg_we & !reg_error; + + assign prio30_wd = reg_wdata[1:0]; + assign prio31_we = addr_hit[31] & reg_we & !reg_error; + + assign prio31_wd = reg_wdata[1:0]; + assign prio32_we = addr_hit[32] & reg_we & !reg_error; + + assign prio32_wd = reg_wdata[1:0]; + assign prio33_we = addr_hit[33] & reg_we & !reg_error; + + assign prio33_wd = reg_wdata[1:0]; + assign prio34_we = addr_hit[34] & reg_we & !reg_error; + + assign prio34_wd = reg_wdata[1:0]; + assign prio35_we = addr_hit[35] & reg_we & !reg_error; + + assign prio35_wd = reg_wdata[1:0]; + assign prio36_we = addr_hit[36] & reg_we & !reg_error; + + assign prio36_wd = reg_wdata[1:0]; + assign prio37_we = addr_hit[37] & reg_we & !reg_error; + + assign prio37_wd = reg_wdata[1:0]; + assign prio38_we = addr_hit[38] & reg_we & !reg_error; + + assign prio38_wd = reg_wdata[1:0]; + assign prio39_we = addr_hit[39] & reg_we & !reg_error; + + assign prio39_wd = reg_wdata[1:0]; + assign prio40_we = addr_hit[40] & reg_we & !reg_error; + + assign prio40_wd = reg_wdata[1:0]; + assign prio41_we = addr_hit[41] & reg_we & !reg_error; + + assign prio41_wd = reg_wdata[1:0]; + assign prio42_we = addr_hit[42] & reg_we & !reg_error; + + assign prio42_wd = reg_wdata[1:0]; + assign prio43_we = addr_hit[43] & reg_we & !reg_error; + + assign prio43_wd = reg_wdata[1:0]; + assign prio44_we = addr_hit[44] & reg_we & !reg_error; + + assign prio44_wd = reg_wdata[1:0]; + assign prio45_we = addr_hit[45] & reg_we & !reg_error; + + assign prio45_wd = reg_wdata[1:0]; + assign prio46_we = addr_hit[46] & reg_we & !reg_error; + + assign prio46_wd = reg_wdata[1:0]; + assign prio47_we = addr_hit[47] & reg_we & !reg_error; + + assign prio47_wd = reg_wdata[1:0]; + assign prio48_we = addr_hit[48] & reg_we & !reg_error; + + assign prio48_wd = reg_wdata[1:0]; + assign prio49_we = addr_hit[49] & reg_we & !reg_error; + + assign prio49_wd = reg_wdata[1:0]; + assign prio50_we = addr_hit[50] & reg_we & !reg_error; + + assign prio50_wd = reg_wdata[1:0]; + assign prio51_we = addr_hit[51] & reg_we & !reg_error; + + assign prio51_wd = reg_wdata[1:0]; + assign prio52_we = addr_hit[52] & reg_we & !reg_error; + + assign prio52_wd = reg_wdata[1:0]; + assign prio53_we = addr_hit[53] & reg_we & !reg_error; + + assign prio53_wd = reg_wdata[1:0]; + assign prio54_we = addr_hit[54] & reg_we & !reg_error; + + assign prio54_wd = reg_wdata[1:0]; + assign prio55_we = addr_hit[55] & reg_we & !reg_error; + + assign prio55_wd = reg_wdata[1:0]; + assign prio56_we = addr_hit[56] & reg_we & !reg_error; + + assign prio56_wd = reg_wdata[1:0]; + assign prio57_we = addr_hit[57] & reg_we & !reg_error; + + assign prio57_wd = reg_wdata[1:0]; + assign prio58_we = addr_hit[58] & reg_we & !reg_error; + + assign prio58_wd = reg_wdata[1:0]; + assign prio59_we = addr_hit[59] & reg_we & !reg_error; + + assign prio59_wd = reg_wdata[1:0]; + assign prio60_we = addr_hit[60] & reg_we & !reg_error; + + assign prio60_wd = reg_wdata[1:0]; + assign prio61_we = addr_hit[61] & reg_we & !reg_error; + + assign prio61_wd = reg_wdata[1:0]; + assign prio62_we = addr_hit[62] & reg_we & !reg_error; + + assign prio62_wd = reg_wdata[1:0]; + assign prio63_we = addr_hit[63] & reg_we & !reg_error; + + assign prio63_wd = reg_wdata[1:0]; + assign prio64_we = addr_hit[64] & reg_we & !reg_error; + + assign prio64_wd = reg_wdata[1:0]; + assign prio65_we = addr_hit[65] & reg_we & !reg_error; + + assign prio65_wd = reg_wdata[1:0]; + assign prio66_we = addr_hit[66] & reg_we & !reg_error; + + assign prio66_wd = reg_wdata[1:0]; + assign prio67_we = addr_hit[67] & reg_we & !reg_error; + + assign prio67_wd = reg_wdata[1:0]; + assign prio68_we = addr_hit[68] & reg_we & !reg_error; + + assign prio68_wd = reg_wdata[1:0]; + assign prio69_we = addr_hit[69] & reg_we & !reg_error; + + assign prio69_wd = reg_wdata[1:0]; + assign prio70_we = addr_hit[70] & reg_we & !reg_error; + + assign prio70_wd = reg_wdata[1:0]; + assign prio71_we = addr_hit[71] & reg_we & !reg_error; + + assign prio71_wd = reg_wdata[1:0]; + assign prio72_we = addr_hit[72] & reg_we & !reg_error; + + assign prio72_wd = reg_wdata[1:0]; + assign prio73_we = addr_hit[73] & reg_we & !reg_error; + + assign prio73_wd = reg_wdata[1:0]; + assign prio74_we = addr_hit[74] & reg_we & !reg_error; + + assign prio74_wd = reg_wdata[1:0]; + assign prio75_we = addr_hit[75] & reg_we & !reg_error; + + assign prio75_wd = reg_wdata[1:0]; + assign prio76_we = addr_hit[76] & reg_we & !reg_error; + + assign prio76_wd = reg_wdata[1:0]; + assign prio77_we = addr_hit[77] & reg_we & !reg_error; + + assign prio77_wd = reg_wdata[1:0]; + assign prio78_we = addr_hit[78] & reg_we & !reg_error; + + assign prio78_wd = reg_wdata[1:0]; + assign prio79_we = addr_hit[79] & reg_we & !reg_error; + + assign prio79_wd = reg_wdata[1:0]; + assign prio80_we = addr_hit[80] & reg_we & !reg_error; + + assign prio80_wd = reg_wdata[1:0]; + assign prio81_we = addr_hit[81] & reg_we & !reg_error; + + assign prio81_wd = reg_wdata[1:0]; + assign prio82_we = addr_hit[82] & reg_we & !reg_error; + + assign prio82_wd = reg_wdata[1:0]; + assign prio83_we = addr_hit[83] & reg_we & !reg_error; + + assign prio83_wd = reg_wdata[1:0]; + assign prio84_we = addr_hit[84] & reg_we & !reg_error; + + assign prio84_wd = reg_wdata[1:0]; + assign prio85_we = addr_hit[85] & reg_we & !reg_error; + + assign prio85_wd = reg_wdata[1:0]; + assign prio86_we = addr_hit[86] & reg_we & !reg_error; + + assign prio86_wd = reg_wdata[1:0]; + assign prio87_we = addr_hit[87] & reg_we & !reg_error; + + assign prio87_wd = reg_wdata[1:0]; + assign ie0_0_we = addr_hit[91] & reg_we & !reg_error; + + assign ie0_0_e_0_wd = reg_wdata[0]; + + assign ie0_0_e_1_wd = reg_wdata[1]; + + assign ie0_0_e_2_wd = reg_wdata[2]; + + assign ie0_0_e_3_wd = reg_wdata[3]; + + assign ie0_0_e_4_wd = reg_wdata[4]; + + assign ie0_0_e_5_wd = reg_wdata[5]; + + assign ie0_0_e_6_wd = reg_wdata[6]; + + assign ie0_0_e_7_wd = reg_wdata[7]; + + assign ie0_0_e_8_wd = reg_wdata[8]; + + assign ie0_0_e_9_wd = reg_wdata[9]; + + assign ie0_0_e_10_wd = reg_wdata[10]; + + assign ie0_0_e_11_wd = reg_wdata[11]; + + assign ie0_0_e_12_wd = reg_wdata[12]; + + assign ie0_0_e_13_wd = reg_wdata[13]; + + assign ie0_0_e_14_wd = reg_wdata[14]; + + assign ie0_0_e_15_wd = reg_wdata[15]; + + assign ie0_0_e_16_wd = reg_wdata[16]; + + assign ie0_0_e_17_wd = reg_wdata[17]; + + assign ie0_0_e_18_wd = reg_wdata[18]; + + assign ie0_0_e_19_wd = reg_wdata[19]; + + assign ie0_0_e_20_wd = reg_wdata[20]; + + assign ie0_0_e_21_wd = reg_wdata[21]; + + assign ie0_0_e_22_wd = reg_wdata[22]; + + assign ie0_0_e_23_wd = reg_wdata[23]; + + assign ie0_0_e_24_wd = reg_wdata[24]; + + assign ie0_0_e_25_wd = reg_wdata[25]; + + assign ie0_0_e_26_wd = reg_wdata[26]; + + assign ie0_0_e_27_wd = reg_wdata[27]; + + assign ie0_0_e_28_wd = reg_wdata[28]; + + assign ie0_0_e_29_wd = reg_wdata[29]; + + assign ie0_0_e_30_wd = reg_wdata[30]; + + assign ie0_0_e_31_wd = reg_wdata[31]; + assign ie0_1_we = addr_hit[92] & reg_we & !reg_error; + + assign ie0_1_e_32_wd = reg_wdata[0]; + + assign ie0_1_e_33_wd = reg_wdata[1]; + + assign ie0_1_e_34_wd = reg_wdata[2]; + + assign ie0_1_e_35_wd = reg_wdata[3]; + + assign ie0_1_e_36_wd = reg_wdata[4]; + + assign ie0_1_e_37_wd = reg_wdata[5]; + + assign ie0_1_e_38_wd = reg_wdata[6]; + + assign ie0_1_e_39_wd = reg_wdata[7]; + + assign ie0_1_e_40_wd = reg_wdata[8]; + + assign ie0_1_e_41_wd = reg_wdata[9]; + + assign ie0_1_e_42_wd = reg_wdata[10]; + + assign ie0_1_e_43_wd = reg_wdata[11]; + + assign ie0_1_e_44_wd = reg_wdata[12]; + + assign ie0_1_e_45_wd = reg_wdata[13]; + + assign ie0_1_e_46_wd = reg_wdata[14]; + + assign ie0_1_e_47_wd = reg_wdata[15]; + + assign ie0_1_e_48_wd = reg_wdata[16]; + + assign ie0_1_e_49_wd = reg_wdata[17]; + + assign ie0_1_e_50_wd = reg_wdata[18]; + + assign ie0_1_e_51_wd = reg_wdata[19]; + + assign ie0_1_e_52_wd = reg_wdata[20]; + + assign ie0_1_e_53_wd = reg_wdata[21]; + + assign ie0_1_e_54_wd = reg_wdata[22]; + + assign ie0_1_e_55_wd = reg_wdata[23]; + + assign ie0_1_e_56_wd = reg_wdata[24]; + + assign ie0_1_e_57_wd = reg_wdata[25]; + + assign ie0_1_e_58_wd = reg_wdata[26]; + + assign ie0_1_e_59_wd = reg_wdata[27]; + + assign ie0_1_e_60_wd = reg_wdata[28]; + + assign ie0_1_e_61_wd = reg_wdata[29]; + + assign ie0_1_e_62_wd = reg_wdata[30]; + + assign ie0_1_e_63_wd = reg_wdata[31]; + assign ie0_2_we = addr_hit[93] & reg_we & !reg_error; + + assign ie0_2_e_64_wd = reg_wdata[0]; + + assign ie0_2_e_65_wd = reg_wdata[1]; + + assign ie0_2_e_66_wd = reg_wdata[2]; + + assign ie0_2_e_67_wd = reg_wdata[3]; + + assign ie0_2_e_68_wd = reg_wdata[4]; + + assign ie0_2_e_69_wd = reg_wdata[5]; + + assign ie0_2_e_70_wd = reg_wdata[6]; + + assign ie0_2_e_71_wd = reg_wdata[7]; + + assign ie0_2_e_72_wd = reg_wdata[8]; + + assign ie0_2_e_73_wd = reg_wdata[9]; + + assign ie0_2_e_74_wd = reg_wdata[10]; + + assign ie0_2_e_75_wd = reg_wdata[11]; + + assign ie0_2_e_76_wd = reg_wdata[12]; + + assign ie0_2_e_77_wd = reg_wdata[13]; + + assign ie0_2_e_78_wd = reg_wdata[14]; + + assign ie0_2_e_79_wd = reg_wdata[15]; + + assign ie0_2_e_80_wd = reg_wdata[16]; + + assign ie0_2_e_81_wd = reg_wdata[17]; + + assign ie0_2_e_82_wd = reg_wdata[18]; + + assign ie0_2_e_83_wd = reg_wdata[19]; + + assign ie0_2_e_84_wd = reg_wdata[20]; + + assign ie0_2_e_85_wd = reg_wdata[21]; + + assign ie0_2_e_86_wd = reg_wdata[22]; + + assign ie0_2_e_87_wd = reg_wdata[23]; + assign threshold0_we = addr_hit[94] & reg_we & !reg_error; + + assign threshold0_wd = reg_wdata[1:0]; + assign cc0_re = addr_hit[95] & reg_re & !reg_error; + assign cc0_we = addr_hit[95] & reg_we & !reg_error; + + assign cc0_wd = reg_wdata[6:0]; + assign msip0_we = addr_hit[96] & reg_we & !reg_error; + + assign msip0_wd = reg_wdata[0]; + assign alert_test_we = addr_hit[97] & reg_we & !reg_error; + + assign alert_test_wd = reg_wdata[0]; + + // Assign write-enables to checker logic vector. + always_comb begin + reg_we_check = '0; + reg_we_check[0] = prio0_we; + reg_we_check[1] = prio1_we; + reg_we_check[2] = prio2_we; + reg_we_check[3] = prio3_we; + reg_we_check[4] = prio4_we; + reg_we_check[5] = prio5_we; + reg_we_check[6] = prio6_we; + reg_we_check[7] = prio7_we; + reg_we_check[8] = prio8_we; + reg_we_check[9] = prio9_we; + reg_we_check[10] = prio10_we; + reg_we_check[11] = prio11_we; + reg_we_check[12] = prio12_we; + reg_we_check[13] = prio13_we; + reg_we_check[14] = prio14_we; + reg_we_check[15] = prio15_we; + reg_we_check[16] = prio16_we; + reg_we_check[17] = prio17_we; + reg_we_check[18] = prio18_we; + reg_we_check[19] = prio19_we; + reg_we_check[20] = prio20_we; + reg_we_check[21] = prio21_we; + reg_we_check[22] = prio22_we; + reg_we_check[23] = prio23_we; + reg_we_check[24] = prio24_we; + reg_we_check[25] = prio25_we; + reg_we_check[26] = prio26_we; + reg_we_check[27] = prio27_we; + reg_we_check[28] = prio28_we; + reg_we_check[29] = prio29_we; + reg_we_check[30] = prio30_we; + reg_we_check[31] = prio31_we; + reg_we_check[32] = prio32_we; + reg_we_check[33] = prio33_we; + reg_we_check[34] = prio34_we; + reg_we_check[35] = prio35_we; + reg_we_check[36] = prio36_we; + reg_we_check[37] = prio37_we; + reg_we_check[38] = prio38_we; + reg_we_check[39] = prio39_we; + reg_we_check[40] = prio40_we; + reg_we_check[41] = prio41_we; + reg_we_check[42] = prio42_we; + reg_we_check[43] = prio43_we; + reg_we_check[44] = prio44_we; + reg_we_check[45] = prio45_we; + reg_we_check[46] = prio46_we; + reg_we_check[47] = prio47_we; + reg_we_check[48] = prio48_we; + reg_we_check[49] = prio49_we; + reg_we_check[50] = prio50_we; + reg_we_check[51] = prio51_we; + reg_we_check[52] = prio52_we; + reg_we_check[53] = prio53_we; + reg_we_check[54] = prio54_we; + reg_we_check[55] = prio55_we; + reg_we_check[56] = prio56_we; + reg_we_check[57] = prio57_we; + reg_we_check[58] = prio58_we; + reg_we_check[59] = prio59_we; + reg_we_check[60] = prio60_we; + reg_we_check[61] = prio61_we; + reg_we_check[62] = prio62_we; + reg_we_check[63] = prio63_we; + reg_we_check[64] = prio64_we; + reg_we_check[65] = prio65_we; + reg_we_check[66] = prio66_we; + reg_we_check[67] = prio67_we; + reg_we_check[68] = prio68_we; + reg_we_check[69] = prio69_we; + reg_we_check[70] = prio70_we; + reg_we_check[71] = prio71_we; + reg_we_check[72] = prio72_we; + reg_we_check[73] = prio73_we; + reg_we_check[74] = prio74_we; + reg_we_check[75] = prio75_we; + reg_we_check[76] = prio76_we; + reg_we_check[77] = prio77_we; + reg_we_check[78] = prio78_we; + reg_we_check[79] = prio79_we; + reg_we_check[80] = prio80_we; + reg_we_check[81] = prio81_we; + reg_we_check[82] = prio82_we; + reg_we_check[83] = prio83_we; + reg_we_check[84] = prio84_we; + reg_we_check[85] = prio85_we; + reg_we_check[86] = prio86_we; + reg_we_check[87] = prio87_we; + reg_we_check[88] = 1'b0; + reg_we_check[89] = 1'b0; + reg_we_check[90] = 1'b0; + reg_we_check[91] = ie0_0_we; + reg_we_check[92] = ie0_1_we; + reg_we_check[93] = ie0_2_we; + reg_we_check[94] = threshold0_we; + reg_we_check[95] = cc0_we; + reg_we_check[96] = msip0_we; + reg_we_check[97] = alert_test_we; + end + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (1'b1) + addr_hit[0]: begin + reg_rdata_next[1:0] = prio0_qs; + end + + addr_hit[1]: begin + reg_rdata_next[1:0] = prio1_qs; + end + + addr_hit[2]: begin + reg_rdata_next[1:0] = prio2_qs; + end + + addr_hit[3]: begin + reg_rdata_next[1:0] = prio3_qs; + end + + addr_hit[4]: begin + reg_rdata_next[1:0] = prio4_qs; + end + + addr_hit[5]: begin + reg_rdata_next[1:0] = prio5_qs; + end + + addr_hit[6]: begin + reg_rdata_next[1:0] = prio6_qs; + end + + addr_hit[7]: begin + reg_rdata_next[1:0] = prio7_qs; + end + + addr_hit[8]: begin + reg_rdata_next[1:0] = prio8_qs; + end + + addr_hit[9]: begin + reg_rdata_next[1:0] = prio9_qs; + end + + addr_hit[10]: begin + reg_rdata_next[1:0] = prio10_qs; + end + + addr_hit[11]: begin + reg_rdata_next[1:0] = prio11_qs; + end + + addr_hit[12]: begin + reg_rdata_next[1:0] = prio12_qs; + end + + addr_hit[13]: begin + reg_rdata_next[1:0] = prio13_qs; + end + + addr_hit[14]: begin + reg_rdata_next[1:0] = prio14_qs; + end + + addr_hit[15]: begin + reg_rdata_next[1:0] = prio15_qs; + end + + addr_hit[16]: begin + reg_rdata_next[1:0] = prio16_qs; + end + + addr_hit[17]: begin + reg_rdata_next[1:0] = prio17_qs; + end + + addr_hit[18]: begin + reg_rdata_next[1:0] = prio18_qs; + end + + addr_hit[19]: begin + reg_rdata_next[1:0] = prio19_qs; + end + + addr_hit[20]: begin + reg_rdata_next[1:0] = prio20_qs; + end + + addr_hit[21]: begin + reg_rdata_next[1:0] = prio21_qs; + end + + addr_hit[22]: begin + reg_rdata_next[1:0] = prio22_qs; + end + + addr_hit[23]: begin + reg_rdata_next[1:0] = prio23_qs; + end + + addr_hit[24]: begin + reg_rdata_next[1:0] = prio24_qs; + end + + addr_hit[25]: begin + reg_rdata_next[1:0] = prio25_qs; + end + + addr_hit[26]: begin + reg_rdata_next[1:0] = prio26_qs; + end + + addr_hit[27]: begin + reg_rdata_next[1:0] = prio27_qs; + end + + addr_hit[28]: begin + reg_rdata_next[1:0] = prio28_qs; + end + + addr_hit[29]: begin + reg_rdata_next[1:0] = prio29_qs; + end + + addr_hit[30]: begin + reg_rdata_next[1:0] = prio30_qs; + end + + addr_hit[31]: begin + reg_rdata_next[1:0] = prio31_qs; + end + + addr_hit[32]: begin + reg_rdata_next[1:0] = prio32_qs; + end + + addr_hit[33]: begin + reg_rdata_next[1:0] = prio33_qs; + end + + addr_hit[34]: begin + reg_rdata_next[1:0] = prio34_qs; + end + + addr_hit[35]: begin + reg_rdata_next[1:0] = prio35_qs; + end + + addr_hit[36]: begin + reg_rdata_next[1:0] = prio36_qs; + end + + addr_hit[37]: begin + reg_rdata_next[1:0] = prio37_qs; + end + + addr_hit[38]: begin + reg_rdata_next[1:0] = prio38_qs; + end + + addr_hit[39]: begin + reg_rdata_next[1:0] = prio39_qs; + end + + addr_hit[40]: begin + reg_rdata_next[1:0] = prio40_qs; + end + + addr_hit[41]: begin + reg_rdata_next[1:0] = prio41_qs; + end + + addr_hit[42]: begin + reg_rdata_next[1:0] = prio42_qs; + end + + addr_hit[43]: begin + reg_rdata_next[1:0] = prio43_qs; + end + + addr_hit[44]: begin + reg_rdata_next[1:0] = prio44_qs; + end + + addr_hit[45]: begin + reg_rdata_next[1:0] = prio45_qs; + end + + addr_hit[46]: begin + reg_rdata_next[1:0] = prio46_qs; + end + + addr_hit[47]: begin + reg_rdata_next[1:0] = prio47_qs; + end + + addr_hit[48]: begin + reg_rdata_next[1:0] = prio48_qs; + end + + addr_hit[49]: begin + reg_rdata_next[1:0] = prio49_qs; + end + + addr_hit[50]: begin + reg_rdata_next[1:0] = prio50_qs; + end + + addr_hit[51]: begin + reg_rdata_next[1:0] = prio51_qs; + end + + addr_hit[52]: begin + reg_rdata_next[1:0] = prio52_qs; + end + + addr_hit[53]: begin + reg_rdata_next[1:0] = prio53_qs; + end + + addr_hit[54]: begin + reg_rdata_next[1:0] = prio54_qs; + end + + addr_hit[55]: begin + reg_rdata_next[1:0] = prio55_qs; + end + + addr_hit[56]: begin + reg_rdata_next[1:0] = prio56_qs; + end + + addr_hit[57]: begin + reg_rdata_next[1:0] = prio57_qs; + end + + addr_hit[58]: begin + reg_rdata_next[1:0] = prio58_qs; + end + + addr_hit[59]: begin + reg_rdata_next[1:0] = prio59_qs; + end + + addr_hit[60]: begin + reg_rdata_next[1:0] = prio60_qs; + end + + addr_hit[61]: begin + reg_rdata_next[1:0] = prio61_qs; + end + + addr_hit[62]: begin + reg_rdata_next[1:0] = prio62_qs; + end + + addr_hit[63]: begin + reg_rdata_next[1:0] = prio63_qs; + end + + addr_hit[64]: begin + reg_rdata_next[1:0] = prio64_qs; + end + + addr_hit[65]: begin + reg_rdata_next[1:0] = prio65_qs; + end + + addr_hit[66]: begin + reg_rdata_next[1:0] = prio66_qs; + end + + addr_hit[67]: begin + reg_rdata_next[1:0] = prio67_qs; + end + + addr_hit[68]: begin + reg_rdata_next[1:0] = prio68_qs; + end + + addr_hit[69]: begin + reg_rdata_next[1:0] = prio69_qs; + end + + addr_hit[70]: begin + reg_rdata_next[1:0] = prio70_qs; + end + + addr_hit[71]: begin + reg_rdata_next[1:0] = prio71_qs; + end + + addr_hit[72]: begin + reg_rdata_next[1:0] = prio72_qs; + end + + addr_hit[73]: begin + reg_rdata_next[1:0] = prio73_qs; + end + + addr_hit[74]: begin + reg_rdata_next[1:0] = prio74_qs; + end + + addr_hit[75]: begin + reg_rdata_next[1:0] = prio75_qs; + end + + addr_hit[76]: begin + reg_rdata_next[1:0] = prio76_qs; + end + + addr_hit[77]: begin + reg_rdata_next[1:0] = prio77_qs; + end + + addr_hit[78]: begin + reg_rdata_next[1:0] = prio78_qs; + end + + addr_hit[79]: begin + reg_rdata_next[1:0] = prio79_qs; + end + + addr_hit[80]: begin + reg_rdata_next[1:0] = prio80_qs; + end + + addr_hit[81]: begin + reg_rdata_next[1:0] = prio81_qs; + end + + addr_hit[82]: begin + reg_rdata_next[1:0] = prio82_qs; + end + + addr_hit[83]: begin + reg_rdata_next[1:0] = prio83_qs; + end + + addr_hit[84]: begin + reg_rdata_next[1:0] = prio84_qs; + end + + addr_hit[85]: begin + reg_rdata_next[1:0] = prio85_qs; + end + + addr_hit[86]: begin + reg_rdata_next[1:0] = prio86_qs; + end + + addr_hit[87]: begin + reg_rdata_next[1:0] = prio87_qs; + end + + addr_hit[88]: begin + reg_rdata_next[0] = ip_0_p_0_qs; + reg_rdata_next[1] = ip_0_p_1_qs; + reg_rdata_next[2] = ip_0_p_2_qs; + reg_rdata_next[3] = ip_0_p_3_qs; + reg_rdata_next[4] = ip_0_p_4_qs; + reg_rdata_next[5] = ip_0_p_5_qs; + reg_rdata_next[6] = ip_0_p_6_qs; + reg_rdata_next[7] = ip_0_p_7_qs; + reg_rdata_next[8] = ip_0_p_8_qs; + reg_rdata_next[9] = ip_0_p_9_qs; + reg_rdata_next[10] = ip_0_p_10_qs; + reg_rdata_next[11] = ip_0_p_11_qs; + reg_rdata_next[12] = ip_0_p_12_qs; + reg_rdata_next[13] = ip_0_p_13_qs; + reg_rdata_next[14] = ip_0_p_14_qs; + reg_rdata_next[15] = ip_0_p_15_qs; + reg_rdata_next[16] = ip_0_p_16_qs; + reg_rdata_next[17] = ip_0_p_17_qs; + reg_rdata_next[18] = ip_0_p_18_qs; + reg_rdata_next[19] = ip_0_p_19_qs; + reg_rdata_next[20] = ip_0_p_20_qs; + reg_rdata_next[21] = ip_0_p_21_qs; + reg_rdata_next[22] = ip_0_p_22_qs; + reg_rdata_next[23] = ip_0_p_23_qs; + reg_rdata_next[24] = ip_0_p_24_qs; + reg_rdata_next[25] = ip_0_p_25_qs; + reg_rdata_next[26] = ip_0_p_26_qs; + reg_rdata_next[27] = ip_0_p_27_qs; + reg_rdata_next[28] = ip_0_p_28_qs; + reg_rdata_next[29] = ip_0_p_29_qs; + reg_rdata_next[30] = ip_0_p_30_qs; + reg_rdata_next[31] = ip_0_p_31_qs; + end + + addr_hit[89]: begin + reg_rdata_next[0] = ip_1_p_32_qs; + reg_rdata_next[1] = ip_1_p_33_qs; + reg_rdata_next[2] = ip_1_p_34_qs; + reg_rdata_next[3] = ip_1_p_35_qs; + reg_rdata_next[4] = ip_1_p_36_qs; + reg_rdata_next[5] = ip_1_p_37_qs; + reg_rdata_next[6] = ip_1_p_38_qs; + reg_rdata_next[7] = ip_1_p_39_qs; + reg_rdata_next[8] = ip_1_p_40_qs; + reg_rdata_next[9] = ip_1_p_41_qs; + reg_rdata_next[10] = ip_1_p_42_qs; + reg_rdata_next[11] = ip_1_p_43_qs; + reg_rdata_next[12] = ip_1_p_44_qs; + reg_rdata_next[13] = ip_1_p_45_qs; + reg_rdata_next[14] = ip_1_p_46_qs; + reg_rdata_next[15] = ip_1_p_47_qs; + reg_rdata_next[16] = ip_1_p_48_qs; + reg_rdata_next[17] = ip_1_p_49_qs; + reg_rdata_next[18] = ip_1_p_50_qs; + reg_rdata_next[19] = ip_1_p_51_qs; + reg_rdata_next[20] = ip_1_p_52_qs; + reg_rdata_next[21] = ip_1_p_53_qs; + reg_rdata_next[22] = ip_1_p_54_qs; + reg_rdata_next[23] = ip_1_p_55_qs; + reg_rdata_next[24] = ip_1_p_56_qs; + reg_rdata_next[25] = ip_1_p_57_qs; + reg_rdata_next[26] = ip_1_p_58_qs; + reg_rdata_next[27] = ip_1_p_59_qs; + reg_rdata_next[28] = ip_1_p_60_qs; + reg_rdata_next[29] = ip_1_p_61_qs; + reg_rdata_next[30] = ip_1_p_62_qs; + reg_rdata_next[31] = ip_1_p_63_qs; + end + + addr_hit[90]: begin + reg_rdata_next[0] = ip_2_p_64_qs; + reg_rdata_next[1] = ip_2_p_65_qs; + reg_rdata_next[2] = ip_2_p_66_qs; + reg_rdata_next[3] = ip_2_p_67_qs; + reg_rdata_next[4] = ip_2_p_68_qs; + reg_rdata_next[5] = ip_2_p_69_qs; + reg_rdata_next[6] = ip_2_p_70_qs; + reg_rdata_next[7] = ip_2_p_71_qs; + reg_rdata_next[8] = ip_2_p_72_qs; + reg_rdata_next[9] = ip_2_p_73_qs; + reg_rdata_next[10] = ip_2_p_74_qs; + reg_rdata_next[11] = ip_2_p_75_qs; + reg_rdata_next[12] = ip_2_p_76_qs; + reg_rdata_next[13] = ip_2_p_77_qs; + reg_rdata_next[14] = ip_2_p_78_qs; + reg_rdata_next[15] = ip_2_p_79_qs; + reg_rdata_next[16] = ip_2_p_80_qs; + reg_rdata_next[17] = ip_2_p_81_qs; + reg_rdata_next[18] = ip_2_p_82_qs; + reg_rdata_next[19] = ip_2_p_83_qs; + reg_rdata_next[20] = ip_2_p_84_qs; + reg_rdata_next[21] = ip_2_p_85_qs; + reg_rdata_next[22] = ip_2_p_86_qs; + reg_rdata_next[23] = ip_2_p_87_qs; + end + + addr_hit[91]: begin + reg_rdata_next[0] = ie0_0_e_0_qs; + reg_rdata_next[1] = ie0_0_e_1_qs; + reg_rdata_next[2] = ie0_0_e_2_qs; + reg_rdata_next[3] = ie0_0_e_3_qs; + reg_rdata_next[4] = ie0_0_e_4_qs; + reg_rdata_next[5] = ie0_0_e_5_qs; + reg_rdata_next[6] = ie0_0_e_6_qs; + reg_rdata_next[7] = ie0_0_e_7_qs; + reg_rdata_next[8] = ie0_0_e_8_qs; + reg_rdata_next[9] = ie0_0_e_9_qs; + reg_rdata_next[10] = ie0_0_e_10_qs; + reg_rdata_next[11] = ie0_0_e_11_qs; + reg_rdata_next[12] = ie0_0_e_12_qs; + reg_rdata_next[13] = ie0_0_e_13_qs; + reg_rdata_next[14] = ie0_0_e_14_qs; + reg_rdata_next[15] = ie0_0_e_15_qs; + reg_rdata_next[16] = ie0_0_e_16_qs; + reg_rdata_next[17] = ie0_0_e_17_qs; + reg_rdata_next[18] = ie0_0_e_18_qs; + reg_rdata_next[19] = ie0_0_e_19_qs; + reg_rdata_next[20] = ie0_0_e_20_qs; + reg_rdata_next[21] = ie0_0_e_21_qs; + reg_rdata_next[22] = ie0_0_e_22_qs; + reg_rdata_next[23] = ie0_0_e_23_qs; + reg_rdata_next[24] = ie0_0_e_24_qs; + reg_rdata_next[25] = ie0_0_e_25_qs; + reg_rdata_next[26] = ie0_0_e_26_qs; + reg_rdata_next[27] = ie0_0_e_27_qs; + reg_rdata_next[28] = ie0_0_e_28_qs; + reg_rdata_next[29] = ie0_0_e_29_qs; + reg_rdata_next[30] = ie0_0_e_30_qs; + reg_rdata_next[31] = ie0_0_e_31_qs; + end + + addr_hit[92]: begin + reg_rdata_next[0] = ie0_1_e_32_qs; + reg_rdata_next[1] = ie0_1_e_33_qs; + reg_rdata_next[2] = ie0_1_e_34_qs; + reg_rdata_next[3] = ie0_1_e_35_qs; + reg_rdata_next[4] = ie0_1_e_36_qs; + reg_rdata_next[5] = ie0_1_e_37_qs; + reg_rdata_next[6] = ie0_1_e_38_qs; + reg_rdata_next[7] = ie0_1_e_39_qs; + reg_rdata_next[8] = ie0_1_e_40_qs; + reg_rdata_next[9] = ie0_1_e_41_qs; + reg_rdata_next[10] = ie0_1_e_42_qs; + reg_rdata_next[11] = ie0_1_e_43_qs; + reg_rdata_next[12] = ie0_1_e_44_qs; + reg_rdata_next[13] = ie0_1_e_45_qs; + reg_rdata_next[14] = ie0_1_e_46_qs; + reg_rdata_next[15] = ie0_1_e_47_qs; + reg_rdata_next[16] = ie0_1_e_48_qs; + reg_rdata_next[17] = ie0_1_e_49_qs; + reg_rdata_next[18] = ie0_1_e_50_qs; + reg_rdata_next[19] = ie0_1_e_51_qs; + reg_rdata_next[20] = ie0_1_e_52_qs; + reg_rdata_next[21] = ie0_1_e_53_qs; + reg_rdata_next[22] = ie0_1_e_54_qs; + reg_rdata_next[23] = ie0_1_e_55_qs; + reg_rdata_next[24] = ie0_1_e_56_qs; + reg_rdata_next[25] = ie0_1_e_57_qs; + reg_rdata_next[26] = ie0_1_e_58_qs; + reg_rdata_next[27] = ie0_1_e_59_qs; + reg_rdata_next[28] = ie0_1_e_60_qs; + reg_rdata_next[29] = ie0_1_e_61_qs; + reg_rdata_next[30] = ie0_1_e_62_qs; + reg_rdata_next[31] = ie0_1_e_63_qs; + end + + addr_hit[93]: begin + reg_rdata_next[0] = ie0_2_e_64_qs; + reg_rdata_next[1] = ie0_2_e_65_qs; + reg_rdata_next[2] = ie0_2_e_66_qs; + reg_rdata_next[3] = ie0_2_e_67_qs; + reg_rdata_next[4] = ie0_2_e_68_qs; + reg_rdata_next[5] = ie0_2_e_69_qs; + reg_rdata_next[6] = ie0_2_e_70_qs; + reg_rdata_next[7] = ie0_2_e_71_qs; + reg_rdata_next[8] = ie0_2_e_72_qs; + reg_rdata_next[9] = ie0_2_e_73_qs; + reg_rdata_next[10] = ie0_2_e_74_qs; + reg_rdata_next[11] = ie0_2_e_75_qs; + reg_rdata_next[12] = ie0_2_e_76_qs; + reg_rdata_next[13] = ie0_2_e_77_qs; + reg_rdata_next[14] = ie0_2_e_78_qs; + reg_rdata_next[15] = ie0_2_e_79_qs; + reg_rdata_next[16] = ie0_2_e_80_qs; + reg_rdata_next[17] = ie0_2_e_81_qs; + reg_rdata_next[18] = ie0_2_e_82_qs; + reg_rdata_next[19] = ie0_2_e_83_qs; + reg_rdata_next[20] = ie0_2_e_84_qs; + reg_rdata_next[21] = ie0_2_e_85_qs; + reg_rdata_next[22] = ie0_2_e_86_qs; + reg_rdata_next[23] = ie0_2_e_87_qs; + end + + addr_hit[94]: begin + reg_rdata_next[1:0] = threshold0_qs; + end + + addr_hit[95]: begin + reg_rdata_next[6:0] = cc0_qs; + end + + addr_hit[96]: begin + reg_rdata_next[0] = msip0_qs; + end + + addr_hit[97]: begin + reg_rdata_next[0] = '0; + 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_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_target.sv b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_target.sv new file mode 100644 index 0000000000000..301dff3e99f8a --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rtl/rv_plic_target.sv @@ -0,0 +1,74 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// RISC-V Platform-Level Interrupt Generator for Target +// +// This module basically doing IE & IP based on priority and threshold_i. +// Keep in mind that increasing MAX_PRIO affects logic size a lot. +// +// The module implements a binary tree to find the maximal entry. the solution +// has O(N) area and O(log(N)) delay complexity, and thus scales well with +// many input sources. +// + +`include "prim_assert.sv" + +module rv_plic_target #( + parameter int N_SOURCE = 32, + parameter int MAX_PRIO = 7, + + // Local param (Do not change this through parameter + localparam int SrcWidth = $clog2(N_SOURCE), // derived parameter + localparam int PrioWidth = $clog2(MAX_PRIO+1) // derived parameter +) ( + input clk_i, + input rst_ni, + + input [N_SOURCE-1:0] ip_i, + input [N_SOURCE-1:0] ie_i, + + input [N_SOURCE-1:0][PrioWidth-1:0] prio_i, + input [PrioWidth-1:0] threshold_i, + + output logic irq_o, + output logic [SrcWidth-1:0] irq_id_o +); + + // Find maximum value and index using a binary tree implementation. + logic max_valid; + logic [PrioWidth-1:0] max_value; + logic [SrcWidth-1:0] max_idx; + prim_max_tree #( + .NumSrc(N_SOURCE), + .Width(PrioWidth) + ) u_prim_max_tree ( + .clk_i, + .rst_ni, + .values_i(prio_i), + .valid_i(ip_i & ie_i), + .max_value_o(max_value), + .max_idx_o(max_idx), + .max_valid_o(max_valid) + ); + + logic irq_d, irq_q; + logic [SrcWidth-1:0] irq_id_d, irq_id_q; + + assign irq_d = (max_value > threshold_i) ? max_valid : 1'b0; + assign irq_id_d = (max_valid) ? max_idx : '0; + + always_ff @(posedge clk_i or negedge rst_ni) begin : gen_regs + if (!rst_ni) begin + irq_q <= 1'b0; + irq_id_q <= '0; + end else begin + irq_q <= irq_d; + irq_id_q <= irq_id_d; + end + end + + assign irq_o = irq_q; + assign irq_id_o = irq_id_q; + +endmodule diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic.core b/hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic.core new file mode 100644 index 0000000000000..3dd4bc1955e8d --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic.core @@ -0,0 +1,40 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rv_plic:0.1 +description: "RISC-V Platform Interrupt Controller (PLIC)" + +filesets: + files_rtl: + depend: + - lowrisc:opentitan:top_englishbreakfast_rv_plic_component:0.1 + - lowrisc:ip:tlul + - lowrisc:prim:subreg + files: + - rtl/rv_plic_reg_pkg.sv + - rtl/rv_plic_reg_top.sv + - rtl/rv_plic.sv + file_type: systemVerilogSource + +parameters: + SYNTHESIS: + datatype: bool + paramtype: vlogdefine + +targets: + default: &default_target + filesets: + - files_rtl + toplevel: rv_plic + + lint: + <<: *default_target + default_tool: verilator + parameters: + - SYNTHESIS=true + tools: + verilator: + mode: lint-only + verilator_options: + - "-Wall" diff --git a/hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic_component.core b/hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic_component.core new file mode 100644 index 0000000000000..25010a1cb4545 --- /dev/null +++ b/hw/top_englishbreakfast/ip_autogen/rv_plic/rv_plic_component.core @@ -0,0 +1,51 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: lowrisc:opentitan:top_englishbreakfast_rv_plic_component:0.1 +description: "RISC-V Platform Interrupt Controller (PLIC)" + +filesets: + files_rtl: + depend: + - lowrisc:prim:assert + - lowrisc:prim:alert + - lowrisc:prim:max_tree + - lowrisc:prim:flop_2sync + - lowrisc:prim:reg_we_check + files: + - rtl/rv_plic_gateway.sv + - rtl/rv_plic_target.sv + file_type: systemVerilogSource + + files_verilator_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/rv_plic.vlt + file_type: vlt + + files_ascentlint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + files: + - lint/rv_plic.waiver + file_type: waiver + + files_veriblelint_waiver: + depend: + # common waivers + - lowrisc:lint:common + - lowrisc:lint:comportable + +targets: + default: + filesets: + - tool_verilator ? (files_verilator_waiver) + - tool_ascentlint ? (files_ascentlint_waiver) + - tool_veriblelint ? (files_veriblelint_waiver) + - files_rtl diff --git a/hw/top_englishbreakfast/lint/top_englishbreakfast_lint_cfgs.hjson b/hw/top_englishbreakfast/lint/top_englishbreakfast_lint_cfgs.hjson index 28346679cabff..e3d49be0ab769 100644 --- a/hw/top_englishbreakfast/lint/top_englishbreakfast_lint_cfgs.hjson +++ b/hw/top_englishbreakfast/lint/top_englishbreakfast_lint_cfgs.hjson @@ -63,21 +63,20 @@ ] }, { name: sensor_ctrl - fusesoc_core: lowrisc:systems:sensor_ctrl + fusesoc_core: lowrisc:systems:top_earlgrey_sensor_ctrl import_cfgs: ["{proj_root}/hw/lint/tools/dvsim/common_lint_cfg.hjson"] rel_path: "hw/top_englishbreakfast/ip/sensor_ctrl/lint/{tool}" }, - // This currently doesn't work. We need to tell dvsim to call topgen. - //{ name: top_englishbreakfast - // fusesoc_core: lowrisc:systems:top_englishbreakfast - // import_cfgs: ["{proj_root}/hw/lint/tools/dvsim/common_lint_cfg.hjson"] - // rel_path: "hw/top_englishbreakfast/lint/{tool}" - // overrides: [ - // { - // name: design_level - // value: "top" - // } - // ] - //}, + { name: top_englishbreakfast + fusesoc_core: lowrisc:systems:top_englishbreakfast + import_cfgs: ["{proj_root}/hw/lint/tools/dvsim/common_lint_cfg.hjson"] + rel_path: "hw/top_englishbreakfast/lint/{tool}" + overrides: [ + { + name: design_level + value: "top" + } + ] + }, ] } diff --git a/hw/top_englishbreakfast/padring.core b/hw/top_englishbreakfast/padring.core deleted file mode 120000 index 2e02d06a10d1a..0000000000000 --- a/hw/top_englishbreakfast/padring.core +++ /dev/null @@ -1 +0,0 @@ -../top_earlgrey/padring.core \ No newline at end of file diff --git a/hw/top_englishbreakfast/physical_pads.core b/hw/top_englishbreakfast/physical_pads.core deleted file mode 120000 index e0ddc4de7415d..0000000000000 --- a/hw/top_englishbreakfast/physical_pads.core +++ /dev/null @@ -1 +0,0 @@ -../top_earlgrey/physical_pads.core \ No newline at end of file diff --git a/hw/top_englishbreakfast/rtl/autogen/chip_englishbreakfast_cw305.sv b/hw/top_englishbreakfast/rtl/autogen/chip_englishbreakfast_cw305.sv new file mode 100644 index 0000000000000..1f8817e1de507 --- /dev/null +++ b/hw/top_englishbreakfast/rtl/autogen/chip_englishbreakfast_cw305.sv @@ -0,0 +1,1110 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson \ +// -o hw/top_englishbreakfast/ \ +// --rnd_cnst_seed \ +// 4881560218908238235 + + +module chip_englishbreakfast_cw305 #( + // Path to a VMEM file containing the contents of the boot ROM, which will be + // baked into the FPGA bitstream. + parameter BootRomInitFile = "test_rom_fpga_cw305.32.vmem", + // Path to a VMEM file containing the contents of the emulated OTP, which will be + // baked into the FPGA bitstream. + parameter OtpCtrlMemInitFile = "otp_img_fpga_cw305.vmem" +) ( + // Dedicated Pads + inout POR_N, // Manual Pad + inout USB_P, // Manual Pad + inout USB_N, // Manual Pad + inout SPI_DEV_D0, // Dedicated Pad for spi_device_sd + inout SPI_DEV_D1, // Dedicated Pad for spi_device_sd + inout SPI_DEV_CLK, // Dedicated Pad for spi_device_sck + inout SPI_DEV_CS_L, // Dedicated Pad for spi_device_csb + inout IO_CLK, // Manual Pad + inout POR_BUTTON_N, // Manual Pad + inout IO_USB_SENSE0, // Manual Pad + inout IO_USB_DNPULLUP0, // Manual Pad + inout IO_USB_DPPULLUP0, // Manual Pad + inout IO_CLKOUT, // Manual Pad + inout IO_TRIGGER, // Manual Pad + + // Muxed Pads + inout IOA0, // MIO Pad 0 + inout IOA1, // MIO Pad 1 + inout IOA2, // MIO Pad 2 + inout IOA3, // MIO Pad 3 + inout IOA4, // MIO Pad 4 + inout IOA5, // MIO Pad 5 + inout IOA6, // MIO Pad 6 + inout IOA7, // MIO Pad 7 + inout IOA8, // MIO Pad 8 + inout IOB0, // MIO Pad 9 + inout IOB1, // MIO Pad 10 + inout IOB2, // MIO Pad 11 + inout IOB3, // MIO Pad 12 + inout IOB4, // MIO Pad 13 + inout IOB5, // MIO Pad 14 + inout IOB6, // MIO Pad 15 + inout IOC0, // MIO Pad 22 + inout IOC1, // MIO Pad 23 + inout IOC2, // MIO Pad 24 + inout IOC3, // MIO Pad 25 + inout IOC4, // MIO Pad 26 + inout IOC5, // MIO Pad 27 + inout IOC8, // MIO Pad 30 + inout IOR4 // MIO Pad 39 +); + + import top_englishbreakfast_pkg::*; + import prim_pad_wrapper_pkg::*; + + //////////////////////////// + // Special Signal Indices // + //////////////////////////// + + localparam int Tap0PadIdx = 30; + localparam int Tap1PadIdx = 27; + localparam int Dft0PadIdx = 40; + localparam int Dft1PadIdx = 42; + localparam int TckPadIdx = 57; + localparam int TmsPadIdx = 58; + localparam int TrstNPadIdx = 39; + localparam int TdiPadIdx = 51; + localparam int TdoPadIdx = 52; + + // DFT and Debug signal positions in the pinout. + localparam pinmux_pkg::target_cfg_t PinmuxTargetCfg = '{ + tck_idx: TckPadIdx, + tms_idx: TmsPadIdx, + trst_idx: TrstNPadIdx, + tdi_idx: TdiPadIdx, + tdo_idx: TdoPadIdx, + tap_strap0_idx: Tap0PadIdx, + tap_strap1_idx: Tap1PadIdx, + dft_strap0_idx: Dft0PadIdx, + dft_strap1_idx: Dft1PadIdx, + // TODO: check whether there is a better way to pass these USB-specific params + usb_dp_idx: DioUsbdevUsbDp, + usb_dn_idx: DioUsbdevUsbDn, + usb_sense_idx: MioInUsbdevSense, + // Pad types for attribute WARL behavior + dio_pad_type: { + BidirStd, // DIO spi_host0_csb + BidirStd, // DIO spi_host0_sck + InputStd, // DIO spi_device_csb + InputStd, // DIO spi_device_sck + BidirStd, // DIO usbdev_usb_dn + BidirStd, // DIO usbdev_usb_dp + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_device_sd + BidirStd, // DIO spi_host0_sd + BidirStd, // DIO spi_host0_sd + BidirStd, // DIO spi_host0_sd + BidirStd // DIO spi_host0_sd + }, + mio_pad_type: { + BidirOd, // MIO Pad 46 + BidirOd, // MIO Pad 45 + BidirOd, // MIO Pad 44 + BidirOd, // MIO Pad 43 + BidirStd, // MIO Pad 42 + BidirStd, // MIO Pad 41 + BidirStd, // MIO Pad 40 + BidirStd, // MIO Pad 39 + BidirStd, // MIO Pad 38 + BidirStd, // MIO Pad 37 + BidirStd, // MIO Pad 36 + BidirStd, // MIO Pad 35 + BidirOd, // MIO Pad 34 + BidirOd, // MIO Pad 33 + BidirOd, // MIO Pad 32 + BidirStd, // MIO Pad 31 + BidirStd, // MIO Pad 30 + BidirStd, // MIO Pad 29 + BidirStd, // MIO Pad 28 + BidirStd, // MIO Pad 27 + BidirStd, // MIO Pad 26 + BidirStd, // MIO Pad 25 + BidirStd, // MIO Pad 24 + BidirStd, // MIO Pad 23 + BidirStd, // MIO Pad 22 + BidirOd, // MIO Pad 21 + BidirOd, // MIO Pad 20 + BidirOd, // MIO Pad 19 + BidirOd, // MIO Pad 18 + BidirStd, // MIO Pad 17 + BidirStd, // MIO Pad 16 + BidirStd, // MIO Pad 15 + BidirStd, // MIO Pad 14 + BidirStd, // MIO Pad 13 + BidirStd, // MIO Pad 12 + BidirStd, // MIO Pad 11 + BidirStd, // MIO Pad 10 + BidirStd, // MIO Pad 9 + BidirOd, // MIO Pad 8 + BidirOd, // MIO Pad 7 + BidirOd, // MIO Pad 6 + BidirStd, // MIO Pad 5 + BidirStd, // MIO Pad 4 + BidirStd, // MIO Pad 3 + BidirStd, // MIO Pad 2 + BidirStd, // MIO Pad 1 + BidirStd // MIO Pad 0 + }, + // Pad scan roles + dio_scan_role: { + NoScan, // DIO spi_host0_csb + NoScan, // DIO spi_host0_sck + NoScan, // DIO spi_device_csb + NoScan, // DIO spi_device_sck + NoScan, // DIO usbdev_usb_dn + NoScan, // DIO usbdev_usb_dp + NoScan, // DIO spi_device_sd + NoScan, // DIO spi_device_sd + NoScan, // DIO spi_device_sd + NoScan, // DIO spi_device_sd + NoScan, // DIO spi_host0_sd + NoScan, // DIO spi_host0_sd + NoScan, // DIO spi_host0_sd + NoScan // DIO spi_host0_sd + }, + mio_scan_role: { + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan, + NoScan + } + }; + + //////////////////////// + // Signal definitions // + //////////////////////// + + + logic [3:0] mux_iob_sel; + + pad_attr_t [pinmux_reg_pkg::NMioPads-1:0] mio_attr; + pad_attr_t [pinmux_reg_pkg::NDioPads-1:0] dio_attr; + logic [pinmux_reg_pkg::NMioPads-1:0] mio_out; + logic [pinmux_reg_pkg::NMioPads-1:0] mio_oe; + logic [pinmux_reg_pkg::NMioPads-1:0] mio_in; + logic [pinmux_reg_pkg::NMioPads-1:0] mio_in_raw; + logic [14-1:0] dio_in_raw; + logic [pinmux_reg_pkg::NDioPads-1:0] dio_out; + logic [pinmux_reg_pkg::NDioPads-1:0] dio_oe; + logic [pinmux_reg_pkg::NDioPads-1:0] dio_in; + + logic unused_mio_in_raw; + logic unused_dio_in_raw; + assign unused_mio_in_raw = ^mio_in_raw; + assign unused_dio_in_raw = ^dio_in_raw; + + // Manual pads + logic manual_in_por_n, manual_out_por_n, manual_oe_por_n; + logic manual_in_usb_p, manual_out_usb_p, manual_oe_usb_p; + logic manual_in_usb_n, manual_out_usb_n, manual_oe_usb_n; + logic manual_in_io_clk, manual_out_io_clk, manual_oe_io_clk; + logic manual_in_por_button_n, manual_out_por_button_n, manual_oe_por_button_n; + logic manual_in_io_usb_sense0, manual_out_io_usb_sense0, manual_oe_io_usb_sense0; + logic manual_in_io_usb_dnpullup0, manual_out_io_usb_dnpullup0, manual_oe_io_usb_dnpullup0; + logic manual_in_io_usb_dppullup0, manual_out_io_usb_dppullup0, manual_oe_io_usb_dppullup0; + logic manual_in_io_clkout, manual_out_io_clkout, manual_oe_io_clkout; + logic manual_in_io_trigger, manual_out_io_trigger, manual_oe_io_trigger; + + pad_attr_t manual_attr_por_n; + pad_attr_t manual_attr_usb_p; + pad_attr_t manual_attr_usb_n; + pad_attr_t manual_attr_io_clk; + pad_attr_t manual_attr_por_button_n; + pad_attr_t manual_attr_io_usb_sense0; + pad_attr_t manual_attr_io_usb_dnpullup0; + pad_attr_t manual_attr_io_usb_dppullup0; + pad_attr_t manual_attr_io_clkout; + pad_attr_t manual_attr_io_trigger; + + ///////////////////////// + // Stubbed pad tie-off // + ///////////////////////// + + // Only signals going to non-custom pads need to be tied off. + logic [66:0] unused_sig; + assign dio_in[DioSpiHost0Sd0] = 1'b0; + assign unused_sig[8] = dio_out[DioSpiHost0Sd0] ^ dio_oe[DioSpiHost0Sd0]; + assign dio_in[DioSpiHost0Sd1] = 1'b0; + assign unused_sig[9] = dio_out[DioSpiHost0Sd1] ^ dio_oe[DioSpiHost0Sd1]; + assign dio_in[DioSpiHost0Sd2] = 1'b0; + assign unused_sig[10] = dio_out[DioSpiHost0Sd2] ^ dio_oe[DioSpiHost0Sd2]; + assign dio_in[DioSpiHost0Sd3] = 1'b0; + assign unused_sig[11] = dio_out[DioSpiHost0Sd3] ^ dio_oe[DioSpiHost0Sd3]; + assign dio_in[DioSpiHost0Sck] = 1'b0; + assign unused_sig[12] = dio_out[DioSpiHost0Sck] ^ dio_oe[DioSpiHost0Sck]; + assign dio_in[DioSpiHost0Csb] = 1'b0; + assign unused_sig[13] = dio_out[DioSpiHost0Csb] ^ dio_oe[DioSpiHost0Csb]; + assign dio_in[DioSpiDeviceSd2] = 1'b0; + assign unused_sig[16] = dio_out[DioSpiDeviceSd2] ^ dio_oe[DioSpiDeviceSd2]; + assign dio_in[DioSpiDeviceSd3] = 1'b0; + assign unused_sig[17] = dio_out[DioSpiDeviceSd3] ^ dio_oe[DioSpiDeviceSd3]; + assign mio_in[16] = 1'b0; + assign mio_in_raw[16] = 1'b0; + assign unused_sig[36] = mio_out[16] ^ mio_oe[16]; + assign mio_in[17] = 1'b0; + assign mio_in_raw[17] = 1'b0; + assign unused_sig[37] = mio_out[17] ^ mio_oe[17]; + assign mio_in[18] = 1'b0; + assign mio_in_raw[18] = 1'b0; + assign unused_sig[38] = mio_out[18] ^ mio_oe[18]; + assign mio_in[19] = 1'b0; + assign mio_in_raw[19] = 1'b0; + assign unused_sig[39] = mio_out[19] ^ mio_oe[19]; + assign mio_in[20] = 1'b0; + assign mio_in_raw[20] = 1'b0; + assign unused_sig[40] = mio_out[20] ^ mio_oe[20]; + assign mio_in[21] = 1'b0; + assign mio_in_raw[21] = 1'b0; + assign unused_sig[41] = mio_out[21] ^ mio_oe[21]; + assign mio_in[28] = 1'b0; + assign mio_in_raw[28] = 1'b0; + assign unused_sig[48] = mio_out[28] ^ mio_oe[28]; + assign mio_in[29] = 1'b0; + assign mio_in_raw[29] = 1'b0; + assign unused_sig[49] = mio_out[29] ^ mio_oe[29]; + assign mio_in[31] = 1'b0; + assign mio_in_raw[31] = 1'b0; + assign unused_sig[51] = mio_out[31] ^ mio_oe[31]; + assign mio_in[32] = 1'b0; + assign mio_in_raw[32] = 1'b0; + assign unused_sig[52] = mio_out[32] ^ mio_oe[32]; + assign mio_in[33] = 1'b0; + assign mio_in_raw[33] = 1'b0; + assign unused_sig[53] = mio_out[33] ^ mio_oe[33]; + assign mio_in[34] = 1'b0; + assign mio_in_raw[34] = 1'b0; + assign unused_sig[54] = mio_out[34] ^ mio_oe[34]; + assign mio_in[35] = 1'b0; + assign mio_in_raw[35] = 1'b0; + assign unused_sig[55] = mio_out[35] ^ mio_oe[35]; + assign mio_in[36] = 1'b0; + assign mio_in_raw[36] = 1'b0; + assign unused_sig[56] = mio_out[36] ^ mio_oe[36]; + assign mio_in[37] = 1'b0; + assign mio_in_raw[37] = 1'b0; + assign unused_sig[57] = mio_out[37] ^ mio_oe[37]; + assign mio_in[38] = 1'b0; + assign mio_in_raw[38] = 1'b0; + assign unused_sig[58] = mio_out[38] ^ mio_oe[38]; + assign mio_in[40] = 1'b0; + assign mio_in_raw[40] = 1'b0; + assign unused_sig[60] = mio_out[40] ^ mio_oe[40]; + assign mio_in[41] = 1'b0; + assign mio_in_raw[41] = 1'b0; + assign unused_sig[61] = mio_out[41] ^ mio_oe[41]; + assign mio_in[42] = 1'b0; + assign mio_in_raw[42] = 1'b0; + assign unused_sig[62] = mio_out[42] ^ mio_oe[42]; + assign mio_in[43] = 1'b0; + assign mio_in_raw[43] = 1'b0; + assign unused_sig[63] = mio_out[43] ^ mio_oe[43]; + assign mio_in[44] = 1'b0; + assign mio_in_raw[44] = 1'b0; + assign unused_sig[64] = mio_out[44] ^ mio_oe[44]; + assign mio_in[45] = 1'b0; + assign mio_in_raw[45] = 1'b0; + assign unused_sig[65] = mio_out[45] ^ mio_oe[45]; + assign mio_in[46] = 1'b0; + assign mio_in_raw[46] = 1'b0; + assign unused_sig[66] = mio_out[46] ^ mio_oe[46]; + + ////////////////////// + // Padring Instance // + ////////////////////// + + ast_pkg::ast_clks_t ast_base_clks; + + + padring #( + // Padring specific counts may differ from pinmux config due + // to custom, stubbed or added pads. + .NDioPads(14), + .NMioPads(24), + .DioPadType ({ + BidirStd, // IO_TRIGGER + BidirStd, // IO_CLKOUT + BidirStd, // IO_USB_DPPULLUP0 + BidirStd, // IO_USB_DNPULLUP0 + BidirStd, // IO_USB_SENSE0 + InputStd, // POR_BUTTON_N + InputStd, // IO_CLK + InputStd, // SPI_DEV_CS_L + InputStd, // SPI_DEV_CLK + BidirStd, // SPI_DEV_D1 + BidirStd, // SPI_DEV_D0 + BidirTol, // USB_N + BidirTol, // USB_P + InputStd // POR_N + }), + .MioPadType ({ + BidirStd, // IOR4 + BidirStd, // IOC8 + BidirStd, // IOC5 + BidirStd, // IOC4 + BidirStd, // IOC3 + BidirStd, // IOC2 + BidirStd, // IOC1 + BidirStd, // IOC0 + BidirStd, // IOB6 + BidirStd, // IOB5 + BidirStd, // IOB4 + BidirStd, // IOB3 + BidirStd, // IOB2 + BidirStd, // IOB1 + BidirStd, // IOB0 + BidirOd, // IOA8 + BidirOd, // IOA7 + BidirOd, // IOA6 + BidirStd, // IOA5 + BidirStd, // IOA4 + BidirStd, // IOA3 + BidirStd, // IOA2 + BidirStd, // IOA1 + BidirStd // IOA0 + }) + ) u_padring ( + // This is only used for scan and DFT purposes + .clk_scan_i ( 1'b0 ), + .scanmode_i ( prim_mubi_pkg::MuBi4False ), + .mux_iob_sel_i ( mux_iob_sel ), + .dio_in_raw_o ( dio_in_raw ), + // Chip IOs + .dio_pad_io ({ + IO_TRIGGER, + IO_CLKOUT, + IO_USB_DPPULLUP0, + IO_USB_DNPULLUP0, + IO_USB_SENSE0, + POR_BUTTON_N, + IO_CLK, + SPI_DEV_CS_L, + SPI_DEV_CLK, + SPI_DEV_D1, + SPI_DEV_D0, + USB_N, + USB_P, + POR_N + }), + + .mio_pad_io ({ + IOR4, + IOC8, + IOC5, + IOC4, + IOC3, + IOC2, + IOC1, + IOC0, + IOB6, + IOB5, + IOB4, + IOB3, + IOB2, + IOB1, + IOB0, + IOA8, + IOA7, + IOA6, + IOA5, + IOA4, + IOA3, + IOA2, + IOA1, + IOA0 + }), + + // Core-facing + .dio_in_o ({ + manual_in_io_trigger, + manual_in_io_clkout, + manual_in_io_usb_dppullup0, + manual_in_io_usb_dnpullup0, + manual_in_io_usb_sense0, + manual_in_por_button_n, + manual_in_io_clk, + dio_in[DioSpiDeviceCsb], + dio_in[DioSpiDeviceSck], + dio_in[DioSpiDeviceSd1], + dio_in[DioSpiDeviceSd0], + manual_in_usb_n, + manual_in_usb_p, + manual_in_por_n + }), + .dio_out_i ({ + manual_out_io_trigger, + manual_out_io_clkout, + manual_out_io_usb_dppullup0, + manual_out_io_usb_dnpullup0, + manual_out_io_usb_sense0, + manual_out_por_button_n, + manual_out_io_clk, + dio_out[DioSpiDeviceCsb], + dio_out[DioSpiDeviceSck], + dio_out[DioSpiDeviceSd1], + dio_out[DioSpiDeviceSd0], + manual_out_usb_n, + manual_out_usb_p, + manual_out_por_n + }), + .dio_oe_i ({ + manual_oe_io_trigger, + manual_oe_io_clkout, + manual_oe_io_usb_dppullup0, + manual_oe_io_usb_dnpullup0, + manual_oe_io_usb_sense0, + manual_oe_por_button_n, + manual_oe_io_clk, + dio_oe[DioSpiDeviceCsb], + dio_oe[DioSpiDeviceSck], + dio_oe[DioSpiDeviceSd1], + dio_oe[DioSpiDeviceSd0], + manual_oe_usb_n, + manual_oe_usb_p, + manual_oe_por_n + }), + .dio_attr_i ({ + manual_attr_io_trigger, + manual_attr_io_clkout, + manual_attr_io_usb_dppullup0, + manual_attr_io_usb_dnpullup0, + manual_attr_io_usb_sense0, + manual_attr_por_button_n, + manual_attr_io_clk, + dio_attr[DioSpiDeviceCsb], + dio_attr[DioSpiDeviceSck], + dio_attr[DioSpiDeviceSd1], + dio_attr[DioSpiDeviceSd0], + manual_attr_usb_n, + manual_attr_usb_p, + manual_attr_por_n + }), + + .mio_in_o ({ + mio_in[39], + mio_in[30], + mio_in[27:22], + mio_in[15:0] + }), + .mio_out_i ({ + mio_out[39], + mio_out[30], + mio_out[27:22], + mio_out[15:0] + }), + .mio_oe_i ({ + mio_oe[39], + mio_oe[30], + mio_oe[27:22], + mio_oe[15:0] + }), + .mio_attr_i ({ + mio_attr[39], + mio_attr[30], + mio_attr[27:22], + mio_attr[15:0] + }), + .mio_in_raw_o ({ + mio_in_raw[39], + mio_in_raw[30], + mio_in_raw[27:22], + mio_in_raw[15:0] + }) + ); + + + logic usb_dp_pullup_en; + logic usb_dn_pullup_en; + logic usb_rx_d; + logic usb_tx_d; + logic usb_tx_se0; + logic usb_tx_use_d_se0; + logic usb_rx_enable; + + // Connect the DP pad + assign dio_in[DioUsbdevUsbDp] = manual_in_usb_p; + assign manual_out_usb_p = dio_out[DioUsbdevUsbDp]; + assign manual_oe_usb_p = dio_oe[DioUsbdevUsbDp]; + assign manual_attr_usb_p = dio_attr[DioUsbdevUsbDp]; + + // Connect the DN pad + assign dio_in[DioUsbdevUsbDn] = manual_in_usb_n; + assign manual_out_usb_n = dio_out[DioUsbdevUsbDn]; + assign manual_oe_usb_n = dio_oe[DioUsbdevUsbDn]; + assign manual_attr_usb_n = dio_attr[DioUsbdevUsbDn]; + + // Connect DN pullup + assign manual_out_io_usb_dnpullup0 = usb_dn_pullup_en; + assign manual_oe_io_usb_dnpullup0 = 1'b1; + assign manual_attr_io_dnpullup0 = '0; + + // Connect DP pullup + assign manual_out_io_usb_dppullup0 = usb_dp_pullup_en; + assign manual_oe_io_usb_dppullup0 = 1'b1; + assign manual_attr_io_dppullup0 = '0; + + // Tie-off unused signals + assign usb_rx_d = 1'b0; + + + + + ////////////////////////////////// + // AST - Common for all targets // + ////////////////////////////////// + + // pwrmgr interface + pwrmgr_pkg::pwr_ast_req_t base_ast_pwr; + pwrmgr_pkg::pwr_ast_rsp_t ast_base_pwr; + + // assorted ast status + ast_pkg::ast_pwst_t ast_pwst; + ast_pkg::ast_pwst_t ast_pwst_h; + + // TLUL interface + tlul_pkg::tl_h2d_t base_ast_bus; + tlul_pkg::tl_d2h_t ast_base_bus; + + // synchronization clocks / rests + clkmgr_pkg::clkmgr_out_t clkmgr_aon_clocks; + rstmgr_pkg::rstmgr_out_t rstmgr_aon_resets; + + // external clock + logic ext_clk; + + // monitored clock + logic sck_monitor; + + // observe interface + logic [7:0] fla_obs; + logic [7:0] otp_obs; + ast_pkg::ast_obs_ctrl_t obs_ctrl; + + // otp power sequence + otp_ctrl_pkg::otp_ast_req_t otp_ctrl_otp_ast_pwr_seq; + otp_ctrl_pkg::otp_ast_rsp_t otp_ctrl_otp_ast_pwr_seq_h; + + logic usb_ref_pulse; + logic usb_ref_val; + + // adc + ast_pkg::adc_ast_req_t adc_req; + ast_pkg::adc_ast_rsp_t adc_rsp; + + // entropy source interface + // The entropy source pacakge definition should eventually be moved to es + entropy_src_pkg::entropy_src_rng_req_t es_rng_req; + entropy_src_pkg::entropy_src_rng_rsp_t es_rng_rsp; + logic es_rng_fips; + + // entropy distribution network + edn_pkg::edn_req_t ast_edn_edn_req; + edn_pkg::edn_rsp_t ast_edn_edn_rsp; + + // alerts interface + ast_pkg::ast_alert_rsp_t ast_alert_rsp; + ast_pkg::ast_alert_req_t ast_alert_req; + + // Flash connections + prim_mubi_pkg::mubi4_t flash_bist_enable; + logic flash_power_down_h; + logic flash_power_ready_h; + + // clock bypass req/ack + prim_mubi_pkg::mubi4_t io_clk_byp_req; + prim_mubi_pkg::mubi4_t io_clk_byp_ack; + prim_mubi_pkg::mubi4_t all_clk_byp_req; + prim_mubi_pkg::mubi4_t all_clk_byp_ack; + prim_mubi_pkg::mubi4_t hi_speed_sel; + prim_mubi_pkg::mubi4_t div_step_down_req; + + // DFT connections + logic scan_en; + lc_ctrl_pkg::lc_tx_t dft_en; + pinmux_pkg::dft_strap_test_req_t dft_strap_test; + + // Debug connections + logic [ast_pkg::Ast2PadOutWidth-1:0] ast2pinmux; + logic [ast_pkg::Pad2AstInWidth-1:0] pad2ast; + + // Jitter enable + prim_mubi_pkg::mubi4_t jen; + + // reset domain connections + import rstmgr_pkg::PowerDomains; + import rstmgr_pkg::DomainAonSel; + import rstmgr_pkg::Domain0Sel; + + // Memory configuration connections + ast_pkg::spm_rm_t ast_ram_1p_cfg; + ast_pkg::spm_rm_t ast_rf_cfg; + ast_pkg::spm_rm_t ast_rom_cfg; + ast_pkg::dpm_rm_t ast_ram_2p_fcfg; + ast_pkg::dpm_rm_t ast_ram_2p_lcfg; + + prim_ram_1p_pkg::ram_1p_cfg_t ram_1p_cfg; + prim_ram_2p_pkg::ram_2p_cfg_t spi_ram_2p_cfg; + prim_ram_1p_pkg::ram_1p_cfg_t usb_ram_1p_cfg; + prim_rom_pkg::rom_cfg_t rom_cfg; + + // conversion from ast structure to memory centric structures + assign ram_1p_cfg = '{ + ram_cfg: '{ + test: ast_ram_1p_cfg.test, + cfg_en: ast_ram_1p_cfg.marg_en, + cfg: ast_ram_1p_cfg.marg + }, + rf_cfg: '{ + test: ast_rf_cfg.test, + cfg_en: ast_rf_cfg.marg_en, + cfg: ast_rf_cfg.marg + } + }; + + assign usb_ram_1p_cfg = '{ + ram_cfg: '{ + test: ast_ram_1p_cfg.test, + cfg_en: ast_ram_1p_cfg.marg_en, + cfg: ast_ram_1p_cfg.marg + }, + rf_cfg: '{ + test: ast_rf_cfg.test, + cfg_en: ast_rf_cfg.marg_en, + cfg: ast_rf_cfg.marg + } + }; + + // this maps as follows: + // assign spi_ram_2p_cfg = {10'h000, ram_2p_cfg_i.a_ram_lcfg, ram_2p_cfg_i.b_ram_lcfg}; + assign spi_ram_2p_cfg = '{ + a_ram_lcfg: '{ + test: ast_ram_2p_lcfg.test_a, + cfg_en: ast_ram_2p_lcfg.marg_en_a, + cfg: ast_ram_2p_lcfg.marg_a + }, + b_ram_lcfg: '{ + test: ast_ram_2p_lcfg.test_b, + cfg_en: ast_ram_2p_lcfg.marg_en_b, + cfg: ast_ram_2p_lcfg.marg_b + }, + default: '0 + }; + + assign rom_cfg = '{ + test: ast_rom_cfg.test, + cfg_en: ast_rom_cfg.marg_en, + cfg: ast_rom_cfg.marg + }; + + // unused cfg bits + logic unused_ram_cfg; + assign unused_ram_cfg = ^ast_ram_2p_fcfg; + + ////////////////////////////////// + // AST - Custom for targets // + ////////////////////////////////// + + + assign ast_base_pwr.main_pok = ast_pwst.main_pok; + + logic [rstmgr_pkg::PowerDomains-1:0] por_n; + assign por_n = {ast_pwst.main_pok, ast_pwst.aon_pok}; + + // TODO: Hook this up when FPGA pads are updated + assign ext_clk = '0; + assign pad2ast = '0; + + logic clk_main, clk_usb_48mhz, clk_aon, rst_n, srst_n; + clkgen_xil7series # ( + .AddClkBuf(0) + ) clkgen ( + .clk_i(manual_in_io_clk), + .rst_ni(manual_in_por_n), + .srst_ni(srst_n), + .clk_main_o(clk_main), + .clk_48MHz_o(clk_usb_48mhz), + .clk_aon_o(clk_aon), + .rst_no(rst_n) + ); + + logic [31:0] fpga_info; + usr_access_xil7series u_info ( + .info_o(fpga_info) + ); + + ast_pkg::clks_osc_byp_t clks_osc_byp; + assign clks_osc_byp = '{ + usb: clk_usb_48mhz, + sys: clk_main, + io: clk_main, + aon: clk_aon + }; + + + prim_mubi_pkg::mubi4_t ast_init_done; + + ast u_ast ( + // external POR + .por_ni ( rst_n ), + + // USB IO Pull-up Calibration Setting + .usb_io_pu_cal_o ( ), + + // clocks' oschillator bypass for FPGA + .clk_osc_byp_i ( clks_osc_byp ), + + // adc + .adc_a0_ai ( '0 ), + .adc_a1_ai ( '0 ), + + // Direct short to PAD + .ast2pad_t0_ao ( ), + .ast2pad_t1_ao ( ), + + // clocks and resets supplied for detection + .sns_clks_i ( clkmgr_aon_clocks ), + .sns_rsts_i ( rstmgr_aon_resets ), + .sns_spi_ext_clk_i ( sck_monitor ), + // tlul + .tl_i ( base_ast_bus ), + .tl_o ( ast_base_bus ), + // init done indication + .ast_init_done_o ( ast_init_done ), + // buffered clocks & resets + .clk_ast_tlul_i (clkmgr_aon_clocks.clk_io_div4_secure), + .clk_ast_adc_i (clkmgr_aon_clocks.clk_aon_secure), + .clk_ast_alert_i (clkmgr_aon_clocks.clk_io_div4_secure), + .clk_ast_es_i (clkmgr_aon_clocks.clk_main_secure), + .clk_ast_rng_i (clkmgr_aon_clocks.clk_main_secure), + .clk_ast_usb_i (clkmgr_aon_clocks.clk_usb_peri), + .rst_ast_tlul_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]), + .rst_ast_adc_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::Domain0Sel]), + .rst_ast_alert_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]), + .rst_ast_es_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]), + .rst_ast_rng_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]), + .rst_ast_usb_ni (rstmgr_aon_resets.rst_usb_n[rstmgr_pkg::Domain0Sel]), + .clk_ast_ext_i ( ext_clk ), + + // pok test for FPGA + .vcc_supp_i ( 1'b1 ), + .vcaon_supp_i ( 1'b1 ), + .vcmain_supp_i ( 1'b1 ), + .vioa_supp_i ( 1'b1 ), + .viob_supp_i ( 1'b1 ), + // pok + .ast_pwst_o ( ast_pwst ), + .ast_pwst_h_o ( ast_pwst_h ), + // main regulator + .main_env_iso_en_i ( base_ast_pwr.pwr_clamp_env ), + .main_pd_ni ( base_ast_pwr.main_pd_n ), + // pdm control (flash)/otp + .flash_power_down_h_o ( flash_power_down_h ), + .flash_power_ready_h_o ( flash_power_ready_h ), + .otp_power_seq_i ( otp_ctrl_otp_ast_pwr_seq ), + .otp_power_seq_h_o ( otp_ctrl_otp_ast_pwr_seq_h ), + // system source clock + .clk_src_sys_en_i ( base_ast_pwr.core_clk_en ), + // need to add function in clkmgr + .clk_src_sys_jen_i ( jen ), + .clk_src_sys_o ( ast_base_clks.clk_sys ), + .clk_src_sys_val_o ( ast_base_pwr.core_clk_val ), + // aon source clock + .clk_src_aon_o ( ast_base_clks.clk_aon ), + .clk_src_aon_val_o ( ast_base_pwr.slow_clk_val ), + // io source clock + .clk_src_io_en_i ( base_ast_pwr.io_clk_en ), + .clk_src_io_o ( ast_base_clks.clk_io ), + .clk_src_io_val_o ( ast_base_pwr.io_clk_val ), + .clk_src_io_48m_o ( div_step_down_req ), + // usb source clock + .usb_ref_pulse_i ( usb_ref_pulse ), + .usb_ref_val_i ( usb_ref_val ), + .clk_src_usb_en_i ( base_ast_pwr.usb_clk_en ), + .clk_src_usb_o ( ast_base_clks.clk_usb ), + .clk_src_usb_val_o ( ast_base_pwr.usb_clk_val ), + // adc + .adc_pd_i ( adc_req.pd ), + .adc_chnsel_i ( adc_req.channel_sel ), + .adc_d_o ( adc_rsp.data ), + .adc_d_val_o ( adc_rsp.data_valid ), + // rng + .rng_en_i ( es_rng_req.rng_enable ), + .rng_fips_i ( es_rng_fips ), + .rng_val_o ( es_rng_rsp.rng_valid ), + .rng_b_o ( es_rng_rsp.rng_b ), + // entropy + .entropy_rsp_i ( ast_edn_edn_rsp ), + .entropy_req_o ( ast_edn_edn_req ), + // alerts + .alert_rsp_i ( ast_alert_rsp ), + .alert_req_o ( ast_alert_req ), + // dft + .dft_strap_test_i ( dft_strap_test ), + .lc_dft_en_i ( dft_en ), + .fla_obs_i ( fla_obs ), + .otp_obs_i ( otp_obs ), + .otm_obs_i ( '0 ), + .usb_obs_i ( usb_diff_rx_obs ), + .obs_ctrl_o ( obs_ctrl ), + // pinmux related + .padmux2ast_i ( pad2ast ), + .ast2padmux_o ( ast2pinmux ), + .mux_iob_sel_o ( mux_iob_sel ), + .ext_freq_is_96m_i ( hi_speed_sel ), + .all_clk_byp_req_i ( all_clk_byp_req ), + .all_clk_byp_ack_o ( all_clk_byp_ack ), + .io_clk_byp_req_i ( io_clk_byp_req ), + .io_clk_byp_ack_o ( io_clk_byp_ack ), + .flash_bist_en_o ( flash_bist_enable ), + // Memory configuration connections + .dpram_rmf_o ( ast_ram_2p_fcfg ), + .dpram_rml_o ( ast_ram_2p_lcfg ), + .spram_rm_o ( ast_ram_1p_cfg ), + .sprgf_rm_o ( ast_rf_cfg ), + .sprom_rm_o ( ast_rom_cfg ), + // scan + .dft_scan_md_o ( scanmode ), + .scan_shift_en_o ( scan_en ), + .scan_reset_no ( scan_rst_n ) + ); + + + + + ////////////////// + // PLL for FPGA // + ////////////////// + + assign manual_attr_io_clk = '0; + assign manual_out_io_clk = 1'b0; + assign manual_oe_io_clk = 1'b0; + assign manual_attr_por_n = '0; + assign manual_out_por_n = 1'b0; + assign manual_oe_por_n = 1'b0; + assign manual_attr_por_button_n = '0; + assign manual_out_por_button_n = 1'b0; + assign manual_oe_por_button_n = 1'b0; + + assign srst_n = manual_in_por_button_n; + + // TODO: follow-up later and hardwire all ast connects that do not + // exist for this target + assign otp_obs_o = '0; + + ////////////////////// + // Top-level design // + ////////////////////// + + // the rst_ni pin only goes to AST + // the rest of the logic generates reset based on the 'pok' signal. + // for verilator purposes, make these two the same. + prim_mubi_pkg::mubi4_t lc_clk_bypass; // TODO Tim + +// TODO: align this with ASIC version to minimize the duplication. +// Also need to add AST simulation and FPGA emulation models for things like entropy source - +// otherwise Verilator / FPGA will hang. + top_englishbreakfast #( + .RvCoreIbexPipeLine(0), + .SecAesMasking(1'b1), + .SecAesSBoxImpl(aes_pkg::SBoxImplDom), + .SecAesStartTriggerDelay(320), + .SecAesAllowForcingMasks(1'b1), + .SecAesSkipPRNGReseeding(1'b1), + .UsbdevStub(1'b1), + .RvCoreIbexSecureIbex(0), + .RomCtrlBootRomInitFile(BootRomInitFile), + .RvCoreIbexRegFile(ibex_pkg::RegFileFPGA), + .SramCtrlMainInstrExec(1), + .PinmuxAonTargetCfg(PinmuxTargetCfg) + ) top_englishbreakfast ( + .por_n_i ( por_n ), + .clk_main_i ( ast_base_clks.clk_sys ), + .clk_io_i ( ast_base_clks.clk_io ), + .clk_usb_i ( ast_base_clks.clk_usb ), + .clk_aon_i ( ast_base_clks.clk_aon ), + .clks_ast_o ( clkmgr_aon_clocks ), + .clk_main_jitter_en_o ( jen ), + .rsts_ast_o ( rstmgr_aon_resets ), + .sck_monitor_o ( sck_monitor ), + .pwrmgr_ast_req_o ( base_ast_pwr ), + .pwrmgr_ast_rsp_i ( ast_base_pwr ), + .usb_dp_pullup_en_o ( usb_dp_pullup_en ), + .usb_dn_pullup_en_o ( usb_dn_pullup_en ), + .usbdev_usb_rx_d_i ( usb_rx_d ), + .usbdev_usb_tx_d_o ( usb_tx_d ), + .usbdev_usb_tx_se0_o ( usb_tx_se0 ), + .usbdev_usb_tx_use_d_se0_o ( usb_tx_use_d_se0 ), + .usbdev_usb_rx_enable_o ( usb_rx_enable ), + .usbdev_usb_ref_val_o ( usb_ref_val ), + .usbdev_usb_ref_pulse_o ( usb_ref_pulse ), + .ast_edn_req_i ( ast_edn_edn_req ), + .ast_edn_rsp_o ( ast_edn_edn_rsp ), + .obs_ctrl_i ( obs_ctrl ), + .flash_bist_enable_i ( flash_bist_enable ), + .flash_power_down_h_i ( 1'b0 ), + .flash_power_ready_h_i ( 1'b1 ), + .flash_obs_o ( flash_obs ), + .io_clk_byp_req_o ( io_clk_byp_req ), + .io_clk_byp_ack_i ( io_clk_byp_ack ), + .all_clk_byp_req_o ( all_clk_byp_req ), + .all_clk_byp_ack_i ( all_clk_byp_ack ), + .hi_speed_sel_o ( hi_speed_sel ), + .div_step_down_req_i ( div_step_down_req ), + .fpga_info_i ( fpga_info ), + + // Multiplexed I/O + .mio_in_i ( mio_in ), + .mio_out_o ( mio_out ), + .mio_oe_o ( mio_oe ), + + // Dedicated I/O + .dio_in_i ( dio_in ), + .dio_out_o ( dio_out ), + .dio_oe_o ( dio_oe ), + + // Pad attributes + .mio_attr_o ( mio_attr ), + .dio_attr_o ( dio_attr ), + + // Memory attributes + .ram_1p_cfg_i ( '0 ), + .spi_ram_2p_cfg_i( '0 ), + .usb_ram_1p_cfg_i( '0 ), + .rom_cfg_i ( '0 ), + + // DFT signals + .dft_hold_tap_sel_i ( '0 ), + .scan_rst_ni ( 1'b1 ), + .scan_en_i ( 1'b0 ), + .scanmode_i ( prim_mubi_pkg::MuBi4False ) + ); + + + ///////////////////////////////////////////////////// + // ChipWhisperer CW310/305 Capture Board Interface // + ///////////////////////////////////////////////////// + // This is used to interface OpenTitan as a target with a capture board trough the ChipWhisperer + // 20-pin connector. This is used for SCA/FI experiments only. + + logic unused_inputs; + assign unused_inputs = manual_in_io_clkout ^ manual_in_io_trigger; + + // Synchronous clock output to capture board. + assign manual_out_io_clkout = manual_in_io_clk; + assign manual_oe_io_clkout = 1'b1; + + // Capture trigger. + // We use the clkmgr_aon_idle signal of the IP of interest to form a precise capture trigger. + // GPIO[11:10] is used for selecting the IP of interest. The encoding is as follows (see + // hint_names_e enum in clkmgr_pkg.sv for details). + // + // IP - GPIO[11:10] - Index for clkmgr_aon_idle + // ------------------------------------------------------------- + // AES - 00 - 0 + // HMAC - 01 - 1 - not implemented on CW305 + // KMAC - 10 - 2 - not implemented on CW305 + // OTBN - 11 - 3 - not implemented on CW305 + // + // GPIO9 is used for gating the selected capture trigger in software. Alternatively, GPIO8 + // can be used to implement a less precise but fully software-controlled capture trigger + // similar to what can be done on ASIC. + // + // Note that on the CW305, GPIO[9,8] are connected to LED[5(Green),7(Red)]. + + prim_mubi_pkg::mubi4_t clk_trans_idle, manual_in_io_clk_idle; + + assign clk_trans_idle = top_englishbreakfast.clkmgr_aon_idle; + + logic clk_io_div4_trigger_hw_en, manual_in_io_clk_trigger_hw_en; + logic clk_io_div4_trigger_hw_oe, manual_in_io_clk_trigger_hw_oe; + logic clk_io_div4_trigger_sw_en, manual_in_io_clk_trigger_sw_en; + logic clk_io_div4_trigger_sw_oe, manual_in_io_clk_trigger_sw_oe; + assign clk_io_div4_trigger_hw_en = mio_out[MioOutGpioGpio9]; + assign clk_io_div4_trigger_hw_oe = mio_oe[MioOutGpioGpio9]; + assign clk_io_div4_trigger_sw_en = mio_out[MioOutGpioGpio8]; + assign clk_io_div4_trigger_sw_oe = mio_oe[MioOutGpioGpio8]; + + // Synchronize signals to manual_in_io_clk. + prim_flop_2sync #( + .Width ($bits(clk_trans_idle) + 4) + ) u_sync_trigger ( + .clk_i (manual_in_io_clk), + .rst_ni(manual_in_por_n), + .d_i ({clk_trans_idle, + clk_io_div4_trigger_hw_en, + clk_io_div4_trigger_hw_oe, + clk_io_div4_trigger_sw_en, + clk_io_div4_trigger_sw_oe}), + .q_o ({manual_in_io_clk_idle, + manual_in_io_clk_trigger_hw_en, + manual_in_io_clk_trigger_hw_oe, + manual_in_io_clk_trigger_sw_en, + manual_in_io_clk_trigger_sw_oe}) + ); + + // Generate the actual trigger signal as trigger_sw OR trigger_hw. + assign manual_attr_io_trigger = '0; + assign manual_oe_io_trigger = + manual_in_io_clk_trigger_sw_oe | manual_in_io_clk_trigger_hw_oe; + assign manual_out_io_trigger = + manual_in_io_clk_trigger_sw_en | (manual_in_io_clk_trigger_hw_en & + prim_mubi_pkg::mubi4_test_false_strict(manual_in_io_clk_idle)); + +endmodule : chip_englishbreakfast_cw305 diff --git a/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast.sv b/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast.sv new file mode 100644 index 0000000000000..d919b81f77967 --- /dev/null +++ b/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast.sv @@ -0,0 +1,1674 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson \ +// -o hw/top_englishbreakfast/ \ +// --rnd_cnst_seed \ +// 4881560218908238235 + +module top_englishbreakfast #( + // Manually defined parameters + + // Auto-inferred parameters + // parameters for uart0 + // parameters for uart1 + // parameters for gpio + parameter bit GpioGpioAsyncOn = 1, + parameter bit GpioGpioAsHwStrapsEn = 1'b1, + // parameters for spi_device + parameter spi_device_pkg::sram_type_e SpiDeviceSramType = spi_device_pkg::DefaultSramType, + // parameters for spi_host0 + // parameters for rv_timer + // parameters for usbdev + parameter bit UsbdevStub = 0, + parameter int UsbdevRcvrWakeTimeUs = 1, + // parameters for pwrmgr_aon + // parameters for rstmgr_aon + parameter bit SecRstmgrAonCheck = 0, + parameter int SecRstmgrAonMaxSyncDelay = 2, + // parameters for clkmgr_aon + // parameters for pinmux_aon + parameter bit SecPinmuxAonVolatileRawUnlockEn = 1'b0, + parameter pinmux_pkg::target_cfg_t PinmuxAonTargetCfg = pinmux_pkg::DefaultTargetCfg, + // parameters for aon_timer_aon + // parameters for flash_ctrl + parameter bit SecFlashCtrlScrambleEn = 0, + parameter int FlashCtrlProgFifoDepth = 16, + parameter int FlashCtrlRdFifoDepth = 16, + // parameters for rv_plic + // parameters for aes + parameter bit SecAesMasking = 1, + parameter aes_pkg::sbox_impl_e SecAesSBoxImpl = aes_pkg::SBoxImplDom, + parameter int unsigned SecAesStartTriggerDelay = 0, + parameter bit SecAesAllowForcingMasks = 1'b0, + parameter bit SecAesSkipPRNGReseeding = 1'b0, + // parameters for sram_ctrl_main + parameter int SramCtrlMainInstSize = 4096, + parameter int SramCtrlMainNumRamInst = 1, + parameter bit SramCtrlMainInstrExec = 1, + parameter int SramCtrlMainNumPrinceRoundsHalf = 3, + // parameters for rom_ctrl + parameter RomCtrlBootRomInitFile = "", + parameter bit SecRomCtrlDisableScrambling = 1'b1, + // parameters for rv_core_ibex + parameter bit RvCoreIbexPMPEnable = 0, + parameter int unsigned RvCoreIbexPMPGranularity = 0, + parameter int unsigned RvCoreIbexPMPNumRegions = 16, + parameter int unsigned RvCoreIbexMHPMCounterNum = 0, + parameter int unsigned RvCoreIbexMHPMCounterWidth = 32, + parameter ibex_pkg::pmp_cfg_t RvCoreIbexPMPRstCfg[16] = ibex_pkg::PmpCfgRst, + parameter logic [33:0] RvCoreIbexPMPRstAddr[16] = ibex_pkg::PmpAddrRst, + parameter ibex_pkg::pmp_mseccfg_t RvCoreIbexPMPRstMsecCfg = ibex_pkg::PmpMseccfgRst, + parameter bit RvCoreIbexRV32E = 0, + parameter ibex_pkg::rv32m_e RvCoreIbexRV32M = ibex_pkg::RV32MSingleCycle, + parameter ibex_pkg::rv32b_e RvCoreIbexRV32B = ibex_pkg::RV32BNone, + parameter ibex_pkg::regfile_e RvCoreIbexRegFile = ibex_pkg::RegFileFF, + parameter bit RvCoreIbexBranchTargetALU = 1, + parameter bit RvCoreIbexWritebackStage = 1, + parameter bit RvCoreIbexICache = 0, + parameter bit RvCoreIbexICacheECC = 0, + parameter bit RvCoreIbexICacheScramble = 0, + parameter int unsigned RvCoreIbexICacheNWays = 2, + parameter bit RvCoreIbexBranchPredictor = 0, + parameter bit RvCoreIbexDbgTriggerEn = 1, + parameter int RvCoreIbexDbgHwBreakNum = 1, + parameter bit RvCoreIbexSecureIbex = 0, + parameter int unsigned RvCoreIbexDmBaseAddr = 437321728, + parameter int unsigned RvCoreIbexDmAddrMask = 4095, + parameter int unsigned RvCoreIbexDmHaltAddr = 0, + parameter int unsigned RvCoreIbexDmExceptionAddr = 0, + parameter bit RvCoreIbexPipeLine = 0 +) ( + // Multiplexed I/O + input [46:0] mio_in_i, + output logic [46:0] mio_out_o, + output logic [46:0] mio_oe_o, + // Dedicated I/O + input [13:0] dio_in_i, + output logic [13:0] dio_out_o, + output logic [13:0] dio_oe_o, + + // pad attributes to padring + output prim_pad_wrapper_pkg::pad_attr_t [pinmux_reg_pkg::NMioPads-1:0] mio_attr_o, + output prim_pad_wrapper_pkg::pad_attr_t [pinmux_reg_pkg::NDioPads-1:0] dio_attr_o, + + + // Inter-module Signal External type + input edn_pkg::edn_req_t ast_edn_req_i, + output edn_pkg::edn_rsp_t ast_edn_rsp_o, + output lc_ctrl_pkg::lc_tx_t ast_lc_dft_en_o, + input prim_ram_1p_pkg::ram_1p_cfg_t ram_1p_cfg_i, + input prim_ram_2p_pkg::ram_2p_cfg_t spi_ram_2p_cfg_i, + input prim_ram_1p_pkg::ram_1p_cfg_t usb_ram_1p_cfg_i, + input prim_rom_pkg::rom_cfg_t rom_cfg_i, + output prim_mubi_pkg::mubi4_t clk_main_jitter_en_o, + output prim_mubi_pkg::mubi4_t hi_speed_sel_o, + input prim_mubi_pkg::mubi4_t div_step_down_req_i, + output prim_mubi_pkg::mubi4_t all_clk_byp_req_o, + input prim_mubi_pkg::mubi4_t all_clk_byp_ack_i, + output prim_mubi_pkg::mubi4_t io_clk_byp_req_o, + input prim_mubi_pkg::mubi4_t io_clk_byp_ack_i, + input prim_mubi_pkg::mubi4_t flash_bist_enable_i, + input logic flash_power_down_h_i, + input logic flash_power_ready_h_i, + input ast_pkg::ast_obs_ctrl_t obs_ctrl_i, + output logic [7:0] flash_obs_o, + output tlul_pkg::tl_h2d_t ast_tl_req_o, + input tlul_pkg::tl_d2h_t ast_tl_rsp_i, + output pinmux_pkg::dft_strap_test_req_t dft_strap_test_o, + input logic dft_hold_tap_sel_i, + output logic usb_dp_pullup_en_o, + output logic usb_dn_pullup_en_o, + output pwrmgr_pkg::pwr_ast_req_t pwrmgr_ast_req_o, + input pwrmgr_pkg::pwr_ast_rsp_t pwrmgr_ast_rsp_i, + input logic [1:0] por_n_i, + input logic [31:0] fpga_info_i, + input logic usbdev_usb_rx_d_i, + output logic usbdev_usb_tx_d_o, + output logic usbdev_usb_tx_se0_o, + output logic usbdev_usb_tx_use_d_se0_o, + output logic usbdev_usb_rx_enable_o, + output logic usbdev_usb_ref_val_o, + output logic usbdev_usb_ref_pulse_o, + output logic sck_monitor_o, + + + // All externally supplied clocks + input clk_main_i, + input clk_io_i, + input clk_usb_i, + input clk_aon_i, + + // All clocks forwarded to ast + output clkmgr_pkg::clkmgr_out_t clks_ast_o, + output rstmgr_pkg::rstmgr_out_t rsts_ast_o, + + input scan_rst_ni, // reset used for test mode + input scan_en_i, + input prim_mubi_pkg::mubi4_t scanmode_i // lc_ctrl_pkg::On for Scan +); + + import tlul_pkg::*; + import top_pkg::*; + import tl_main_pkg::*; + import top_englishbreakfast_pkg::*; + // Compile-time random constants + import top_englishbreakfast_rnd_cnst_pkg::*; + + // Local Parameters + // local parameters for spi_host0 + localparam int SpiHost0NumCS = 1; + // local parameters for rv_core_ibex + localparam int unsigned RvCoreIbexNEscalationSeverities = 4; + localparam int unsigned RvCoreIbexWidthPingCounter = 16; + + // Signals + logic [37:0] mio_p2d; + logic [34:0] mio_d2p; + logic [34:0] mio_en_d2p; + logic [13:0] dio_p2d; + logic [13:0] dio_d2p; + logic [13:0] dio_en_d2p; + // uart0 + logic cio_uart0_rx_p2d; + logic cio_uart0_tx_d2p; + logic cio_uart0_tx_en_d2p; + // uart1 + logic cio_uart1_rx_p2d; + logic cio_uart1_tx_d2p; + logic cio_uart1_tx_en_d2p; + // gpio + logic [31:0] cio_gpio_gpio_p2d; + logic [31:0] cio_gpio_gpio_d2p; + logic [31:0] cio_gpio_gpio_en_d2p; + // spi_device + logic cio_spi_device_sck_p2d; + logic cio_spi_device_csb_p2d; + logic cio_spi_device_tpm_csb_p2d; + logic [3:0] cio_spi_device_sd_p2d; + logic [3:0] cio_spi_device_sd_d2p; + logic [3:0] cio_spi_device_sd_en_d2p; + // spi_host0 + logic [3:0] cio_spi_host0_sd_p2d; + logic cio_spi_host0_sck_d2p; + logic cio_spi_host0_sck_en_d2p; + logic cio_spi_host0_csb_d2p; + logic cio_spi_host0_csb_en_d2p; + logic [3:0] cio_spi_host0_sd_d2p; + logic [3:0] cio_spi_host0_sd_en_d2p; + // rv_timer + // usbdev + logic cio_usbdev_sense_p2d; + logic cio_usbdev_usb_dp_p2d; + logic cio_usbdev_usb_dn_p2d; + logic cio_usbdev_usb_dp_d2p; + logic cio_usbdev_usb_dp_en_d2p; + logic cio_usbdev_usb_dn_d2p; + logic cio_usbdev_usb_dn_en_d2p; + // pwrmgr_aon + // rstmgr_aon + // clkmgr_aon + // pinmux_aon + // aon_timer_aon + // flash_ctrl + logic cio_flash_ctrl_tck_p2d; + logic cio_flash_ctrl_tms_p2d; + logic cio_flash_ctrl_tdi_p2d; + logic cio_flash_ctrl_tdo_d2p; + logic cio_flash_ctrl_tdo_en_d2p; + // rv_plic + // aes + // sram_ctrl_main + // rom_ctrl + // rv_core_ibex + + + logic [87:0] intr_vector; + // Interrupt source list + logic intr_uart0_tx_watermark; + logic intr_uart0_rx_watermark; + logic intr_uart0_tx_done; + logic intr_uart0_rx_overflow; + logic intr_uart0_rx_frame_err; + logic intr_uart0_rx_break_err; + logic intr_uart0_rx_timeout; + logic intr_uart0_rx_parity_err; + logic intr_uart0_tx_empty; + logic intr_uart1_tx_watermark; + logic intr_uart1_rx_watermark; + logic intr_uart1_tx_done; + logic intr_uart1_rx_overflow; + logic intr_uart1_rx_frame_err; + logic intr_uart1_rx_break_err; + logic intr_uart1_rx_timeout; + logic intr_uart1_rx_parity_err; + logic intr_uart1_tx_empty; + logic [31:0] intr_gpio_gpio; + logic intr_spi_device_upload_cmdfifo_not_empty; + logic intr_spi_device_upload_payload_not_empty; + logic intr_spi_device_upload_payload_overflow; + logic intr_spi_device_readbuf_watermark; + logic intr_spi_device_readbuf_flip; + logic intr_spi_device_tpm_header_not_empty; + logic intr_spi_device_tpm_rdfifo_cmd_end; + logic intr_spi_device_tpm_rdfifo_drop; + logic intr_spi_host0_error; + logic intr_spi_host0_spi_event; + logic intr_rv_timer_timer_expired_hart0_timer0; + logic intr_usbdev_pkt_received; + logic intr_usbdev_pkt_sent; + logic intr_usbdev_disconnected; + logic intr_usbdev_host_lost; + logic intr_usbdev_link_reset; + logic intr_usbdev_link_suspend; + logic intr_usbdev_link_resume; + logic intr_usbdev_av_out_empty; + logic intr_usbdev_rx_full; + logic intr_usbdev_av_overflow; + logic intr_usbdev_link_in_err; + logic intr_usbdev_rx_crc_err; + logic intr_usbdev_rx_pid_err; + logic intr_usbdev_rx_bitstuff_err; + logic intr_usbdev_frame; + logic intr_usbdev_powered; + logic intr_usbdev_link_out_err; + logic intr_usbdev_av_setup_empty; + logic intr_pwrmgr_aon_wakeup; + logic intr_aon_timer_aon_wkup_timer_expired; + logic intr_aon_timer_aon_wdog_timer_bark; + logic intr_flash_ctrl_prog_empty; + logic intr_flash_ctrl_prog_lvl; + logic intr_flash_ctrl_rd_full; + logic intr_flash_ctrl_rd_lvl; + logic intr_flash_ctrl_op_done; + logic intr_flash_ctrl_corr_err; + + // Alert list + prim_alert_pkg::alert_tx_t [alert_pkg::NAlerts-1:0] alert_tx; + prim_alert_pkg::alert_rx_t [alert_pkg::NAlerts-1:0] alert_rx; + + + // define inter-module signals + pwrmgr_pkg::pwr_flash_t pwrmgr_aon_pwr_flash; + pwrmgr_pkg::pwr_rst_req_t pwrmgr_aon_pwr_rst_req; + pwrmgr_pkg::pwr_rst_rsp_t pwrmgr_aon_pwr_rst_rsp; + pwrmgr_pkg::pwr_clk_req_t pwrmgr_aon_pwr_clk_req; + pwrmgr_pkg::pwr_clk_rsp_t pwrmgr_aon_pwr_clk_rsp; + logic pwrmgr_aon_strap; + logic pwrmgr_aon_low_power; + lc_ctrl_pkg::lc_tx_t pwrmgr_aon_fetch_en; + logic usbdev_usb_dp_pullup; + logic usbdev_usb_dn_pullup; + logic usbdev_usb_aon_suspend_req; + logic usbdev_usb_aon_wake_ack; + logic usbdev_usb_aon_bus_reset; + logic usbdev_usb_aon_sense_lost; + logic pinmux_aon_usbdev_wake_detect_active; + prim_mubi_pkg::mubi4_t clkmgr_aon_idle; + logic rv_plic_msip; + logic rv_plic_irq; + rv_core_ibex_pkg::cpu_crash_dump_t rv_core_ibex_crash_dump; + rv_core_ibex_pkg::cpu_pwrmgr_t rv_core_ibex_pwrmgr; + spi_device_pkg::passthrough_req_t spi_device_passthrough_req; + spi_device_pkg::passthrough_rsp_t spi_device_passthrough_rsp; + prim_mubi_pkg::mubi4_t rstmgr_aon_sw_rst_req; + logic [2:0] pwrmgr_aon_wakeups; + logic pwrmgr_aon_rstreqs; + tlul_pkg::tl_h2d_t main_tl_rv_core_ibex__corei_req; + tlul_pkg::tl_d2h_t main_tl_rv_core_ibex__corei_rsp; + tlul_pkg::tl_h2d_t main_tl_rv_core_ibex__cored_req; + tlul_pkg::tl_d2h_t main_tl_rv_core_ibex__cored_rsp; + tlul_pkg::tl_h2d_t rom_ctrl_rom_tl_req; + tlul_pkg::tl_d2h_t rom_ctrl_rom_tl_rsp; + tlul_pkg::tl_h2d_t rom_ctrl_regs_tl_req; + tlul_pkg::tl_d2h_t rom_ctrl_regs_tl_rsp; + tlul_pkg::tl_h2d_t main_tl_peri_req; + tlul_pkg::tl_d2h_t main_tl_peri_rsp; + tlul_pkg::tl_h2d_t flash_ctrl_core_tl_req; + tlul_pkg::tl_d2h_t flash_ctrl_core_tl_rsp; + tlul_pkg::tl_h2d_t flash_ctrl_prim_tl_req; + tlul_pkg::tl_d2h_t flash_ctrl_prim_tl_rsp; + tlul_pkg::tl_h2d_t flash_ctrl_mem_tl_req; + tlul_pkg::tl_d2h_t flash_ctrl_mem_tl_rsp; + tlul_pkg::tl_h2d_t aes_tl_req; + tlul_pkg::tl_d2h_t aes_tl_rsp; + tlul_pkg::tl_h2d_t rv_plic_tl_req; + tlul_pkg::tl_d2h_t rv_plic_tl_rsp; + tlul_pkg::tl_h2d_t rv_core_ibex_cfg_tl_d_req; + tlul_pkg::tl_d2h_t rv_core_ibex_cfg_tl_d_rsp; + tlul_pkg::tl_h2d_t sram_ctrl_main_regs_tl_req; + tlul_pkg::tl_d2h_t sram_ctrl_main_regs_tl_rsp; + tlul_pkg::tl_h2d_t sram_ctrl_main_ram_tl_req; + tlul_pkg::tl_d2h_t sram_ctrl_main_ram_tl_rsp; + tlul_pkg::tl_h2d_t uart0_tl_req; + tlul_pkg::tl_d2h_t uart0_tl_rsp; + tlul_pkg::tl_h2d_t uart1_tl_req; + tlul_pkg::tl_d2h_t uart1_tl_rsp; + tlul_pkg::tl_h2d_t gpio_tl_req; + tlul_pkg::tl_d2h_t gpio_tl_rsp; + tlul_pkg::tl_h2d_t spi_device_tl_req; + tlul_pkg::tl_d2h_t spi_device_tl_rsp; + tlul_pkg::tl_h2d_t spi_host0_tl_req; + tlul_pkg::tl_d2h_t spi_host0_tl_rsp; + tlul_pkg::tl_h2d_t rv_timer_tl_req; + tlul_pkg::tl_d2h_t rv_timer_tl_rsp; + tlul_pkg::tl_h2d_t usbdev_tl_req; + tlul_pkg::tl_d2h_t usbdev_tl_rsp; + tlul_pkg::tl_h2d_t pwrmgr_aon_tl_req; + tlul_pkg::tl_d2h_t pwrmgr_aon_tl_rsp; + tlul_pkg::tl_h2d_t rstmgr_aon_tl_req; + tlul_pkg::tl_d2h_t rstmgr_aon_tl_rsp; + tlul_pkg::tl_h2d_t clkmgr_aon_tl_req; + tlul_pkg::tl_d2h_t clkmgr_aon_tl_rsp; + tlul_pkg::tl_h2d_t pinmux_aon_tl_req; + tlul_pkg::tl_d2h_t pinmux_aon_tl_rsp; + clkmgr_pkg::clkmgr_out_t clkmgr_aon_clocks; + clkmgr_pkg::clkmgr_cg_en_t clkmgr_aon_cg_en; + rstmgr_pkg::rstmgr_out_t rstmgr_aon_resets; + rstmgr_pkg::rstmgr_rst_en_t rstmgr_aon_rst_en; + logic rv_core_ibex_irq_timer; + logic [31:0] rv_core_ibex_hart_id; + logic [31:0] rv_core_ibex_boot_addr; + lc_ctrl_pkg::lc_tx_t rv_core_ibex_lc_cpu_en; + jtag_pkg::jtag_req_t pinmux_aon_dft_jtag_req; + jtag_pkg::jtag_rsp_t pinmux_aon_dft_jtag_rsp; + prim_mubi_pkg::mubi8_t sram_ctrl_main_otp_en_sram_ifetch; + + // define mixed connection to port + + // define partial inter-module tie-off + + // assign partial inter-module tie-off + + + + + // See #7978 This below is a hack. + // This is because ast is a comportable-like module that sits outside + // of top_englishbreakfast's boundary. + assign clks_ast_o = clkmgr_aon_clocks; + assign rsts_ast_o = rstmgr_aon_resets; + + // ibex specific assignments + // TODO: This should be further automated in the future. + assign rv_core_ibex_irq_timer = intr_rv_timer_timer_expired_hart0_timer0; + assign rv_core_ibex_hart_id = '0; + + assign rv_core_ibex_boot_addr = ADDR_SPACE_ROM_CTRL__ROM; + + assign rv_core_ibex_lc_cpu_en = lc_ctrl_pkg::On; + + // Struct breakout module tool-inserted DFT TAP signals + pinmux_jtag_breakout u_dft_tap_breakout ( + .req_i (pinmux_aon_dft_jtag_req), + .rsp_o (pinmux_aon_dft_jtag_rsp), + .tck_o (), + .trst_no (), + .tms_o (), + .tdi_o (), + .tdo_i (1'b0), + .tdo_oe_i (1'b0) + ); + + // Wire up alert handler LPGs + prim_mubi_pkg::mubi4_t [alert_pkg::NLpg-1:0] lpg_cg_en; + prim_mubi_pkg::mubi4_t [alert_pkg::NLpg-1:0] lpg_rst_en; + + + // peri_lc_io_div4_0 + assign lpg_cg_en[0] = clkmgr_aon_cg_en.io_div4_peri; + assign lpg_rst_en[0] = rstmgr_aon_rst_en.lc_io_div4[rstmgr_pkg::Domain0Sel]; + // peri_sys_io_div4_0 + assign lpg_cg_en[1] = clkmgr_aon_cg_en.io_div4_peri; + assign lpg_rst_en[1] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::Domain0Sel]; + // peri_spi_device_0 + assign lpg_cg_en[2] = clkmgr_aon_cg_en.io_div4_peri; + assign lpg_rst_en[2] = rstmgr_aon_rst_en.spi_device[rstmgr_pkg::Domain0Sel]; + // peri_spi_host0_0 + assign lpg_cg_en[3] = clkmgr_aon_cg_en.io_peri; + assign lpg_rst_en[3] = rstmgr_aon_rst_en.spi_host0[rstmgr_pkg::Domain0Sel]; + // timers_sys_io_div4_0 + assign lpg_cg_en[4] = clkmgr_aon_cg_en.io_div4_timers; + assign lpg_rst_en[4] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::Domain0Sel]; + // peri_usb_0 + assign lpg_cg_en[5] = clkmgr_aon_cg_en.usb_peri; + assign lpg_rst_en[5] = rstmgr_aon_rst_en.usb[rstmgr_pkg::Domain0Sel]; + // powerup_por_io_div4_Aon + assign lpg_cg_en[6] = clkmgr_aon_cg_en.io_div4_powerup; + assign lpg_rst_en[6] = rstmgr_aon_rst_en.por_io_div4[rstmgr_pkg::DomainAonSel]; + // powerup_lc_io_div4_Aon + assign lpg_cg_en[7] = clkmgr_aon_cg_en.io_div4_powerup; + assign lpg_rst_en[7] = rstmgr_aon_rst_en.lc_io_div4[rstmgr_pkg::DomainAonSel]; + // timers_sys_io_div4_Aon + assign lpg_cg_en[8] = clkmgr_aon_cg_en.io_div4_timers; + assign lpg_rst_en[8] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::DomainAonSel]; + // secure_lc_io_div4_0 + assign lpg_cg_en[9] = clkmgr_aon_cg_en.io_div4_secure; + assign lpg_rst_en[9] = rstmgr_aon_rst_en.lc_io_div4[rstmgr_pkg::Domain0Sel]; + // infra_lc_0 + assign lpg_cg_en[10] = clkmgr_aon_cg_en.main_infra; + assign lpg_rst_en[10] = rstmgr_aon_rst_en.lc[rstmgr_pkg::Domain0Sel]; + // secure_sys_0 + assign lpg_cg_en[11] = clkmgr_aon_cg_en.main_secure; + assign lpg_rst_en[11] = rstmgr_aon_rst_en.sys[rstmgr_pkg::Domain0Sel]; + // aes_trans_sys_0 + assign lpg_cg_en[12] = clkmgr_aon_cg_en.main_aes; + assign lpg_rst_en[12] = rstmgr_aon_rst_en.sys[rstmgr_pkg::Domain0Sel]; + // infra_sys_0 + assign lpg_cg_en[13] = clkmgr_aon_cg_en.main_infra; + assign lpg_rst_en[13] = rstmgr_aon_rst_en.sys[rstmgr_pkg::Domain0Sel]; + + +// tie-off unused connections +//VCS coverage off +// pragma coverage off + prim_mubi_pkg::mubi4_t unused_cg_en_0; + assign unused_cg_en_0 = clkmgr_aon_cg_en.aon_powerup; + prim_mubi_pkg::mubi4_t unused_cg_en_1; + assign unused_cg_en_1 = clkmgr_aon_cg_en.main_powerup; + prim_mubi_pkg::mubi4_t unused_cg_en_2; + assign unused_cg_en_2 = clkmgr_aon_cg_en.io_powerup; + prim_mubi_pkg::mubi4_t unused_cg_en_3; + assign unused_cg_en_3 = clkmgr_aon_cg_en.usb_powerup; + prim_mubi_pkg::mubi4_t unused_cg_en_4; + assign unused_cg_en_4 = clkmgr_aon_cg_en.io_div2_powerup; + prim_mubi_pkg::mubi4_t unused_cg_en_5; + assign unused_cg_en_5 = clkmgr_aon_cg_en.aon_secure; + prim_mubi_pkg::mubi4_t unused_cg_en_6; + assign unused_cg_en_6 = clkmgr_aon_cg_en.aon_peri; + prim_mubi_pkg::mubi4_t unused_cg_en_7; + assign unused_cg_en_7 = clkmgr_aon_cg_en.aon_timers; + prim_mubi_pkg::mubi4_t unused_cg_en_8; + assign unused_cg_en_8 = clkmgr_aon_cg_en.io_div4_infra; + prim_mubi_pkg::mubi4_t unused_cg_en_9; + assign unused_cg_en_9 = clkmgr_aon_cg_en.io_infra; + prim_mubi_pkg::mubi4_t unused_cg_en_10; + assign unused_cg_en_10 = clkmgr_aon_cg_en.usb_infra; + prim_mubi_pkg::mubi4_t unused_cg_en_11; + assign unused_cg_en_11 = clkmgr_aon_cg_en.io_div2_peri; + prim_mubi_pkg::mubi4_t unused_rst_en_0; + assign unused_rst_en_0 = rstmgr_aon_rst_en.por_aon[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_1; + assign unused_rst_en_1 = rstmgr_aon_rst_en.por_aon[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_2; + assign unused_rst_en_2 = rstmgr_aon_rst_en.por[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_3; + assign unused_rst_en_3 = rstmgr_aon_rst_en.por[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_4; + assign unused_rst_en_4 = rstmgr_aon_rst_en.por_io[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_5; + assign unused_rst_en_5 = rstmgr_aon_rst_en.por_io[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_6; + assign unused_rst_en_6 = rstmgr_aon_rst_en.por_io_div2[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_7; + assign unused_rst_en_7 = rstmgr_aon_rst_en.por_io_div2[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_8; + assign unused_rst_en_8 = rstmgr_aon_rst_en.por_io_div4_shadowed[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_9; + assign unused_rst_en_9 = rstmgr_aon_rst_en.por_io_div4_shadowed[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_10; + assign unused_rst_en_10 = rstmgr_aon_rst_en.por_io_div4[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_11; + assign unused_rst_en_11 = rstmgr_aon_rst_en.por_usb[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_12; + assign unused_rst_en_12 = rstmgr_aon_rst_en.por_usb[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_13; + assign unused_rst_en_13 = rstmgr_aon_rst_en.lc_shadowed[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_14; + assign unused_rst_en_14 = rstmgr_aon_rst_en.lc[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_15; + assign unused_rst_en_15 = rstmgr_aon_rst_en.lc_shadowed[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_16; + assign unused_rst_en_16 = rstmgr_aon_rst_en.sys_shadowed[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_17; + assign unused_rst_en_17 = rstmgr_aon_rst_en.sys[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_18; + assign unused_rst_en_18 = rstmgr_aon_rst_en.sys_shadowed[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_19; + assign unused_rst_en_19 = rstmgr_aon_rst_en.sys_aon[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_20; + assign unused_rst_en_20 = rstmgr_aon_rst_en.sys_aon[rstmgr_pkg::Domain0Sel]; + prim_mubi_pkg::mubi4_t unused_rst_en_21; + assign unused_rst_en_21 = rstmgr_aon_rst_en.spi_device[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_22; + assign unused_rst_en_22 = rstmgr_aon_rst_en.spi_host0[rstmgr_pkg::DomainAonSel]; + prim_mubi_pkg::mubi4_t unused_rst_en_23; + assign unused_rst_en_23 = rstmgr_aon_rst_en.usb[rstmgr_pkg::DomainAonSel]; +//VCS coverage on +// pragma coverage on + + // Peripheral Instantiation + + + uart #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[0:0]) + ) u_uart0 ( + + // Input + .cio_rx_i (cio_uart0_rx_p2d), + + // Output + .cio_tx_o (cio_uart0_tx_d2p), + .cio_tx_en_o (cio_uart0_tx_en_d2p), + + // Interrupt + .intr_tx_watermark_o (intr_uart0_tx_watermark), + .intr_rx_watermark_o (intr_uart0_rx_watermark), + .intr_tx_done_o (intr_uart0_tx_done), + .intr_rx_overflow_o (intr_uart0_rx_overflow), + .intr_rx_frame_err_o (intr_uart0_rx_frame_err), + .intr_rx_break_err_o (intr_uart0_rx_break_err), + .intr_rx_timeout_o (intr_uart0_rx_timeout), + .intr_rx_parity_err_o (intr_uart0_rx_parity_err), + .intr_tx_empty_o (intr_uart0_tx_empty), + // [0]: fatal_fault + .alert_tx_o ( alert_tx[0:0] ), + .alert_rx_i ( alert_rx[0:0] ), + + // Inter-module signals + .lsio_trigger_o(), + .tl_i(uart0_tl_req), + .tl_o(uart0_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_peri), + .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + uart #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[1:1]) + ) u_uart1 ( + + // Input + .cio_rx_i (cio_uart1_rx_p2d), + + // Output + .cio_tx_o (cio_uart1_tx_d2p), + .cio_tx_en_o (cio_uart1_tx_en_d2p), + + // Interrupt + .intr_tx_watermark_o (intr_uart1_tx_watermark), + .intr_rx_watermark_o (intr_uart1_rx_watermark), + .intr_tx_done_o (intr_uart1_tx_done), + .intr_rx_overflow_o (intr_uart1_rx_overflow), + .intr_rx_frame_err_o (intr_uart1_rx_frame_err), + .intr_rx_break_err_o (intr_uart1_rx_break_err), + .intr_rx_timeout_o (intr_uart1_rx_timeout), + .intr_rx_parity_err_o (intr_uart1_rx_parity_err), + .intr_tx_empty_o (intr_uart1_tx_empty), + // [1]: fatal_fault + .alert_tx_o ( alert_tx[1:1] ), + .alert_rx_i ( alert_rx[1:1] ), + + // Inter-module signals + .lsio_trigger_o(), + .tl_i(uart1_tl_req), + .tl_o(uart1_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_peri), + .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + gpio #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[2:2]), + .GpioAsyncOn(GpioGpioAsyncOn), + .GpioAsHwStrapsEn(GpioGpioAsHwStrapsEn) + ) u_gpio ( + + // Input + .cio_gpio_i (cio_gpio_gpio_p2d), + + // Output + .cio_gpio_o (cio_gpio_gpio_d2p), + .cio_gpio_en_o (cio_gpio_gpio_en_d2p), + + // Interrupt + .intr_gpio_o (intr_gpio_gpio), + // [2]: fatal_fault + .alert_tx_o ( alert_tx[2:2] ), + .alert_rx_i ( alert_rx[2:2] ), + + // Inter-module signals + .strap_en_i(1'b0), + .sampled_straps_o(), + .tl_i(gpio_tl_req), + .tl_o(gpio_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_peri), + .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + spi_device #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[3:3]), + .SramType(SpiDeviceSramType) + ) u_spi_device ( + + // Input + .cio_sck_i (cio_spi_device_sck_p2d), + .cio_csb_i (cio_spi_device_csb_p2d), + .cio_tpm_csb_i (cio_spi_device_tpm_csb_p2d), + .cio_sd_i (cio_spi_device_sd_p2d), + + // Output + .cio_sd_o (cio_spi_device_sd_d2p), + .cio_sd_en_o (cio_spi_device_sd_en_d2p), + + // Interrupt + .intr_upload_cmdfifo_not_empty_o (intr_spi_device_upload_cmdfifo_not_empty), + .intr_upload_payload_not_empty_o (intr_spi_device_upload_payload_not_empty), + .intr_upload_payload_overflow_o (intr_spi_device_upload_payload_overflow), + .intr_readbuf_watermark_o (intr_spi_device_readbuf_watermark), + .intr_readbuf_flip_o (intr_spi_device_readbuf_flip), + .intr_tpm_header_not_empty_o (intr_spi_device_tpm_header_not_empty), + .intr_tpm_rdfifo_cmd_end_o (intr_spi_device_tpm_rdfifo_cmd_end), + .intr_tpm_rdfifo_drop_o (intr_spi_device_tpm_rdfifo_drop), + // [3]: fatal_fault + .alert_tx_o ( alert_tx[3:3] ), + .alert_rx_i ( alert_rx[3:3] ), + + // Inter-module signals + .ram_cfg_sys2spi_i(prim_ram_2p_pkg::RAM_2P_CFG_DEFAULT), + .ram_cfg_rsp_sys2spi_o(), + .ram_cfg_spi2sys_i(prim_ram_2p_pkg::RAM_2P_CFG_DEFAULT), + .ram_cfg_rsp_spi2sys_o(), + .passthrough_o(spi_device_passthrough_req), + .passthrough_i(spi_device_passthrough_rsp), + .mbist_en_i('0), + .sck_monitor_o(sck_monitor_o), + .tl_i(spi_device_tl_req), + .tl_o(spi_device_tl_rsp), + .scanmode_i, + .scan_rst_ni, + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_peri), + .scan_clk_i (clkmgr_aon_clocks.clk_io_div2_peri), + .rst_ni (rstmgr_aon_resets.rst_spi_device_n[rstmgr_pkg::Domain0Sel]) + ); + spi_host #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[4:4]), + .NumCS(SpiHost0NumCS) + ) u_spi_host0 ( + + // Input + .cio_sd_i (cio_spi_host0_sd_p2d), + + // Output + .cio_sck_o (cio_spi_host0_sck_d2p), + .cio_sck_en_o (cio_spi_host0_sck_en_d2p), + .cio_csb_o (cio_spi_host0_csb_d2p), + .cio_csb_en_o (cio_spi_host0_csb_en_d2p), + .cio_sd_o (cio_spi_host0_sd_d2p), + .cio_sd_en_o (cio_spi_host0_sd_en_d2p), + + // Interrupt + .intr_error_o (intr_spi_host0_error), + .intr_spi_event_o (intr_spi_host0_spi_event), + // [4]: fatal_fault + .alert_tx_o ( alert_tx[4:4] ), + .alert_rx_i ( alert_rx[4:4] ), + + // Inter-module signals + .passthrough_i(spi_device_passthrough_req), + .passthrough_o(spi_device_passthrough_rsp), + .lsio_trigger_o(), + .tl_i(spi_host0_tl_req), + .tl_o(spi_host0_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_peri), + .rst_ni (rstmgr_aon_resets.rst_spi_host0_n[rstmgr_pkg::Domain0Sel]) + ); + rv_timer #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[5:5]) + ) u_rv_timer ( + + // Interrupt + .intr_timer_expired_hart0_timer0_o (intr_rv_timer_timer_expired_hart0_timer0), + // [5]: fatal_fault + .alert_tx_o ( alert_tx[5:5] ), + .alert_rx_i ( alert_rx[5:5] ), + + // Inter-module signals + .tl_i(rv_timer_tl_req), + .tl_o(rv_timer_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_timers), + .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + usbdev #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[6:6]), + .Stub(UsbdevStub), + .RcvrWakeTimeUs(UsbdevRcvrWakeTimeUs) + ) u_usbdev ( + + // Input + .cio_sense_i (cio_usbdev_sense_p2d), + .cio_usb_dp_i (cio_usbdev_usb_dp_p2d), + .cio_usb_dn_i (cio_usbdev_usb_dn_p2d), + + // Output + .cio_usb_dp_o (cio_usbdev_usb_dp_d2p), + .cio_usb_dp_en_o (cio_usbdev_usb_dp_en_d2p), + .cio_usb_dn_o (cio_usbdev_usb_dn_d2p), + .cio_usb_dn_en_o (cio_usbdev_usb_dn_en_d2p), + + // Interrupt + .intr_pkt_received_o (intr_usbdev_pkt_received), + .intr_pkt_sent_o (intr_usbdev_pkt_sent), + .intr_disconnected_o (intr_usbdev_disconnected), + .intr_host_lost_o (intr_usbdev_host_lost), + .intr_link_reset_o (intr_usbdev_link_reset), + .intr_link_suspend_o (intr_usbdev_link_suspend), + .intr_link_resume_o (intr_usbdev_link_resume), + .intr_av_out_empty_o (intr_usbdev_av_out_empty), + .intr_rx_full_o (intr_usbdev_rx_full), + .intr_av_overflow_o (intr_usbdev_av_overflow), + .intr_link_in_err_o (intr_usbdev_link_in_err), + .intr_rx_crc_err_o (intr_usbdev_rx_crc_err), + .intr_rx_pid_err_o (intr_usbdev_rx_pid_err), + .intr_rx_bitstuff_err_o (intr_usbdev_rx_bitstuff_err), + .intr_frame_o (intr_usbdev_frame), + .intr_powered_o (intr_usbdev_powered), + .intr_link_out_err_o (intr_usbdev_link_out_err), + .intr_av_setup_empty_o (intr_usbdev_av_setup_empty), + // [6]: fatal_fault + .alert_tx_o ( alert_tx[6:6] ), + .alert_rx_i ( alert_rx[6:6] ), + + // Inter-module signals + .usb_rx_d_i(usbdev_usb_rx_d_i), + .usb_tx_d_o(usbdev_usb_tx_d_o), + .usb_tx_se0_o(usbdev_usb_tx_se0_o), + .usb_tx_use_d_se0_o(usbdev_usb_tx_use_d_se0_o), + .usb_dp_pullup_o(usbdev_usb_dp_pullup), + .usb_dn_pullup_o(usbdev_usb_dn_pullup), + .usb_rx_enable_o(usbdev_usb_rx_enable_o), + .usb_ref_val_o(usbdev_usb_ref_val_o), + .usb_ref_pulse_o(usbdev_usb_ref_pulse_o), + .usb_aon_suspend_req_o(usbdev_usb_aon_suspend_req), + .usb_aon_wake_ack_o(usbdev_usb_aon_wake_ack), + .usb_aon_bus_reset_i(usbdev_usb_aon_bus_reset), + .usb_aon_sense_lost_i(usbdev_usb_aon_sense_lost), + .usb_aon_bus_not_idle_i('0), + .usb_aon_wake_detect_active_i(pinmux_aon_usbdev_wake_detect_active), + .ram_cfg_i(prim_ram_1p_pkg::RAM_1P_CFG_DEFAULT), + .ram_cfg_rsp_o(), + .tl_i(usbdev_tl_req), + .tl_o(usbdev_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_usb_peri), + .clk_aon_i (clkmgr_aon_clocks.clk_aon_peri), + .rst_ni (rstmgr_aon_resets.rst_usb_n[rstmgr_pkg::Domain0Sel]), + .rst_aon_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::Domain0Sel]) + ); + pwrmgr #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[7:7]), + .EscNumSeverities(4), + .EscPingCountWidth(16) + ) u_pwrmgr_aon ( + + // Interrupt + .intr_wakeup_o (intr_pwrmgr_aon_wakeup), + // [7]: fatal_fault + .alert_tx_o ( alert_tx[7:7] ), + .alert_rx_i ( alert_rx[7:7] ), + + // Inter-module signals + .pwr_ast_o(pwrmgr_ast_req_o), + .pwr_ast_i(pwrmgr_ast_rsp_i), + .pwr_rst_o(pwrmgr_aon_pwr_rst_req), + .pwr_rst_i(pwrmgr_aon_pwr_rst_rsp), + .pwr_clk_o(pwrmgr_aon_pwr_clk_req), + .pwr_clk_i(pwrmgr_aon_pwr_clk_rsp), + .pwr_otp_o(), + .pwr_otp_i(pwrmgr_pkg::PWR_OTP_RSP_DEFAULT), + .pwr_lc_o(), + .pwr_lc_i(pwrmgr_pkg::PWR_LC_RSP_DEFAULT), + .pwr_flash_i(pwrmgr_aon_pwr_flash), + .esc_rst_tx_i(prim_esc_pkg::ESC_TX_DEFAULT), + .esc_rst_rx_o(), + .pwr_cpu_i(rv_core_ibex_pwrmgr), + .wakeups_i(pwrmgr_aon_wakeups), + .rstreqs_i(pwrmgr_aon_rstreqs), + .ndmreset_req_i('0), + .strap_o(pwrmgr_aon_strap), + .low_power_o(pwrmgr_aon_low_power), + .rom_ctrl_i(rom_ctrl_pkg::PWRMGR_DATA_DEFAULT), + .fetch_en_o(pwrmgr_aon_fetch_en), + .lc_dft_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .lc_hw_debug_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .sw_rst_req_i(rstmgr_aon_sw_rst_req), + .tl_i(pwrmgr_aon_tl_req), + .tl_o(pwrmgr_aon_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .clk_slow_i (clkmgr_aon_clocks.clk_aon_powerup), + .clk_lc_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .clk_esc_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .rst_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_lc_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_esc_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_main_ni (rstmgr_aon_resets.rst_por_aon_n[rstmgr_pkg::DomainAonSel]), + .rst_slow_ni (rstmgr_aon_resets.rst_por_aon_n[rstmgr_pkg::DomainAonSel]) + ); + rstmgr #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[9:8]), + .SecCheck(SecRstmgrAonCheck), + .SecMaxSyncDelay(SecRstmgrAonMaxSyncDelay) + ) u_rstmgr_aon ( + // [8]: fatal_fault + // [9]: fatal_cnsty_fault + .alert_tx_o ( alert_tx[9:8] ), + .alert_rx_i ( alert_rx[9:8] ), + + // Inter-module signals + .por_n_i(por_n_i), + .pwr_i(pwrmgr_aon_pwr_rst_req), + .pwr_o(pwrmgr_aon_pwr_rst_rsp), + .resets_o(rstmgr_aon_resets), + .rst_en_o(rstmgr_aon_rst_en), + .alert_dump_i(alert_pkg::ALERT_CRASHDUMP_DEFAULT), + .cpu_dump_i(rv_core_ibex_crash_dump), + .sw_rst_req_o(rstmgr_aon_sw_rst_req), + .tl_i(rstmgr_aon_tl_req), + .tl_o(rstmgr_aon_tl_rsp), + .scanmode_i, + .scan_rst_ni, + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .clk_por_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .clk_aon_i (clkmgr_aon_clocks.clk_aon_powerup), + .clk_main_i (clkmgr_aon_clocks.clk_main_powerup), + .clk_io_i (clkmgr_aon_clocks.clk_io_powerup), + .clk_usb_i (clkmgr_aon_clocks.clk_usb_powerup), + .clk_io_div2_i (clkmgr_aon_clocks.clk_io_div2_powerup), + .clk_io_div4_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_por_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]) + ); + clkmgr #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[11:10]) + ) u_clkmgr_aon ( + // [10]: recov_fault + // [11]: fatal_fault + .alert_tx_o ( alert_tx[11:10] ), + .alert_rx_i ( alert_rx[11:10] ), + + // Inter-module signals + .clocks_o(clkmgr_aon_clocks), + .cg_en_o(clkmgr_aon_cg_en), + .lc_hw_debug_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .io_clk_byp_req_o(io_clk_byp_req_o), + .io_clk_byp_ack_i(io_clk_byp_ack_i), + .all_clk_byp_req_o(all_clk_byp_req_o), + .all_clk_byp_ack_i(all_clk_byp_ack_i), + .hi_speed_sel_o(hi_speed_sel_o), + .div_step_down_req_i(div_step_down_req_i), + .lc_clk_byp_req_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .lc_clk_byp_ack_o(), + .jitter_en_o(clk_main_jitter_en_o), + .pwr_i(pwrmgr_aon_pwr_clk_req), + .pwr_o(pwrmgr_aon_pwr_clk_rsp), + .idle_i(clkmgr_aon_idle), + .calib_rdy_i(prim_mubi_pkg::MuBi4True), + .tl_i(clkmgr_aon_tl_req), + .tl_o(clkmgr_aon_tl_rsp), + .scanmode_i, + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .clk_main_i (clk_main_i), + .clk_io_i (clk_io_i), + .clk_usb_i (clk_usb_i), + .clk_aon_i (clk_aon_i), + .rst_shadowed_ni (rstmgr_aon_resets.rst_por_io_div4_shadowed_n[rstmgr_pkg::DomainAonSel]), + .rst_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_aon_ni (rstmgr_aon_resets.rst_por_aon_n[rstmgr_pkg::DomainAonSel]), + .rst_io_ni (rstmgr_aon_resets.rst_por_io_n[rstmgr_pkg::DomainAonSel]), + .rst_io_div2_ni (rstmgr_aon_resets.rst_por_io_div2_n[rstmgr_pkg::DomainAonSel]), + .rst_io_div4_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_main_ni (rstmgr_aon_resets.rst_por_n[rstmgr_pkg::DomainAonSel]), + .rst_usb_ni (rstmgr_aon_resets.rst_por_usb_n[rstmgr_pkg::DomainAonSel]), + .rst_root_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_root_io_ni (rstmgr_aon_resets.rst_por_io_n[rstmgr_pkg::DomainAonSel]), + .rst_root_io_div2_ni (rstmgr_aon_resets.rst_por_io_div2_n[rstmgr_pkg::DomainAonSel]), + .rst_root_io_div4_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_root_main_ni (rstmgr_aon_resets.rst_por_n[rstmgr_pkg::DomainAonSel]), + .rst_root_usb_ni (rstmgr_aon_resets.rst_por_usb_n[rstmgr_pkg::DomainAonSel]) + ); + pinmux #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[12:12]), + .SecVolatileRawUnlockEn(SecPinmuxAonVolatileRawUnlockEn), + .TargetCfg(PinmuxAonTargetCfg) + ) u_pinmux_aon ( + // [12]: fatal_fault + .alert_tx_o ( alert_tx[12:12] ), + .alert_rx_i ( alert_rx[12:12] ), + + // Inter-module signals + .lc_hw_debug_en_i(lc_ctrl_pkg::Off), + .lc_dft_en_i(lc_ctrl_pkg::Off), + .lc_escalate_en_i(lc_ctrl_pkg::Off), + .lc_check_byp_en_i(lc_ctrl_pkg::Off), + .pinmux_hw_debug_en_o(), + .lc_jtag_o(), + .lc_jtag_i(jtag_pkg::JTAG_RSP_DEFAULT), + .rv_jtag_o(), + .rv_jtag_i(jtag_pkg::JTAG_RSP_DEFAULT), + .dft_jtag_o(pinmux_aon_dft_jtag_req), + .dft_jtag_i(pinmux_aon_dft_jtag_rsp), + .dft_strap_test_o(dft_strap_test_o), + .dft_hold_tap_sel_i(dft_hold_tap_sel_i), + .sleep_en_i(pwrmgr_aon_low_power), + .strap_en_i(pwrmgr_aon_strap), + .strap_en_override_i(1'b0), + .pin_wkup_req_o(pwrmgr_aon_wakeups[0]), + .usbdev_dppullup_en_i(usbdev_usb_dp_pullup), + .usbdev_dnpullup_en_i(usbdev_usb_dn_pullup), + .usb_dppullup_en_o(usb_dp_pullup_en_o), + .usb_dnpullup_en_o(usb_dn_pullup_en_o), + .usb_wkup_req_o(pwrmgr_aon_wakeups[1]), + .usbdev_suspend_req_i(usbdev_usb_aon_suspend_req), + .usbdev_wake_ack_i(usbdev_usb_aon_wake_ack), + .usbdev_bus_not_idle_o(), + .usbdev_bus_reset_o(usbdev_usb_aon_bus_reset), + .usbdev_sense_lost_o(usbdev_usb_aon_sense_lost), + .usbdev_wake_detect_active_o(pinmux_aon_usbdev_wake_detect_active), + .tl_i(pinmux_aon_tl_req), + .tl_o(pinmux_aon_tl_rsp), + + .periph_to_mio_i (mio_d2p ), + .periph_to_mio_oe_i (mio_en_d2p ), + .mio_to_periph_o (mio_p2d ), + + .mio_attr_o, + .mio_out_o, + .mio_oe_o, + .mio_in_i, + + .periph_to_dio_i (dio_d2p ), + .periph_to_dio_oe_i (dio_en_d2p ), + .dio_to_periph_o (dio_p2d ), + + .dio_attr_o, + .dio_out_o, + .dio_oe_o, + .dio_in_i, + + .scanmode_i, + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_powerup), + .clk_aon_i (clkmgr_aon_clocks.clk_aon_powerup), + .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_aon_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::DomainAonSel]), + .rst_sys_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::DomainAonSel]) + ); + aon_timer #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[13:13]) + ) u_aon_timer_aon ( + + // Interrupt + .intr_wkup_timer_expired_o (intr_aon_timer_aon_wkup_timer_expired), + .intr_wdog_timer_bark_o (intr_aon_timer_aon_wdog_timer_bark), + // [13]: fatal_fault + .alert_tx_o ( alert_tx[13:13] ), + .alert_rx_i ( alert_rx[13:13] ), + + // Inter-module signals + .nmi_wdog_timer_bark_o(), + .wkup_req_o(pwrmgr_aon_wakeups[2]), + .aon_timer_rst_req_o(pwrmgr_aon_rstreqs), + .lc_escalate_en_i(lc_ctrl_pkg::Off), + .sleep_mode_i(pwrmgr_aon_low_power), + .tl_i(tlul_pkg::TL_H2D_DEFAULT), + .tl_o(), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_io_div4_timers), + .clk_aon_i (clkmgr_aon_clocks.clk_aon_timers), + .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::DomainAonSel]), + .rst_aon_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::DomainAonSel]) + ); + flash_ctrl #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[18:14]), + .RndCnstAddrKey(RndCnstFlashCtrlAddrKey), + .RndCnstDataKey(RndCnstFlashCtrlDataKey), + .RndCnstAllSeeds(RndCnstFlashCtrlAllSeeds), + .RndCnstLfsrSeed(RndCnstFlashCtrlLfsrSeed), + .RndCnstLfsrPerm(RndCnstFlashCtrlLfsrPerm), + .SecScrambleEn(SecFlashCtrlScrambleEn), + .ProgFifoDepth(FlashCtrlProgFifoDepth), + .RdFifoDepth(FlashCtrlRdFifoDepth) + ) u_flash_ctrl ( + + // Input + .cio_tck_i (cio_flash_ctrl_tck_p2d), + .cio_tms_i (cio_flash_ctrl_tms_p2d), + .cio_tdi_i (cio_flash_ctrl_tdi_p2d), + + // Output + .cio_tdo_o (cio_flash_ctrl_tdo_d2p), + .cio_tdo_en_o (cio_flash_ctrl_tdo_en_d2p), + + // Interrupt + .intr_prog_empty_o (intr_flash_ctrl_prog_empty), + .intr_prog_lvl_o (intr_flash_ctrl_prog_lvl), + .intr_rd_full_o (intr_flash_ctrl_rd_full), + .intr_rd_lvl_o (intr_flash_ctrl_rd_lvl), + .intr_op_done_o (intr_flash_ctrl_op_done), + .intr_corr_err_o (intr_flash_ctrl_corr_err), + // [14]: recov_err + // [15]: fatal_std_err + // [16]: fatal_err + // [17]: fatal_prim_flash_alert + // [18]: recov_prim_flash_alert + .alert_tx_o ( alert_tx[18:14] ), + .alert_rx_i ( alert_rx[18:14] ), + + // Inter-module signals + .otp_o(), + .otp_i(otp_ctrl_pkg::FLASH_OTP_KEY_RSP_DEFAULT), + .lc_nvm_debug_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .flash_bist_enable_i(flash_bist_enable_i), + .flash_power_down_h_i(flash_power_down_h_i), + .flash_power_ready_h_i(flash_power_ready_h_i), + .flash_test_mode_a_io(), + .flash_test_voltage_h_io(), + .lc_creator_seed_sw_rw_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .lc_owner_seed_sw_rw_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .lc_iso_part_sw_rd_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .lc_iso_part_sw_wr_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .lc_seed_hw_rd_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .lc_escalate_en_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .rma_req_i(lc_ctrl_pkg::LC_TX_DEFAULT), + .rma_ack_o(), + .rma_seed_i(lc_ctrl_pkg::LC_FLASH_RMA_SEED_DEFAULT), + .pwrmgr_o(pwrmgr_aon_pwr_flash), + .keymgr_o(), + .obs_ctrl_i(obs_ctrl_i), + .fla_obs_o(flash_obs_o), + .core_tl_i(flash_ctrl_core_tl_req), + .core_tl_o(flash_ctrl_core_tl_rsp), + .prim_tl_i(flash_ctrl_prim_tl_req), + .prim_tl_o(flash_ctrl_prim_tl_rsp), + .mem_tl_i(flash_ctrl_mem_tl_req), + .mem_tl_o(flash_ctrl_mem_tl_rsp), + .scanmode_i, + .scan_rst_ni, + .scan_en_i, + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_main_infra), + .clk_otp_i (clkmgr_aon_clocks.clk_io_div4_infra), + .rst_shadowed_ni (rstmgr_aon_resets.rst_lc_shadowed_n[rstmgr_pkg::Domain0Sel]), + .rst_ni (rstmgr_aon_resets.rst_lc_n[rstmgr_pkg::Domain0Sel]), + .rst_otp_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + rv_plic #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[19:19]) + ) u_rv_plic ( + // [19]: fatal_fault + .alert_tx_o ( alert_tx[19:19] ), + .alert_rx_i ( alert_rx[19:19] ), + + // Inter-module signals + .irq_o(rv_plic_irq), + .irq_id_o(), + .msip_o(rv_plic_msip), + .tl_i(rv_plic_tl_req), + .tl_o(rv_plic_tl_rsp), + .intr_src_i (intr_vector), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_main_secure), + .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]) + ); + aes #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[21:20]), + .AES192Enable(1'b1), + .SecMasking(SecAesMasking), + .SecSBoxImpl(SecAesSBoxImpl), + .SecStartTriggerDelay(SecAesStartTriggerDelay), + .SecAllowForcingMasks(SecAesAllowForcingMasks), + .SecSkipPRNGReseeding(SecAesSkipPRNGReseeding), + .RndCnstClearingLfsrSeed(RndCnstAesClearingLfsrSeed), + .RndCnstClearingLfsrPerm(RndCnstAesClearingLfsrPerm), + .RndCnstClearingSharePerm(RndCnstAesClearingSharePerm), + .RndCnstMaskingLfsrSeed(RndCnstAesMaskingLfsrSeed), + .RndCnstMaskingLfsrPerm(RndCnstAesMaskingLfsrPerm) + ) u_aes ( + // [20]: recov_ctrl_update_err + // [21]: fatal_fault + .alert_tx_o ( alert_tx[21:20] ), + .alert_rx_i ( alert_rx[21:20] ), + + // Inter-module signals + .idle_o(clkmgr_aon_idle), + .lc_escalate_en_i(lc_ctrl_pkg::Off), + .edn_o(), + .edn_i(edn_pkg::EDN_RSP_DEFAULT), + .keymgr_key_i(keymgr_pkg::HW_KEY_REQ_DEFAULT), + .tl_i(aes_tl_req), + .tl_o(aes_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_main_aes), + .clk_edn_i (clkmgr_aon_clocks.clk_main_aes), + .rst_shadowed_ni (rstmgr_aon_resets.rst_sys_shadowed_n[rstmgr_pkg::Domain0Sel]), + .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]), + .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]) + ); + sram_ctrl #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[22:22]), + .RndCnstSramKey(RndCnstSramCtrlMainSramKey), + .RndCnstSramNonce(RndCnstSramCtrlMainSramNonce), + .RndCnstLfsrSeed(RndCnstSramCtrlMainLfsrSeed), + .RndCnstLfsrPerm(RndCnstSramCtrlMainLfsrPerm), + .MemSizeRam(131072), + .InstSize(SramCtrlMainInstSize), + .NumRamInst(SramCtrlMainNumRamInst), + .InstrExec(SramCtrlMainInstrExec), + .NumPrinceRoundsHalf(SramCtrlMainNumPrinceRoundsHalf) + ) u_sram_ctrl_main ( + // [22]: fatal_error + .alert_tx_o ( alert_tx[22:22] ), + .alert_rx_i ( alert_rx[22:22] ), + + // Inter-module signals + .sram_otp_key_o(), + .sram_otp_key_i(otp_ctrl_pkg::SRAM_OTP_KEY_RSP_DEFAULT), + .cfg_i('0), + .cfg_rsp_o(), + .lc_escalate_en_i(lc_ctrl_pkg::Off), + .lc_hw_debug_en_i(lc_ctrl_pkg::Off), + .otp_en_sram_ifetch_i(sram_ctrl_main_otp_en_sram_ifetch), + .regs_tl_i(sram_ctrl_main_regs_tl_req), + .regs_tl_o(sram_ctrl_main_regs_tl_rsp), + .ram_tl_i(sram_ctrl_main_ram_tl_req), + .ram_tl_o(sram_ctrl_main_ram_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_main_secure), + .clk_otp_i (clkmgr_aon_clocks.clk_io_div4_secure), + .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]), + .rst_otp_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + rom_ctrl #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[23:23]), + .BootRomInitFile(RomCtrlBootRomInitFile), + .RndCnstScrNonce(RndCnstRomCtrlScrNonce), + .RndCnstScrKey(RndCnstRomCtrlScrKey), + .SecDisableScrambling(SecRomCtrlDisableScrambling), + .MemSizeRom(32768) + ) u_rom_ctrl ( + // [23]: fatal + .alert_tx_o ( alert_tx[23:23] ), + .alert_rx_i ( alert_rx[23:23] ), + + // Inter-module signals + .rom_cfg_i(prim_rom_pkg::ROM_CFG_DEFAULT), + .pwrmgr_data_o(), + .keymgr_data_o(), + .kmac_data_o(), + .kmac_data_i(kmac_pkg::APP_RSP_DEFAULT), + .regs_tl_i(rom_ctrl_regs_tl_req), + .regs_tl_o(rom_ctrl_regs_tl_rsp), + .rom_tl_i(rom_ctrl_rom_tl_req), + .rom_tl_o(rom_ctrl_rom_tl_rsp), + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_main_infra), + .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]) + ); + rv_core_ibex #( + .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[27:24]), + .RndCnstLfsrSeed(RndCnstRvCoreIbexLfsrSeed), + .RndCnstLfsrPerm(RndCnstRvCoreIbexLfsrPerm), + .RndCnstIbexKeyDefault(RndCnstRvCoreIbexIbexKeyDefault), + .RndCnstIbexNonceDefault(RndCnstRvCoreIbexIbexNonceDefault), + .NEscalationSeverities(RvCoreIbexNEscalationSeverities), + .WidthPingCounter(RvCoreIbexWidthPingCounter), + .PMPEnable(RvCoreIbexPMPEnable), + .PMPGranularity(RvCoreIbexPMPGranularity), + .PMPNumRegions(RvCoreIbexPMPNumRegions), + .MHPMCounterNum(RvCoreIbexMHPMCounterNum), + .MHPMCounterWidth(RvCoreIbexMHPMCounterWidth), + .PMPRstCfg(RvCoreIbexPMPRstCfg), + .PMPRstAddr(RvCoreIbexPMPRstAddr), + .PMPRstMsecCfg(RvCoreIbexPMPRstMsecCfg), + .RV32E(RvCoreIbexRV32E), + .RV32M(RvCoreIbexRV32M), + .RV32B(RvCoreIbexRV32B), + .RegFile(RvCoreIbexRegFile), + .BranchTargetALU(RvCoreIbexBranchTargetALU), + .WritebackStage(RvCoreIbexWritebackStage), + .ICache(RvCoreIbexICache), + .ICacheECC(RvCoreIbexICacheECC), + .ICacheScramble(RvCoreIbexICacheScramble), + .ICacheNWays(RvCoreIbexICacheNWays), + .BranchPredictor(RvCoreIbexBranchPredictor), + .DbgTriggerEn(RvCoreIbexDbgTriggerEn), + .DbgHwBreakNum(RvCoreIbexDbgHwBreakNum), + .SecureIbex(RvCoreIbexSecureIbex), + .DmBaseAddr(RvCoreIbexDmBaseAddr), + .DmAddrMask(RvCoreIbexDmAddrMask), + .DmHaltAddr(RvCoreIbexDmHaltAddr), + .DmExceptionAddr(RvCoreIbexDmExceptionAddr), + .PipeLine(RvCoreIbexPipeLine) + ) u_rv_core_ibex ( + // [24]: fatal_sw_err + // [25]: recov_sw_err + // [26]: fatal_hw_err + // [27]: recov_hw_err + .alert_tx_o ( alert_tx[27:24] ), + .alert_rx_i ( alert_rx[27:24] ), + + // Inter-module signals + .rst_cpu_n_o(), + .ram_cfg_icache_tag_i(prim_ram_1p_pkg::RAM_1P_CFG_DEFAULT), + .ram_cfg_rsp_icache_tag_o(), + .ram_cfg_icache_data_i(prim_ram_1p_pkg::RAM_1P_CFG_DEFAULT), + .ram_cfg_rsp_icache_data_o(), + .hart_id_i(rv_core_ibex_hart_id), + .boot_addr_i(rv_core_ibex_boot_addr), + .irq_software_i(rv_plic_msip), + .irq_timer_i(rv_core_ibex_irq_timer), + .irq_external_i(rv_plic_irq), + .esc_tx_i(prim_esc_pkg::ESC_TX_DEFAULT), + .esc_rx_o(), + .debug_req_i('0), + .crash_dump_o(rv_core_ibex_crash_dump), + .lc_cpu_en_i(rv_core_ibex_lc_cpu_en), + .pwrmgr_cpu_en_i(pwrmgr_aon_fetch_en), + .pwrmgr_o(rv_core_ibex_pwrmgr), + .nmi_wdog_i('0), + .edn_o(), + .edn_i(edn_pkg::EDN_RSP_DEFAULT), + .icache_otp_key_o(), + .icache_otp_key_i(otp_ctrl_pkg::SRAM_OTP_KEY_RSP_DEFAULT), + .fpga_info_i(fpga_info_i), + .corei_tl_h_o(main_tl_rv_core_ibex__corei_req), + .corei_tl_h_i(main_tl_rv_core_ibex__corei_rsp), + .cored_tl_h_o(main_tl_rv_core_ibex__cored_req), + .cored_tl_h_i(main_tl_rv_core_ibex__cored_rsp), + .cfg_tl_d_i(rv_core_ibex_cfg_tl_d_req), + .cfg_tl_d_o(rv_core_ibex_cfg_tl_d_rsp), + .scanmode_i, + .scan_rst_ni, + + // Clock and reset connections + .clk_i (clkmgr_aon_clocks.clk_main_infra), + .clk_edn_i (clkmgr_aon_clocks.clk_main_infra), + .clk_esc_i (clkmgr_aon_clocks.clk_io_div4_infra), + .clk_otp_i (clkmgr_aon_clocks.clk_io_div4_infra), + .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]), + .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]), + .rst_esc_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]), + .rst_otp_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]) + ); + + + // interrupt assignments + assign intr_vector = { + intr_flash_ctrl_corr_err, // IDs [87 +: 1] + intr_flash_ctrl_op_done, // IDs [86 +: 1] + intr_flash_ctrl_rd_lvl, // IDs [85 +: 1] + intr_flash_ctrl_rd_full, // IDs [84 +: 1] + intr_flash_ctrl_prog_lvl, // IDs [83 +: 1] + intr_flash_ctrl_prog_empty, // IDs [82 +: 1] + intr_aon_timer_aon_wdog_timer_bark, // IDs [81 +: 1] + intr_aon_timer_aon_wkup_timer_expired, // IDs [80 +: 1] + intr_pwrmgr_aon_wakeup, // IDs [79 +: 1] + intr_usbdev_av_setup_empty, // IDs [78 +: 1] + intr_usbdev_link_out_err, // IDs [77 +: 1] + intr_usbdev_powered, // IDs [76 +: 1] + intr_usbdev_frame, // IDs [75 +: 1] + intr_usbdev_rx_bitstuff_err, // IDs [74 +: 1] + intr_usbdev_rx_pid_err, // IDs [73 +: 1] + intr_usbdev_rx_crc_err, // IDs [72 +: 1] + intr_usbdev_link_in_err, // IDs [71 +: 1] + intr_usbdev_av_overflow, // IDs [70 +: 1] + intr_usbdev_rx_full, // IDs [69 +: 1] + intr_usbdev_av_out_empty, // IDs [68 +: 1] + intr_usbdev_link_resume, // IDs [67 +: 1] + intr_usbdev_link_suspend, // IDs [66 +: 1] + intr_usbdev_link_reset, // IDs [65 +: 1] + intr_usbdev_host_lost, // IDs [64 +: 1] + intr_usbdev_disconnected, // IDs [63 +: 1] + intr_usbdev_pkt_sent, // IDs [62 +: 1] + intr_usbdev_pkt_received, // IDs [61 +: 1] + intr_spi_host0_spi_event, // IDs [60 +: 1] + intr_spi_host0_error, // IDs [59 +: 1] + intr_spi_device_tpm_rdfifo_drop, // IDs [58 +: 1] + intr_spi_device_tpm_rdfifo_cmd_end, // IDs [57 +: 1] + intr_spi_device_tpm_header_not_empty, // IDs [56 +: 1] + intr_spi_device_readbuf_flip, // IDs [55 +: 1] + intr_spi_device_readbuf_watermark, // IDs [54 +: 1] + intr_spi_device_upload_payload_overflow, // IDs [53 +: 1] + intr_spi_device_upload_payload_not_empty, // IDs [52 +: 1] + intr_spi_device_upload_cmdfifo_not_empty, // IDs [51 +: 1] + intr_gpio_gpio, // IDs [19 +: 32] + intr_uart1_tx_empty, // IDs [18 +: 1] + intr_uart1_rx_parity_err, // IDs [17 +: 1] + intr_uart1_rx_timeout, // IDs [16 +: 1] + intr_uart1_rx_break_err, // IDs [15 +: 1] + intr_uart1_rx_frame_err, // IDs [14 +: 1] + intr_uart1_rx_overflow, // IDs [13 +: 1] + intr_uart1_tx_done, // IDs [12 +: 1] + intr_uart1_rx_watermark, // IDs [11 +: 1] + intr_uart1_tx_watermark, // IDs [10 +: 1] + intr_uart0_tx_empty, // IDs [9 +: 1] + intr_uart0_rx_parity_err, // IDs [8 +: 1] + intr_uart0_rx_timeout, // IDs [7 +: 1] + intr_uart0_rx_break_err, // IDs [6 +: 1] + intr_uart0_rx_frame_err, // IDs [5 +: 1] + intr_uart0_rx_overflow, // IDs [4 +: 1] + intr_uart0_tx_done, // IDs [3 +: 1] + intr_uart0_rx_watermark, // IDs [2 +: 1] + intr_uart0_tx_watermark, // IDs [1 +: 1] + 1'b 0 // ID [0 +: 1] is a special case and tied to zero. + }; + + // TL-UL Crossbar + xbar_main u_xbar_main ( + .clk_main_i (clkmgr_aon_clocks.clk_main_infra), + .clk_fixed_i (clkmgr_aon_clocks.clk_io_div4_infra), + .rst_main_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]), + .rst_fixed_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel]), + + // port: tl_rv_core_ibex__corei + .tl_rv_core_ibex__corei_i(main_tl_rv_core_ibex__corei_req), + .tl_rv_core_ibex__corei_o(main_tl_rv_core_ibex__corei_rsp), + + // port: tl_rv_core_ibex__cored + .tl_rv_core_ibex__cored_i(main_tl_rv_core_ibex__cored_req), + .tl_rv_core_ibex__cored_o(main_tl_rv_core_ibex__cored_rsp), + + // port: tl_rom_ctrl__rom + .tl_rom_ctrl__rom_o(rom_ctrl_rom_tl_req), + .tl_rom_ctrl__rom_i(rom_ctrl_rom_tl_rsp), + + // port: tl_rom_ctrl__regs + .tl_rom_ctrl__regs_o(rom_ctrl_regs_tl_req), + .tl_rom_ctrl__regs_i(rom_ctrl_regs_tl_rsp), + + // port: tl_peri + .tl_peri_o(main_tl_peri_req), + .tl_peri_i(main_tl_peri_rsp), + + // port: tl_flash_ctrl__core + .tl_flash_ctrl__core_o(flash_ctrl_core_tl_req), + .tl_flash_ctrl__core_i(flash_ctrl_core_tl_rsp), + + // port: tl_flash_ctrl__prim + .tl_flash_ctrl__prim_o(flash_ctrl_prim_tl_req), + .tl_flash_ctrl__prim_i(flash_ctrl_prim_tl_rsp), + + // port: tl_flash_ctrl__mem + .tl_flash_ctrl__mem_o(flash_ctrl_mem_tl_req), + .tl_flash_ctrl__mem_i(flash_ctrl_mem_tl_rsp), + + // port: tl_aes + .tl_aes_o(aes_tl_req), + .tl_aes_i(aes_tl_rsp), + + // port: tl_rv_plic + .tl_rv_plic_o(rv_plic_tl_req), + .tl_rv_plic_i(rv_plic_tl_rsp), + + // port: tl_rv_core_ibex__cfg + .tl_rv_core_ibex__cfg_o(rv_core_ibex_cfg_tl_d_req), + .tl_rv_core_ibex__cfg_i(rv_core_ibex_cfg_tl_d_rsp), + + // port: tl_sram_ctrl_main__regs + .tl_sram_ctrl_main__regs_o(sram_ctrl_main_regs_tl_req), + .tl_sram_ctrl_main__regs_i(sram_ctrl_main_regs_tl_rsp), + + // port: tl_sram_ctrl_main__ram + .tl_sram_ctrl_main__ram_o(sram_ctrl_main_ram_tl_req), + .tl_sram_ctrl_main__ram_i(sram_ctrl_main_ram_tl_rsp), + + + .scanmode_i + ); + xbar_peri u_xbar_peri ( + .clk_peri_i (clkmgr_aon_clocks.clk_io_div4_infra), + .clk_spi_host0_i (clkmgr_aon_clocks.clk_io_infra), + .clk_usb_i (clkmgr_aon_clocks.clk_usb_infra), + .rst_peri_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel]), + .rst_spi_host0_ni (rstmgr_aon_resets.rst_spi_host0_n[rstmgr_pkg::Domain0Sel]), + .rst_usb_ni (rstmgr_aon_resets.rst_usb_n[rstmgr_pkg::Domain0Sel]), + + // port: tl_main + .tl_main_i(main_tl_peri_req), + .tl_main_o(main_tl_peri_rsp), + + // port: tl_uart0 + .tl_uart0_o(uart0_tl_req), + .tl_uart0_i(uart0_tl_rsp), + + // port: tl_uart1 + .tl_uart1_o(uart1_tl_req), + .tl_uart1_i(uart1_tl_rsp), + + // port: tl_gpio + .tl_gpio_o(gpio_tl_req), + .tl_gpio_i(gpio_tl_rsp), + + // port: tl_spi_device + .tl_spi_device_o(spi_device_tl_req), + .tl_spi_device_i(spi_device_tl_rsp), + + // port: tl_spi_host0 + .tl_spi_host0_o(spi_host0_tl_req), + .tl_spi_host0_i(spi_host0_tl_rsp), + + // port: tl_rv_timer + .tl_rv_timer_o(rv_timer_tl_req), + .tl_rv_timer_i(rv_timer_tl_rsp), + + // port: tl_usbdev + .tl_usbdev_o(usbdev_tl_req), + .tl_usbdev_i(usbdev_tl_rsp), + + // port: tl_pwrmgr_aon + .tl_pwrmgr_aon_o(pwrmgr_aon_tl_req), + .tl_pwrmgr_aon_i(pwrmgr_aon_tl_rsp), + + // port: tl_rstmgr_aon + .tl_rstmgr_aon_o(rstmgr_aon_tl_req), + .tl_rstmgr_aon_i(rstmgr_aon_tl_rsp), + + // port: tl_clkmgr_aon + .tl_clkmgr_aon_o(clkmgr_aon_tl_req), + .tl_clkmgr_aon_i(clkmgr_aon_tl_rsp), + + // port: tl_pinmux_aon + .tl_pinmux_aon_o(pinmux_aon_tl_req), + .tl_pinmux_aon_i(pinmux_aon_tl_rsp), + + // port: tl_ast + .tl_ast_o(ast_tl_req_o), + .tl_ast_i(ast_tl_rsp_i), + + + .scanmode_i + ); + + // Pinmux connections + // All muxed inputs + assign cio_gpio_gpio_p2d[0] = mio_p2d[MioInGpioGpio0]; + assign cio_gpio_gpio_p2d[1] = mio_p2d[MioInGpioGpio1]; + assign cio_gpio_gpio_p2d[2] = mio_p2d[MioInGpioGpio2]; + assign cio_gpio_gpio_p2d[3] = mio_p2d[MioInGpioGpio3]; + assign cio_gpio_gpio_p2d[4] = mio_p2d[MioInGpioGpio4]; + assign cio_gpio_gpio_p2d[5] = mio_p2d[MioInGpioGpio5]; + assign cio_gpio_gpio_p2d[6] = mio_p2d[MioInGpioGpio6]; + assign cio_gpio_gpio_p2d[7] = mio_p2d[MioInGpioGpio7]; + assign cio_gpio_gpio_p2d[8] = mio_p2d[MioInGpioGpio8]; + assign cio_gpio_gpio_p2d[9] = mio_p2d[MioInGpioGpio9]; + assign cio_gpio_gpio_p2d[10] = mio_p2d[MioInGpioGpio10]; + assign cio_gpio_gpio_p2d[11] = mio_p2d[MioInGpioGpio11]; + assign cio_gpio_gpio_p2d[12] = mio_p2d[MioInGpioGpio12]; + assign cio_gpio_gpio_p2d[13] = mio_p2d[MioInGpioGpio13]; + assign cio_gpio_gpio_p2d[14] = mio_p2d[MioInGpioGpio14]; + assign cio_gpio_gpio_p2d[15] = mio_p2d[MioInGpioGpio15]; + assign cio_gpio_gpio_p2d[16] = mio_p2d[MioInGpioGpio16]; + assign cio_gpio_gpio_p2d[17] = mio_p2d[MioInGpioGpio17]; + assign cio_gpio_gpio_p2d[18] = mio_p2d[MioInGpioGpio18]; + assign cio_gpio_gpio_p2d[19] = mio_p2d[MioInGpioGpio19]; + assign cio_gpio_gpio_p2d[20] = mio_p2d[MioInGpioGpio20]; + assign cio_gpio_gpio_p2d[21] = mio_p2d[MioInGpioGpio21]; + assign cio_gpio_gpio_p2d[22] = mio_p2d[MioInGpioGpio22]; + assign cio_gpio_gpio_p2d[23] = mio_p2d[MioInGpioGpio23]; + assign cio_gpio_gpio_p2d[24] = mio_p2d[MioInGpioGpio24]; + assign cio_gpio_gpio_p2d[25] = mio_p2d[MioInGpioGpio25]; + assign cio_gpio_gpio_p2d[26] = mio_p2d[MioInGpioGpio26]; + assign cio_gpio_gpio_p2d[27] = mio_p2d[MioInGpioGpio27]; + assign cio_gpio_gpio_p2d[28] = mio_p2d[MioInGpioGpio28]; + assign cio_gpio_gpio_p2d[29] = mio_p2d[MioInGpioGpio29]; + assign cio_gpio_gpio_p2d[30] = mio_p2d[MioInGpioGpio30]; + assign cio_gpio_gpio_p2d[31] = mio_p2d[MioInGpioGpio31]; + assign cio_uart0_rx_p2d = mio_p2d[MioInUart0Rx]; + assign cio_uart1_rx_p2d = mio_p2d[MioInUart1Rx]; + assign cio_flash_ctrl_tck_p2d = mio_p2d[MioInFlashCtrlTck]; + assign cio_flash_ctrl_tms_p2d = mio_p2d[MioInFlashCtrlTms]; + assign cio_flash_ctrl_tdi_p2d = mio_p2d[MioInFlashCtrlTdi]; + assign cio_usbdev_sense_p2d = mio_p2d[MioInUsbdevSense]; + + // All muxed outputs + assign mio_d2p[MioOutGpioGpio0] = cio_gpio_gpio_d2p[0]; + assign mio_d2p[MioOutGpioGpio1] = cio_gpio_gpio_d2p[1]; + assign mio_d2p[MioOutGpioGpio2] = cio_gpio_gpio_d2p[2]; + assign mio_d2p[MioOutGpioGpio3] = cio_gpio_gpio_d2p[3]; + assign mio_d2p[MioOutGpioGpio4] = cio_gpio_gpio_d2p[4]; + assign mio_d2p[MioOutGpioGpio5] = cio_gpio_gpio_d2p[5]; + assign mio_d2p[MioOutGpioGpio6] = cio_gpio_gpio_d2p[6]; + assign mio_d2p[MioOutGpioGpio7] = cio_gpio_gpio_d2p[7]; + assign mio_d2p[MioOutGpioGpio8] = cio_gpio_gpio_d2p[8]; + assign mio_d2p[MioOutGpioGpio9] = cio_gpio_gpio_d2p[9]; + assign mio_d2p[MioOutGpioGpio10] = cio_gpio_gpio_d2p[10]; + assign mio_d2p[MioOutGpioGpio11] = cio_gpio_gpio_d2p[11]; + assign mio_d2p[MioOutGpioGpio12] = cio_gpio_gpio_d2p[12]; + assign mio_d2p[MioOutGpioGpio13] = cio_gpio_gpio_d2p[13]; + assign mio_d2p[MioOutGpioGpio14] = cio_gpio_gpio_d2p[14]; + assign mio_d2p[MioOutGpioGpio15] = cio_gpio_gpio_d2p[15]; + assign mio_d2p[MioOutGpioGpio16] = cio_gpio_gpio_d2p[16]; + assign mio_d2p[MioOutGpioGpio17] = cio_gpio_gpio_d2p[17]; + assign mio_d2p[MioOutGpioGpio18] = cio_gpio_gpio_d2p[18]; + assign mio_d2p[MioOutGpioGpio19] = cio_gpio_gpio_d2p[19]; + assign mio_d2p[MioOutGpioGpio20] = cio_gpio_gpio_d2p[20]; + assign mio_d2p[MioOutGpioGpio21] = cio_gpio_gpio_d2p[21]; + assign mio_d2p[MioOutGpioGpio22] = cio_gpio_gpio_d2p[22]; + assign mio_d2p[MioOutGpioGpio23] = cio_gpio_gpio_d2p[23]; + assign mio_d2p[MioOutGpioGpio24] = cio_gpio_gpio_d2p[24]; + assign mio_d2p[MioOutGpioGpio25] = cio_gpio_gpio_d2p[25]; + assign mio_d2p[MioOutGpioGpio26] = cio_gpio_gpio_d2p[26]; + assign mio_d2p[MioOutGpioGpio27] = cio_gpio_gpio_d2p[27]; + assign mio_d2p[MioOutGpioGpio28] = cio_gpio_gpio_d2p[28]; + assign mio_d2p[MioOutGpioGpio29] = cio_gpio_gpio_d2p[29]; + assign mio_d2p[MioOutGpioGpio30] = cio_gpio_gpio_d2p[30]; + assign mio_d2p[MioOutGpioGpio31] = cio_gpio_gpio_d2p[31]; + assign mio_d2p[MioOutUart0Tx] = cio_uart0_tx_d2p; + assign mio_d2p[MioOutUart1Tx] = cio_uart1_tx_d2p; + assign mio_d2p[MioOutFlashCtrlTdo] = cio_flash_ctrl_tdo_d2p; + + // All muxed output enables + assign mio_en_d2p[MioOutGpioGpio0] = cio_gpio_gpio_en_d2p[0]; + assign mio_en_d2p[MioOutGpioGpio1] = cio_gpio_gpio_en_d2p[1]; + assign mio_en_d2p[MioOutGpioGpio2] = cio_gpio_gpio_en_d2p[2]; + assign mio_en_d2p[MioOutGpioGpio3] = cio_gpio_gpio_en_d2p[3]; + assign mio_en_d2p[MioOutGpioGpio4] = cio_gpio_gpio_en_d2p[4]; + assign mio_en_d2p[MioOutGpioGpio5] = cio_gpio_gpio_en_d2p[5]; + assign mio_en_d2p[MioOutGpioGpio6] = cio_gpio_gpio_en_d2p[6]; + assign mio_en_d2p[MioOutGpioGpio7] = cio_gpio_gpio_en_d2p[7]; + assign mio_en_d2p[MioOutGpioGpio8] = cio_gpio_gpio_en_d2p[8]; + assign mio_en_d2p[MioOutGpioGpio9] = cio_gpio_gpio_en_d2p[9]; + assign mio_en_d2p[MioOutGpioGpio10] = cio_gpio_gpio_en_d2p[10]; + assign mio_en_d2p[MioOutGpioGpio11] = cio_gpio_gpio_en_d2p[11]; + assign mio_en_d2p[MioOutGpioGpio12] = cio_gpio_gpio_en_d2p[12]; + assign mio_en_d2p[MioOutGpioGpio13] = cio_gpio_gpio_en_d2p[13]; + assign mio_en_d2p[MioOutGpioGpio14] = cio_gpio_gpio_en_d2p[14]; + assign mio_en_d2p[MioOutGpioGpio15] = cio_gpio_gpio_en_d2p[15]; + assign mio_en_d2p[MioOutGpioGpio16] = cio_gpio_gpio_en_d2p[16]; + assign mio_en_d2p[MioOutGpioGpio17] = cio_gpio_gpio_en_d2p[17]; + assign mio_en_d2p[MioOutGpioGpio18] = cio_gpio_gpio_en_d2p[18]; + assign mio_en_d2p[MioOutGpioGpio19] = cio_gpio_gpio_en_d2p[19]; + assign mio_en_d2p[MioOutGpioGpio20] = cio_gpio_gpio_en_d2p[20]; + assign mio_en_d2p[MioOutGpioGpio21] = cio_gpio_gpio_en_d2p[21]; + assign mio_en_d2p[MioOutGpioGpio22] = cio_gpio_gpio_en_d2p[22]; + assign mio_en_d2p[MioOutGpioGpio23] = cio_gpio_gpio_en_d2p[23]; + assign mio_en_d2p[MioOutGpioGpio24] = cio_gpio_gpio_en_d2p[24]; + assign mio_en_d2p[MioOutGpioGpio25] = cio_gpio_gpio_en_d2p[25]; + assign mio_en_d2p[MioOutGpioGpio26] = cio_gpio_gpio_en_d2p[26]; + assign mio_en_d2p[MioOutGpioGpio27] = cio_gpio_gpio_en_d2p[27]; + assign mio_en_d2p[MioOutGpioGpio28] = cio_gpio_gpio_en_d2p[28]; + assign mio_en_d2p[MioOutGpioGpio29] = cio_gpio_gpio_en_d2p[29]; + assign mio_en_d2p[MioOutGpioGpio30] = cio_gpio_gpio_en_d2p[30]; + assign mio_en_d2p[MioOutGpioGpio31] = cio_gpio_gpio_en_d2p[31]; + assign mio_en_d2p[MioOutUart0Tx] = cio_uart0_tx_en_d2p; + assign mio_en_d2p[MioOutUart1Tx] = cio_uart1_tx_en_d2p; + assign mio_en_d2p[MioOutFlashCtrlTdo] = cio_flash_ctrl_tdo_en_d2p; + + // All dedicated inputs + logic [13:0] unused_dio_p2d; + assign unused_dio_p2d = dio_p2d; + assign cio_spi_host0_sd_p2d[0] = dio_p2d[DioSpiHost0Sd0]; + assign cio_spi_host0_sd_p2d[1] = dio_p2d[DioSpiHost0Sd1]; + assign cio_spi_host0_sd_p2d[2] = dio_p2d[DioSpiHost0Sd2]; + assign cio_spi_host0_sd_p2d[3] = dio_p2d[DioSpiHost0Sd3]; + assign cio_spi_device_sd_p2d[0] = dio_p2d[DioSpiDeviceSd0]; + assign cio_spi_device_sd_p2d[1] = dio_p2d[DioSpiDeviceSd1]; + assign cio_spi_device_sd_p2d[2] = dio_p2d[DioSpiDeviceSd2]; + assign cio_spi_device_sd_p2d[3] = dio_p2d[DioSpiDeviceSd3]; + assign cio_usbdev_usb_dp_p2d = dio_p2d[DioUsbdevUsbDp]; + assign cio_usbdev_usb_dn_p2d = dio_p2d[DioUsbdevUsbDn]; + assign cio_spi_device_sck_p2d = dio_p2d[DioSpiDeviceSck]; + assign cio_spi_device_csb_p2d = dio_p2d[DioSpiDeviceCsb]; + + // All dedicated outputs + assign dio_d2p[DioSpiHost0Sd0] = cio_spi_host0_sd_d2p[0]; + assign dio_d2p[DioSpiHost0Sd1] = cio_spi_host0_sd_d2p[1]; + assign dio_d2p[DioSpiHost0Sd2] = cio_spi_host0_sd_d2p[2]; + assign dio_d2p[DioSpiHost0Sd3] = cio_spi_host0_sd_d2p[3]; + assign dio_d2p[DioSpiDeviceSd0] = cio_spi_device_sd_d2p[0]; + assign dio_d2p[DioSpiDeviceSd1] = cio_spi_device_sd_d2p[1]; + assign dio_d2p[DioSpiDeviceSd2] = cio_spi_device_sd_d2p[2]; + assign dio_d2p[DioSpiDeviceSd3] = cio_spi_device_sd_d2p[3]; + assign dio_d2p[DioUsbdevUsbDp] = cio_usbdev_usb_dp_d2p; + assign dio_d2p[DioUsbdevUsbDn] = cio_usbdev_usb_dn_d2p; + assign dio_d2p[DioSpiDeviceSck] = 1'b0; + assign dio_d2p[DioSpiDeviceCsb] = 1'b0; + assign dio_d2p[DioSpiHost0Sck] = cio_spi_host0_sck_d2p; + assign dio_d2p[DioSpiHost0Csb] = cio_spi_host0_csb_d2p; + + // All dedicated output enables + assign dio_en_d2p[DioSpiHost0Sd0] = cio_spi_host0_sd_en_d2p[0]; + assign dio_en_d2p[DioSpiHost0Sd1] = cio_spi_host0_sd_en_d2p[1]; + assign dio_en_d2p[DioSpiHost0Sd2] = cio_spi_host0_sd_en_d2p[2]; + assign dio_en_d2p[DioSpiHost0Sd3] = cio_spi_host0_sd_en_d2p[3]; + assign dio_en_d2p[DioSpiDeviceSd0] = cio_spi_device_sd_en_d2p[0]; + assign dio_en_d2p[DioSpiDeviceSd1] = cio_spi_device_sd_en_d2p[1]; + assign dio_en_d2p[DioSpiDeviceSd2] = cio_spi_device_sd_en_d2p[2]; + assign dio_en_d2p[DioSpiDeviceSd3] = cio_spi_device_sd_en_d2p[3]; + assign dio_en_d2p[DioUsbdevUsbDp] = cio_usbdev_usb_dp_en_d2p; + assign dio_en_d2p[DioUsbdevUsbDn] = cio_usbdev_usb_dn_en_d2p; + assign dio_en_d2p[DioSpiDeviceSck] = 1'b0; + assign dio_en_d2p[DioSpiDeviceCsb] = 1'b0; + assign dio_en_d2p[DioSpiHost0Sck] = cio_spi_host0_sck_en_d2p; + assign dio_en_d2p[DioSpiHost0Csb] = cio_spi_host0_csb_en_d2p; + + + // make sure scanmode_i is never X (including during reset) + `ASSERT_KNOWN(scanmodeKnown, scanmode_i, clk_main_i, 0) + +endmodule diff --git a/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_pkg.sv b/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_pkg.sv new file mode 100644 index 0000000000000..20d3fada43f68 --- /dev/null +++ b/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_pkg.sv @@ -0,0 +1,562 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson \ +// -o hw/top_englishbreakfast/ \ +// --rnd_cnst_seed \ +// 4881560218908238235 + +package top_englishbreakfast_pkg; + /** + * Peripheral base address for uart0 in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR = 32'h40000000; + + /** + * Peripheral size in bytes for uart0 in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_UART0_SIZE_BYTES = 32'h40; + + /** + * Peripheral base address for uart1 in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR = 32'h40010000; + + /** + * Peripheral size in bytes for uart1 in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_UART1_SIZE_BYTES = 32'h40; + + /** + * Peripheral base address for gpio in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR = 32'h40040000; + + /** + * Peripheral size in bytes for gpio in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_GPIO_SIZE_BYTES = 32'h80; + + /** + * Peripheral base address for spi_device in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR = 32'h40050000; + + /** + * Peripheral size in bytes for spi_device in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SPI_DEVICE_SIZE_BYTES = 32'h2000; + + /** + * Peripheral base address for spi_host0 in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR = 32'h40060000; + + /** + * Peripheral size in bytes for spi_host0 in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SPI_HOST0_SIZE_BYTES = 32'h40; + + /** + * Peripheral base address for rv_timer in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RV_TIMER_BASE_ADDR = 32'h40100000; + + /** + * Peripheral size in bytes for rv_timer in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RV_TIMER_SIZE_BYTES = 32'h200; + + /** + * Peripheral base address for usbdev in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR = 32'h40320000; + + /** + * Peripheral size in bytes for usbdev in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_USBDEV_SIZE_BYTES = 32'h1000; + + /** + * Peripheral base address for pwrmgr_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR = 32'h40400000; + + /** + * Peripheral size in bytes for pwrmgr_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_PWRMGR_AON_SIZE_BYTES = 32'h80; + + /** + * Peripheral base address for rstmgr_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RSTMGR_AON_BASE_ADDR = 32'h40410000; + + /** + * Peripheral size in bytes for rstmgr_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RSTMGR_AON_SIZE_BYTES = 32'h80; + + /** + * Peripheral base address for clkmgr_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_CLKMGR_AON_BASE_ADDR = 32'h40420000; + + /** + * Peripheral size in bytes for clkmgr_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_CLKMGR_AON_SIZE_BYTES = 32'h80; + + /** + * Peripheral base address for pinmux_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_PINMUX_AON_BASE_ADDR = 32'h40460000; + + /** + * Peripheral size in bytes for pinmux_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_PINMUX_AON_SIZE_BYTES = 32'h1000; + + /** + * Peripheral base address for aon_timer_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR = 32'h40470000; + + /** + * Peripheral size in bytes for aon_timer_aon in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_AON_TIMER_AON_SIZE_BYTES = 32'h40; + + /** + * Peripheral base address for ast in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_AST_BASE_ADDR = 32'h40480000; + + /** + * Peripheral size in bytes for ast in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_AST_SIZE_BYTES = 32'h400; + + /** + * Peripheral base address for core device on flash_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR = 32'h41000000; + + /** + * Peripheral size in bytes for core device on flash_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_SIZE_BYTES = 32'h200; + + /** + * Peripheral base address for prim device on flash_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_BASE_ADDR = 32'h41008000; + + /** + * Peripheral size in bytes for prim device on flash_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_SIZE_BYTES = 32'h80; + + /** + * Peripheral base address for mem device on flash_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_BASE_ADDR = 32'h20000000; + + /** + * Peripheral size in bytes for mem device on flash_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_SIZE_BYTES = 32'h10000; + + /** + * Peripheral base address for rv_plic in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR = 32'h48000000; + + /** + * Peripheral size in bytes for rv_plic in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RV_PLIC_SIZE_BYTES = 32'h8000000; + + /** + * Peripheral base address for aes in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_AES_BASE_ADDR = 32'h41100000; + + /** + * Peripheral size in bytes for aes in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_AES_SIZE_BYTES = 32'h100; + + /** + * Peripheral base address for regs device on sram_ctrl_main in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_BASE_ADDR = 32'h411C0000; + + /** + * Peripheral size in bytes for regs device on sram_ctrl_main in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_SIZE_BYTES = 32'h40; + + /** + * Peripheral base address for ram device on sram_ctrl_main in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_BASE_ADDR = 32'h10000000; + + /** + * Peripheral size in bytes for ram device on sram_ctrl_main in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_SIZE_BYTES = 32'h20000; + + /** + * Peripheral base address for regs device on rom_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_BASE_ADDR = 32'h411E0000; + + /** + * Peripheral size in bytes for regs device on rom_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_SIZE_BYTES = 32'h80; + + /** + * Peripheral base address for rom device on rom_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_BASE_ADDR = 32'h8000; + + /** + * Peripheral size in bytes for rom device on rom_ctrl in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_SIZE_BYTES = 32'h8000; + + /** + * Peripheral base address for cfg device on rv_core_ibex in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_BASE_ADDR = 32'h411F0000; + + /** + * Peripheral size in bytes for cfg device on rv_core_ibex in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_SIZE_BYTES = 32'h100; + + /** + * Memory base address for eflash in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_EFLASH_BASE_ADDR = 32'h20000000; + + /** + * Memory size for eflash in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_EFLASH_SIZE_BYTES = 32'h10000; + + /** + * Memory base address for ram_main in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RAM_MAIN_BASE_ADDR = 32'h10000000; + + /** + * Memory size for ram_main in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_RAM_MAIN_SIZE_BYTES = 32'h20000; + + /** + * Memory base address for rom in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_ROM_BASE_ADDR = 32'h8000; + + /** + * Memory size for rom in top englishbreakfast. + */ + parameter int unsigned TOP_ENGLISHBREAKFAST_ROM_SIZE_BYTES = 32'h8000; + + + // Enumeration of alert modules + typedef enum int unsigned { + TopEnglishbreakfastAlertPeripheralUart0 = 0, + TopEnglishbreakfastAlertPeripheralUart1 = 1, + TopEnglishbreakfastAlertPeripheralGpio = 2, + TopEnglishbreakfastAlertPeripheralSpiDevice = 3, + TopEnglishbreakfastAlertPeripheralSpiHost0 = 4, + TopEnglishbreakfastAlertPeripheralRvTimer = 5, + TopEnglishbreakfastAlertPeripheralUsbdev = 6, + TopEnglishbreakfastAlertPeripheralPwrmgrAon = 7, + TopEnglishbreakfastAlertPeripheralRstmgrAon = 8, + TopEnglishbreakfastAlertPeripheralClkmgrAon = 9, + TopEnglishbreakfastAlertPeripheralPinmuxAon = 10, + TopEnglishbreakfastAlertPeripheralAonTimerAon = 11, + TopEnglishbreakfastAlertPeripheralFlashCtrl = 12, + TopEnglishbreakfastAlertPeripheralRvPlic = 13, + TopEnglishbreakfastAlertPeripheralAes = 14, + TopEnglishbreakfastAlertPeripheralSramCtrlMain = 15, + TopEnglishbreakfastAlertPeripheralRomCtrl = 16, + TopEnglishbreakfastAlertPeripheralRvCoreIbex = 17, + TopEnglishbreakfastAlertPeripheralCount + } alert_peripheral_e; + + // Enumeration of alerts + typedef enum int unsigned { + TopEnglishbreakfastAlertIdUart0FatalFault = 0, + TopEnglishbreakfastAlertIdUart1FatalFault = 1, + TopEnglishbreakfastAlertIdGpioFatalFault = 2, + TopEnglishbreakfastAlertIdSpiDeviceFatalFault = 3, + TopEnglishbreakfastAlertIdSpiHost0FatalFault = 4, + TopEnglishbreakfastAlertIdRvTimerFatalFault = 5, + TopEnglishbreakfastAlertIdUsbdevFatalFault = 6, + TopEnglishbreakfastAlertIdPwrmgrAonFatalFault = 7, + TopEnglishbreakfastAlertIdRstmgrAonFatalFault = 8, + TopEnglishbreakfastAlertIdRstmgrAonFatalCnstyFault = 9, + TopEnglishbreakfastAlertIdClkmgrAonRecovFault = 10, + TopEnglishbreakfastAlertIdClkmgrAonFatalFault = 11, + TopEnglishbreakfastAlertIdPinmuxAonFatalFault = 12, + TopEnglishbreakfastAlertIdAonTimerAonFatalFault = 13, + TopEnglishbreakfastAlertIdFlashCtrlRecovErr = 14, + TopEnglishbreakfastAlertIdFlashCtrlFatalStdErr = 15, + TopEnglishbreakfastAlertIdFlashCtrlFatalErr = 16, + TopEnglishbreakfastAlertIdFlashCtrlFatalPrimFlashAlert = 17, + TopEnglishbreakfastAlertIdFlashCtrlRecovPrimFlashAlert = 18, + TopEnglishbreakfastAlertIdRvPlicFatalFault = 19, + TopEnglishbreakfastAlertIdAesRecovCtrlUpdateErr = 20, + TopEnglishbreakfastAlertIdAesFatalFault = 21, + TopEnglishbreakfastAlertIdSramCtrlMainFatalError = 22, + TopEnglishbreakfastAlertIdRomCtrlFatal = 23, + TopEnglishbreakfastAlertIdRvCoreIbexFatalSwErr = 24, + TopEnglishbreakfastAlertIdRvCoreIbexRecovSwErr = 25, + TopEnglishbreakfastAlertIdRvCoreIbexFatalHwErr = 26, + TopEnglishbreakfastAlertIdRvCoreIbexRecovHwErr = 27, + TopEnglishbreakfastAlertIdCount + } alert_id_e; + + // Enumeration of IO power domains. + // Only used in ASIC target. + typedef enum logic [2:0] { + IoBankVcc = 0, + IoBankAvcc = 1, + IoBankVioa = 2, + IoBankViob = 3, + IoBankCount = 4 + } pwr_dom_e; + + // Enumeration for MIO signals on the top-level. + typedef enum int unsigned { + MioInGpioGpio0 = 0, + MioInGpioGpio1 = 1, + MioInGpioGpio2 = 2, + MioInGpioGpio3 = 3, + MioInGpioGpio4 = 4, + MioInGpioGpio5 = 5, + MioInGpioGpio6 = 6, + MioInGpioGpio7 = 7, + MioInGpioGpio8 = 8, + MioInGpioGpio9 = 9, + MioInGpioGpio10 = 10, + MioInGpioGpio11 = 11, + MioInGpioGpio12 = 12, + MioInGpioGpio13 = 13, + MioInGpioGpio14 = 14, + MioInGpioGpio15 = 15, + MioInGpioGpio16 = 16, + MioInGpioGpio17 = 17, + MioInGpioGpio18 = 18, + MioInGpioGpio19 = 19, + MioInGpioGpio20 = 20, + MioInGpioGpio21 = 21, + MioInGpioGpio22 = 22, + MioInGpioGpio23 = 23, + MioInGpioGpio24 = 24, + MioInGpioGpio25 = 25, + MioInGpioGpio26 = 26, + MioInGpioGpio27 = 27, + MioInGpioGpio28 = 28, + MioInGpioGpio29 = 29, + MioInGpioGpio30 = 30, + MioInGpioGpio31 = 31, + MioInUart0Rx = 32, + MioInUart1Rx = 33, + MioInFlashCtrlTck = 34, + MioInFlashCtrlTms = 35, + MioInFlashCtrlTdi = 36, + MioInUsbdevSense = 37, + MioInCount = 38 + } mio_in_e; + + typedef enum { + MioOutGpioGpio0 = 0, + MioOutGpioGpio1 = 1, + MioOutGpioGpio2 = 2, + MioOutGpioGpio3 = 3, + MioOutGpioGpio4 = 4, + MioOutGpioGpio5 = 5, + MioOutGpioGpio6 = 6, + MioOutGpioGpio7 = 7, + MioOutGpioGpio8 = 8, + MioOutGpioGpio9 = 9, + MioOutGpioGpio10 = 10, + MioOutGpioGpio11 = 11, + MioOutGpioGpio12 = 12, + MioOutGpioGpio13 = 13, + MioOutGpioGpio14 = 14, + MioOutGpioGpio15 = 15, + MioOutGpioGpio16 = 16, + MioOutGpioGpio17 = 17, + MioOutGpioGpio18 = 18, + MioOutGpioGpio19 = 19, + MioOutGpioGpio20 = 20, + MioOutGpioGpio21 = 21, + MioOutGpioGpio22 = 22, + MioOutGpioGpio23 = 23, + MioOutGpioGpio24 = 24, + MioOutGpioGpio25 = 25, + MioOutGpioGpio26 = 26, + MioOutGpioGpio27 = 27, + MioOutGpioGpio28 = 28, + MioOutGpioGpio29 = 29, + MioOutGpioGpio30 = 30, + MioOutGpioGpio31 = 31, + MioOutUart0Tx = 32, + MioOutUart1Tx = 33, + MioOutFlashCtrlTdo = 34, + MioOutCount = 35 + } mio_out_e; + + // Enumeration for DIO signals, used on both the top and chip-levels. + typedef enum int unsigned { + DioSpiHost0Sd0 = 0, + DioSpiHost0Sd1 = 1, + DioSpiHost0Sd2 = 2, + DioSpiHost0Sd3 = 3, + DioSpiDeviceSd0 = 4, + DioSpiDeviceSd1 = 5, + DioSpiDeviceSd2 = 6, + DioSpiDeviceSd3 = 7, + DioUsbdevUsbDp = 8, + DioUsbdevUsbDn = 9, + DioSpiDeviceSck = 10, + DioSpiDeviceCsb = 11, + DioSpiHost0Sck = 12, + DioSpiHost0Csb = 13, + DioCount = 14 + } dio_e; + + // Enumeration for the types of pads. + typedef enum { + MioPad, + DioPad + } pad_type_e; + + // Raw MIO/DIO input array indices on chip-level. + // TODO: Does not account for target specific stubbed/added pads. + // Need to make a target-specific package for those. + typedef enum int unsigned { + MioPadIoa0 = 0, + MioPadIoa1 = 1, + MioPadIoa2 = 2, + MioPadIoa3 = 3, + MioPadIoa4 = 4, + MioPadIoa5 = 5, + MioPadIoa6 = 6, + MioPadIoa7 = 7, + MioPadIoa8 = 8, + MioPadIob0 = 9, + MioPadIob1 = 10, + MioPadIob2 = 11, + MioPadIob3 = 12, + MioPadIob4 = 13, + MioPadIob5 = 14, + MioPadIob6 = 15, + MioPadIob7 = 16, + MioPadIob8 = 17, + MioPadIob9 = 18, + MioPadIob10 = 19, + MioPadIob11 = 20, + MioPadIob12 = 21, + MioPadIoc0 = 22, + MioPadIoc1 = 23, + MioPadIoc2 = 24, + MioPadIoc3 = 25, + MioPadIoc4 = 26, + MioPadIoc5 = 27, + MioPadIoc6 = 28, + MioPadIoc7 = 29, + MioPadIoc8 = 30, + MioPadIoc9 = 31, + MioPadIoc10 = 32, + MioPadIoc11 = 33, + MioPadIoc12 = 34, + MioPadIor0 = 35, + MioPadIor1 = 36, + MioPadIor2 = 37, + MioPadIor3 = 38, + MioPadIor4 = 39, + MioPadIor5 = 40, + MioPadIor6 = 41, + MioPadIor7 = 42, + MioPadIor10 = 43, + MioPadIor11 = 44, + MioPadIor12 = 45, + MioPadIor13 = 46, + MioPadCount + } mio_pad_e; + + typedef enum int unsigned { + DioPadPorN = 0, + DioPadUsbP = 1, + DioPadUsbN = 2, + DioPadCc1 = 3, + DioPadCc2 = 4, + DioPadFlashTestVolt = 5, + DioPadFlashTestMode0 = 6, + DioPadFlashTestMode1 = 7, + DioPadSpiHostD0 = 8, + DioPadSpiHostD1 = 9, + DioPadSpiHostD2 = 10, + DioPadSpiHostD3 = 11, + DioPadSpiHostClk = 12, + DioPadSpiHostCsL = 13, + DioPadSpiDevD0 = 14, + DioPadSpiDevD1 = 15, + DioPadSpiDevD2 = 16, + DioPadSpiDevD3 = 17, + DioPadSpiDevClk = 18, + DioPadSpiDevCsL = 19, + DioPadCount + } dio_pad_e; + + // List of peripheral instantiated in this chip. + typedef enum { + PeripheralAes, + PeripheralAonTimerAon, + PeripheralAst, + PeripheralClkmgrAon, + PeripheralFlashCtrl, + PeripheralGpio, + PeripheralPinmuxAon, + PeripheralPwrmgrAon, + PeripheralRomCtrl, + PeripheralRstmgrAon, + PeripheralRvCoreIbex, + PeripheralRvPlic, + PeripheralRvTimer, + PeripheralSpiDevice, + PeripheralSpiHost0, + PeripheralSramCtrlMain, + PeripheralUart0, + PeripheralUart1, + PeripheralUsbdev, + PeripheralCount + } peripheral_e; + + // TODO: Enumeration for PLIC Interrupt source peripheral. + // TODO: Enumeration for PLIC Interrupt Ids. + +// MACROs for AST analog simulation support +`ifdef ANALOGSIM + `define INOUT_AI input ast_pkg::awire_t + `define INOUT_AO output ast_pkg::awire_t +`else + `define INOUT_AI inout + `define INOUT_AO inout +`endif + +endpackage diff --git a/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_rnd_cnst_pkg.sv b/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_rnd_cnst_pkg.sv new file mode 100644 index 0000000000000..315db1846c615 --- /dev/null +++ b/hw/top_englishbreakfast/rtl/autogen/top_englishbreakfast_rnd_cnst_pkg.sv @@ -0,0 +1,139 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson \ +// -o hw/top_englishbreakfast/ \ +// --rnd_cnst_seed \ +// 4881560218908238235 + + +package top_englishbreakfast_rnd_cnst_pkg; + + //////////////////////////////////////////// + // flash_ctrl + //////////////////////////////////////////// + // Compile-time random bits for default address key + parameter flash_ctrl_pkg::flash_key_t RndCnstFlashCtrlAddrKey = { + 128'h9E90F8E6_5F8CDC02_8E681EDC_B14CB2E8 + }; + + // Compile-time random bits for default data key + parameter flash_ctrl_pkg::flash_key_t RndCnstFlashCtrlDataKey = { + 128'h1C9634B9_FA84FEC1_CCC9E252_5B4ACFBE + }; + + // Compile-time random bits for default seeds + parameter flash_ctrl_pkg::all_seeds_t RndCnstFlashCtrlAllSeeds = { + 256'hF1354B09_69540F0F_285312FD_274E1F61_36763B10_AEF74FEA_8020040B_2A0B515E, + 256'hD5E666D7_71EF5001_237710FE_B20A90ED_FFD46B00_CE07C1B5_411E7934_82C8143E + }; + + // Compile-time random bits for initial LFSR seed + parameter flash_ctrl_pkg::lfsr_seed_t RndCnstFlashCtrlLfsrSeed = { + 32'h6AE2B721 + }; + + // Compile-time random permutation for LFSR output + parameter flash_ctrl_pkg::lfsr_perm_t RndCnstFlashCtrlLfsrPerm = { + 160'h757EDCD0_D2E4D0B4_EAE27D83_1600B8E9_06756E1E + }; + + //////////////////////////////////////////// + // aes + //////////////////////////////////////////// + // Default seed of the PRNG used for register clearing. + parameter aes_pkg::clearing_lfsr_seed_t RndCnstAesClearingLfsrSeed = { + 64'hC5A44F9D_C00A807E + }; + + // Permutation applied to the LFSR of the PRNG used for clearing. + parameter aes_pkg::clearing_lfsr_perm_t RndCnstAesClearingLfsrPerm = { + 128'h80E79CF4_8B437E73_292EB407_C40D04FF, + 256'h2C3B476C_F9368E13_6D55D650_F912F1A8_82F89D5D_877BAF1B_AB18A819_A58D9285 + }; + + // Permutation applied to the clearing PRNG output for clearing the second share of registers. + parameter aes_pkg::clearing_lfsr_perm_t RndCnstAesClearingSharePerm = { + 128'h80D40CBF_860E2277_9193A5F5_4B4D997D, + 256'h60D3F2B9_A3C4AF47_54497F09_BCA214BA_3BC1D6AA_073E5C86_EF8F254D_EDB29180 + }; + + // Default seed of the PRNG used for masking. + parameter aes_pkg::masking_lfsr_seed_t RndCnstAesMaskingLfsrSeed = { + 32'hFF657FC2, + 256'h9427D0F4_8AAD106E_3859890C_09023558_95A38418_FA02E124_5E46FAC2_4FA1FC04 + }; + + // Permutation applied to the output of the PRNG used for masking. + parameter aes_pkg::masking_lfsr_perm_t RndCnstAesMaskingLfsrPerm = { + 256'h9D12152E_8B3C0F99_008D9510_71673B88_2F61057F_1E7B1668_5439498C_5F34735A, + 256'h4F59705B_7437751A_369C0C64_291B4B2C_879A657A_9B254A20_76401D24_6D06698F, + 256'h52770103_57433197_48324218_9019932B_7C9F274D_08603A35_8545621F_2A81500E, + 256'h923D5178_6C2D4602_1C6E445E_589E7280_3F66418E_6B6F6A17_0D565D8A_82237D79, + 256'h94980933_0B4C530A_91868463_89133830_04832696_3E4E1147_555C0722_1421287E + }; + + //////////////////////////////////////////// + // sram_ctrl_main + //////////////////////////////////////////// + // Compile-time random reset value for SRAM scrambling key. + parameter otp_ctrl_pkg::sram_key_t RndCnstSramCtrlMainSramKey = { + 128'hA84AFD11_0E65E2C0_9D401249_1AC45C2D + }; + + // Compile-time random reset value for SRAM scrambling nonce. + parameter otp_ctrl_pkg::sram_nonce_t RndCnstSramCtrlMainSramNonce = { + 128'h07799E69_9C02A50A_EE3B25AF_703B953B + }; + + // Compile-time random bits for initial LFSR seed + parameter sram_ctrl_pkg::lfsr_seed_t RndCnstSramCtrlMainLfsrSeed = { + 32'h72C25ACD + }; + + // Compile-time random permutation for LFSR output + parameter sram_ctrl_pkg::lfsr_perm_t RndCnstSramCtrlMainLfsrPerm = { + 160'h70F1C202_29AEF41B_AEC26351_432B3283_CB33FBBF + }; + + //////////////////////////////////////////// + // rom_ctrl + //////////////////////////////////////////// + // Fixed nonce used for address / data scrambling + parameter bit [63:0] RndCnstRomCtrlScrNonce = { + 64'hA055CD15_3E14AFCF + }; + + // Randomised constant used as a scrambling key for ROM data + parameter bit [127:0] RndCnstRomCtrlScrKey = { + 128'hAF2B8B9B_A0EEEEEA_B949B446_2A2E7E3B + }; + + //////////////////////////////////////////// + // rv_core_ibex + //////////////////////////////////////////// + // Default seed of the PRNG used for random instructions. + parameter ibex_pkg::lfsr_seed_t RndCnstRvCoreIbexLfsrSeed = { + 32'h88F2805B + }; + + // Permutation applied to the LFSR of the PRNG used for random instructions. + parameter ibex_pkg::lfsr_perm_t RndCnstRvCoreIbexLfsrPerm = { + 160'hC19B5091_071AF9EF_D36FC952_E8A99300_AF097756 + }; + + // Default icache scrambling key + parameter logic [ibex_pkg::SCRAMBLE_KEY_W-1:0] RndCnstRvCoreIbexIbexKeyDefault = { + 128'h6AEABF22_75AFC88A_1D1273B9_9C6D2D23 + }; + + // Default icache scrambling nonce + parameter logic [ibex_pkg::SCRAMBLE_NONCE_W-1:0] RndCnstRvCoreIbexIbexNonceDefault = { + 64'h9F28888F_3EF00FC7 + }; + +endpackage : top_englishbreakfast_rnd_cnst_pkg diff --git a/hw/top_englishbreakfast/rtl/autogen/top_racl_pkg.sv b/hw/top_englishbreakfast/rtl/autogen/top_racl_pkg.sv new file mode 100644 index 0000000000000..4cf73c448639b --- /dev/null +++ b/hw/top_englishbreakfast/rtl/autogen/top_racl_pkg.sv @@ -0,0 +1,69 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson \ +// -o hw/top_englishbreakfast/ \ +// --rnd_cnst_seed \ +// 4881560218908238235 + + +package top_racl_pkg; + // Number of RACL policies used + parameter int unsigned NrRaclPolicies = 1; + + // Number of RACL bits transferred + parameter int unsigned NrRaclBits = 4; + + // Number of CTN UID bits transferred + parameter int unsigned NrCtnUidBits = 8; + + // RACL role type binary encoded + typedef logic [NrRaclBits-1:0] racl_role_t; + + // CTN UID assigned the bus originator + typedef logic [NrCtnUidBits-1:0] ctn_uid_t; + + // RACL permission: A one-hot encoded role vector + typedef logic [(2**NrRaclBits)-1:0] racl_role_vec_t; + + // RACL policy containing a read and write permission + typedef struct packed { + racl_role_vec_t read_perm; + racl_role_vec_t write_perm; + } racl_policy_t; + + // RACL policy vector for distributing RACL policies from the RACL widget to the subscribing IP + typedef racl_policy_t [NrRaclPolicies-1:0] racl_policy_vec_t; + + // RACL information logged in case of a denial + typedef struct packed { + racl_role_t racl_role; + ctn_uid_t ctn_uid; + // 0: Write access, 1: Read access + logic read_not_write; + } racl_error_log_t; + + // Extract RACL role bits from the TLUL reserved user bits + function automatic racl_role_t tlul_extract_racl_role_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); + // Waive unused bits + logic unused_rsvd_bits; + unused_rsvd_bits = ^{rsvd}; + + return racl_role_t'(rsvd[11:8]); + endfunction + + // Extract CTN UID bits from the TLUL reserved user bits + function automatic ctn_uid_t tlul_extract_ctn_uid_bits(logic [tlul_pkg::RsvdWidth-1:0] rsvd); + // Waive unused bits + logic unused_rsvd_bits; + unused_rsvd_bits = ^{rsvd}; + + return ctn_uid_t'(rsvd[7:0]); + endfunction + + +endpackage diff --git a/hw/top_englishbreakfast/rtl/padring.sv b/hw/top_englishbreakfast/rtl/padring.sv deleted file mode 120000 index 0d11523bb31e5..0000000000000 --- a/hw/top_englishbreakfast/rtl/padring.sv +++ /dev/null @@ -1 +0,0 @@ -../../top_earlgrey/rtl/padring.sv \ No newline at end of file diff --git a/hw/top_englishbreakfast/rtl/physical_pads.sv b/hw/top_englishbreakfast/rtl/physical_pads.sv deleted file mode 120000 index 50d0d57e1d4b8..0000000000000 --- a/hw/top_englishbreakfast/rtl/physical_pads.sv +++ /dev/null @@ -1 +0,0 @@ -../../top_earlgrey/rtl/physical_pads.sv \ No newline at end of file diff --git a/hw/top_englishbreakfast/rtl/top_pkg.sv b/hw/top_englishbreakfast/rtl/top_pkg.sv deleted file mode 120000 index 2044d82592e83..0000000000000 --- a/hw/top_englishbreakfast/rtl/top_pkg.sv +++ /dev/null @@ -1 +0,0 @@ -../../top_earlgrey/rtl/top_pkg.sv \ No newline at end of file diff --git a/hw/top_englishbreakfast/sw/autogen/.clang-format b/hw/top_englishbreakfast/sw/autogen/.clang-format new file mode 100644 index 0000000000000..7cb47a7a72ec7 --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/.clang-format @@ -0,0 +1,4 @@ +# This disables clang-format on all files in the sw/autogen directory. +# This is needed so that git-clang-format and similar scripts work. +DisableFormat: true +SortIncludes: false diff --git a/hw/top_englishbreakfast/sw/autogen/BUILD b/hw/top_englishbreakfast/sw/autogen/BUILD new file mode 100644 index 0000000000000..7c1720a6e7a67 --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/BUILD @@ -0,0 +1,28 @@ +# Copyright lowRISC contributors (OpenTitan project). +# 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: +# util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson +# -o hw/top_englishbreakfast + +load("//rules:linker.bzl", "ld_library") + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "top_englishbreakfast", + srcs = [ + "top_englishbreakfast.c", + ], + hdrs = [ + "top_englishbreakfast.h", + "top_englishbreakfast_memory.h", + ], +) + +ld_library( + name = "top_englishbreakfast_memory", + includes = ["top_englishbreakfast_memory.ld"], +) diff --git a/hw/top_englishbreakfast/sw/autogen/chip/mod.rs b/hw/top_englishbreakfast/sw/autogen/chip/mod.rs new file mode 100644 index 0000000000000..3d0a9bd8923ac --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/chip/mod.rs @@ -0,0 +1,5 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +pub mod top_englishbreakfast; diff --git a/hw/top_englishbreakfast/sw/autogen/chip/top_englishbreakfast.rs b/hw/top_englishbreakfast/sw/autogen/chip/top_englishbreakfast.rs new file mode 100644 index 0000000000000..5184f830de83b --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/chip/top_englishbreakfast.rs @@ -0,0 +1,1682 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file was generated automatically. +// Please do not modify content of this file directly. +// File generated by using template: "toplevel.rs.tpl" +// To regenerate this file follow OpenTitan topgen documentations. + +#![allow(dead_code)] + +//! This file contains enums and consts for use within the Rust codebase. +//! +//! These definitions are for information that depends on the top-specific chip +//! configuration, which includes: +//! - Device Memory Information (for Peripherals and Memory) +//! - PLIC Interrupt ID Names and Source Mappings +//! - Alert ID Names and Source Mappings +//! - Pinmux Pin/Select Names +//! - Power Manager Wakeups + +use core::convert::TryFrom; + +/// Peripheral base address for uart0 in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const UART0_BASE_ADDR: usize = 0x40000000; + +/// Peripheral size for uart0 in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #UART0_BASE_ADDR and +/// `UART0_BASE_ADDR + UART0_SIZE_BYTES`. +pub const UART0_SIZE_BYTES: usize = 0x40; + +/// Peripheral base address for uart1 in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const UART1_BASE_ADDR: usize = 0x40010000; + +/// Peripheral size for uart1 in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #UART1_BASE_ADDR and +/// `UART1_BASE_ADDR + UART1_SIZE_BYTES`. +pub const UART1_SIZE_BYTES: usize = 0x40; + +/// Peripheral base address for gpio in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const GPIO_BASE_ADDR: usize = 0x40040000; + +/// Peripheral size for gpio in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #GPIO_BASE_ADDR and +/// `GPIO_BASE_ADDR + GPIO_SIZE_BYTES`. +pub const GPIO_SIZE_BYTES: usize = 0x80; + +/// Peripheral base address for spi_device in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const SPI_DEVICE_BASE_ADDR: usize = 0x40050000; + +/// Peripheral size for spi_device in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #SPI_DEVICE_BASE_ADDR and +/// `SPI_DEVICE_BASE_ADDR + SPI_DEVICE_SIZE_BYTES`. +pub const SPI_DEVICE_SIZE_BYTES: usize = 0x2000; + +/// Peripheral base address for spi_host0 in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const SPI_HOST0_BASE_ADDR: usize = 0x40060000; + +/// Peripheral size for spi_host0 in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #SPI_HOST0_BASE_ADDR and +/// `SPI_HOST0_BASE_ADDR + SPI_HOST0_SIZE_BYTES`. +pub const SPI_HOST0_SIZE_BYTES: usize = 0x40; + +/// Peripheral base address for rv_timer in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const RV_TIMER_BASE_ADDR: usize = 0x40100000; + +/// Peripheral size for rv_timer in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #RV_TIMER_BASE_ADDR and +/// `RV_TIMER_BASE_ADDR + RV_TIMER_SIZE_BYTES`. +pub const RV_TIMER_SIZE_BYTES: usize = 0x200; + +/// Peripheral base address for usbdev in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const USBDEV_BASE_ADDR: usize = 0x40320000; + +/// Peripheral size for usbdev in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #USBDEV_BASE_ADDR and +/// `USBDEV_BASE_ADDR + USBDEV_SIZE_BYTES`. +pub const USBDEV_SIZE_BYTES: usize = 0x1000; + +/// Peripheral base address for pwrmgr_aon in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const PWRMGR_AON_BASE_ADDR: usize = 0x40400000; + +/// Peripheral size for pwrmgr_aon in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #PWRMGR_AON_BASE_ADDR and +/// `PWRMGR_AON_BASE_ADDR + PWRMGR_AON_SIZE_BYTES`. +pub const PWRMGR_AON_SIZE_BYTES: usize = 0x80; + +/// Peripheral base address for rstmgr_aon in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const RSTMGR_AON_BASE_ADDR: usize = 0x40410000; + +/// Peripheral size for rstmgr_aon in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #RSTMGR_AON_BASE_ADDR and +/// `RSTMGR_AON_BASE_ADDR + RSTMGR_AON_SIZE_BYTES`. +pub const RSTMGR_AON_SIZE_BYTES: usize = 0x80; + +/// Peripheral base address for clkmgr_aon in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const CLKMGR_AON_BASE_ADDR: usize = 0x40420000; + +/// Peripheral size for clkmgr_aon in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #CLKMGR_AON_BASE_ADDR and +/// `CLKMGR_AON_BASE_ADDR + CLKMGR_AON_SIZE_BYTES`. +pub const CLKMGR_AON_SIZE_BYTES: usize = 0x80; + +/// Peripheral base address for pinmux_aon in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const PINMUX_AON_BASE_ADDR: usize = 0x40460000; + +/// Peripheral size for pinmux_aon in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #PINMUX_AON_BASE_ADDR and +/// `PINMUX_AON_BASE_ADDR + PINMUX_AON_SIZE_BYTES`. +pub const PINMUX_AON_SIZE_BYTES: usize = 0x1000; + +/// Peripheral base address for aon_timer_aon in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const AON_TIMER_AON_BASE_ADDR: usize = 0x40470000; + +/// Peripheral size for aon_timer_aon in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #AON_TIMER_AON_BASE_ADDR and +/// `AON_TIMER_AON_BASE_ADDR + AON_TIMER_AON_SIZE_BYTES`. +pub const AON_TIMER_AON_SIZE_BYTES: usize = 0x40; + +/// Peripheral base address for ast in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const AST_BASE_ADDR: usize = 0x40480000; + +/// Peripheral size for ast in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #AST_BASE_ADDR and +/// `AST_BASE_ADDR + AST_SIZE_BYTES`. +pub const AST_SIZE_BYTES: usize = 0x400; + +/// Peripheral base address for core device on flash_ctrl in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const FLASH_CTRL_CORE_BASE_ADDR: usize = 0x41000000; + +/// Peripheral size for core device on flash_ctrl in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #FLASH_CTRL_CORE_BASE_ADDR and +/// `FLASH_CTRL_CORE_BASE_ADDR + FLASH_CTRL_CORE_SIZE_BYTES`. +pub const FLASH_CTRL_CORE_SIZE_BYTES: usize = 0x200; + +/// Peripheral base address for prim device on flash_ctrl in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const FLASH_CTRL_PRIM_BASE_ADDR: usize = 0x41008000; + +/// Peripheral size for prim device on flash_ctrl in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #FLASH_CTRL_PRIM_BASE_ADDR and +/// `FLASH_CTRL_PRIM_BASE_ADDR + FLASH_CTRL_PRIM_SIZE_BYTES`. +pub const FLASH_CTRL_PRIM_SIZE_BYTES: usize = 0x80; + +/// Peripheral base address for mem device on flash_ctrl in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const FLASH_CTRL_MEM_BASE_ADDR: usize = 0x20000000; + +/// Peripheral size for mem device on flash_ctrl in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #FLASH_CTRL_MEM_BASE_ADDR and +/// `FLASH_CTRL_MEM_BASE_ADDR + FLASH_CTRL_MEM_SIZE_BYTES`. +pub const FLASH_CTRL_MEM_SIZE_BYTES: usize = 0x10000; + +/// Peripheral base address for rv_plic in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const RV_PLIC_BASE_ADDR: usize = 0x48000000; + +/// Peripheral size for rv_plic in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #RV_PLIC_BASE_ADDR and +/// `RV_PLIC_BASE_ADDR + RV_PLIC_SIZE_BYTES`. +pub const RV_PLIC_SIZE_BYTES: usize = 0x8000000; + +/// Peripheral base address for aes in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const AES_BASE_ADDR: usize = 0x41100000; + +/// Peripheral size for aes in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #AES_BASE_ADDR and +/// `AES_BASE_ADDR + AES_SIZE_BYTES`. +pub const AES_SIZE_BYTES: usize = 0x100; + +/// Peripheral base address for regs device on sram_ctrl_main in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const SRAM_CTRL_MAIN_REGS_BASE_ADDR: usize = 0x411C0000; + +/// Peripheral size for regs device on sram_ctrl_main in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #SRAM_CTRL_MAIN_REGS_BASE_ADDR and +/// `SRAM_CTRL_MAIN_REGS_BASE_ADDR + SRAM_CTRL_MAIN_REGS_SIZE_BYTES`. +pub const SRAM_CTRL_MAIN_REGS_SIZE_BYTES: usize = 0x40; + +/// Peripheral base address for ram device on sram_ctrl_main in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const SRAM_CTRL_MAIN_RAM_BASE_ADDR: usize = 0x10000000; + +/// Peripheral size for ram device on sram_ctrl_main in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #SRAM_CTRL_MAIN_RAM_BASE_ADDR and +/// `SRAM_CTRL_MAIN_RAM_BASE_ADDR + SRAM_CTRL_MAIN_RAM_SIZE_BYTES`. +pub const SRAM_CTRL_MAIN_RAM_SIZE_BYTES: usize = 0x20000; + +/// Peripheral base address for regs device on rom_ctrl in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const ROM_CTRL_REGS_BASE_ADDR: usize = 0x411E0000; + +/// Peripheral size for regs device on rom_ctrl in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #ROM_CTRL_REGS_BASE_ADDR and +/// `ROM_CTRL_REGS_BASE_ADDR + ROM_CTRL_REGS_SIZE_BYTES`. +pub const ROM_CTRL_REGS_SIZE_BYTES: usize = 0x80; + +/// Peripheral base address for rom device on rom_ctrl in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const ROM_CTRL_ROM_BASE_ADDR: usize = 0x8000; + +/// Peripheral size for rom device on rom_ctrl in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #ROM_CTRL_ROM_BASE_ADDR and +/// `ROM_CTRL_ROM_BASE_ADDR + ROM_CTRL_ROM_SIZE_BYTES`. +pub const ROM_CTRL_ROM_SIZE_BYTES: usize = 0x8000; + +/// Peripheral base address for cfg device on rv_core_ibex in top englishbreakfast. +/// +/// This should be used with #mmio_region_from_addr to access the memory-mapped +/// registers associated with the peripheral (usually via a DIF). +pub const RV_CORE_IBEX_CFG_BASE_ADDR: usize = 0x411F0000; + +/// Peripheral size for cfg device on rv_core_ibex in top englishbreakfast. +/// +/// This is the size (in bytes) of the peripheral's reserved memory area. All +/// memory-mapped registers associated with this peripheral should have an +/// address between #RV_CORE_IBEX_CFG_BASE_ADDR and +/// `RV_CORE_IBEX_CFG_BASE_ADDR + RV_CORE_IBEX_CFG_SIZE_BYTES`. +pub const RV_CORE_IBEX_CFG_SIZE_BYTES: usize = 0x100; + +/// Memory base address for eflash in top englishbreakfast. +pub const EFLASH_BASE_ADDR: usize = 0x20000000; + +/// Memory size for eflash in top englishbreakfast. +pub const EFLASH_SIZE_BYTES: usize = 0x10000; + +/// Memory base address for ram_main in top englishbreakfast. +pub const RAM_MAIN_BASE_ADDR: usize = 0x10000000; + +/// Memory size for ram_main in top englishbreakfast. +pub const RAM_MAIN_SIZE_BYTES: usize = 0x20000; + +/// Memory base address for rom in top englishbreakfast. +pub const ROM_BASE_ADDR: usize = 0x8000; + +/// Memory size for rom in top englishbreakfast. +pub const ROM_SIZE_BYTES: usize = 0x8000; + +/// PLIC Interrupt Source Peripheral. +/// +/// Enumeration used to determine which peripheral asserted the corresponding +/// interrupt. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PlicPeripheral { + /// Unknown Peripheral + Unknown = 0, + /// uart0 + Uart0 = 1, + /// uart1 + Uart1 = 2, + /// gpio + Gpio = 3, + /// spi_device + SpiDevice = 4, + /// spi_host0 + SpiHost0 = 5, + /// usbdev + Usbdev = 6, + /// pwrmgr_aon + PwrmgrAon = 7, + /// aon_timer_aon + AonTimerAon = 8, + /// flash_ctrl + FlashCtrl = 9, +} + +impl TryFrom for PlicPeripheral { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::Unknown), + 1 => Ok(Self::Uart0), + 2 => Ok(Self::Uart1), + 3 => Ok(Self::Gpio), + 4 => Ok(Self::SpiDevice), + 5 => Ok(Self::SpiHost0), + 6 => Ok(Self::Usbdev), + 7 => Ok(Self::PwrmgrAon), + 8 => Ok(Self::AonTimerAon), + 9 => Ok(Self::FlashCtrl), + _ => Err(val), + } + } +} + +/// PLIC Interrupt Source. +/// +/// Enumeration of all PLIC interrupt sources. The interrupt sources belonging to +/// the same peripheral are guaranteed to be consecutive. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PlicIrqId { + /// No Interrupt + None = 0, + /// uart0_tx_watermark + Uart0TxWatermark = 1, + /// uart0_rx_watermark + Uart0RxWatermark = 2, + /// uart0_tx_done + Uart0TxDone = 3, + /// uart0_rx_overflow + Uart0RxOverflow = 4, + /// uart0_rx_frame_err + Uart0RxFrameErr = 5, + /// uart0_rx_break_err + Uart0RxBreakErr = 6, + /// uart0_rx_timeout + Uart0RxTimeout = 7, + /// uart0_rx_parity_err + Uart0RxParityErr = 8, + /// uart0_tx_empty + Uart0TxEmpty = 9, + /// uart1_tx_watermark + Uart1TxWatermark = 10, + /// uart1_rx_watermark + Uart1RxWatermark = 11, + /// uart1_tx_done + Uart1TxDone = 12, + /// uart1_rx_overflow + Uart1RxOverflow = 13, + /// uart1_rx_frame_err + Uart1RxFrameErr = 14, + /// uart1_rx_break_err + Uart1RxBreakErr = 15, + /// uart1_rx_timeout + Uart1RxTimeout = 16, + /// uart1_rx_parity_err + Uart1RxParityErr = 17, + /// uart1_tx_empty + Uart1TxEmpty = 18, + /// gpio_gpio 0 + GpioGpio0 = 19, + /// gpio_gpio 1 + GpioGpio1 = 20, + /// gpio_gpio 2 + GpioGpio2 = 21, + /// gpio_gpio 3 + GpioGpio3 = 22, + /// gpio_gpio 4 + GpioGpio4 = 23, + /// gpio_gpio 5 + GpioGpio5 = 24, + /// gpio_gpio 6 + GpioGpio6 = 25, + /// gpio_gpio 7 + GpioGpio7 = 26, + /// gpio_gpio 8 + GpioGpio8 = 27, + /// gpio_gpio 9 + GpioGpio9 = 28, + /// gpio_gpio 10 + GpioGpio10 = 29, + /// gpio_gpio 11 + GpioGpio11 = 30, + /// gpio_gpio 12 + GpioGpio12 = 31, + /// gpio_gpio 13 + GpioGpio13 = 32, + /// gpio_gpio 14 + GpioGpio14 = 33, + /// gpio_gpio 15 + GpioGpio15 = 34, + /// gpio_gpio 16 + GpioGpio16 = 35, + /// gpio_gpio 17 + GpioGpio17 = 36, + /// gpio_gpio 18 + GpioGpio18 = 37, + /// gpio_gpio 19 + GpioGpio19 = 38, + /// gpio_gpio 20 + GpioGpio20 = 39, + /// gpio_gpio 21 + GpioGpio21 = 40, + /// gpio_gpio 22 + GpioGpio22 = 41, + /// gpio_gpio 23 + GpioGpio23 = 42, + /// gpio_gpio 24 + GpioGpio24 = 43, + /// gpio_gpio 25 + GpioGpio25 = 44, + /// gpio_gpio 26 + GpioGpio26 = 45, + /// gpio_gpio 27 + GpioGpio27 = 46, + /// gpio_gpio 28 + GpioGpio28 = 47, + /// gpio_gpio 29 + GpioGpio29 = 48, + /// gpio_gpio 30 + GpioGpio30 = 49, + /// gpio_gpio 31 + GpioGpio31 = 50, + /// spi_device_upload_cmdfifo_not_empty + SpiDeviceUploadCmdfifoNotEmpty = 51, + /// spi_device_upload_payload_not_empty + SpiDeviceUploadPayloadNotEmpty = 52, + /// spi_device_upload_payload_overflow + SpiDeviceUploadPayloadOverflow = 53, + /// spi_device_readbuf_watermark + SpiDeviceReadbufWatermark = 54, + /// spi_device_readbuf_flip + SpiDeviceReadbufFlip = 55, + /// spi_device_tpm_header_not_empty + SpiDeviceTpmHeaderNotEmpty = 56, + /// spi_device_tpm_rdfifo_cmd_end + SpiDeviceTpmRdfifoCmdEnd = 57, + /// spi_device_tpm_rdfifo_drop + SpiDeviceTpmRdfifoDrop = 58, + /// spi_host0_error + SpiHost0Error = 59, + /// spi_host0_spi_event + SpiHost0SpiEvent = 60, + /// usbdev_pkt_received + UsbdevPktReceived = 61, + /// usbdev_pkt_sent + UsbdevPktSent = 62, + /// usbdev_disconnected + UsbdevDisconnected = 63, + /// usbdev_host_lost + UsbdevHostLost = 64, + /// usbdev_link_reset + UsbdevLinkReset = 65, + /// usbdev_link_suspend + UsbdevLinkSuspend = 66, + /// usbdev_link_resume + UsbdevLinkResume = 67, + /// usbdev_av_out_empty + UsbdevAvOutEmpty = 68, + /// usbdev_rx_full + UsbdevRxFull = 69, + /// usbdev_av_overflow + UsbdevAvOverflow = 70, + /// usbdev_link_in_err + UsbdevLinkInErr = 71, + /// usbdev_rx_crc_err + UsbdevRxCrcErr = 72, + /// usbdev_rx_pid_err + UsbdevRxPidErr = 73, + /// usbdev_rx_bitstuff_err + UsbdevRxBitstuffErr = 74, + /// usbdev_frame + UsbdevFrame = 75, + /// usbdev_powered + UsbdevPowered = 76, + /// usbdev_link_out_err + UsbdevLinkOutErr = 77, + /// usbdev_av_setup_empty + UsbdevAvSetupEmpty = 78, + /// pwrmgr_aon_wakeup + PwrmgrAonWakeup = 79, + /// aon_timer_aon_wkup_timer_expired + AonTimerAonWkupTimerExpired = 80, + /// aon_timer_aon_wdog_timer_bark + AonTimerAonWdogTimerBark = 81, + /// flash_ctrl_prog_empty + FlashCtrlProgEmpty = 82, + /// flash_ctrl_prog_lvl + FlashCtrlProgLvl = 83, + /// flash_ctrl_rd_full + FlashCtrlRdFull = 84, + /// flash_ctrl_rd_lvl + FlashCtrlRdLvl = 85, + /// flash_ctrl_op_done + FlashCtrlOpDone = 86, + /// flash_ctrl_corr_err + FlashCtrlCorrErr = 87, +} + +impl TryFrom for PlicIrqId { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::None), + 1 => Ok(Self::Uart0TxWatermark), + 2 => Ok(Self::Uart0RxWatermark), + 3 => Ok(Self::Uart0TxDone), + 4 => Ok(Self::Uart0RxOverflow), + 5 => Ok(Self::Uart0RxFrameErr), + 6 => Ok(Self::Uart0RxBreakErr), + 7 => Ok(Self::Uart0RxTimeout), + 8 => Ok(Self::Uart0RxParityErr), + 9 => Ok(Self::Uart0TxEmpty), + 10 => Ok(Self::Uart1TxWatermark), + 11 => Ok(Self::Uart1RxWatermark), + 12 => Ok(Self::Uart1TxDone), + 13 => Ok(Self::Uart1RxOverflow), + 14 => Ok(Self::Uart1RxFrameErr), + 15 => Ok(Self::Uart1RxBreakErr), + 16 => Ok(Self::Uart1RxTimeout), + 17 => Ok(Self::Uart1RxParityErr), + 18 => Ok(Self::Uart1TxEmpty), + 19 => Ok(Self::GpioGpio0), + 20 => Ok(Self::GpioGpio1), + 21 => Ok(Self::GpioGpio2), + 22 => Ok(Self::GpioGpio3), + 23 => Ok(Self::GpioGpio4), + 24 => Ok(Self::GpioGpio5), + 25 => Ok(Self::GpioGpio6), + 26 => Ok(Self::GpioGpio7), + 27 => Ok(Self::GpioGpio8), + 28 => Ok(Self::GpioGpio9), + 29 => Ok(Self::GpioGpio10), + 30 => Ok(Self::GpioGpio11), + 31 => Ok(Self::GpioGpio12), + 32 => Ok(Self::GpioGpio13), + 33 => Ok(Self::GpioGpio14), + 34 => Ok(Self::GpioGpio15), + 35 => Ok(Self::GpioGpio16), + 36 => Ok(Self::GpioGpio17), + 37 => Ok(Self::GpioGpio18), + 38 => Ok(Self::GpioGpio19), + 39 => Ok(Self::GpioGpio20), + 40 => Ok(Self::GpioGpio21), + 41 => Ok(Self::GpioGpio22), + 42 => Ok(Self::GpioGpio23), + 43 => Ok(Self::GpioGpio24), + 44 => Ok(Self::GpioGpio25), + 45 => Ok(Self::GpioGpio26), + 46 => Ok(Self::GpioGpio27), + 47 => Ok(Self::GpioGpio28), + 48 => Ok(Self::GpioGpio29), + 49 => Ok(Self::GpioGpio30), + 50 => Ok(Self::GpioGpio31), + 51 => Ok(Self::SpiDeviceUploadCmdfifoNotEmpty), + 52 => Ok(Self::SpiDeviceUploadPayloadNotEmpty), + 53 => Ok(Self::SpiDeviceUploadPayloadOverflow), + 54 => Ok(Self::SpiDeviceReadbufWatermark), + 55 => Ok(Self::SpiDeviceReadbufFlip), + 56 => Ok(Self::SpiDeviceTpmHeaderNotEmpty), + 57 => Ok(Self::SpiDeviceTpmRdfifoCmdEnd), + 58 => Ok(Self::SpiDeviceTpmRdfifoDrop), + 59 => Ok(Self::SpiHost0Error), + 60 => Ok(Self::SpiHost0SpiEvent), + 61 => Ok(Self::UsbdevPktReceived), + 62 => Ok(Self::UsbdevPktSent), + 63 => Ok(Self::UsbdevDisconnected), + 64 => Ok(Self::UsbdevHostLost), + 65 => Ok(Self::UsbdevLinkReset), + 66 => Ok(Self::UsbdevLinkSuspend), + 67 => Ok(Self::UsbdevLinkResume), + 68 => Ok(Self::UsbdevAvOutEmpty), + 69 => Ok(Self::UsbdevRxFull), + 70 => Ok(Self::UsbdevAvOverflow), + 71 => Ok(Self::UsbdevLinkInErr), + 72 => Ok(Self::UsbdevRxCrcErr), + 73 => Ok(Self::UsbdevRxPidErr), + 74 => Ok(Self::UsbdevRxBitstuffErr), + 75 => Ok(Self::UsbdevFrame), + 76 => Ok(Self::UsbdevPowered), + 77 => Ok(Self::UsbdevLinkOutErr), + 78 => Ok(Self::UsbdevAvSetupEmpty), + 79 => Ok(Self::PwrmgrAonWakeup), + 80 => Ok(Self::AonTimerAonWkupTimerExpired), + 81 => Ok(Self::AonTimerAonWdogTimerBark), + 82 => Ok(Self::FlashCtrlProgEmpty), + 83 => Ok(Self::FlashCtrlProgLvl), + 84 => Ok(Self::FlashCtrlRdFull), + 85 => Ok(Self::FlashCtrlRdLvl), + 86 => Ok(Self::FlashCtrlOpDone), + 87 => Ok(Self::FlashCtrlCorrErr), + _ => Err(val), + } + } +} + +/// PLIC Interrupt Target. +/// +/// Enumeration used to determine which set of IE, CC, threshold registers to +/// access for a given interrupt target. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PlicTarget { + /// Ibex Core 0 + Ibex0 = 0, +} + +/// PLIC Interrupt Source to Peripheral Map +/// +/// This array is a mapping from `PlicIrqId` to +/// `PlicPeripheral`. +pub const PLIC_INTERRUPT_FOR_PERIPHERAL: [PlicPeripheral; 88] = [ + // None -> PlicPeripheral::Unknown + PlicPeripheral::Unknown, + // Uart0TxWatermark -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0RxWatermark -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0TxDone -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0RxOverflow -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0RxFrameErr -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0RxBreakErr -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0RxTimeout -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0RxParityErr -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart0TxEmpty -> PlicPeripheral::Uart0 + PlicPeripheral::Uart0, + // Uart1TxWatermark -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1RxWatermark -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1TxDone -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1RxOverflow -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1RxFrameErr -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1RxBreakErr -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1RxTimeout -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1RxParityErr -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // Uart1TxEmpty -> PlicPeripheral::Uart1 + PlicPeripheral::Uart1, + // GpioGpio0 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio1 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio2 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio3 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio4 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio5 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio6 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio7 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio8 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio9 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio10 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio11 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio12 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio13 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio14 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio15 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio16 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio17 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio18 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio19 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio20 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio21 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio22 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio23 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio24 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio25 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio26 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio27 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio28 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio29 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio30 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // GpioGpio31 -> PlicPeripheral::Gpio + PlicPeripheral::Gpio, + // SpiDeviceUploadCmdfifoNotEmpty -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiDeviceUploadPayloadNotEmpty -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiDeviceUploadPayloadOverflow -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiDeviceReadbufWatermark -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiDeviceReadbufFlip -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiDeviceTpmHeaderNotEmpty -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiDeviceTpmRdfifoCmdEnd -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiDeviceTpmRdfifoDrop -> PlicPeripheral::SpiDevice + PlicPeripheral::SpiDevice, + // SpiHost0Error -> PlicPeripheral::SpiHost0 + PlicPeripheral::SpiHost0, + // SpiHost0SpiEvent -> PlicPeripheral::SpiHost0 + PlicPeripheral::SpiHost0, + // UsbdevPktReceived -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevPktSent -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevDisconnected -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevHostLost -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevLinkReset -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevLinkSuspend -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevLinkResume -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevAvOutEmpty -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevRxFull -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevAvOverflow -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevLinkInErr -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevRxCrcErr -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevRxPidErr -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevRxBitstuffErr -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevFrame -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevPowered -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevLinkOutErr -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // UsbdevAvSetupEmpty -> PlicPeripheral::Usbdev + PlicPeripheral::Usbdev, + // PwrmgrAonWakeup -> PlicPeripheral::PwrmgrAon + PlicPeripheral::PwrmgrAon, + // AonTimerAonWkupTimerExpired -> PlicPeripheral::AonTimerAon + PlicPeripheral::AonTimerAon, + // AonTimerAonWdogTimerBark -> PlicPeripheral::AonTimerAon + PlicPeripheral::AonTimerAon, + // FlashCtrlProgEmpty -> PlicPeripheral::FlashCtrl + PlicPeripheral::FlashCtrl, + // FlashCtrlProgLvl -> PlicPeripheral::FlashCtrl + PlicPeripheral::FlashCtrl, + // FlashCtrlRdFull -> PlicPeripheral::FlashCtrl + PlicPeripheral::FlashCtrl, + // FlashCtrlRdLvl -> PlicPeripheral::FlashCtrl + PlicPeripheral::FlashCtrl, + // FlashCtrlOpDone -> PlicPeripheral::FlashCtrl + PlicPeripheral::FlashCtrl, + // FlashCtrlCorrErr -> PlicPeripheral::FlashCtrl + PlicPeripheral::FlashCtrl, +]; + +// PERIPH_INSEL ranges from 0 to NUM_MIO_PADS + 2 -1} +// 0 and 1 are tied to value 0 and 1 +pub const NUM_MIO_PADS: usize = 47; +pub const NUM_DIO_PADS: usize = 14; + +pub const PINMUX_MIO_PERIPH_INSEL_IDX_OFFSET: usize = 2; +pub const PINMUX_PERIPH_OUTSEL_IDX_OFFSET: usize = 3; + +/// Pinmux Peripheral Input. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PinmuxPeripheralIn { + /// Peripheral Input 0 + GpioGpio0 = 0, + /// Peripheral Input 1 + GpioGpio1 = 1, + /// Peripheral Input 2 + GpioGpio2 = 2, + /// Peripheral Input 3 + GpioGpio3 = 3, + /// Peripheral Input 4 + GpioGpio4 = 4, + /// Peripheral Input 5 + GpioGpio5 = 5, + /// Peripheral Input 6 + GpioGpio6 = 6, + /// Peripheral Input 7 + GpioGpio7 = 7, + /// Peripheral Input 8 + GpioGpio8 = 8, + /// Peripheral Input 9 + GpioGpio9 = 9, + /// Peripheral Input 10 + GpioGpio10 = 10, + /// Peripheral Input 11 + GpioGpio11 = 11, + /// Peripheral Input 12 + GpioGpio12 = 12, + /// Peripheral Input 13 + GpioGpio13 = 13, + /// Peripheral Input 14 + GpioGpio14 = 14, + /// Peripheral Input 15 + GpioGpio15 = 15, + /// Peripheral Input 16 + GpioGpio16 = 16, + /// Peripheral Input 17 + GpioGpio17 = 17, + /// Peripheral Input 18 + GpioGpio18 = 18, + /// Peripheral Input 19 + GpioGpio19 = 19, + /// Peripheral Input 20 + GpioGpio20 = 20, + /// Peripheral Input 21 + GpioGpio21 = 21, + /// Peripheral Input 22 + GpioGpio22 = 22, + /// Peripheral Input 23 + GpioGpio23 = 23, + /// Peripheral Input 24 + GpioGpio24 = 24, + /// Peripheral Input 25 + GpioGpio25 = 25, + /// Peripheral Input 26 + GpioGpio26 = 26, + /// Peripheral Input 27 + GpioGpio27 = 27, + /// Peripheral Input 28 + GpioGpio28 = 28, + /// Peripheral Input 29 + GpioGpio29 = 29, + /// Peripheral Input 30 + GpioGpio30 = 30, + /// Peripheral Input 31 + GpioGpio31 = 31, + /// Peripheral Input 32 + Uart0Rx = 32, + /// Peripheral Input 33 + Uart1Rx = 33, + /// Peripheral Input 34 + FlashCtrlTck = 34, + /// Peripheral Input 35 + FlashCtrlTms = 35, + /// Peripheral Input 36 + FlashCtrlTdi = 36, + /// Peripheral Input 37 + UsbdevSense = 37, +} + +impl TryFrom for PinmuxPeripheralIn { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::GpioGpio0), + 1 => Ok(Self::GpioGpio1), + 2 => Ok(Self::GpioGpio2), + 3 => Ok(Self::GpioGpio3), + 4 => Ok(Self::GpioGpio4), + 5 => Ok(Self::GpioGpio5), + 6 => Ok(Self::GpioGpio6), + 7 => Ok(Self::GpioGpio7), + 8 => Ok(Self::GpioGpio8), + 9 => Ok(Self::GpioGpio9), + 10 => Ok(Self::GpioGpio10), + 11 => Ok(Self::GpioGpio11), + 12 => Ok(Self::GpioGpio12), + 13 => Ok(Self::GpioGpio13), + 14 => Ok(Self::GpioGpio14), + 15 => Ok(Self::GpioGpio15), + 16 => Ok(Self::GpioGpio16), + 17 => Ok(Self::GpioGpio17), + 18 => Ok(Self::GpioGpio18), + 19 => Ok(Self::GpioGpio19), + 20 => Ok(Self::GpioGpio20), + 21 => Ok(Self::GpioGpio21), + 22 => Ok(Self::GpioGpio22), + 23 => Ok(Self::GpioGpio23), + 24 => Ok(Self::GpioGpio24), + 25 => Ok(Self::GpioGpio25), + 26 => Ok(Self::GpioGpio26), + 27 => Ok(Self::GpioGpio27), + 28 => Ok(Self::GpioGpio28), + 29 => Ok(Self::GpioGpio29), + 30 => Ok(Self::GpioGpio30), + 31 => Ok(Self::GpioGpio31), + 32 => Ok(Self::Uart0Rx), + 33 => Ok(Self::Uart1Rx), + 34 => Ok(Self::FlashCtrlTck), + 35 => Ok(Self::FlashCtrlTms), + 36 => Ok(Self::FlashCtrlTdi), + 37 => Ok(Self::UsbdevSense), + _ => Err(val), + } + } +} + +/// Pinmux MIO Input Selector. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PinmuxInsel { + /// Tie constantly to zero + ConstantZero = 0, + /// Tie constantly to one + ConstantOne = 1, + /// MIO Pad 0 + Ioa0 = 2, + /// MIO Pad 1 + Ioa1 = 3, + /// MIO Pad 2 + Ioa2 = 4, + /// MIO Pad 3 + Ioa3 = 5, + /// MIO Pad 4 + Ioa4 = 6, + /// MIO Pad 5 + Ioa5 = 7, + /// MIO Pad 6 + Ioa6 = 8, + /// MIO Pad 7 + Ioa7 = 9, + /// MIO Pad 8 + Ioa8 = 10, + /// MIO Pad 9 + Iob0 = 11, + /// MIO Pad 10 + Iob1 = 12, + /// MIO Pad 11 + Iob2 = 13, + /// MIO Pad 12 + Iob3 = 14, + /// MIO Pad 13 + Iob4 = 15, + /// MIO Pad 14 + Iob5 = 16, + /// MIO Pad 15 + Iob6 = 17, + /// MIO Pad 16 + Iob7 = 18, + /// MIO Pad 17 + Iob8 = 19, + /// MIO Pad 18 + Iob9 = 20, + /// MIO Pad 19 + Iob10 = 21, + /// MIO Pad 20 + Iob11 = 22, + /// MIO Pad 21 + Iob12 = 23, + /// MIO Pad 22 + Ioc0 = 24, + /// MIO Pad 23 + Ioc1 = 25, + /// MIO Pad 24 + Ioc2 = 26, + /// MIO Pad 25 + Ioc3 = 27, + /// MIO Pad 26 + Ioc4 = 28, + /// MIO Pad 27 + Ioc5 = 29, + /// MIO Pad 28 + Ioc6 = 30, + /// MIO Pad 29 + Ioc7 = 31, + /// MIO Pad 30 + Ioc8 = 32, + /// MIO Pad 31 + Ioc9 = 33, + /// MIO Pad 32 + Ioc10 = 34, + /// MIO Pad 33 + Ioc11 = 35, + /// MIO Pad 34 + Ioc12 = 36, + /// MIO Pad 35 + Ior0 = 37, + /// MIO Pad 36 + Ior1 = 38, + /// MIO Pad 37 + Ior2 = 39, + /// MIO Pad 38 + Ior3 = 40, + /// MIO Pad 39 + Ior4 = 41, + /// MIO Pad 40 + Ior5 = 42, + /// MIO Pad 41 + Ior6 = 43, + /// MIO Pad 42 + Ior7 = 44, + /// MIO Pad 43 + Ior10 = 45, + /// MIO Pad 44 + Ior11 = 46, + /// MIO Pad 45 + Ior12 = 47, + /// MIO Pad 46 + Ior13 = 48, +} + +impl TryFrom for PinmuxInsel { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::ConstantZero), + 1 => Ok(Self::ConstantOne), + 2 => Ok(Self::Ioa0), + 3 => Ok(Self::Ioa1), + 4 => Ok(Self::Ioa2), + 5 => Ok(Self::Ioa3), + 6 => Ok(Self::Ioa4), + 7 => Ok(Self::Ioa5), + 8 => Ok(Self::Ioa6), + 9 => Ok(Self::Ioa7), + 10 => Ok(Self::Ioa8), + 11 => Ok(Self::Iob0), + 12 => Ok(Self::Iob1), + 13 => Ok(Self::Iob2), + 14 => Ok(Self::Iob3), + 15 => Ok(Self::Iob4), + 16 => Ok(Self::Iob5), + 17 => Ok(Self::Iob6), + 18 => Ok(Self::Iob7), + 19 => Ok(Self::Iob8), + 20 => Ok(Self::Iob9), + 21 => Ok(Self::Iob10), + 22 => Ok(Self::Iob11), + 23 => Ok(Self::Iob12), + 24 => Ok(Self::Ioc0), + 25 => Ok(Self::Ioc1), + 26 => Ok(Self::Ioc2), + 27 => Ok(Self::Ioc3), + 28 => Ok(Self::Ioc4), + 29 => Ok(Self::Ioc5), + 30 => Ok(Self::Ioc6), + 31 => Ok(Self::Ioc7), + 32 => Ok(Self::Ioc8), + 33 => Ok(Self::Ioc9), + 34 => Ok(Self::Ioc10), + 35 => Ok(Self::Ioc11), + 36 => Ok(Self::Ioc12), + 37 => Ok(Self::Ior0), + 38 => Ok(Self::Ior1), + 39 => Ok(Self::Ior2), + 40 => Ok(Self::Ior3), + 41 => Ok(Self::Ior4), + 42 => Ok(Self::Ior5), + 43 => Ok(Self::Ior6), + 44 => Ok(Self::Ior7), + 45 => Ok(Self::Ior10), + 46 => Ok(Self::Ior11), + 47 => Ok(Self::Ior12), + 48 => Ok(Self::Ior13), + _ => Err(val), + } + } +} + +/// Pinmux MIO Output. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PinmuxMioOut { + /// MIO Pad 0 + Ioa0 = 0, + /// MIO Pad 1 + Ioa1 = 1, + /// MIO Pad 2 + Ioa2 = 2, + /// MIO Pad 3 + Ioa3 = 3, + /// MIO Pad 4 + Ioa4 = 4, + /// MIO Pad 5 + Ioa5 = 5, + /// MIO Pad 6 + Ioa6 = 6, + /// MIO Pad 7 + Ioa7 = 7, + /// MIO Pad 8 + Ioa8 = 8, + /// MIO Pad 9 + Iob0 = 9, + /// MIO Pad 10 + Iob1 = 10, + /// MIO Pad 11 + Iob2 = 11, + /// MIO Pad 12 + Iob3 = 12, + /// MIO Pad 13 + Iob4 = 13, + /// MIO Pad 14 + Iob5 = 14, + /// MIO Pad 15 + Iob6 = 15, + /// MIO Pad 16 + Iob7 = 16, + /// MIO Pad 17 + Iob8 = 17, + /// MIO Pad 18 + Iob9 = 18, + /// MIO Pad 19 + Iob10 = 19, + /// MIO Pad 20 + Iob11 = 20, + /// MIO Pad 21 + Iob12 = 21, + /// MIO Pad 22 + Ioc0 = 22, + /// MIO Pad 23 + Ioc1 = 23, + /// MIO Pad 24 + Ioc2 = 24, + /// MIO Pad 25 + Ioc3 = 25, + /// MIO Pad 26 + Ioc4 = 26, + /// MIO Pad 27 + Ioc5 = 27, + /// MIO Pad 28 + Ioc6 = 28, + /// MIO Pad 29 + Ioc7 = 29, + /// MIO Pad 30 + Ioc8 = 30, + /// MIO Pad 31 + Ioc9 = 31, + /// MIO Pad 32 + Ioc10 = 32, + /// MIO Pad 33 + Ioc11 = 33, + /// MIO Pad 34 + Ioc12 = 34, + /// MIO Pad 35 + Ior0 = 35, + /// MIO Pad 36 + Ior1 = 36, + /// MIO Pad 37 + Ior2 = 37, + /// MIO Pad 38 + Ior3 = 38, + /// MIO Pad 39 + Ior4 = 39, + /// MIO Pad 40 + Ior5 = 40, + /// MIO Pad 41 + Ior6 = 41, + /// MIO Pad 42 + Ior7 = 42, + /// MIO Pad 43 + Ior10 = 43, + /// MIO Pad 44 + Ior11 = 44, + /// MIO Pad 45 + Ior12 = 45, + /// MIO Pad 46 + Ior13 = 46, +} + +impl TryFrom for PinmuxMioOut { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::Ioa0), + 1 => Ok(Self::Ioa1), + 2 => Ok(Self::Ioa2), + 3 => Ok(Self::Ioa3), + 4 => Ok(Self::Ioa4), + 5 => Ok(Self::Ioa5), + 6 => Ok(Self::Ioa6), + 7 => Ok(Self::Ioa7), + 8 => Ok(Self::Ioa8), + 9 => Ok(Self::Iob0), + 10 => Ok(Self::Iob1), + 11 => Ok(Self::Iob2), + 12 => Ok(Self::Iob3), + 13 => Ok(Self::Iob4), + 14 => Ok(Self::Iob5), + 15 => Ok(Self::Iob6), + 16 => Ok(Self::Iob7), + 17 => Ok(Self::Iob8), + 18 => Ok(Self::Iob9), + 19 => Ok(Self::Iob10), + 20 => Ok(Self::Iob11), + 21 => Ok(Self::Iob12), + 22 => Ok(Self::Ioc0), + 23 => Ok(Self::Ioc1), + 24 => Ok(Self::Ioc2), + 25 => Ok(Self::Ioc3), + 26 => Ok(Self::Ioc4), + 27 => Ok(Self::Ioc5), + 28 => Ok(Self::Ioc6), + 29 => Ok(Self::Ioc7), + 30 => Ok(Self::Ioc8), + 31 => Ok(Self::Ioc9), + 32 => Ok(Self::Ioc10), + 33 => Ok(Self::Ioc11), + 34 => Ok(Self::Ioc12), + 35 => Ok(Self::Ior0), + 36 => Ok(Self::Ior1), + 37 => Ok(Self::Ior2), + 38 => Ok(Self::Ior3), + 39 => Ok(Self::Ior4), + 40 => Ok(Self::Ior5), + 41 => Ok(Self::Ior6), + 42 => Ok(Self::Ior7), + 43 => Ok(Self::Ior10), + 44 => Ok(Self::Ior11), + 45 => Ok(Self::Ior12), + 46 => Ok(Self::Ior13), + _ => Err(val), + } + } +} + +/// Pinmux Peripheral Output Selector. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PinmuxOutsel { + /// Tie constantly to zero + ConstantZero = 0, + /// Tie constantly to one + ConstantOne = 1, + /// Tie constantly to high-Z + ConstantHighZ = 2, + /// Peripheral Output 0 + GpioGpio0 = 3, + /// Peripheral Output 1 + GpioGpio1 = 4, + /// Peripheral Output 2 + GpioGpio2 = 5, + /// Peripheral Output 3 + GpioGpio3 = 6, + /// Peripheral Output 4 + GpioGpio4 = 7, + /// Peripheral Output 5 + GpioGpio5 = 8, + /// Peripheral Output 6 + GpioGpio6 = 9, + /// Peripheral Output 7 + GpioGpio7 = 10, + /// Peripheral Output 8 + GpioGpio8 = 11, + /// Peripheral Output 9 + GpioGpio9 = 12, + /// Peripheral Output 10 + GpioGpio10 = 13, + /// Peripheral Output 11 + GpioGpio11 = 14, + /// Peripheral Output 12 + GpioGpio12 = 15, + /// Peripheral Output 13 + GpioGpio13 = 16, + /// Peripheral Output 14 + GpioGpio14 = 17, + /// Peripheral Output 15 + GpioGpio15 = 18, + /// Peripheral Output 16 + GpioGpio16 = 19, + /// Peripheral Output 17 + GpioGpio17 = 20, + /// Peripheral Output 18 + GpioGpio18 = 21, + /// Peripheral Output 19 + GpioGpio19 = 22, + /// Peripheral Output 20 + GpioGpio20 = 23, + /// Peripheral Output 21 + GpioGpio21 = 24, + /// Peripheral Output 22 + GpioGpio22 = 25, + /// Peripheral Output 23 + GpioGpio23 = 26, + /// Peripheral Output 24 + GpioGpio24 = 27, + /// Peripheral Output 25 + GpioGpio25 = 28, + /// Peripheral Output 26 + GpioGpio26 = 29, + /// Peripheral Output 27 + GpioGpio27 = 30, + /// Peripheral Output 28 + GpioGpio28 = 31, + /// Peripheral Output 29 + GpioGpio29 = 32, + /// Peripheral Output 30 + GpioGpio30 = 33, + /// Peripheral Output 31 + GpioGpio31 = 34, + /// Peripheral Output 32 + Uart0Tx = 35, + /// Peripheral Output 33 + Uart1Tx = 36, + /// Peripheral Output 34 + FlashCtrlTdo = 37, +} + +impl TryFrom for PinmuxOutsel { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::ConstantZero), + 1 => Ok(Self::ConstantOne), + 2 => Ok(Self::ConstantHighZ), + 3 => Ok(Self::GpioGpio0), + 4 => Ok(Self::GpioGpio1), + 5 => Ok(Self::GpioGpio2), + 6 => Ok(Self::GpioGpio3), + 7 => Ok(Self::GpioGpio4), + 8 => Ok(Self::GpioGpio5), + 9 => Ok(Self::GpioGpio6), + 10 => Ok(Self::GpioGpio7), + 11 => Ok(Self::GpioGpio8), + 12 => Ok(Self::GpioGpio9), + 13 => Ok(Self::GpioGpio10), + 14 => Ok(Self::GpioGpio11), + 15 => Ok(Self::GpioGpio12), + 16 => Ok(Self::GpioGpio13), + 17 => Ok(Self::GpioGpio14), + 18 => Ok(Self::GpioGpio15), + 19 => Ok(Self::GpioGpio16), + 20 => Ok(Self::GpioGpio17), + 21 => Ok(Self::GpioGpio18), + 22 => Ok(Self::GpioGpio19), + 23 => Ok(Self::GpioGpio20), + 24 => Ok(Self::GpioGpio21), + 25 => Ok(Self::GpioGpio22), + 26 => Ok(Self::GpioGpio23), + 27 => Ok(Self::GpioGpio24), + 28 => Ok(Self::GpioGpio25), + 29 => Ok(Self::GpioGpio26), + 30 => Ok(Self::GpioGpio27), + 31 => Ok(Self::GpioGpio28), + 32 => Ok(Self::GpioGpio29), + 33 => Ok(Self::GpioGpio30), + 34 => Ok(Self::GpioGpio31), + 35 => Ok(Self::Uart0Tx), + 36 => Ok(Self::Uart1Tx), + 37 => Ok(Self::FlashCtrlTdo), + _ => Err(val), + } + } +} + +/// Dedicated Pad Selects +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum DirectPads { + SpiHost0Sd0 = 0, + SpiHost0Sd1 = 1, + SpiHost0Sd2 = 2, + SpiHost0Sd3 = 3, + SpiDeviceSd0 = 4, + SpiDeviceSd1 = 5, + SpiDeviceSd2 = 6, + SpiDeviceSd3 = 7, + UsbdevUsbDp = 8, + UsbdevUsbDn = 9, + SpiDeviceSck = 10, + SpiDeviceCsb = 11, + SpiHost0Sck = 12, + SpiHost0Csb = 13, +} + +impl TryFrom for DirectPads { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::SpiHost0Sd0), + 1 => Ok(Self::SpiHost0Sd1), + 2 => Ok(Self::SpiHost0Sd2), + 3 => Ok(Self::SpiHost0Sd3), + 4 => Ok(Self::SpiDeviceSd0), + 5 => Ok(Self::SpiDeviceSd1), + 6 => Ok(Self::SpiDeviceSd2), + 7 => Ok(Self::SpiDeviceSd3), + 8 => Ok(Self::UsbdevUsbDp), + 9 => Ok(Self::UsbdevUsbDn), + 10 => Ok(Self::SpiDeviceSck), + 11 => Ok(Self::SpiDeviceCsb), + 12 => Ok(Self::SpiHost0Sck), + 13 => Ok(Self::SpiHost0Csb), + _ => Err(val), + } + } +} + +/// Muxed Pad Selects +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum MuxedPads { + Ioa0 = 0, + Ioa1 = 1, + Ioa2 = 2, + Ioa3 = 3, + Ioa4 = 4, + Ioa5 = 5, + Ioa6 = 6, + Ioa7 = 7, + Ioa8 = 8, + Iob0 = 9, + Iob1 = 10, + Iob2 = 11, + Iob3 = 12, + Iob4 = 13, + Iob5 = 14, + Iob6 = 15, + Iob7 = 16, + Iob8 = 17, + Iob9 = 18, + Iob10 = 19, + Iob11 = 20, + Iob12 = 21, + Ioc0 = 22, + Ioc1 = 23, + Ioc2 = 24, + Ioc3 = 25, + Ioc4 = 26, + Ioc5 = 27, + Ioc6 = 28, + Ioc7 = 29, + Ioc8 = 30, + Ioc9 = 31, + Ioc10 = 32, + Ioc11 = 33, + Ioc12 = 34, + Ior0 = 35, + Ior1 = 36, + Ior2 = 37, + Ior3 = 38, + Ior4 = 39, + Ior5 = 40, + Ior6 = 41, + Ior7 = 42, + Ior10 = 43, + Ior11 = 44, + Ior12 = 45, + Ior13 = 46, +} + +impl TryFrom for MuxedPads { + type Error = u32; + fn try_from(val: u32) -> Result { + match val { + 0 => Ok(Self::Ioa0), + 1 => Ok(Self::Ioa1), + 2 => Ok(Self::Ioa2), + 3 => Ok(Self::Ioa3), + 4 => Ok(Self::Ioa4), + 5 => Ok(Self::Ioa5), + 6 => Ok(Self::Ioa6), + 7 => Ok(Self::Ioa7), + 8 => Ok(Self::Ioa8), + 9 => Ok(Self::Iob0), + 10 => Ok(Self::Iob1), + 11 => Ok(Self::Iob2), + 12 => Ok(Self::Iob3), + 13 => Ok(Self::Iob4), + 14 => Ok(Self::Iob5), + 15 => Ok(Self::Iob6), + 16 => Ok(Self::Iob7), + 17 => Ok(Self::Iob8), + 18 => Ok(Self::Iob9), + 19 => Ok(Self::Iob10), + 20 => Ok(Self::Iob11), + 21 => Ok(Self::Iob12), + 22 => Ok(Self::Ioc0), + 23 => Ok(Self::Ioc1), + 24 => Ok(Self::Ioc2), + 25 => Ok(Self::Ioc3), + 26 => Ok(Self::Ioc4), + 27 => Ok(Self::Ioc5), + 28 => Ok(Self::Ioc6), + 29 => Ok(Self::Ioc7), + 30 => Ok(Self::Ioc8), + 31 => Ok(Self::Ioc9), + 32 => Ok(Self::Ioc10), + 33 => Ok(Self::Ioc11), + 34 => Ok(Self::Ioc12), + 35 => Ok(Self::Ior0), + 36 => Ok(Self::Ior1), + 37 => Ok(Self::Ior2), + 38 => Ok(Self::Ior3), + 39 => Ok(Self::Ior4), + 40 => Ok(Self::Ior5), + 41 => Ok(Self::Ior6), + 42 => Ok(Self::Ior7), + 43 => Ok(Self::Ior10), + 44 => Ok(Self::Ior11), + 45 => Ok(Self::Ior12), + 46 => Ok(Self::Ior13), + _ => Err(val), + } + } +} + +/// Power Manager Wakeup Signals +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PowerManagerWakeUps { + PinmuxAonPinWkupReq = 0, + PinmuxAonUsbWkupReq = 1, + AonTimerAonWkupReq = 2, +} + +/// Reset Manager Software Controlled Resets +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum ResetManagerSwResets { + SpiDevice = 0, + SpiHost0 = 1, + Usb = 2, +} + +/// Power Manager Reset Request Signals +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum PowerManagerResetRequests { + AonTimerAonAonTimerRstReq = 0, +} + +/// Clock Manager Software-Controlled ("Gated") Clocks. +/// +/// The Software has full control over these clocks. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum GateableClocks { + /// Clock clk_io_div4_peri in group peri + IoDiv4Peri = 0, + /// Clock clk_io_div2_peri in group peri + IoDiv2Peri = 1, + /// Clock clk_io_peri in group peri + IoPeri = 2, + /// Clock clk_usb_peri in group peri + UsbPeri = 3, +} + +/// Clock Manager Software-Hinted Clocks. +/// +/// The Software has partial control over these clocks. It can ask them to stop, +/// but the clock manager is in control of whether the clock actually is stopped. +#[derive(Copy, Clone, PartialEq, Eq)] +#[repr(u32)] +pub enum HintableClocks { + /// Clock clk_main_aes in group trans + MainAes = 0, +} + +/// MMIO Region +/// +/// MMIO region excludes any memory that is separate from the module +/// configuration space, i.e. ROM, main SRAM, and flash are excluded but +/// retention SRAM, spi_device memory, or usbdev memory are included. +pub const TOP_ENGLISHBREAKFAST_MMIO_BASE_ADDR: usize = 0x40000000; +pub const TOP_ENGLISHBREAKFAST_MMIO_SIZE_BYTES: usize = 0x10000000; diff --git a/hw/top_englishbreakfast/sw/autogen/tests/plic_all_irqs_test.c b/hw/top_englishbreakfast/sw/autogen/tests/plic_all_irqs_test.c new file mode 100644 index 0000000000000..8bb99864109d7 --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/tests/plic_all_irqs_test.c @@ -0,0 +1,887 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// clang-format off +// +// ------------------- 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: +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson +// -o hw/top_englishbreakfast +#include + +// This test should avoid otp_ctrl interrupts in rom_ext, since the rom +// extension configures CSR accesses to OTP and AST to become illegal. +// +// This test is getting too big so we need to split it up. To do so, +// each peripheral is given an ID (according to their alphabetical order) +// and we define TEST_MIN_IRQ_PERIPHERAL and TEST_MAX_IRQ_PERIPHERAL to +// choose which ones are being tested. + +#ifndef TEST_MIN_IRQ_PERIPHERAL +#define TEST_MIN_IRQ_PERIPHERAL 0 +#endif + +#ifndef TEST_MAX_IRQ_PERIPHERAL +#define TEST_MAX_IRQ_PERIPHERAL 8 +#endif + +#include "sw/device/lib/arch/boot_stage.h" +#include "sw/device/lib/base/csr.h" +#include "sw/device/lib/base/mmio.h" +#include "sw/device/lib/dif/dif_aon_timer.h" +#include "sw/device/lib/dif/dif_flash_ctrl.h" +#include "sw/device/lib/dif/dif_gpio.h" +#include "sw/device/lib/dif/dif_pwrmgr.h" +#include "sw/device/lib/dif/dif_rv_plic.h" +#include "sw/device/lib/dif/dif_spi_device.h" +#include "sw/device/lib/dif/dif_spi_host.h" +#include "sw/device/lib/dif/dif_uart.h" +#include "sw/device/lib/dif/dif_usbdev.h" +#include "sw/device/lib/runtime/ibex.h" +#include "sw/device/lib/runtime/irq.h" +#include "sw/device/lib/runtime/log.h" +#include "sw/device/lib/testing/rv_plic_testutils.h" +#include "sw/device/lib/testing/test_framework/check.h" +#include "sw/device/lib/testing/test_framework/ottf_main.h" +#include "sw/device/lib/testing/test_framework/status.h" + +#include "hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.h" + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL +static dif_aon_timer_t aon_timer_aon; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL +static dif_flash_ctrl_t flash_ctrl; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL +static dif_gpio_t gpio; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL +static dif_pwrmgr_t pwrmgr_aon; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL +static dif_spi_device_t spi_device; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL +static dif_spi_host_t spi_host0; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL +static dif_uart_t uart0; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL +static dif_uart_t uart1; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL +static dif_usbdev_t usbdev; +#endif + +static dif_rv_plic_t plic; +static const top_englishbreakfast_plic_target_t kHart = kTopEnglishbreakfastPlicTargetIbex0; + +/** + * Flag indicating which peripheral is under test. + * + * Declared volatile because it is referenced in the main program flow as well + * as the ISR. + */ +static volatile top_englishbreakfast_plic_peripheral_t peripheral_expected; + +/** + * Flags indicating the IRQ expected to have triggered and serviced within the + * peripheral. + * + * Declared volatile because it is referenced in the main program flow as well + * as the ISR. + */ + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_aon_timer_irq_t aon_timer_irq_expected; +static volatile dif_aon_timer_irq_t aon_timer_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_flash_ctrl_irq_t flash_ctrl_irq_expected; +static volatile dif_flash_ctrl_irq_t flash_ctrl_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_gpio_irq_t gpio_irq_expected; +static volatile dif_gpio_irq_t gpio_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_pwrmgr_irq_t pwrmgr_irq_expected; +static volatile dif_pwrmgr_irq_t pwrmgr_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_spi_device_irq_t spi_device_irq_expected; +static volatile dif_spi_device_irq_t spi_device_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_spi_host_irq_t spi_host_irq_expected; +static volatile dif_spi_host_irq_t spi_host_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_uart_irq_t uart_irq_expected; +static volatile dif_uart_irq_t uart_irq_serviced; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL +static volatile dif_usbdev_irq_t usbdev_irq_expected; +static volatile dif_usbdev_irq_t usbdev_irq_serviced; +#endif + +/** + * Provides external IRQ handling for this test. + * + * This function overrides the default OTTF external ISR. + * + * For each IRQ, it performs the following: + * 1. Claims the IRQ fired (finds PLIC IRQ index). + * 2. Checks that the index belongs to the expected peripheral. + * 3. Checks that the correct and the only IRQ from the expected peripheral + * triggered. + * 4. Clears the IRQ at the peripheral. + * 5. Completes the IRQ service at PLIC. + */ +void ottf_external_isr(uint32_t *exc_info) { + dif_rv_plic_irq_id_t plic_irq_id; + CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic, kHart, &plic_irq_id)); + + top_englishbreakfast_plic_peripheral_t peripheral = (top_englishbreakfast_plic_peripheral_t) + top_englishbreakfast_plic_interrupt_for_peripheral[plic_irq_id]; + CHECK(peripheral == peripheral_expected, + "Interrupt from incorrect peripheral: exp = %d, obs = %d", + peripheral_expected, peripheral); + + switch (peripheral) { +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralAonTimerAon: { + dif_aon_timer_irq_t irq = + (dif_aon_timer_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdAonTimerAonWkupTimerExpired); + CHECK(irq == aon_timer_irq_expected, + "Incorrect aon_timer_aon IRQ triggered: exp = %d, obs = %d", + aon_timer_irq_expected, irq); + aon_timer_irq_serviced = irq; + + dif_aon_timer_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_aon_timer_irq_get_state(&aon_timer_aon, &snapshot)); + CHECK(snapshot == (dif_aon_timer_irq_state_snapshot_t)(1 << irq), + "Only aon_timer_aon IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_aon_timer_irq_acknowledge(&aon_timer_aon, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralFlashCtrl: { + dif_flash_ctrl_irq_t irq = + (dif_flash_ctrl_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdFlashCtrlProgEmpty); + CHECK(irq == flash_ctrl_irq_expected, + "Incorrect flash_ctrl IRQ triggered: exp = %d, obs = %d", + flash_ctrl_irq_expected, irq); + flash_ctrl_irq_serviced = irq; + + dif_flash_ctrl_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_flash_ctrl_irq_get_state(&flash_ctrl, &snapshot)); + CHECK(snapshot == (dif_flash_ctrl_irq_state_snapshot_t)((1 << irq) | 0x3), + "Expected flash_ctrl interrupt status %x. Actual interrupt " + "status = %x", + (1 << irq) | 0x3, snapshot); + + if (0xf & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_flash_ctrl_irq_force(&flash_ctrl, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x3 & (1 << irq))) { + CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(&flash_ctrl, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_flash_ctrl_irq_acknowledge(&flash_ctrl, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralGpio: { + dif_gpio_irq_t irq = + (dif_gpio_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdGpioGpio0); + CHECK(irq == gpio_irq_expected, + "Incorrect gpio IRQ triggered: exp = %d, obs = %d", + gpio_irq_expected, irq); + gpio_irq_serviced = irq; + + dif_gpio_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_gpio_irq_get_state(&gpio, &snapshot)); + CHECK(snapshot == (dif_gpio_irq_state_snapshot_t)(1 << irq), + "Only gpio IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_gpio_irq_acknowledge(&gpio, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralPwrmgrAon: { + dif_pwrmgr_irq_t irq = + (dif_pwrmgr_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdPwrmgrAonWakeup); + CHECK(irq == pwrmgr_irq_expected, + "Incorrect pwrmgr_aon IRQ triggered: exp = %d, obs = %d", + pwrmgr_irq_expected, irq); + pwrmgr_irq_serviced = irq; + + dif_pwrmgr_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_pwrmgr_irq_get_state(&pwrmgr_aon, &snapshot)); + CHECK(snapshot == (dif_pwrmgr_irq_state_snapshot_t)(1 << irq), + "Only pwrmgr_aon IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge(&pwrmgr_aon, irq)); + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralSpiDevice: { + dif_spi_device_irq_t irq = + (dif_spi_device_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty); + CHECK(irq == spi_device_irq_expected, + "Incorrect spi_device IRQ triggered: exp = %d, obs = %d", + spi_device_irq_expected, irq); + spi_device_irq_serviced = irq; + + dif_spi_device_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_spi_device_irq_get_state(&spi_device, &snapshot)); + CHECK(snapshot == (dif_spi_device_irq_state_snapshot_t)(1 << irq), + "Only spi_device IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x20 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_spi_device_irq_force(&spi_device, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_spi_device_irq_set_enabled(&spi_device, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_spi_device_irq_acknowledge(&spi_device, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralSpiHost0: { + dif_spi_host_irq_t irq = + (dif_spi_host_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdSpiHost0Error); + CHECK(irq == spi_host_irq_expected, + "Incorrect spi_host0 IRQ triggered: exp = %d, obs = %d", + spi_host_irq_expected, irq); + spi_host_irq_serviced = irq; + + dif_spi_host_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_spi_host_irq_get_state(&spi_host0, &snapshot)); + CHECK(snapshot == (dif_spi_host_irq_state_snapshot_t)(1 << irq), + "Only spi_host0 IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x2 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_spi_host_irq_force(&spi_host0, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_spi_host_irq_set_enabled(&spi_host0, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_spi_host_irq_acknowledge(&spi_host0, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralUart0: { + dif_uart_irq_t irq = + (dif_uart_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdUart0TxWatermark); + CHECK(irq == uart_irq_expected, + "Incorrect uart0 IRQ triggered: exp = %d, obs = %d", + uart_irq_expected, irq); + uart_irq_serviced = irq; + + dif_uart_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_uart_irq_get_state(&uart0, &snapshot)); + CHECK(snapshot == (dif_uart_irq_state_snapshot_t)((1 << irq) | 0x101), + "Expected uart0 interrupt status %x. Actual interrupt " + "status = %x", + (1 << irq) | 0x101, snapshot); + + if (0x103 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_uart_irq_force(&uart0, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x101 & (1 << irq))) { + CHECK_DIF_OK(dif_uart_irq_set_enabled(&uart0, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_uart_irq_acknowledge(&uart0, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralUart1: { + dif_uart_irq_t irq = + (dif_uart_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdUart1TxWatermark); + CHECK(irq == uart_irq_expected, + "Incorrect uart1 IRQ triggered: exp = %d, obs = %d", + uart_irq_expected, irq); + uart_irq_serviced = irq; + + dif_uart_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_uart_irq_get_state(&uart1, &snapshot)); + CHECK(snapshot == (dif_uart_irq_state_snapshot_t)((1 << irq) | 0x101), + "Expected uart1 interrupt status %x. Actual interrupt " + "status = %x", + (1 << irq) | 0x101, snapshot); + + if (0x103 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_uart_irq_force(&uart1, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x101 & (1 << irq))) { + CHECK_DIF_OK(dif_uart_irq_set_enabled(&uart1, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_uart_irq_acknowledge(&uart1, irq)); + } + break; + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + case kTopEnglishbreakfastPlicPeripheralUsbdev: { + dif_usbdev_irq_t irq = + (dif_usbdev_irq_t)(plic_irq_id - + (dif_rv_plic_irq_id_t) + kTopEnglishbreakfastPlicIrqIdUsbdevPktReceived); + CHECK(irq == usbdev_irq_expected, + "Incorrect usbdev IRQ triggered: exp = %d, obs = %d", + usbdev_irq_expected, irq); + usbdev_irq_serviced = irq; + + dif_usbdev_irq_state_snapshot_t snapshot; + CHECK_DIF_OK(dif_usbdev_irq_get_state(&usbdev, &snapshot)); + CHECK(snapshot == (dif_usbdev_irq_state_snapshot_t)(1 << irq), + "Only usbdev IRQ %d expected to fire. Actual interrupt " + "status = %x", + irq, snapshot); + + if (0x20183 & (1 << irq)) { + // We do not acknowledge status type interrupt at the IP side, but we + // need to clear the test force register. + CHECK_DIF_OK(dif_usbdev_irq_force(&usbdev, irq, false)); + // In case this status interrupt is asserted by default, we also + // disable it at this point so that it does not interfere with the + // rest of the test. + if ((0x0 & (1 << irq))) { + CHECK_DIF_OK(dif_usbdev_irq_set_enabled(&usbdev, irq, false)); + } + } else { + // We acknowledge event type interrupt. + CHECK_DIF_OK(dif_usbdev_irq_acknowledge(&usbdev, irq)); + } + break; + } +#endif + + default: + LOG_FATAL("ISR is not implemented!"); + test_status_set(kTestStatusFailed); + } + // Complete the IRQ at PLIC. + CHECK_DIF_OK(dif_rv_plic_irq_complete(&plic, kHart, plic_irq_id)); +} + +/** + * Initializes the handles to all peripherals. + */ +static void peripherals_init(void) { + mmio_region_t base_addr; + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR); + CHECK_DIF_OK(dif_aon_timer_init(base_addr, &aon_timer_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR); + CHECK_DIF_OK(dif_flash_ctrl_init(base_addr, &flash_ctrl)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR); + CHECK_DIF_OK(dif_gpio_init(base_addr, &gpio)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR); + CHECK_DIF_OK(dif_pwrmgr_init(base_addr, &pwrmgr_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR); + CHECK_DIF_OK(dif_spi_device_init(base_addr, &spi_device)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR); + CHECK_DIF_OK(dif_spi_host_init(base_addr, &spi_host0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR); + CHECK_DIF_OK(dif_uart_init(base_addr, &uart0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR); + CHECK_DIF_OK(dif_uart_init(base_addr, &uart1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR); + CHECK_DIF_OK(dif_usbdev_init(base_addr, &usbdev)); +#endif + + base_addr = mmio_region_from_addr(TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR); + CHECK_DIF_OK(dif_rv_plic_init(base_addr, &plic)); +} + +/** + * Clears pending IRQs in all peripherals. + */ +static void peripheral_irqs_clear(void) { +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_aon_timer_irq_acknowledge_all(&aon_timer_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_flash_ctrl_irq_acknowledge_all(&flash_ctrl)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_gpio_irq_acknowledge_all(&gpio)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge_all(&pwrmgr_aon)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_device_irq_acknowledge_all(&spi_device)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_host_irq_acknowledge_all(&spi_host0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_uart_irq_acknowledge_all(&uart0)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_uart_irq_acknowledge_all(&uart1)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_usbdev_irq_acknowledge_all(&usbdev)); +#endif +} + +/** + * Enables all IRQs in all peripherals. + */ +static void peripheral_irqs_enable(void) { +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + // Note: this peripheral contains status interrupts that are asserted by + // default. Therefore, not all interrupts are enabled here, since that + // would interfere with this test. Instead, these interrupts are enabled on + // demand once they are being tested. + dif_flash_ctrl_irq_state_snapshot_t flash_ctrl_irqs = + (dif_flash_ctrl_irq_state_snapshot_t)0xfffffffc; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + dif_gpio_irq_state_snapshot_t gpio_irqs = + (dif_gpio_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + dif_pwrmgr_irq_state_snapshot_t pwrmgr_irqs = + (dif_pwrmgr_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + dif_spi_device_irq_state_snapshot_t spi_device_irqs = + (dif_spi_device_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + dif_spi_host_irq_state_snapshot_t spi_host_irqs = + (dif_spi_host_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + // Note: this peripheral contains status interrupts that are asserted by + // default. Therefore, not all interrupts are enabled here, since that + // would interfere with this test. Instead, these interrupts are enabled on + // demand once they are being tested. + dif_uart_irq_state_snapshot_t uart_irqs = + (dif_uart_irq_state_snapshot_t)0xfffffefe; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + dif_usbdev_irq_state_snapshot_t usbdev_irqs = + (dif_usbdev_irq_state_snapshot_t)0xffffffff; +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_flash_ctrl_irq_restore_all(&flash_ctrl, &flash_ctrl_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_gpio_irq_restore_all(&gpio, &gpio_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_pwrmgr_irq_restore_all(&pwrmgr_aon, &pwrmgr_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_device_irq_restore_all(&spi_device, &spi_device_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_spi_host_irq_restore_all(&spi_host0, &spi_host_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + // lowrisc/opentitan#8656: Skip UART0 in non-DV setups due to interference + // from the logging facility. + if (kDeviceType == kDeviceSimDV) { + CHECK_DIF_OK(dif_uart_irq_restore_all(&uart0, &uart_irqs)); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_uart_irq_restore_all(&uart1, &uart_irqs)); +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + CHECK_DIF_OK(dif_usbdev_irq_restore_all(&usbdev, &usbdev_irqs)); +#endif +} + +/** + * Triggers all IRQs in all peripherals one by one. + * + * Walks through all instances of all peripherals and triggers an interrupt one + * by one, by forcing with the `intr_test` CSR. On trigger, the CPU instantly + * jumps into the ISR. The main flow of execution thus proceeds to check that + * the correct IRQ was serviced immediately. The ISR, in turn checks if the + * expected IRQ from the expected peripheral triggered. + */ +static void peripheral_irqs_trigger(void) { + unsigned int status_default_mask; + // Depending on the build configuration, this variable may show up as unused + // in the clang linter. This statement waives that error. + (void)status_default_mask; + +#if TEST_MIN_IRQ_PERIPHERAL <= 0 && 0 < TEST_MAX_IRQ_PERIPHERAL + // lowrisc/opentitan#8656: Skip UART0 in non-DV setups due to interference + // from the logging facility. + // aon_timer may generate a NMI instead of a PLIC IRQ depending on the ROM. + // Since there are other tests covering this already, we just skip this for + // non-DV setups. + if (kDeviceType == kDeviceSimDV) { + peripheral_expected = kTopEnglishbreakfastPlicPeripheralAonTimerAon; + for (dif_aon_timer_irq_t irq = kDifAonTimerIrqWkupTimerExpired; irq <= kDifAonTimerIrqWdogTimerBark; + ++irq) { + aon_timer_irq_expected = irq; + LOG_INFO("Triggering aon_timer_aon IRQ %d.", irq); + CHECK_DIF_OK(dif_aon_timer_irq_force(&aon_timer_aon, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(aon_timer_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from aon_timer_aon is serviced.", irq); + } + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 1 && 1 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopEnglishbreakfastPlicPeripheralFlashCtrl; + status_default_mask = 0x3; + for (dif_flash_ctrl_irq_t irq = kDifFlashCtrlIrqProgEmpty; irq <= kDifFlashCtrlIrqCorrErr; + ++irq) { + flash_ctrl_irq_expected = irq; + LOG_INFO("Triggering flash_ctrl IRQ %d.", irq); + CHECK_DIF_OK(dif_flash_ctrl_irq_force(&flash_ctrl, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_flash_ctrl_irq_set_enabled(&flash_ctrl, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(flash_ctrl_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from flash_ctrl is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 2 && 2 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopEnglishbreakfastPlicPeripheralGpio; + for (dif_gpio_irq_t irq = kDifGpioIrqGpio0; irq <= kDifGpioIrqGpio31; + ++irq) { + gpio_irq_expected = irq; + LOG_INFO("Triggering gpio IRQ %d.", irq); + CHECK_DIF_OK(dif_gpio_irq_force(&gpio, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(gpio_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from gpio is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 3 && 3 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopEnglishbreakfastPlicPeripheralPwrmgrAon; + for (dif_pwrmgr_irq_t irq = kDifPwrmgrIrqWakeup; irq <= kDifPwrmgrIrqWakeup; + ++irq) { + pwrmgr_irq_expected = irq; + LOG_INFO("Triggering pwrmgr_aon IRQ %d.", irq); + CHECK_DIF_OK(dif_pwrmgr_irq_force(&pwrmgr_aon, irq, true)); + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(pwrmgr_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from pwrmgr_aon is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 4 && 4 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopEnglishbreakfastPlicPeripheralSpiDevice; + status_default_mask = 0x0; + for (dif_spi_device_irq_t irq = kDifSpiDeviceIrqUploadCmdfifoNotEmpty; irq <= kDifSpiDeviceIrqTpmRdfifoDrop; + ++irq) { + spi_device_irq_expected = irq; + LOG_INFO("Triggering spi_device IRQ %d.", irq); + CHECK_DIF_OK(dif_spi_device_irq_force(&spi_device, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_spi_device_irq_set_enabled(&spi_device, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(spi_device_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from spi_device is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 5 && 5 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopEnglishbreakfastPlicPeripheralSpiHost0; + status_default_mask = 0x0; + for (dif_spi_host_irq_t irq = kDifSpiHostIrqError; irq <= kDifSpiHostIrqSpiEvent; + ++irq) { + spi_host_irq_expected = irq; + LOG_INFO("Triggering spi_host0 IRQ %d.", irq); + CHECK_DIF_OK(dif_spi_host_irq_force(&spi_host0, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_spi_host_irq_set_enabled(&spi_host0, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(spi_host_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from spi_host0 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + // lowrisc/opentitan#8656: Skip UART0 in non-DV setups due to interference + // from the logging facility. + // aon_timer may generate a NMI instead of a PLIC IRQ depending on the ROM. + // Since there are other tests covering this already, we just skip this for + // non-DV setups. + if (kDeviceType == kDeviceSimDV) { + peripheral_expected = kTopEnglishbreakfastPlicPeripheralUart0; + status_default_mask = 0x101; + for (dif_uart_irq_t irq = kDifUartIrqTxWatermark; irq <= kDifUartIrqTxEmpty; + ++irq) { + uart_irq_expected = irq; + LOG_INFO("Triggering uart0 IRQ %d.", irq); + CHECK_DIF_OK(dif_uart_irq_force(&uart0, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_uart_irq_set_enabled(&uart0, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(uart_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from uart0 is serviced.", irq); + } + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 6 && 6 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopEnglishbreakfastPlicPeripheralUart1; + status_default_mask = 0x101; + for (dif_uart_irq_t irq = kDifUartIrqTxWatermark; irq <= kDifUartIrqTxEmpty; + ++irq) { + uart_irq_expected = irq; + LOG_INFO("Triggering uart1 IRQ %d.", irq); + CHECK_DIF_OK(dif_uart_irq_force(&uart1, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_uart_irq_set_enabled(&uart1, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(uart_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from uart1 is serviced.", irq); + } +#endif + +#if TEST_MIN_IRQ_PERIPHERAL <= 7 && 7 < TEST_MAX_IRQ_PERIPHERAL + peripheral_expected = kTopEnglishbreakfastPlicPeripheralUsbdev; + status_default_mask = 0x0; + for (dif_usbdev_irq_t irq = kDifUsbdevIrqPktReceived; irq <= kDifUsbdevIrqAvSetupEmpty; + ++irq) { + usbdev_irq_expected = irq; + LOG_INFO("Triggering usbdev IRQ %d.", irq); + CHECK_DIF_OK(dif_usbdev_irq_force(&usbdev, irq, true)); + + // In this case, the interrupt has not been enabled yet because that would + // interfere with testing other interrupts. We enable it here and let the + // interrupt handler disable it again. + if ((status_default_mask & 0x1)) { + CHECK_DIF_OK(dif_usbdev_irq_set_enabled(&usbdev, irq, true)); + } + status_default_mask >>= 1; + + // This avoids a race where *irq_serviced is read before + // entering the ISR. + IBEX_SPIN_FOR(usbdev_irq_serviced == irq, 1); + LOG_INFO("IRQ %d from usbdev is serviced.", irq); + } +#endif +} + +/** + * Checks that the target ID corresponds to the ID of the hart on which + * this test is executed on. This check is meant to be used in a + * single-hart system only. + */ +static void check_hart_id(uint32_t exp_hart_id) { + uint32_t act_hart_id; + CSR_READ(CSR_REG_MHARTID, &act_hart_id); + CHECK(act_hart_id == exp_hart_id, "Processor has unexpected HART ID."); +} + +OTTF_DEFINE_TEST_CONFIG(); + +bool test_main(void) { + irq_global_ctrl(true); + irq_external_ctrl(true); + peripherals_init(); + check_hart_id((uint32_t)kHart); + rv_plic_testutils_irq_range_enable( + &plic, kHart, kTopEnglishbreakfastPlicIrqIdNone + 1, kTopEnglishbreakfastPlicIrqIdLast); + peripheral_irqs_clear(); + peripheral_irqs_enable(); + peripheral_irqs_trigger(); + return true; +} + +// clang-format on diff --git a/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.c b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.c new file mode 100644 index 0000000000000..6b287456331f9 --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.c @@ -0,0 +1,108 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson +// -o hw/top_englishbreakfast + +#include "hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.h" + +/** + * PLIC Interrupt Source to Peripheral Map + * + * This array is a mapping from `top_englishbreakfast_plic_irq_id_t` to + * `top_englishbreakfast_plic_peripheral_t`. + */ +const top_englishbreakfast_plic_peripheral_t + top_englishbreakfast_plic_interrupt_for_peripheral[88] = { + [kTopEnglishbreakfastPlicIrqIdNone] = kTopEnglishbreakfastPlicPeripheralUnknown, + [kTopEnglishbreakfastPlicIrqIdUart0TxWatermark] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0RxWatermark] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0TxDone] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0RxOverflow] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0RxFrameErr] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0RxBreakErr] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0RxTimeout] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0RxParityErr] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart0TxEmpty] = kTopEnglishbreakfastPlicPeripheralUart0, + [kTopEnglishbreakfastPlicIrqIdUart1TxWatermark] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1RxWatermark] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1TxDone] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1RxOverflow] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1RxFrameErr] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1RxBreakErr] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1RxTimeout] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1RxParityErr] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdUart1TxEmpty] = kTopEnglishbreakfastPlicPeripheralUart1, + [kTopEnglishbreakfastPlicIrqIdGpioGpio0] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio1] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio2] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio3] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio4] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio5] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio6] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio7] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio8] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio9] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio10] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio11] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio12] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio13] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio14] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio15] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio16] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio17] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio18] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio19] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio20] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio21] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio22] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio23] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio24] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio25] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio26] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio27] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio28] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio29] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio30] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdGpioGpio31] = kTopEnglishbreakfastPlicPeripheralGpio, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceUploadPayloadNotEmpty] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceUploadPayloadOverflow] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceReadbufWatermark] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceReadbufFlip] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceTpmHeaderNotEmpty] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceTpmRdfifoCmdEnd] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiDeviceTpmRdfifoDrop] = kTopEnglishbreakfastPlicPeripheralSpiDevice, + [kTopEnglishbreakfastPlicIrqIdSpiHost0Error] = kTopEnglishbreakfastPlicPeripheralSpiHost0, + [kTopEnglishbreakfastPlicIrqIdSpiHost0SpiEvent] = kTopEnglishbreakfastPlicPeripheralSpiHost0, + [kTopEnglishbreakfastPlicIrqIdUsbdevPktReceived] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevPktSent] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevDisconnected] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevHostLost] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevLinkReset] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevLinkSuspend] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevLinkResume] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevAvOutEmpty] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevRxFull] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevAvOverflow] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevLinkInErr] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevRxCrcErr] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevRxPidErr] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevRxBitstuffErr] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevFrame] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevPowered] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevLinkOutErr] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdUsbdevAvSetupEmpty] = kTopEnglishbreakfastPlicPeripheralUsbdev, + [kTopEnglishbreakfastPlicIrqIdPwrmgrAonWakeup] = kTopEnglishbreakfastPlicPeripheralPwrmgrAon, + [kTopEnglishbreakfastPlicIrqIdAonTimerAonWkupTimerExpired] = kTopEnglishbreakfastPlicPeripheralAonTimerAon, + [kTopEnglishbreakfastPlicIrqIdAonTimerAonWdogTimerBark] = kTopEnglishbreakfastPlicPeripheralAonTimerAon, + [kTopEnglishbreakfastPlicIrqIdFlashCtrlProgEmpty] = kTopEnglishbreakfastPlicPeripheralFlashCtrl, + [kTopEnglishbreakfastPlicIrqIdFlashCtrlProgLvl] = kTopEnglishbreakfastPlicPeripheralFlashCtrl, + [kTopEnglishbreakfastPlicIrqIdFlashCtrlRdFull] = kTopEnglishbreakfastPlicPeripheralFlashCtrl, + [kTopEnglishbreakfastPlicIrqIdFlashCtrlRdLvl] = kTopEnglishbreakfastPlicPeripheralFlashCtrl, + [kTopEnglishbreakfastPlicIrqIdFlashCtrlOpDone] = kTopEnglishbreakfastPlicPeripheralFlashCtrl, + [kTopEnglishbreakfastPlicIrqIdFlashCtrlCorrErr] = kTopEnglishbreakfastPlicPeripheralFlashCtrl, +}; diff --git a/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.h b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.h new file mode 100644 index 0000000000000..7b78346b0855e --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast.h @@ -0,0 +1,967 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson +// -o hw/top_englishbreakfast + +#ifndef OPENTITAN_HW_TOP_ENGLISHBREAKFAST_SW_AUTOGEN_TOP_ENGLISHBREAKFAST_H_ +#define OPENTITAN_HW_TOP_ENGLISHBREAKFAST_SW_AUTOGEN_TOP_ENGLISHBREAKFAST_H_ + +/** + * @file + * @brief Top-specific Definitions + * + * This file contains preprocessor and type definitions for use within the + * device C/C++ codebase. + * + * These definitions are for information that depends on the top-specific chip + * configuration, which includes: + * - Device Memory Information (for Peripherals and Memory) + * - PLIC Interrupt ID Names and Source Mappings + * - Pinmux Pin/Select Names + * - Power Manager Wakeups + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Peripheral base address for uart0 in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR 0x40000000u + +/** + * Peripheral size for uart0 in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR + TOP_ENGLISHBREAKFAST_UART0_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_UART0_SIZE_BYTES 0x40u + +/** + * Peripheral base address for uart1 in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR 0x40010000u + +/** + * Peripheral size for uart1 in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR + TOP_ENGLISHBREAKFAST_UART1_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_UART1_SIZE_BYTES 0x40u + +/** + * Peripheral base address for gpio in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR 0x40040000u + +/** + * Peripheral size for gpio in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR + TOP_ENGLISHBREAKFAST_GPIO_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_GPIO_SIZE_BYTES 0x80u + +/** + * Peripheral base address for spi_device in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR 0x40050000u + +/** + * Peripheral size for spi_device in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR + TOP_ENGLISHBREAKFAST_SPI_DEVICE_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SPI_DEVICE_SIZE_BYTES 0x2000u + +/** + * Peripheral base address for spi_host0 in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR 0x40060000u + +/** + * Peripheral size for spi_host0 in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR + TOP_ENGLISHBREAKFAST_SPI_HOST0_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SPI_HOST0_SIZE_BYTES 0x40u + +/** + * Peripheral base address for rv_timer in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RV_TIMER_BASE_ADDR 0x40100000u + +/** + * Peripheral size for rv_timer in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RV_TIMER_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RV_TIMER_BASE_ADDR + TOP_ENGLISHBREAKFAST_RV_TIMER_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RV_TIMER_SIZE_BYTES 0x200u + +/** + * Peripheral base address for usbdev in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR 0x40320000u + +/** + * Peripheral size for usbdev in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR + TOP_ENGLISHBREAKFAST_USBDEV_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_USBDEV_SIZE_BYTES 0x1000u + +/** + * Peripheral base address for pwrmgr_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR 0x40400000u + +/** + * Peripheral size for pwrmgr_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_PWRMGR_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_PWRMGR_AON_SIZE_BYTES 0x80u + +/** + * Peripheral base address for rstmgr_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RSTMGR_AON_BASE_ADDR 0x40410000u + +/** + * Peripheral size for rstmgr_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RSTMGR_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RSTMGR_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_RSTMGR_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RSTMGR_AON_SIZE_BYTES 0x80u + +/** + * Peripheral base address for clkmgr_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_CLKMGR_AON_BASE_ADDR 0x40420000u + +/** + * Peripheral size for clkmgr_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_CLKMGR_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_CLKMGR_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_CLKMGR_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_CLKMGR_AON_SIZE_BYTES 0x80u + +/** + * Peripheral base address for pinmux_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_PINMUX_AON_BASE_ADDR 0x40460000u + +/** + * Peripheral size for pinmux_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_PINMUX_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_PINMUX_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_PINMUX_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_PINMUX_AON_SIZE_BYTES 0x1000u + +/** + * Peripheral base address for aon_timer_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR 0x40470000u + +/** + * Peripheral size for aon_timer_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_AON_TIMER_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_AON_TIMER_AON_SIZE_BYTES 0x40u + +/** + * Peripheral base address for ast in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_AST_BASE_ADDR 0x40480000u + +/** + * Peripheral size for ast in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_AST_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_AST_BASE_ADDR + TOP_ENGLISHBREAKFAST_AST_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_AST_SIZE_BYTES 0x400u + +/** + * Peripheral base address for core device on flash_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR 0x41000000u + +/** + * Peripheral size for core device on flash_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR + TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_SIZE_BYTES 0x200u + +/** + * Peripheral base address for prim device on flash_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_BASE_ADDR 0x41008000u + +/** + * Peripheral size for prim device on flash_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_BASE_ADDR + TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_SIZE_BYTES 0x80u + +/** + * Peripheral base address for mem device on flash_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_BASE_ADDR 0x20000000u + +/** + * Peripheral size for mem device on flash_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_BASE_ADDR + TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_SIZE_BYTES 0x10000u + +/** + * Peripheral base address for rv_plic in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR 0x48000000u + +/** + * Peripheral size for rv_plic in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR + TOP_ENGLISHBREAKFAST_RV_PLIC_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RV_PLIC_SIZE_BYTES 0x8000000u + +/** + * Peripheral base address for aes in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_AES_BASE_ADDR 0x41100000u + +/** + * Peripheral size for aes in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_AES_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_AES_BASE_ADDR + TOP_ENGLISHBREAKFAST_AES_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_AES_SIZE_BYTES 0x100u + +/** + * Peripheral base address for regs device on sram_ctrl_main in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_BASE_ADDR 0x411C0000u + +/** + * Peripheral size for regs device on sram_ctrl_main in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_BASE_ADDR + TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_SIZE_BYTES 0x40u + +/** + * Peripheral base address for ram device on sram_ctrl_main in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_BASE_ADDR 0x10000000u + +/** + * Peripheral size for ram device on sram_ctrl_main in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_BASE_ADDR + TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_SIZE_BYTES 0x20000u + +/** + * Peripheral base address for regs device on rom_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_BASE_ADDR 0x411E0000u + +/** + * Peripheral size for regs device on rom_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_BASE_ADDR + TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_SIZE_BYTES 0x80u + +/** + * Peripheral base address for rom device on rom_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_BASE_ADDR 0x8000u + +/** + * Peripheral size for rom device on rom_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_BASE_ADDR + TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_SIZE_BYTES 0x8000u + +/** + * Peripheral base address for cfg device on rv_core_ibex in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_BASE_ADDR 0x411F0000u + +/** + * Peripheral size for cfg device on rv_core_ibex in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_BASE_ADDR + TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_SIZE_BYTES 0x100u + + +/** + * Memory base address for eflash in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_EFLASH_BASE_ADDR 0x20000000u + +/** + * Memory size for eflash in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_EFLASH_SIZE_BYTES 0x10000u + +/** + * Memory base address for ram_main in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_RAM_MAIN_BASE_ADDR 0x10000000u + +/** + * Memory size for ram_main in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_RAM_MAIN_SIZE_BYTES 0x20000u + +/** + * Memory base address for rom in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_ROM_BASE_ADDR 0x8000u + +/** + * Memory size for rom in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_ROM_SIZE_BYTES 0x8000u + + +/** + * PLIC Interrupt Source Peripheral. + * + * Enumeration used to determine which peripheral asserted the corresponding + * interrupt. + */ +typedef enum top_englishbreakfast_plic_peripheral { + kTopEnglishbreakfastPlicPeripheralUnknown = 0, /**< Unknown Peripheral */ + kTopEnglishbreakfastPlicPeripheralUart0 = 1, /**< uart0 */ + kTopEnglishbreakfastPlicPeripheralUart1 = 2, /**< uart1 */ + kTopEnglishbreakfastPlicPeripheralGpio = 3, /**< gpio */ + kTopEnglishbreakfastPlicPeripheralSpiDevice = 4, /**< spi_device */ + kTopEnglishbreakfastPlicPeripheralSpiHost0 = 5, /**< spi_host0 */ + kTopEnglishbreakfastPlicPeripheralUsbdev = 6, /**< usbdev */ + kTopEnglishbreakfastPlicPeripheralPwrmgrAon = 7, /**< pwrmgr_aon */ + kTopEnglishbreakfastPlicPeripheralAonTimerAon = 8, /**< aon_timer_aon */ + kTopEnglishbreakfastPlicPeripheralFlashCtrl = 9, /**< flash_ctrl */ + kTopEnglishbreakfastPlicPeripheralLast = 9, /**< \internal Final PLIC peripheral */ +} top_englishbreakfast_plic_peripheral_t; + +/** + * PLIC Interrupt Source. + * + * Enumeration of all PLIC interrupt sources. The interrupt sources belonging to + * the same peripheral are guaranteed to be consecutive. + */ +typedef enum top_englishbreakfast_plic_irq_id { + kTopEnglishbreakfastPlicIrqIdNone = 0, /**< No Interrupt */ + kTopEnglishbreakfastPlicIrqIdUart0TxWatermark = 1, /**< uart0_tx_watermark */ + kTopEnglishbreakfastPlicIrqIdUart0RxWatermark = 2, /**< uart0_rx_watermark */ + kTopEnglishbreakfastPlicIrqIdUart0TxDone = 3, /**< uart0_tx_done */ + kTopEnglishbreakfastPlicIrqIdUart0RxOverflow = 4, /**< uart0_rx_overflow */ + kTopEnglishbreakfastPlicIrqIdUart0RxFrameErr = 5, /**< uart0_rx_frame_err */ + kTopEnglishbreakfastPlicIrqIdUart0RxBreakErr = 6, /**< uart0_rx_break_err */ + kTopEnglishbreakfastPlicIrqIdUart0RxTimeout = 7, /**< uart0_rx_timeout */ + kTopEnglishbreakfastPlicIrqIdUart0RxParityErr = 8, /**< uart0_rx_parity_err */ + kTopEnglishbreakfastPlicIrqIdUart0TxEmpty = 9, /**< uart0_tx_empty */ + kTopEnglishbreakfastPlicIrqIdUart1TxWatermark = 10, /**< uart1_tx_watermark */ + kTopEnglishbreakfastPlicIrqIdUart1RxWatermark = 11, /**< uart1_rx_watermark */ + kTopEnglishbreakfastPlicIrqIdUart1TxDone = 12, /**< uart1_tx_done */ + kTopEnglishbreakfastPlicIrqIdUart1RxOverflow = 13, /**< uart1_rx_overflow */ + kTopEnglishbreakfastPlicIrqIdUart1RxFrameErr = 14, /**< uart1_rx_frame_err */ + kTopEnglishbreakfastPlicIrqIdUart1RxBreakErr = 15, /**< uart1_rx_break_err */ + kTopEnglishbreakfastPlicIrqIdUart1RxTimeout = 16, /**< uart1_rx_timeout */ + kTopEnglishbreakfastPlicIrqIdUart1RxParityErr = 17, /**< uart1_rx_parity_err */ + kTopEnglishbreakfastPlicIrqIdUart1TxEmpty = 18, /**< uart1_tx_empty */ + kTopEnglishbreakfastPlicIrqIdGpioGpio0 = 19, /**< gpio_gpio 0 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio1 = 20, /**< gpio_gpio 1 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio2 = 21, /**< gpio_gpio 2 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio3 = 22, /**< gpio_gpio 3 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio4 = 23, /**< gpio_gpio 4 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio5 = 24, /**< gpio_gpio 5 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio6 = 25, /**< gpio_gpio 6 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio7 = 26, /**< gpio_gpio 7 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio8 = 27, /**< gpio_gpio 8 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio9 = 28, /**< gpio_gpio 9 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio10 = 29, /**< gpio_gpio 10 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio11 = 30, /**< gpio_gpio 11 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio12 = 31, /**< gpio_gpio 12 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio13 = 32, /**< gpio_gpio 13 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio14 = 33, /**< gpio_gpio 14 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio15 = 34, /**< gpio_gpio 15 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio16 = 35, /**< gpio_gpio 16 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio17 = 36, /**< gpio_gpio 17 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio18 = 37, /**< gpio_gpio 18 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio19 = 38, /**< gpio_gpio 19 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio20 = 39, /**< gpio_gpio 20 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio21 = 40, /**< gpio_gpio 21 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio22 = 41, /**< gpio_gpio 22 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio23 = 42, /**< gpio_gpio 23 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio24 = 43, /**< gpio_gpio 24 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio25 = 44, /**< gpio_gpio 25 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio26 = 45, /**< gpio_gpio 26 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio27 = 46, /**< gpio_gpio 27 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio28 = 47, /**< gpio_gpio 28 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio29 = 48, /**< gpio_gpio 29 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio30 = 49, /**< gpio_gpio 30 */ + kTopEnglishbreakfastPlicIrqIdGpioGpio31 = 50, /**< gpio_gpio 31 */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceUploadCmdfifoNotEmpty = 51, /**< spi_device_upload_cmdfifo_not_empty */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceUploadPayloadNotEmpty = 52, /**< spi_device_upload_payload_not_empty */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceUploadPayloadOverflow = 53, /**< spi_device_upload_payload_overflow */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceReadbufWatermark = 54, /**< spi_device_readbuf_watermark */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceReadbufFlip = 55, /**< spi_device_readbuf_flip */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceTpmHeaderNotEmpty = 56, /**< spi_device_tpm_header_not_empty */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceTpmRdfifoCmdEnd = 57, /**< spi_device_tpm_rdfifo_cmd_end */ + kTopEnglishbreakfastPlicIrqIdSpiDeviceTpmRdfifoDrop = 58, /**< spi_device_tpm_rdfifo_drop */ + kTopEnglishbreakfastPlicIrqIdSpiHost0Error = 59, /**< spi_host0_error */ + kTopEnglishbreakfastPlicIrqIdSpiHost0SpiEvent = 60, /**< spi_host0_spi_event */ + kTopEnglishbreakfastPlicIrqIdUsbdevPktReceived = 61, /**< usbdev_pkt_received */ + kTopEnglishbreakfastPlicIrqIdUsbdevPktSent = 62, /**< usbdev_pkt_sent */ + kTopEnglishbreakfastPlicIrqIdUsbdevDisconnected = 63, /**< usbdev_disconnected */ + kTopEnglishbreakfastPlicIrqIdUsbdevHostLost = 64, /**< usbdev_host_lost */ + kTopEnglishbreakfastPlicIrqIdUsbdevLinkReset = 65, /**< usbdev_link_reset */ + kTopEnglishbreakfastPlicIrqIdUsbdevLinkSuspend = 66, /**< usbdev_link_suspend */ + kTopEnglishbreakfastPlicIrqIdUsbdevLinkResume = 67, /**< usbdev_link_resume */ + kTopEnglishbreakfastPlicIrqIdUsbdevAvOutEmpty = 68, /**< usbdev_av_out_empty */ + kTopEnglishbreakfastPlicIrqIdUsbdevRxFull = 69, /**< usbdev_rx_full */ + kTopEnglishbreakfastPlicIrqIdUsbdevAvOverflow = 70, /**< usbdev_av_overflow */ + kTopEnglishbreakfastPlicIrqIdUsbdevLinkInErr = 71, /**< usbdev_link_in_err */ + kTopEnglishbreakfastPlicIrqIdUsbdevRxCrcErr = 72, /**< usbdev_rx_crc_err */ + kTopEnglishbreakfastPlicIrqIdUsbdevRxPidErr = 73, /**< usbdev_rx_pid_err */ + kTopEnglishbreakfastPlicIrqIdUsbdevRxBitstuffErr = 74, /**< usbdev_rx_bitstuff_err */ + kTopEnglishbreakfastPlicIrqIdUsbdevFrame = 75, /**< usbdev_frame */ + kTopEnglishbreakfastPlicIrqIdUsbdevPowered = 76, /**< usbdev_powered */ + kTopEnglishbreakfastPlicIrqIdUsbdevLinkOutErr = 77, /**< usbdev_link_out_err */ + kTopEnglishbreakfastPlicIrqIdUsbdevAvSetupEmpty = 78, /**< usbdev_av_setup_empty */ + kTopEnglishbreakfastPlicIrqIdPwrmgrAonWakeup = 79, /**< pwrmgr_aon_wakeup */ + kTopEnglishbreakfastPlicIrqIdAonTimerAonWkupTimerExpired = 80, /**< aon_timer_aon_wkup_timer_expired */ + kTopEnglishbreakfastPlicIrqIdAonTimerAonWdogTimerBark = 81, /**< aon_timer_aon_wdog_timer_bark */ + kTopEnglishbreakfastPlicIrqIdFlashCtrlProgEmpty = 82, /**< flash_ctrl_prog_empty */ + kTopEnglishbreakfastPlicIrqIdFlashCtrlProgLvl = 83, /**< flash_ctrl_prog_lvl */ + kTopEnglishbreakfastPlicIrqIdFlashCtrlRdFull = 84, /**< flash_ctrl_rd_full */ + kTopEnglishbreakfastPlicIrqIdFlashCtrlRdLvl = 85, /**< flash_ctrl_rd_lvl */ + kTopEnglishbreakfastPlicIrqIdFlashCtrlOpDone = 86, /**< flash_ctrl_op_done */ + kTopEnglishbreakfastPlicIrqIdFlashCtrlCorrErr = 87, /**< flash_ctrl_corr_err */ + kTopEnglishbreakfastPlicIrqIdLast = 87, /**< \internal The Last Valid Interrupt ID. */ +} top_englishbreakfast_plic_irq_id_t; + +/** + * PLIC Interrupt Source to Peripheral Map + * + * This array is a mapping from `top_englishbreakfast_plic_irq_id_t` to + * `top_englishbreakfast_plic_peripheral_t`. + */ +extern const top_englishbreakfast_plic_peripheral_t + top_englishbreakfast_plic_interrupt_for_peripheral[88]; + +/** + * PLIC Interrupt Target. + * + * Enumeration used to determine which set of IE, CC, threshold registers to + * access for a given interrupt target. + */ +typedef enum top_englishbreakfast_plic_target { + kTopEnglishbreakfastPlicTargetIbex0 = 0, /**< Ibex Core 0 */ + kTopEnglishbreakfastPlicTargetLast = 0, /**< \internal Final PLIC target */ +} top_englishbreakfast_plic_target_t; + +#define PINMUX_MIO_PERIPH_INSEL_IDX_OFFSET 2 + +// PERIPH_INSEL ranges from 0 to NUM_MIO_PADS + 2 -1} +// 0 and 1 are tied to value 0 and 1 +#define NUM_MIO_PADS 47 +#define NUM_DIO_PADS 14 + +#define PINMUX_PERIPH_OUTSEL_IDX_OFFSET 3 + +/** + * Pinmux Peripheral Input. + */ +typedef enum top_englishbreakfast_pinmux_peripheral_in { + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio0 = 0, /**< Peripheral Input 0 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio1 = 1, /**< Peripheral Input 1 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio2 = 2, /**< Peripheral Input 2 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio3 = 3, /**< Peripheral Input 3 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio4 = 4, /**< Peripheral Input 4 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio5 = 5, /**< Peripheral Input 5 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio6 = 6, /**< Peripheral Input 6 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio7 = 7, /**< Peripheral Input 7 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio8 = 8, /**< Peripheral Input 8 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio9 = 9, /**< Peripheral Input 9 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio10 = 10, /**< Peripheral Input 10 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio11 = 11, /**< Peripheral Input 11 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio12 = 12, /**< Peripheral Input 12 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio13 = 13, /**< Peripheral Input 13 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio14 = 14, /**< Peripheral Input 14 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio15 = 15, /**< Peripheral Input 15 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio16 = 16, /**< Peripheral Input 16 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio17 = 17, /**< Peripheral Input 17 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio18 = 18, /**< Peripheral Input 18 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio19 = 19, /**< Peripheral Input 19 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio20 = 20, /**< Peripheral Input 20 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio21 = 21, /**< Peripheral Input 21 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio22 = 22, /**< Peripheral Input 22 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio23 = 23, /**< Peripheral Input 23 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio24 = 24, /**< Peripheral Input 24 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio25 = 25, /**< Peripheral Input 25 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio26 = 26, /**< Peripheral Input 26 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio27 = 27, /**< Peripheral Input 27 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio28 = 28, /**< Peripheral Input 28 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio29 = 29, /**< Peripheral Input 29 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio30 = 30, /**< Peripheral Input 30 */ + kTopEnglishbreakfastPinmuxPeripheralInGpioGpio31 = 31, /**< Peripheral Input 31 */ + kTopEnglishbreakfastPinmuxPeripheralInUart0Rx = 32, /**< Peripheral Input 32 */ + kTopEnglishbreakfastPinmuxPeripheralInUart1Rx = 33, /**< Peripheral Input 33 */ + kTopEnglishbreakfastPinmuxPeripheralInFlashCtrlTck = 34, /**< Peripheral Input 34 */ + kTopEnglishbreakfastPinmuxPeripheralInFlashCtrlTms = 35, /**< Peripheral Input 35 */ + kTopEnglishbreakfastPinmuxPeripheralInFlashCtrlTdi = 36, /**< Peripheral Input 36 */ + kTopEnglishbreakfastPinmuxPeripheralInUsbdevSense = 37, /**< Peripheral Input 37 */ + kTopEnglishbreakfastPinmuxPeripheralInLast = 37, /**< \internal Last valid peripheral input */ +} top_englishbreakfast_pinmux_peripheral_in_t; + +/** + * Pinmux MIO Input Selector. + */ +typedef enum top_englishbreakfast_pinmux_insel { + kTopEnglishbreakfastPinmuxInselConstantZero = 0, /**< Tie constantly to zero */ + kTopEnglishbreakfastPinmuxInselConstantOne = 1, /**< Tie constantly to one */ + kTopEnglishbreakfastPinmuxInselIoa0 = 2, /**< MIO Pad 0 */ + kTopEnglishbreakfastPinmuxInselIoa1 = 3, /**< MIO Pad 1 */ + kTopEnglishbreakfastPinmuxInselIoa2 = 4, /**< MIO Pad 2 */ + kTopEnglishbreakfastPinmuxInselIoa3 = 5, /**< MIO Pad 3 */ + kTopEnglishbreakfastPinmuxInselIoa4 = 6, /**< MIO Pad 4 */ + kTopEnglishbreakfastPinmuxInselIoa5 = 7, /**< MIO Pad 5 */ + kTopEnglishbreakfastPinmuxInselIoa6 = 8, /**< MIO Pad 6 */ + kTopEnglishbreakfastPinmuxInselIoa7 = 9, /**< MIO Pad 7 */ + kTopEnglishbreakfastPinmuxInselIoa8 = 10, /**< MIO Pad 8 */ + kTopEnglishbreakfastPinmuxInselIob0 = 11, /**< MIO Pad 9 */ + kTopEnglishbreakfastPinmuxInselIob1 = 12, /**< MIO Pad 10 */ + kTopEnglishbreakfastPinmuxInselIob2 = 13, /**< MIO Pad 11 */ + kTopEnglishbreakfastPinmuxInselIob3 = 14, /**< MIO Pad 12 */ + kTopEnglishbreakfastPinmuxInselIob4 = 15, /**< MIO Pad 13 */ + kTopEnglishbreakfastPinmuxInselIob5 = 16, /**< MIO Pad 14 */ + kTopEnglishbreakfastPinmuxInselIob6 = 17, /**< MIO Pad 15 */ + kTopEnglishbreakfastPinmuxInselIob7 = 18, /**< MIO Pad 16 */ + kTopEnglishbreakfastPinmuxInselIob8 = 19, /**< MIO Pad 17 */ + kTopEnglishbreakfastPinmuxInselIob9 = 20, /**< MIO Pad 18 */ + kTopEnglishbreakfastPinmuxInselIob10 = 21, /**< MIO Pad 19 */ + kTopEnglishbreakfastPinmuxInselIob11 = 22, /**< MIO Pad 20 */ + kTopEnglishbreakfastPinmuxInselIob12 = 23, /**< MIO Pad 21 */ + kTopEnglishbreakfastPinmuxInselIoc0 = 24, /**< MIO Pad 22 */ + kTopEnglishbreakfastPinmuxInselIoc1 = 25, /**< MIO Pad 23 */ + kTopEnglishbreakfastPinmuxInselIoc2 = 26, /**< MIO Pad 24 */ + kTopEnglishbreakfastPinmuxInselIoc3 = 27, /**< MIO Pad 25 */ + kTopEnglishbreakfastPinmuxInselIoc4 = 28, /**< MIO Pad 26 */ + kTopEnglishbreakfastPinmuxInselIoc5 = 29, /**< MIO Pad 27 */ + kTopEnglishbreakfastPinmuxInselIoc6 = 30, /**< MIO Pad 28 */ + kTopEnglishbreakfastPinmuxInselIoc7 = 31, /**< MIO Pad 29 */ + kTopEnglishbreakfastPinmuxInselIoc8 = 32, /**< MIO Pad 30 */ + kTopEnglishbreakfastPinmuxInselIoc9 = 33, /**< MIO Pad 31 */ + kTopEnglishbreakfastPinmuxInselIoc10 = 34, /**< MIO Pad 32 */ + kTopEnglishbreakfastPinmuxInselIoc11 = 35, /**< MIO Pad 33 */ + kTopEnglishbreakfastPinmuxInselIoc12 = 36, /**< MIO Pad 34 */ + kTopEnglishbreakfastPinmuxInselIor0 = 37, /**< MIO Pad 35 */ + kTopEnglishbreakfastPinmuxInselIor1 = 38, /**< MIO Pad 36 */ + kTopEnglishbreakfastPinmuxInselIor2 = 39, /**< MIO Pad 37 */ + kTopEnglishbreakfastPinmuxInselIor3 = 40, /**< MIO Pad 38 */ + kTopEnglishbreakfastPinmuxInselIor4 = 41, /**< MIO Pad 39 */ + kTopEnglishbreakfastPinmuxInselIor5 = 42, /**< MIO Pad 40 */ + kTopEnglishbreakfastPinmuxInselIor6 = 43, /**< MIO Pad 41 */ + kTopEnglishbreakfastPinmuxInselIor7 = 44, /**< MIO Pad 42 */ + kTopEnglishbreakfastPinmuxInselIor10 = 45, /**< MIO Pad 43 */ + kTopEnglishbreakfastPinmuxInselIor11 = 46, /**< MIO Pad 44 */ + kTopEnglishbreakfastPinmuxInselIor12 = 47, /**< MIO Pad 45 */ + kTopEnglishbreakfastPinmuxInselIor13 = 48, /**< MIO Pad 46 */ + kTopEnglishbreakfastPinmuxInselLast = 48, /**< \internal Last valid insel value */ +} top_englishbreakfast_pinmux_insel_t; + +/** + * Pinmux MIO Output. + */ +typedef enum top_englishbreakfast_pinmux_mio_out { + kTopEnglishbreakfastPinmuxMioOutIoa0 = 0, /**< MIO Pad 0 */ + kTopEnglishbreakfastPinmuxMioOutIoa1 = 1, /**< MIO Pad 1 */ + kTopEnglishbreakfastPinmuxMioOutIoa2 = 2, /**< MIO Pad 2 */ + kTopEnglishbreakfastPinmuxMioOutIoa3 = 3, /**< MIO Pad 3 */ + kTopEnglishbreakfastPinmuxMioOutIoa4 = 4, /**< MIO Pad 4 */ + kTopEnglishbreakfastPinmuxMioOutIoa5 = 5, /**< MIO Pad 5 */ + kTopEnglishbreakfastPinmuxMioOutIoa6 = 6, /**< MIO Pad 6 */ + kTopEnglishbreakfastPinmuxMioOutIoa7 = 7, /**< MIO Pad 7 */ + kTopEnglishbreakfastPinmuxMioOutIoa8 = 8, /**< MIO Pad 8 */ + kTopEnglishbreakfastPinmuxMioOutIob0 = 9, /**< MIO Pad 9 */ + kTopEnglishbreakfastPinmuxMioOutIob1 = 10, /**< MIO Pad 10 */ + kTopEnglishbreakfastPinmuxMioOutIob2 = 11, /**< MIO Pad 11 */ + kTopEnglishbreakfastPinmuxMioOutIob3 = 12, /**< MIO Pad 12 */ + kTopEnglishbreakfastPinmuxMioOutIob4 = 13, /**< MIO Pad 13 */ + kTopEnglishbreakfastPinmuxMioOutIob5 = 14, /**< MIO Pad 14 */ + kTopEnglishbreakfastPinmuxMioOutIob6 = 15, /**< MIO Pad 15 */ + kTopEnglishbreakfastPinmuxMioOutIob7 = 16, /**< MIO Pad 16 */ + kTopEnglishbreakfastPinmuxMioOutIob8 = 17, /**< MIO Pad 17 */ + kTopEnglishbreakfastPinmuxMioOutIob9 = 18, /**< MIO Pad 18 */ + kTopEnglishbreakfastPinmuxMioOutIob10 = 19, /**< MIO Pad 19 */ + kTopEnglishbreakfastPinmuxMioOutIob11 = 20, /**< MIO Pad 20 */ + kTopEnglishbreakfastPinmuxMioOutIob12 = 21, /**< MIO Pad 21 */ + kTopEnglishbreakfastPinmuxMioOutIoc0 = 22, /**< MIO Pad 22 */ + kTopEnglishbreakfastPinmuxMioOutIoc1 = 23, /**< MIO Pad 23 */ + kTopEnglishbreakfastPinmuxMioOutIoc2 = 24, /**< MIO Pad 24 */ + kTopEnglishbreakfastPinmuxMioOutIoc3 = 25, /**< MIO Pad 25 */ + kTopEnglishbreakfastPinmuxMioOutIoc4 = 26, /**< MIO Pad 26 */ + kTopEnglishbreakfastPinmuxMioOutIoc5 = 27, /**< MIO Pad 27 */ + kTopEnglishbreakfastPinmuxMioOutIoc6 = 28, /**< MIO Pad 28 */ + kTopEnglishbreakfastPinmuxMioOutIoc7 = 29, /**< MIO Pad 29 */ + kTopEnglishbreakfastPinmuxMioOutIoc8 = 30, /**< MIO Pad 30 */ + kTopEnglishbreakfastPinmuxMioOutIoc9 = 31, /**< MIO Pad 31 */ + kTopEnglishbreakfastPinmuxMioOutIoc10 = 32, /**< MIO Pad 32 */ + kTopEnglishbreakfastPinmuxMioOutIoc11 = 33, /**< MIO Pad 33 */ + kTopEnglishbreakfastPinmuxMioOutIoc12 = 34, /**< MIO Pad 34 */ + kTopEnglishbreakfastPinmuxMioOutIor0 = 35, /**< MIO Pad 35 */ + kTopEnglishbreakfastPinmuxMioOutIor1 = 36, /**< MIO Pad 36 */ + kTopEnglishbreakfastPinmuxMioOutIor2 = 37, /**< MIO Pad 37 */ + kTopEnglishbreakfastPinmuxMioOutIor3 = 38, /**< MIO Pad 38 */ + kTopEnglishbreakfastPinmuxMioOutIor4 = 39, /**< MIO Pad 39 */ + kTopEnglishbreakfastPinmuxMioOutIor5 = 40, /**< MIO Pad 40 */ + kTopEnglishbreakfastPinmuxMioOutIor6 = 41, /**< MIO Pad 41 */ + kTopEnglishbreakfastPinmuxMioOutIor7 = 42, /**< MIO Pad 42 */ + kTopEnglishbreakfastPinmuxMioOutIor10 = 43, /**< MIO Pad 43 */ + kTopEnglishbreakfastPinmuxMioOutIor11 = 44, /**< MIO Pad 44 */ + kTopEnglishbreakfastPinmuxMioOutIor12 = 45, /**< MIO Pad 45 */ + kTopEnglishbreakfastPinmuxMioOutIor13 = 46, /**< MIO Pad 46 */ + kTopEnglishbreakfastPinmuxMioOutLast = 46, /**< \internal Last valid mio output */ +} top_englishbreakfast_pinmux_mio_out_t; + +/** + * Pinmux Peripheral Output Selector. + */ +typedef enum top_englishbreakfast_pinmux_outsel { + kTopEnglishbreakfastPinmuxOutselConstantZero = 0, /**< Tie constantly to zero */ + kTopEnglishbreakfastPinmuxOutselConstantOne = 1, /**< Tie constantly to one */ + kTopEnglishbreakfastPinmuxOutselConstantHighZ = 2, /**< Tie constantly to high-Z */ + kTopEnglishbreakfastPinmuxOutselGpioGpio0 = 3, /**< Peripheral Output 0 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio1 = 4, /**< Peripheral Output 1 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio2 = 5, /**< Peripheral Output 2 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio3 = 6, /**< Peripheral Output 3 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio4 = 7, /**< Peripheral Output 4 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio5 = 8, /**< Peripheral Output 5 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio6 = 9, /**< Peripheral Output 6 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio7 = 10, /**< Peripheral Output 7 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio8 = 11, /**< Peripheral Output 8 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio9 = 12, /**< Peripheral Output 9 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio10 = 13, /**< Peripheral Output 10 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio11 = 14, /**< Peripheral Output 11 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio12 = 15, /**< Peripheral Output 12 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio13 = 16, /**< Peripheral Output 13 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio14 = 17, /**< Peripheral Output 14 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio15 = 18, /**< Peripheral Output 15 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio16 = 19, /**< Peripheral Output 16 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio17 = 20, /**< Peripheral Output 17 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio18 = 21, /**< Peripheral Output 18 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio19 = 22, /**< Peripheral Output 19 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio20 = 23, /**< Peripheral Output 20 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio21 = 24, /**< Peripheral Output 21 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio22 = 25, /**< Peripheral Output 22 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio23 = 26, /**< Peripheral Output 23 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio24 = 27, /**< Peripheral Output 24 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio25 = 28, /**< Peripheral Output 25 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio26 = 29, /**< Peripheral Output 26 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio27 = 30, /**< Peripheral Output 27 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio28 = 31, /**< Peripheral Output 28 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio29 = 32, /**< Peripheral Output 29 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio30 = 33, /**< Peripheral Output 30 */ + kTopEnglishbreakfastPinmuxOutselGpioGpio31 = 34, /**< Peripheral Output 31 */ + kTopEnglishbreakfastPinmuxOutselUart0Tx = 35, /**< Peripheral Output 32 */ + kTopEnglishbreakfastPinmuxOutselUart1Tx = 36, /**< Peripheral Output 33 */ + kTopEnglishbreakfastPinmuxOutselFlashCtrlTdo = 37, /**< Peripheral Output 34 */ + kTopEnglishbreakfastPinmuxOutselLast = 37, /**< \internal Last valid outsel value */ +} top_englishbreakfast_pinmux_outsel_t; + +/** + * Dedicated Pad Selects + */ +typedef enum top_englishbreakfast_direct_pads { + kTopEnglishbreakfastDirectPadsSpiHost0Sd0 = 0, /**< */ + kTopEnglishbreakfastDirectPadsSpiHost0Sd1 = 1, /**< */ + kTopEnglishbreakfastDirectPadsSpiHost0Sd2 = 2, /**< */ + kTopEnglishbreakfastDirectPadsSpiHost0Sd3 = 3, /**< */ + kTopEnglishbreakfastDirectPadsSpiDeviceSd0 = 4, /**< */ + kTopEnglishbreakfastDirectPadsSpiDeviceSd1 = 5, /**< */ + kTopEnglishbreakfastDirectPadsSpiDeviceSd2 = 6, /**< */ + kTopEnglishbreakfastDirectPadsSpiDeviceSd3 = 7, /**< */ + kTopEnglishbreakfastDirectPadsUsbdevUsbDp = 8, /**< */ + kTopEnglishbreakfastDirectPadsUsbdevUsbDn = 9, /**< */ + kTopEnglishbreakfastDirectPadsSpiDeviceSck = 10, /**< */ + kTopEnglishbreakfastDirectPadsSpiDeviceCsb = 11, /**< */ + kTopEnglishbreakfastDirectPadsSpiHost0Sck = 12, /**< */ + kTopEnglishbreakfastDirectPadsSpiHost0Csb = 13, /**< */ + kTopEnglishbreakfastDirectPadsLast = 13, /**< \internal Last valid direct pad */ +} top_englishbreakfast_direct_pads_t; + +/** + * Muxed Pad Selects + */ +typedef enum top_englishbreakfast_muxed_pads { + kTopEnglishbreakfastMuxedPadsIoa0 = 0, /**< */ + kTopEnglishbreakfastMuxedPadsIoa1 = 1, /**< */ + kTopEnglishbreakfastMuxedPadsIoa2 = 2, /**< */ + kTopEnglishbreakfastMuxedPadsIoa3 = 3, /**< */ + kTopEnglishbreakfastMuxedPadsIoa4 = 4, /**< */ + kTopEnglishbreakfastMuxedPadsIoa5 = 5, /**< */ + kTopEnglishbreakfastMuxedPadsIoa6 = 6, /**< */ + kTopEnglishbreakfastMuxedPadsIoa7 = 7, /**< */ + kTopEnglishbreakfastMuxedPadsIoa8 = 8, /**< */ + kTopEnglishbreakfastMuxedPadsIob0 = 9, /**< */ + kTopEnglishbreakfastMuxedPadsIob1 = 10, /**< */ + kTopEnglishbreakfastMuxedPadsIob2 = 11, /**< */ + kTopEnglishbreakfastMuxedPadsIob3 = 12, /**< */ + kTopEnglishbreakfastMuxedPadsIob4 = 13, /**< */ + kTopEnglishbreakfastMuxedPadsIob5 = 14, /**< */ + kTopEnglishbreakfastMuxedPadsIob6 = 15, /**< */ + kTopEnglishbreakfastMuxedPadsIob7 = 16, /**< */ + kTopEnglishbreakfastMuxedPadsIob8 = 17, /**< */ + kTopEnglishbreakfastMuxedPadsIob9 = 18, /**< */ + kTopEnglishbreakfastMuxedPadsIob10 = 19, /**< */ + kTopEnglishbreakfastMuxedPadsIob11 = 20, /**< */ + kTopEnglishbreakfastMuxedPadsIob12 = 21, /**< */ + kTopEnglishbreakfastMuxedPadsIoc0 = 22, /**< */ + kTopEnglishbreakfastMuxedPadsIoc1 = 23, /**< */ + kTopEnglishbreakfastMuxedPadsIoc2 = 24, /**< */ + kTopEnglishbreakfastMuxedPadsIoc3 = 25, /**< */ + kTopEnglishbreakfastMuxedPadsIoc4 = 26, /**< */ + kTopEnglishbreakfastMuxedPadsIoc5 = 27, /**< */ + kTopEnglishbreakfastMuxedPadsIoc6 = 28, /**< */ + kTopEnglishbreakfastMuxedPadsIoc7 = 29, /**< */ + kTopEnglishbreakfastMuxedPadsIoc8 = 30, /**< */ + kTopEnglishbreakfastMuxedPadsIoc9 = 31, /**< */ + kTopEnglishbreakfastMuxedPadsIoc10 = 32, /**< */ + kTopEnglishbreakfastMuxedPadsIoc11 = 33, /**< */ + kTopEnglishbreakfastMuxedPadsIoc12 = 34, /**< */ + kTopEnglishbreakfastMuxedPadsIor0 = 35, /**< */ + kTopEnglishbreakfastMuxedPadsIor1 = 36, /**< */ + kTopEnglishbreakfastMuxedPadsIor2 = 37, /**< */ + kTopEnglishbreakfastMuxedPadsIor3 = 38, /**< */ + kTopEnglishbreakfastMuxedPadsIor4 = 39, /**< */ + kTopEnglishbreakfastMuxedPadsIor5 = 40, /**< */ + kTopEnglishbreakfastMuxedPadsIor6 = 41, /**< */ + kTopEnglishbreakfastMuxedPadsIor7 = 42, /**< */ + kTopEnglishbreakfastMuxedPadsIor10 = 43, /**< */ + kTopEnglishbreakfastMuxedPadsIor11 = 44, /**< */ + kTopEnglishbreakfastMuxedPadsIor12 = 45, /**< */ + kTopEnglishbreakfastMuxedPadsIor13 = 46, /**< */ + kTopEnglishbreakfastMuxedPadsLast = 46, /**< \internal Last valid muxed pad */ +} top_englishbreakfast_muxed_pads_t; + +/** + * Power Manager Wakeup Signals + */ +typedef enum top_englishbreakfast_power_manager_wake_ups { + kTopEnglishbreakfastPowerManagerWakeUpsPinmuxAonPinWkupReq = 0, /**< */ + kTopEnglishbreakfastPowerManagerWakeUpsPinmuxAonUsbWkupReq = 1, /**< */ + kTopEnglishbreakfastPowerManagerWakeUpsAonTimerAonWkupReq = 2, /**< */ + kTopEnglishbreakfastPowerManagerWakeUpsLast = 2, /**< \internal Last valid pwrmgr wakeup signal */ +} top_englishbreakfast_power_manager_wake_ups_t; + +/** + * Reset Manager Software Controlled Resets + */ +typedef enum top_englishbreakfast_reset_manager_sw_resets { + kTopEnglishbreakfastResetManagerSwResetsSpiDevice = 0, /**< */ + kTopEnglishbreakfastResetManagerSwResetsSpiHost0 = 1, /**< */ + kTopEnglishbreakfastResetManagerSwResetsUsb = 2, /**< */ + kTopEnglishbreakfastResetManagerSwResetsLast = 2, /**< \internal Last valid rstmgr software reset request */ +} top_englishbreakfast_reset_manager_sw_resets_t; + +/** + * Power Manager Reset Request Signals + */ +typedef enum top_englishbreakfast_power_manager_reset_requests { + kTopEnglishbreakfastPowerManagerResetRequestsAonTimerAonAonTimerRstReq = 0, /**< */ + kTopEnglishbreakfastPowerManagerResetRequestsLast = 0, /**< \internal Last valid pwrmgr reset_request signal */ +} top_englishbreakfast_power_manager_reset_requests_t; + +/** + * Clock Manager Software-Controlled ("Gated") Clocks. + * + * The Software has full control over these clocks. + */ +typedef enum top_englishbreakfast_gateable_clocks { + kTopEnglishbreakfastGateableClocksIoDiv4Peri = 0, /**< Clock clk_io_div4_peri in group peri */ + kTopEnglishbreakfastGateableClocksIoDiv2Peri = 1, /**< Clock clk_io_div2_peri in group peri */ + kTopEnglishbreakfastGateableClocksIoPeri = 2, /**< Clock clk_io_peri in group peri */ + kTopEnglishbreakfastGateableClocksUsbPeri = 3, /**< Clock clk_usb_peri in group peri */ + kTopEnglishbreakfastGateableClocksLast = 3, /**< \internal Last Valid Gateable Clock */ +} top_englishbreakfast_gateable_clocks_t; + +/** + * Clock Manager Software-Hinted Clocks. + * + * The Software has partial control over these clocks. It can ask them to stop, + * but the clock manager is in control of whether the clock actually is stopped. + */ +typedef enum top_englishbreakfast_hintable_clocks { + kTopEnglishbreakfastHintableClocksMainAes = 0, /**< Clock clk_main_aes in group trans */ + kTopEnglishbreakfastHintableClocksLast = 0, /**< \internal Last Valid Hintable Clock */ +} top_englishbreakfast_hintable_clocks_t; + +/** + * MMIO Region + * + * MMIO region excludes any memory that is separate from the module + * configuration space, i.e. ROM, main SRAM, and flash are excluded but + * retention SRAM, spi_device memory, or usbdev memory are included. + */ +#define TOP_ENGLISHBREAKFAST_MMIO_BASE_ADDR 0x40000000u +#define TOP_ENGLISHBREAKFAST_MMIO_SIZE_BYTES 0x10000000u + +// Header Extern Guard +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // OPENTITAN_HW_TOP_ENGLISHBREAKFAST_SW_AUTOGEN_TOP_ENGLISHBREAKFAST_H_ diff --git a/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.h b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.h new file mode 100644 index 0000000000000..1006bb76acbce --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.h @@ -0,0 +1,465 @@ +// Copyright lowRISC contributors (OpenTitan project). +// 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: +// util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson +// -o hw/top_englishbreakfast + +#ifndef OPENTITAN_HW_TOP_ENGLISHBREAKFAST_SW_AUTOGEN_TOP_ENGLISHBREAKFAST_MEMORY_H_ +#define OPENTITAN_HW_TOP_ENGLISHBREAKFAST_SW_AUTOGEN_TOP_ENGLISHBREAKFAST_MEMORY_H_ + +/** + * @file + * @brief Assembler-only Top-Specific Definitions. + * + * This file contains preprocessor definitions for use within assembly code. + * + * These are not shared with C/C++ code because these are only allowed to be + * preprocessor definitions, no data or type declarations are allowed. The + * assembler is also stricter about literals (not allowing suffixes for + * signed/unsigned which are sensible to use for unsigned values in C/C++). + */ + +// Include guard for assembler +#ifdef __ASSEMBLER__ + + +/** + * Memory base for flash_ctrl_eflash in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_EFLASH_BASE_ADDR 0x20000000 + +/** + * Memory size for flash_ctrl_eflash in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_EFLASH_SIZE_BYTES 0x10000 + +/** + * Memory base for sram_ctrl_main_ram_main in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_RAM_MAIN_BASE_ADDR 0x10000000 + +/** + * Memory size for sram_ctrl_main_ram_main in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_RAM_MAIN_SIZE_BYTES 0x20000 + +/** + * Memory base for rom_ctrl_rom in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_ROM_BASE_ADDR 0x00008000 + +/** + * Memory size for rom_ctrl_rom in top englishbreakfast. + */ +#define TOP_ENGLISHBREAKFAST_ROM_SIZE_BYTES 0x8000 + + + +/** + * Peripheral base address for uart0 in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR 0x40000000 + +/** + * Peripheral size for uart0 in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_UART0_BASE_ADDR + TOP_ENGLISHBREAKFAST_UART0_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_UART0_SIZE_BYTES 0x40 +/** + * Peripheral base address for uart1 in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR 0x40010000 + +/** + * Peripheral size for uart1 in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_UART1_BASE_ADDR + TOP_ENGLISHBREAKFAST_UART1_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_UART1_SIZE_BYTES 0x40 +/** + * Peripheral base address for gpio in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR 0x40040000 + +/** + * Peripheral size for gpio in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_GPIO_BASE_ADDR + TOP_ENGLISHBREAKFAST_GPIO_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_GPIO_SIZE_BYTES 0x80 +/** + * Peripheral base address for spi_device in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR 0x40050000 + +/** + * Peripheral size for spi_device in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SPI_DEVICE_BASE_ADDR + TOP_ENGLISHBREAKFAST_SPI_DEVICE_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SPI_DEVICE_SIZE_BYTES 0x2000 +/** + * Peripheral base address for spi_host0 in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR 0x40060000 + +/** + * Peripheral size for spi_host0 in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SPI_HOST0_BASE_ADDR + TOP_ENGLISHBREAKFAST_SPI_HOST0_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SPI_HOST0_SIZE_BYTES 0x40 +/** + * Peripheral base address for rv_timer in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RV_TIMER_BASE_ADDR 0x40100000 + +/** + * Peripheral size for rv_timer in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RV_TIMER_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RV_TIMER_BASE_ADDR + TOP_ENGLISHBREAKFAST_RV_TIMER_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RV_TIMER_SIZE_BYTES 0x200 +/** + * Peripheral base address for usbdev in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR 0x40320000 + +/** + * Peripheral size for usbdev in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_USBDEV_BASE_ADDR + TOP_ENGLISHBREAKFAST_USBDEV_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_USBDEV_SIZE_BYTES 0x1000 +/** + * Peripheral base address for pwrmgr_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR 0x40400000 + +/** + * Peripheral size for pwrmgr_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_PWRMGR_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_PWRMGR_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_PWRMGR_AON_SIZE_BYTES 0x80 +/** + * Peripheral base address for rstmgr_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RSTMGR_AON_BASE_ADDR 0x40410000 + +/** + * Peripheral size for rstmgr_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RSTMGR_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RSTMGR_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_RSTMGR_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RSTMGR_AON_SIZE_BYTES 0x80 +/** + * Peripheral base address for clkmgr_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_CLKMGR_AON_BASE_ADDR 0x40420000 + +/** + * Peripheral size for clkmgr_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_CLKMGR_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_CLKMGR_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_CLKMGR_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_CLKMGR_AON_SIZE_BYTES 0x80 +/** + * Peripheral base address for pinmux_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_PINMUX_AON_BASE_ADDR 0x40460000 + +/** + * Peripheral size for pinmux_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_PINMUX_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_PINMUX_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_PINMUX_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_PINMUX_AON_SIZE_BYTES 0x1000 +/** + * Peripheral base address for aon_timer_aon in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR 0x40470000 + +/** + * Peripheral size for aon_timer_aon in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_AON_TIMER_AON_BASE_ADDR + TOP_ENGLISHBREAKFAST_AON_TIMER_AON_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_AON_TIMER_AON_SIZE_BYTES 0x40 +/** + * Peripheral base address for ast in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_AST_BASE_ADDR 0x40480000 + +/** + * Peripheral size for ast in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_AST_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_AST_BASE_ADDR + TOP_ENGLISHBREAKFAST_AST_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_AST_SIZE_BYTES 0x400 +/** + * Peripheral base address for core device on flash_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR 0x41000000 + +/** + * Peripheral size for core device on flash_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_BASE_ADDR + TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_CORE_SIZE_BYTES 0x200 +/** + * Peripheral base address for prim device on flash_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_BASE_ADDR 0x41008000 + +/** + * Peripheral size for prim device on flash_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_BASE_ADDR + TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_PRIM_SIZE_BYTES 0x80 +/** + * Peripheral base address for mem device on flash_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_BASE_ADDR 0x20000000 + +/** + * Peripheral size for mem device on flash_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_BASE_ADDR + TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_FLASH_CTRL_MEM_SIZE_BYTES 0x10000 +/** + * Peripheral base address for rv_plic in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR 0x48000000 + +/** + * Peripheral size for rv_plic in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RV_PLIC_BASE_ADDR + TOP_ENGLISHBREAKFAST_RV_PLIC_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RV_PLIC_SIZE_BYTES 0x8000000 +/** + * Peripheral base address for aes in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_AES_BASE_ADDR 0x41100000 + +/** + * Peripheral size for aes in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_AES_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_AES_BASE_ADDR + TOP_ENGLISHBREAKFAST_AES_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_AES_SIZE_BYTES 0x100 +/** + * Peripheral base address for regs device on sram_ctrl_main in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_BASE_ADDR 0x411C0000 + +/** + * Peripheral size for regs device on sram_ctrl_main in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_BASE_ADDR + TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_REGS_SIZE_BYTES 0x40 +/** + * Peripheral base address for ram device on sram_ctrl_main in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_BASE_ADDR 0x10000000 + +/** + * Peripheral size for ram device on sram_ctrl_main in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_BASE_ADDR + TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_SRAM_CTRL_MAIN_RAM_SIZE_BYTES 0x20000 +/** + * Peripheral base address for regs device on rom_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_BASE_ADDR 0x411E0000 + +/** + * Peripheral size for regs device on rom_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_BASE_ADDR + TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_REGS_SIZE_BYTES 0x80 +/** + * Peripheral base address for rom device on rom_ctrl in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_BASE_ADDR 0x8000 + +/** + * Peripheral size for rom device on rom_ctrl in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_BASE_ADDR + TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_ROM_CTRL_ROM_SIZE_BYTES 0x8000 +/** + * Peripheral base address for cfg device on rv_core_ibex in top englishbreakfast. + * + * This should be used with #mmio_region_from_addr to access the memory-mapped + * registers associated with the peripheral (usually via a DIF). + */ +#define TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_BASE_ADDR 0x411F0000 + +/** + * Peripheral size for cfg device on rv_core_ibex in top englishbreakfast. + * + * This is the size (in bytes) of the peripheral's reserved memory area. All + * memory-mapped registers associated with this peripheral should have an + * address between #TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_BASE_ADDR and + * `TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_BASE_ADDR + TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_SIZE_BYTES`. + */ +#define TOP_ENGLISHBREAKFAST_RV_CORE_IBEX_CFG_SIZE_BYTES 0x100 + +/** + * MMIO Region + * + * MMIO region excludes any memory that is separate from the module + * configuration space, i.e. ROM, main SRAM, and flash are excluded but + * retention SRAM, spi_device memory, or usbdev memory are included. + */ +#define TOP_ENGLISHBREAKFAST_MMIO_BASE_ADDR 0x40000000 +#define TOP_ENGLISHBREAKFAST_MMIO_SIZE_BYTES 0x10000000 + +#endif // __ASSEMBLER__ + +#endif // OPENTITAN_HW_TOP_ENGLISHBREAKFAST_SW_AUTOGEN_TOP_ENGLISHBREAKFAST_MEMORY_H_ diff --git a/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.ld b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.ld new file mode 100644 index 0000000000000..fb58f85cb691c --- /dev/null +++ b/hw/top_englishbreakfast/sw/autogen/top_englishbreakfast_memory.ld @@ -0,0 +1,59 @@ +/* Copyright lowRISC contributors (OpenTitan project). */ +/* 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: + * util/topgen.py -t hw/top_englishbreakfast/data/top_englishbreakfast.hjson + * -o hw/top_englishbreakfast + */ + +/** + * Partial linker script for chip memory configuration. + * rom_ext_virtual and owner_virtual are address windows that provide a fixed translation + * address for whichever half of the flash contains the corresponding boot stage. + */ +MEMORY { + eflash(rx) : ORIGIN = 0x20000000, LENGTH = 0x10000 + ram_main(rwx) : ORIGIN = 0x10000000, LENGTH = 0x20000 + rom(rx) : ORIGIN = 0x00008000, LENGTH = 0x8000 + rom_ext_virtual(rx) : ORIGIN = 0x90000000, LENGTH = 0x8000 + owner_virtual(rx) : ORIGIN = 0xa0000000, LENGTH = 0x8000 +} + +/** + * Exception frame at the top of main SRAM + */ +_exception_frame_size = 128; +_exception_frame_end = ORIGIN(ram_main) + LENGTH(ram_main); +_exception_frame_start = _exception_frame_end - _exception_frame_size; + + +/** + * Stack just below the exception frame. + */ +_stack_size = 16384 - _exception_frame_size; +_stack_end = _exception_frame_start; +_stack_start = _stack_end - _stack_size; + +/** + * Size of the `.static_critical` section at the bottom of the main SRAM (in + * bytes). + */ +_static_critical_size = 8168; + +/** + * `.chip_info` at the top of each ROM. + */ +_chip_info_size = 128; +_rom_chip_info_end = ORIGIN(rom) + LENGTH(rom); +_rom_chip_info_start = _rom_chip_info_end - _chip_info_size; + +/** + * Size of the initial ePMP RX region at reset (in bytes). This region must be + * large enough to cover the .crt section. + * + * NOTE: This value must match the size of the RX region in + * hw/ip/rv_core_ibex/rtl/ibex_pmp_reset.svh. + */ +_epmp_reset_rx_size = 2048; diff --git a/hw/top_englishbreakfast/top_englishbreakfast.core b/hw/top_englishbreakfast/top_englishbreakfast.core index 164aba340cf81..d1105d4a96bae 100644 --- a/hw/top_englishbreakfast/top_englishbreakfast.core +++ b/hw/top_englishbreakfast/top_englishbreakfast.core @@ -7,9 +7,8 @@ description: "Technology-independent English Breakfast toplevel" filesets: files_rtl_generic: depend: - - lowrisc:systems:topgen - - lowrisc:constants:top_earlgrey_top_pkg - - lowrisc:tlul:headers + - lowrisc:opentitan:top_englishbreakfast_pwrmgr_pkg + - lowrisc:opentitan:top_earlgrey_alert_handler_pkg # Manually instantiated - lowrisc:ip:rv_core_ibex - lowrisc:ip:rv_dm @@ -30,6 +29,7 @@ filesets: - lowrisc:ip:hmac - lowrisc:ip:kmac - lowrisc:ip:keymgr + - lowrisc:constants:top_earlgrey_top_pkg - lowrisc:ip:otp_ctrl - lowrisc:ip:lc_ctrl - lowrisc:ip:usbdev @@ -43,6 +43,12 @@ filesets: - lowrisc:opentitan:top_englishbreakfast_rv_plic - lowrisc:ip:rom_ctrl - lowrisc:ip:aon_timer + - lowrisc:tlul:headers + - lowrisc:systems:top_englishbreakfast_pkg + files: + - rtl/autogen/top_englishbreakfast_rnd_cnst_pkg.sv + - rtl/autogen/top_englishbreakfast.sv + file_type: systemVerilogSource files_verilator_waiver: depend: diff --git a/topgen-reg-only.core b/hw/top_englishbreakfast/top_englishbreakfast_padring.core similarity index 52% rename from topgen-reg-only.core rename to hw/top_englishbreakfast/top_englishbreakfast_padring.core index 915bfe96fd3c9..b3a8450ecc638 100644 --- a/topgen-reg-only.core +++ b/hw/top_englishbreakfast/top_englishbreakfast_padring.core @@ -2,15 +2,15 @@ CAPI=2: # Copyright lowRISC contributors (OpenTitan project). # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:systems:topgen-reg-only" -description: "Top-level generator tool." +name: "lowrisc:systems:top_englishbreakfast_padring:0.1" +description: "Chip-level padring instance" filesets: - rtl: + files_rtl: depend: - - lowrisc:ip:pinmux_reggen + - lowrisc:systems:top_earlgrey_padring targets: - default: &default + default: &default_target filesets: - - rtl + - files_rtl diff --git a/hw/top_englishbreakfast/top_englishbreakfast_physical_pads.core b/hw/top_englishbreakfast/top_englishbreakfast_physical_pads.core new file mode 100644 index 0000000000000..cadf20d4ecfda --- /dev/null +++ b/hw/top_englishbreakfast/top_englishbreakfast_physical_pads.core @@ -0,0 +1,20 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: "lowrisc:systems:top_englishbreakfast_physical_pads:0.1" +description: "Open-source place-holder for physical pads" + +filesets: + files_rtl: + depend: + - lowrisc:systems:top_earlgrey_physical_pads + - lowrisc:prim:assert + files: + - rtl/physical_pads.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/top_englishbreakfast_pkg.core b/hw/top_englishbreakfast/top_englishbreakfast_pkg.core new file mode 100644 index 0000000000000..de8f7f11459db --- /dev/null +++ b/hw/top_englishbreakfast/top_englishbreakfast_pkg.core @@ -0,0 +1,16 @@ +CAPI=2: +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 +name: "lowrisc:systems:top_englishbreakfast_pkg:0.1" +description: "Autogenerated top_englishbreakfast_pkg used in RTL and DV." +filesets: + files_rtl: + files: + - rtl/autogen/top_englishbreakfast_pkg.sv + file_type: systemVerilogSource + +targets: + default: &default_target + filesets: + - files_rtl diff --git a/hw/top_englishbreakfast/top_pkg.core b/hw/top_englishbreakfast/top_pkg.core index c2d9c1633c354..a95396121e687 100644 --- a/hw/top_englishbreakfast/top_pkg.core +++ b/hw/top_englishbreakfast/top_pkg.core @@ -3,9 +3,6 @@ CAPI=2: # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 -# XXX: This name is currently required as global identifier until we have -# support for "interfaces" or a similar concept. -# Tracked in https://github.com/olofk/fusesoc/issues/235 name: "lowrisc:constants:top_englishbreakfast_top_pkg" description: "Toplevel-wide constants for English Breakfast" diff --git a/hw/top_englishbreakfast/util/prepare_sw.py b/hw/top_englishbreakfast/util/prepare_sw.py index 27fe613df33e2..dbed98b52c8b8 100755 --- a/hw/top_englishbreakfast/util/prepare_sw.py +++ b/hw/top_englishbreakfast/util/prepare_sw.py @@ -138,7 +138,6 @@ def main(): REG_FILES = [ 'ip/ast/data/ast.hjson', 'ip/sensor_ctrl/data/sensor_ctrl.hjson', - 'ip_autogen/alert_handler/data/alert_handler.hjson', 'ip_autogen/clkmgr/data/clkmgr.hjson', 'ip_autogen/flash_ctrl/data/flash_ctrl.hjson', 'ip_autogen/pinmux/data/pinmux.hjson', diff --git a/rules/fusesoc.bzl b/rules/fusesoc.bzl index 2d40d7c439699..fc301d98618c3 100644 --- a/rules/fusesoc.bzl +++ b/rules/fusesoc.bzl @@ -66,10 +66,7 @@ def _fusesoc_build_impl(ctx): format_each = "--cores-root=%s", ) - args.add_all([ - "run", - "--flag=fileset_top", - ]) + args.add("run") args.add(ctx.attr.target, format = "--target=%s") args.add_all([ "--setup", @@ -80,8 +77,6 @@ def _fusesoc_build_impl(ctx): args.add_all(ctx.attr.systems) args.add_all(flags) - # Note: the `fileset_top` flag used above is specific to the OpenTitan - # project to select the correct RTL fileset. ctx.actions.run( mnemonic = "FuseSoC", outputs = outputs, diff --git a/sw/host/opentitanlib/src/chip/autogen/englishbreakfast.rs b/sw/host/opentitanlib/src/chip/autogen/englishbreakfast.rs new file mode 100644 index 0000000000000..f7a7c2ea637a4 --- /dev/null +++ b/sw/host/opentitanlib/src/chip/autogen/englishbreakfast.rs @@ -0,0 +1,282 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +// This file was generated automatically. +// Please do not modify content of this file directly. +// File generated by using template: "host_toplevel.rs.tpl" +// To regenerate this file follow OpenTitan topgen documentations. + +#![allow(dead_code)] + +use crate::with_unknown; + +with_unknown! { + pub enum PinmuxPeripheralIn: u32 [default = Self::End] { + GpioGpio0 = 0, + GpioGpio1 = 1, + GpioGpio2 = 2, + GpioGpio3 = 3, + GpioGpio4 = 4, + GpioGpio5 = 5, + GpioGpio6 = 6, + GpioGpio7 = 7, + GpioGpio8 = 8, + GpioGpio9 = 9, + GpioGpio10 = 10, + GpioGpio11 = 11, + GpioGpio12 = 12, + GpioGpio13 = 13, + GpioGpio14 = 14, + GpioGpio15 = 15, + GpioGpio16 = 16, + GpioGpio17 = 17, + GpioGpio18 = 18, + GpioGpio19 = 19, + GpioGpio20 = 20, + GpioGpio21 = 21, + GpioGpio22 = 22, + GpioGpio23 = 23, + GpioGpio24 = 24, + GpioGpio25 = 25, + GpioGpio26 = 26, + GpioGpio27 = 27, + GpioGpio28 = 28, + GpioGpio29 = 29, + GpioGpio30 = 30, + GpioGpio31 = 31, + Uart0Rx = 32, + Uart1Rx = 33, + FlashCtrlTck = 34, + FlashCtrlTms = 35, + FlashCtrlTdi = 36, + UsbdevSense = 37, + End = 38, + } + + pub enum PinmuxInsel: u32 [default = Self::End] { + ConstantZero = 0, + ConstantOne = 1, + Ioa0 = 2, + Ioa1 = 3, + Ioa2 = 4, + Ioa3 = 5, + Ioa4 = 6, + Ioa5 = 7, + Ioa6 = 8, + Ioa7 = 9, + Ioa8 = 10, + Iob0 = 11, + Iob1 = 12, + Iob2 = 13, + Iob3 = 14, + Iob4 = 15, + Iob5 = 16, + Iob6 = 17, + Iob7 = 18, + Iob8 = 19, + Iob9 = 20, + Iob10 = 21, + Iob11 = 22, + Iob12 = 23, + Ioc0 = 24, + Ioc1 = 25, + Ioc2 = 26, + Ioc3 = 27, + Ioc4 = 28, + Ioc5 = 29, + Ioc6 = 30, + Ioc7 = 31, + Ioc8 = 32, + Ioc9 = 33, + Ioc10 = 34, + Ioc11 = 35, + Ioc12 = 36, + Ior0 = 37, + Ior1 = 38, + Ior2 = 39, + Ior3 = 40, + Ior4 = 41, + Ior5 = 42, + Ior6 = 43, + Ior7 = 44, + Ior10 = 45, + Ior11 = 46, + Ior12 = 47, + Ior13 = 48, + End = 49, + } + + pub enum PinmuxMioOut: u32 [default = Self::End] { + Ioa0 = 0, + Ioa1 = 1, + Ioa2 = 2, + Ioa3 = 3, + Ioa4 = 4, + Ioa5 = 5, + Ioa6 = 6, + Ioa7 = 7, + Ioa8 = 8, + Iob0 = 9, + Iob1 = 10, + Iob2 = 11, + Iob3 = 12, + Iob4 = 13, + Iob5 = 14, + Iob6 = 15, + Iob7 = 16, + Iob8 = 17, + Iob9 = 18, + Iob10 = 19, + Iob11 = 20, + Iob12 = 21, + Ioc0 = 22, + Ioc1 = 23, + Ioc2 = 24, + Ioc3 = 25, + Ioc4 = 26, + Ioc5 = 27, + Ioc6 = 28, + Ioc7 = 29, + Ioc8 = 30, + Ioc9 = 31, + Ioc10 = 32, + Ioc11 = 33, + Ioc12 = 34, + Ior0 = 35, + Ior1 = 36, + Ior2 = 37, + Ior3 = 38, + Ior4 = 39, + Ior5 = 40, + Ior6 = 41, + Ior7 = 42, + Ior10 = 43, + Ior11 = 44, + Ior12 = 45, + Ior13 = 46, + End = 47, + } + + pub enum PinmuxOutsel: u32 [default = Self::End] { + ConstantZero = 0, + ConstantOne = 1, + ConstantHighZ = 2, + GpioGpio0 = 3, + GpioGpio1 = 4, + GpioGpio2 = 5, + GpioGpio3 = 6, + GpioGpio4 = 7, + GpioGpio5 = 8, + GpioGpio6 = 9, + GpioGpio7 = 10, + GpioGpio8 = 11, + GpioGpio9 = 12, + GpioGpio10 = 13, + GpioGpio11 = 14, + GpioGpio12 = 15, + GpioGpio13 = 16, + GpioGpio14 = 17, + GpioGpio15 = 18, + GpioGpio16 = 19, + GpioGpio17 = 20, + GpioGpio18 = 21, + GpioGpio19 = 22, + GpioGpio20 = 23, + GpioGpio21 = 24, + GpioGpio22 = 25, + GpioGpio23 = 26, + GpioGpio24 = 27, + GpioGpio25 = 28, + GpioGpio26 = 29, + GpioGpio27 = 30, + GpioGpio28 = 31, + GpioGpio29 = 32, + GpioGpio30 = 33, + GpioGpio31 = 34, + Uart0Tx = 35, + Uart1Tx = 36, + FlashCtrlTdo = 37, + End = 38, + } + + pub enum DirectPads: u32 [default = Self::End] { + SpiHost0Sd0 = 0, + SpiHost0Sd1 = 1, + SpiHost0Sd2 = 2, + SpiHost0Sd3 = 3, + SpiDeviceSd0 = 4, + SpiDeviceSd1 = 5, + SpiDeviceSd2 = 6, + SpiDeviceSd3 = 7, + UsbdevUsbDp = 8, + UsbdevUsbDn = 9, + SpiDeviceSck = 10, + SpiDeviceCsb = 11, + SpiHost0Sck = 12, + SpiHost0Csb = 13, + End = 14, + } + + pub enum MuxedPads: u32 [default = Self::End] { + Ioa0 = 0, + Ioa1 = 1, + Ioa2 = 2, + Ioa3 = 3, + Ioa4 = 4, + Ioa5 = 5, + Ioa6 = 6, + Ioa7 = 7, + Ioa8 = 8, + Iob0 = 9, + Iob1 = 10, + Iob2 = 11, + Iob3 = 12, + Iob4 = 13, + Iob5 = 14, + Iob6 = 15, + Iob7 = 16, + Iob8 = 17, + Iob9 = 18, + Iob10 = 19, + Iob11 = 20, + Iob12 = 21, + Ioc0 = 22, + Ioc1 = 23, + Ioc2 = 24, + Ioc3 = 25, + Ioc4 = 26, + Ioc5 = 27, + Ioc6 = 28, + Ioc7 = 29, + Ioc8 = 30, + Ioc9 = 31, + Ioc10 = 32, + Ioc11 = 33, + Ioc12 = 34, + Ior0 = 35, + Ior1 = 36, + Ior2 = 37, + Ior3 = 38, + Ior4 = 39, + Ior5 = 40, + Ior6 = 41, + Ior7 = 42, + Ior10 = 43, + Ior11 = 44, + Ior12 = 45, + Ior13 = 46, + End = 47, + } +} + +#[allow(non_camel_case_types)] +pub mod ujson_alias { + use super::*; + // Create aliases for the C names of these types so that the ujson + // created structs can access these structures by their C names. + pub type pinmux_peripheral_in_t = PinmuxPeripheralIn; + pub type pinmux_insel_t = PinmuxInsel; + pub type pinmux_mio_out_t = PinmuxMioOut; + pub type pinmux_outsel_t = PinmuxOutsel; +} diff --git a/topgen.core b/topgen.core deleted file mode 100644 index 77ab40c61378b..0000000000000 --- a/topgen.core +++ /dev/null @@ -1,17 +0,0 @@ -CAPI=2: -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -name: "lowrisc:systems:topgen" -description: "Top-level generator tool." - -filesets: - rtl: - depend: - - lowrisc:systems:generated-topgen - - -targets: - default: &default - filesets: - - rtl diff --git a/util/topgen-fusesoc.py b/util/topgen-fusesoc.py deleted file mode 100755 index 9e4403c3c5cea..0000000000000 --- a/util/topgen-fusesoc.py +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env python3 -# Copyright lowRISC contributors (OpenTitan project). -# Licensed under the Apache License, Version 2.0, see LICENSE for details. -# SPDX-License-Identifier: Apache-2.0 -r"""Stopgap script to generate some cores for the englishbreakfast toplevel. - -All output files are written to $REPO_TOP/build/$TOPNAME-autogen/. -""" - -import argparse -import sys -import yaml -import shutil -import subprocess -import os - -try: - from yaml import CSafeDumper as YamlDumper -except ImportError: - from yaml import SafeDumper as YamlDumper - - -def write_core(core_filepath, generated_core): - with open(core_filepath, 'w') as f: - # FuseSoC requires this line to appear first in the YAML file. - # Inserting this line through the YAML serializer requires ordered dicts - # to be used everywhere, which is annoying syntax-wise on Python <3.7, - # where native dicts are not sorted. - f.write('CAPI=2:\n') - yaml.dump(generated_core, - f, - encoding="utf-8", - Dumper=YamlDumper) - print("Core file written to %s" % (core_filepath, )) - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('--files-root', required=True) - parser.add_argument('--topname', required=True) - - args = parser.parse_args() - topname = args.topname - files_root = args.files_root - - # Call topgen. - files_data = files_root + "/hw/" + topname + "/data/" - files_out = os.path.abspath(files_root + "/build/" + topname + "-autogen/") - shutil.rmtree(files_out, ignore_errors=True) - os.makedirs(files_out, exist_ok=False) - cmd = [files_root + "/util/topgen.py", # "--verbose", - "-t", files_data + topname + ".hjson", - "-o", files_out] - try: - print("Running topgen.") - subprocess.run(cmd, - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - universal_newlines=True) - - except subprocess.CalledProcessError as e: - print("topgen failed: " + str(e)) - print(e.stdout) - sys.exit(1) - - # Create core files. - print("Creating core files.") - - # For some cores such IP package files, we need a separate dependency for the register file. - # Combining this with the generated topgen core file below can lead to cyclic dependencies. - - # reg-only - for ip in ['pinmux']: - core_filepath = os.path.abspath(os.path.join(files_out, 'generated-%s.core' % ip)) - name = 'lowrisc:ip:%s_reggen' % ip, - files = ['ip/%s/rtl/autogen/%s_reg_pkg.sv' % (ip, ip), - 'ip/%s/rtl/autogen/%s_reg_top.sv' % (ip, ip)] - generated_core = { - 'name': '%s' % name, - 'filesets': { - 'files_rtl': { - 'depend': [ - 'lowrisc:ip:tlul', - ], - 'files': files, - 'file_type': 'systemVerilogSource' - }, - }, - 'targets': { - 'default': { - 'filesets': [ - 'files_rtl', - ], - }, - }, - } - write_core(core_filepath, generated_core) - - # topgen - nameparts = topname.split('_') - if nameparts[0] == 'top' and len(nameparts) > 1: - chipname = 'chip_' + '_'.join(nameparts[1:]) - else: - chipname = topname - - core_filepath = os.path.abspath(os.path.join(files_out, 'generated-topgen.core')) - generated_core = { - 'name': "lowrisc:systems:generated-topgen", - 'filesets': { - 'files_rtl': { - 'depend': [ - # Ibex and OTBN constants - 'lowrisc:ibex:ibex_pkg', - 'lowrisc:ip:otbn_pkg', - # flash_ctrl - f'lowrisc:constants:{topname}_top_pkg', - 'lowrisc:prim:util', - 'lowrisc:ip:lc_ctrl_pkg', - f'lowrisc:opentitan:{topname}_clkmgr_pkg', - f'lowrisc:opentitan:{topname}_flash_ctrl_pkg', - f'lowrisc:opentitan:{topname}_pwrmgr_pkg', - f'lowrisc:opentitan:{topname}_rstmgr_pkg', - 'lowrisc:prim:clock_mux2', - # clkmgr - 'lowrisc:prim:all', - 'lowrisc:prim:clock_gating', - 'lowrisc:prim:clock_buf', - 'lowrisc:prim:clock_div', - # Top - # ast and sensor_ctrl not auto-generated, re-used from top_earlgrey - 'lowrisc:systems:top_earlgrey_sensor_ctrl', - 'lowrisc:systems:top_earlgrey_ast_pkg', - # TODO: absorb this into AST longerm - 'lowrisc:systems:clkgen_xil7series', - ], - 'files': [ - # Top - 'rtl/autogen/%s_rnd_cnst_pkg.sv' % topname, - 'rtl/autogen/%s_pkg.sv' % topname, - 'rtl/autogen/%s.sv' % topname, - # TODO: this is not ideal. we should extract - # this info from the target configuration and - # possibly generate separate core files for this. - 'rtl/autogen/%s_cw305.sv' % chipname, - ], - 'file_type': 'systemVerilogSource' - }, - }, - 'targets': { - 'default': { - 'filesets': [ - 'files_rtl', - ], - }, - }, - } - write_core(core_filepath, generated_core) - - return 0 - - -if __name__ == "__main__": - main() diff --git a/util/topgen.py b/util/topgen.py index 77e831b64d499..3074f083dccb5 100755 --- a/util/topgen.py +++ b/util/topgen.py @@ -909,8 +909,7 @@ def _process_top( # Generate Alert Handler if there is an instance if not args.xbar_only: - if lib.find_module(completecfg['module'], 'alert_handler') or \ - completecfg['name'] == 'englishbreakfast': + if lib.find_module(completecfg['module'], 'alert_handler'): generate_alert_handler(completecfg, out_path) if args.alert_handler_only: sys.exit() diff --git a/util/topgen/c_test.py b/util/topgen/c_test.py index dc3bd85830dc8..67aa47d856a27 100644 --- a/util/topgen/c_test.py +++ b/util/topgen/c_test.py @@ -65,8 +65,7 @@ def __init__(self, top_info, name_to_block: Dict[str, IpBlock]): self.irq_peripherals = self._get_irq_peripherals() # Only generate alert_handler and mappings if there is an alert_handler - if find_module(self.top['module'], 'alert_handler') or \ - self.top['name'] == 'englishbreakfast': + if find_module(self.top['module'], 'alert_handler'): self.alert_peripherals = self._get_alert_peripherals() def _get_irq_peripherals(self): diff --git a/util/topgen/lib.py b/util/topgen/lib.py index fafef3d3bdad4..d0febe8ab95b1 100644 --- a/util/topgen/lib.py +++ b/util/topgen/lib.py @@ -875,8 +875,7 @@ def __init__(self, top_info, name_to_block: Dict[str, IpBlock], enum_type, array self._init_plic_mapping() # Only generate alert_handler and mappings if there is an alert_handler - if find_module(self.top['module'], 'alert_handler') or \ - self.top['name'] == 'englishbreakfast': + if find_module(self.top['module'], 'alert_handler'): self._init_alert_mapping() # Only generate pinmux and pad mappings if there is a pinmux if find_module(self.top['module'], 'pinmux'): diff --git a/util/topgen/templates/toplevel.c.tpl b/util/topgen/templates/toplevel.c.tpl index 6a568da29f288..9b9edfa4bc502 100644 --- a/util/topgen/templates/toplevel.c.tpl +++ b/util/topgen/templates/toplevel.c.tpl @@ -5,7 +5,7 @@ ${gencmd} <% import topgen.lib as lib -has_alert_handler = lib.find_module(top['module'], 'alert_handler') or top['name'] == 'englishbreakfast' +has_alert_handler = lib.find_module(top['module'], 'alert_handler') %>\ #include "${helper.header_path}" diff --git a/util/topgen/templates/toplevel.h.tpl b/util/topgen/templates/toplevel.h.tpl index 17b4940025a58..e62d95824937b 100644 --- a/util/topgen/templates/toplevel.h.tpl +++ b/util/topgen/templates/toplevel.h.tpl @@ -8,7 +8,7 @@ import topgen.lib as lib has_pwrmgr = lib.find_module(top['module'], 'pwrmgr') has_pinmux = lib.find_module(top['module'], 'pinmux') -has_alert_handler = lib.find_module(top['module'], 'alert_handler') or top['name'] == 'englishbreakfast' +has_alert_handler = lib.find_module(top['module'], 'alert_handler') has_clkmgr = lib.find_module(top['module'], 'clkmgr') has_rstmgr = lib.find_module(top['module'], 'rstmgr') %>\ diff --git a/util/topgen/templates/toplevel.rs.tpl b/util/topgen/templates/toplevel.rs.tpl index e8d485e2ca9fb..3cd473e727c01 100644 --- a/util/topgen/templates/toplevel.rs.tpl +++ b/util/topgen/templates/toplevel.rs.tpl @@ -7,7 +7,7 @@ import topgen.lib as lib has_pwrmgr = lib.find_module(top['module'], 'pwrmgr') has_pinmux = lib.find_module(top['module'], 'pinmux') -has_alert_handler = lib.find_module(top['module'], 'alert_handler') or top['name'] == 'englishbreakfast' +has_alert_handler = lib.find_module(top['module'], 'alert_handler') has_clkmgr = lib.find_module(top['module'], 'clkmgr') has_rstmgr = lib.find_module(top['module'], 'rstmgr') %>\