feat: refactor memory map definitions and enhance fault handling in Mini SoC

- Updated core_wrapper and mgmt_core_wrapper to use new SOC reset and IRQ addresses.
- Removed obsolete mmap_define.svh file and integrated memory map generation into the build process.
- Enhanced ip_nmi_wrapper to handle fault signals and updated NMI interface assignments.
- Added bus fault and sysctrl fault testbenches to validate fault handling mechanisms.
- Improved memory map generation script and added tests for memory map validation and fault responder behavior.
This commit is contained in:
maksyuki committed 2026-07-20 12:01:48 +08:00
1 parent bd376a0670
commit 82e5c605a8
28 files changed
+1139 -482

No files matched your search

+1 -1
View File
@@ -52,7 +52,7 @@ icsprout55-pdk
IHP-Open-PDK
skywater-pdk
gf180mcu-pdk
demo
demo*
dont_use_cell_*
clusterip
nanoV
+2
View File
@@ -178,6 +178,8 @@ help:
' setup install pinned external dependencies' \
' doctor check tools, paths, and selected configuration' \
' config | manifest print/write the effective configuration' \
' memory-map generate the selected address-map artifacts' \
' check-memory-map validate the canonical address map' \
' check-warnings | metrics analyze flow logs and reports' \
' check-metrics apply the committed metrics policy' \
' sw-format apply clang-format to self-owned embedded C code' \
+201 -201
View File
@@ -4,6 +4,8 @@
#include <stdint.h>
#include <stdbool.h>
#include <retrosoc/generated/memory_map.h>
#ifdef CORE_PICORV32
#define HW_CORE "PicoRV32"
#elif CORE_HAZARD3
@@ -19,231 +21,229 @@
#define PSRAM_SCLK_MAX_FREQ 133 // unit: MHz
#define PSRAM_SCLK_FREQ (CPU_FREQ / 2)
#define SPFS_MEM_START 0x00000000
#define SPFS_MEM_OFFST 32 * 1024 * 1024
#define NMI_MEM_START 0x10000000
#define NMI_MEM_OFFST 256 * 1024 * 1024
#define APB_MEM_START 0x20000000
#define APB_MEM_OFFST 256 * 1024 * 1024
#define SRAM_MEM_START 0x30000000
#define SRAM_MEM_OFFST 128 * 1024
#define SDRAM_MEM_START 0x38000000
#define SDRAM_MEM_OFFST 64 * 1024 * 1024
#define PSRAM_MEM_START 0x40000000
#define PSRAM_MEM_OFFST 8 * 1024 * 1024 * PSRAM_NUM
#define OPIPSRAM_MEM_START 0x48000000
#define OPIPSRAM_MEM_OFFST 32 * 1024 * 1024
#define XPI_MEM_START 0x50000000
#define XPI_MEM_OFFST 256 * 1024 * 1024
#define TF_CARD_START (uint32_t)0x60000000
#define TF_CARD_OFFST (uint32_t)0x40000000
#define SPFS_MEM_START RS_SOC_FLASH_BASE
#define SPFS_MEM_OFFST RS_SOC_FLASH_SIZE
#define SRAM_MEM_START RS_SOC_SRAM_BASE
#define SRAM_MEM_OFFST RS_SOC_SRAM_SIZE
#define SDRAM_MEM_START RS_SOC_SDRAM_BASE
#define SDRAM_MEM_OFFST RS_SOC_SDRAM_SIZE
#define PSRAM_MEM_START RS_SOC_PSRAM_BASE
#define PSRAM_MEM_OFFST RS_SOC_PSRAM_SIZE
#define XPI_MEM_START RS_SOC_XPI_BASE
#define XPI_MEM_OFFST RS_SOC_XPI_SIZE
#define TF_CARD_START RS_SOC_SPISD_BASE
#define TF_CARD_OFFST RS_SOC_SPISD_SIZE
#define RS_SOC_REG32(base, offset) (*(volatile uint32_t *)(uintptr_t)((base) + (offset)))
// gpio
#define reg_gpio_oe (*(volatile uint32_t *)0x10000000)
#define reg_gpio_cs (*(volatile uint32_t *)0x10000004)
#define reg_gpio_pu (*(volatile uint32_t *)0x10000008)
#define reg_gpio_pd (*(volatile uint32_t *)0x1000000c)
#define reg_gpio_do (*(volatile uint32_t *)0x10000010)
#define reg_gpio_di (*(volatile uint32_t *)0x10000014)
#define reg_gpio_ien (*(volatile uint32_t *)0x10000018)
#define reg_gpio_itype0 (*(volatile uint32_t *)0x1000001c)
#define reg_gpio_itype1 (*(volatile uint32_t *)0x10000020)
#define reg_gpio_istat (*(volatile uint32_t *)0x10000024)
#define reg_gpio_iofcfg (*(volatile uint32_t *)0x10000028)
#define reg_gpio_pinmux (*(volatile uint32_t *)0x1000002c)
#define reg_gpio_oe RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x00))
#define reg_gpio_cs RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x04))
#define reg_gpio_pu RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x08))
#define reg_gpio_pd RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x0C))
#define reg_gpio_do RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x10))
#define reg_gpio_di RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x14))
#define reg_gpio_ien RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x18))
#define reg_gpio_itype0 RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x1C))
#define reg_gpio_itype1 RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x20))
#define reg_gpio_istat RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x24))
#define reg_gpio_iofcfg RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x28))
#define reg_gpio_pinmux RS_SOC_REG32(RS_SOC_NMI_GPIO_BASE, UINT32_C(0x2C))
// uart0
#define reg_uart0_clkdiv (*(volatile uint32_t *)0x10001000)
#define reg_uart0_data (*(volatile uint32_t *)0x10001004)
#define reg_uart0_clkdiv RS_SOC_REG32(RS_SOC_NMI_UART0_BASE, UINT32_C(0x00))
#define reg_uart0_data RS_SOC_REG32(RS_SOC_NMI_UART0_BASE, UINT32_C(0x04))
// tim0
#define reg_tim0_cfg (*(volatile uint32_t *)0x10002000)
#define reg_tim0_rld (*(volatile uint32_t *)0x10002004)
#define reg_tim0_val (*(volatile uint32_t *)0x10002008)
#define reg_tim0_cfg RS_SOC_REG32(RS_SOC_NMI_TIM0_BASE, UINT32_C(0x00))
#define reg_tim0_rld RS_SOC_REG32(RS_SOC_NMI_TIM0_BASE, UINT32_C(0x04))
#define reg_tim0_val RS_SOC_REG32(RS_SOC_NMI_TIM0_BASE, UINT32_C(0x08))
// tim1
#define reg_tim1_cfg (*(volatile uint32_t *)0x10003000)
#define reg_tim1_rld (*(volatile uint32_t *)0x10003004)
#define reg_tim1_val (*(volatile uint32_t *)0x10003008)
#define reg_tim1_cfg RS_SOC_REG32(RS_SOC_NMI_TIM1_BASE, UINT32_C(0x00))
#define reg_tim1_rld RS_SOC_REG32(RS_SOC_NMI_TIM1_BASE, UINT32_C(0x04))
#define reg_tim1_val RS_SOC_REG32(RS_SOC_NMI_TIM1_BASE, UINT32_C(0x08))
// psram
#define reg_psram_wait (*(volatile uint32_t *)0x10004000)
#define reg_psram_chd (*(volatile uint32_t *)0x10004004)
#define reg_psram_init (*(volatile uint32_t *)0x10004008)
#define reg_psram_wait RS_SOC_REG32(RS_SOC_NMI_PSRAM_BASE, UINT32_C(0x00))
#define reg_psram_chd RS_SOC_REG32(RS_SOC_NMI_PSRAM_BASE, UINT32_C(0x04))
#define reg_psram_init RS_SOC_REG32(RS_SOC_NMI_PSRAM_BASE, UINT32_C(0x08))
// spisd
#define reg_spisd_mode (*(volatile uint32_t *)0x10005000)
#define reg_spisd_clkdiv (*(volatile uint32_t *)0x10005004)
#define reg_spisd_addr (*(volatile uint32_t *)0x10005008)
#define reg_spisd_txdata (*(volatile uint32_t *)0x1000500C)
#define reg_spisd_rxdata (*(volatile uint32_t *)0x10005010)
#define reg_spisd_status (*(volatile uint32_t *)0x10005014)
#define reg_spisd_sync (*(volatile uint32_t *)0x10005018)
#define reg_spisd_mode RS_SOC_REG32(RS_SOC_NMI_SPISD_BASE, UINT32_C(0x00))
#define reg_spisd_clkdiv RS_SOC_REG32(RS_SOC_NMI_SPISD_BASE, UINT32_C(0x04))
#define reg_spisd_addr RS_SOC_REG32(RS_SOC_NMI_SPISD_BASE, UINT32_C(0x08))
#define reg_spisd_txdata RS_SOC_REG32(RS_SOC_NMI_SPISD_BASE, UINT32_C(0x0C))
#define reg_spisd_rxdata RS_SOC_REG32(RS_SOC_NMI_SPISD_BASE, UINT32_C(0x10))
#define reg_spisd_status RS_SOC_REG32(RS_SOC_NMI_SPISD_BASE, UINT32_C(0x14))
#define reg_spisd_sync RS_SOC_REG32(RS_SOC_NMI_SPISD_BASE, UINT32_C(0x18))
// i2c0
#define reg_i2c0_clkdiv (*(volatile uint32_t *)0x10006000)
#define reg_i2c0_devaddr (*(volatile uint32_t *)0x10006004)
#define reg_i2c0_regaddr (*(volatile uint32_t *)0x10006008)
#define reg_i2c0_txdata (*(volatile uint32_t *)0x1000600C)
#define reg_i2c0_rxdata (*(volatile uint32_t *)0x10006010)
#define reg_i2c0_xfer (*(volatile uint32_t *)0x10006014)
#define reg_i2c0_cfg (*(volatile uint32_t *)0x10006018)
#define reg_i2c0_status (*(volatile uint32_t *)0x1000601C)
#define reg_i2c0_clkdiv RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x00))
#define reg_i2c0_devaddr RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x04))
#define reg_i2c0_regaddr RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x08))
#define reg_i2c0_txdata RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x0C))
#define reg_i2c0_rxdata RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x10))
#define reg_i2c0_xfer RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x14))
#define reg_i2c0_cfg RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x18))
#define reg_i2c0_status RS_SOC_REG32(RS_SOC_NMI_I2C0_BASE, UINT32_C(0x1C))
// i2s
#define reg_i2s_mode (*(volatile uint32_t *)0x10007000)
#define reg_i2s_format (*(volatile uint32_t *)0x10007004)
#define reg_i2s_upbound (*(volatile uint32_t *)0x10007008)
#define reg_i2s_lowbound (*(volatile uint32_t *)0x1000700C)
#define reg_i2s_recven (*(volatile uint32_t *)0x10007010)
#define reg_i2s_txdata (*(volatile uint32_t *)0x10007014)
#define reg_i2s_rxdata (*(volatile uint32_t *)0x10007018)
#define reg_i2s_status (*(volatile uint32_t *)0x1000701C)
#define reg_i2s_mode RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x00))
#define reg_i2s_format RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x04))
#define reg_i2s_upbound RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x08))
#define reg_i2s_lowbound RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x0C))
#define reg_i2s_recven RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x10))
#define reg_i2s_txdata RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x14))
#define reg_i2s_rxdata RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x18))
#define reg_i2s_status RS_SOC_REG32(RS_SOC_NMI_I2S_BASE, UINT32_C(0x1C))
// onewire
#define reg_onewire_clkdiv (*(volatile uint32_t *)0x10008000)
#define reg_onewire_zerocnt (*(volatile uint32_t *)0x10008004)
#define reg_onewire_onecnt (*(volatile uint32_t *)0x10008008)
#define reg_onewire_rstcnt (*(volatile uint32_t *)0x1000800C)
#define reg_onewire_txdata (*(volatile uint32_t *)0x10008010)
#define reg_onewire_ctrl (*(volatile uint32_t *)0x10008014)
#define reg_onewire_status (*(volatile uint32_t *)0x10008018)
#define reg_onewire_clkdiv RS_SOC_REG32(RS_SOC_NMI_ONEWIRE_BASE, UINT32_C(0x00))
#define reg_onewire_zerocnt RS_SOC_REG32(RS_SOC_NMI_ONEWIRE_BASE, UINT32_C(0x04))
#define reg_onewire_onecnt RS_SOC_REG32(RS_SOC_NMI_ONEWIRE_BASE, UINT32_C(0x08))
#define reg_onewire_rstcnt RS_SOC_REG32(RS_SOC_NMI_ONEWIRE_BASE, UINT32_C(0x0C))
#define reg_onewire_txdata RS_SOC_REG32(RS_SOC_NMI_ONEWIRE_BASE, UINT32_C(0x10))
#define reg_onewire_ctrl RS_SOC_REG32(RS_SOC_NMI_ONEWIRE_BASE, UINT32_C(0x14))
#define reg_onewire_status RS_SOC_REG32(RS_SOC_NMI_ONEWIRE_BASE, UINT32_C(0x18))
// xpi
#define reg_xpi_cfgidx (*(volatile uint32_t *)0x10009000)
#define reg_xpi_accmd (*(volatile uint32_t *)0x10009004)
#define reg_xpi_mmstad (*(volatile uint32_t *)0x10009008)
#define reg_xpi_mmoffst (*(volatile uint32_t *)0x1000900C)
#define reg_xpi_mode (*(volatile uint32_t *)0x10009010)
#define reg_xpi_nss (*(volatile uint32_t *)0x10009014)
#define reg_xpi_clkdiv (*(volatile uint32_t *)0x10009018)
#define reg_xpi_rdwr (*(volatile uint32_t *)0x1000901C)
#define reg_xpi_revdat (*(volatile uint32_t *)0x10009020)
#define reg_xpi_txupb (*(volatile uint32_t *)0x10009024)
#define reg_xpi_txlowb (*(volatile uint32_t *)0x10009028)
#define reg_xpi_rxupb (*(volatile uint32_t *)0x1000902C)
#define reg_xpi_rxlowb (*(volatile uint32_t *)0x10009030)
#define reg_xpi_flush (*(volatile uint32_t *)0x10009034)
#define reg_xpi_cmdtyp (*(volatile uint32_t *)0x10009038)
#define reg_xpi_cmdlen (*(volatile uint32_t *)0x1000903C)
#define reg_xpi_cmddat (*(volatile uint32_t *)0x10009040)
#define reg_xpi_adrtyp (*(volatile uint32_t *)0x10009044)
#define reg_xpi_adrlen (*(volatile uint32_t *)0x10009048)
#define reg_xpi_adrdat (*(volatile uint32_t *)0x1000904C)
#define reg_xpi_alttyp (*(volatile uint32_t *)0x10009050)
#define reg_xpi_altlen (*(volatile uint32_t *)0x10009054)
#define reg_xpi_altdat (*(volatile uint32_t *)0x10009058)
#define reg_xpi_tdulen (*(volatile uint32_t *)0x1000905C)
#define reg_xpi_rdulen (*(volatile uint32_t *)0x10009060)
#define reg_xpi_dattyp (*(volatile uint32_t *)0x10009064)
#define reg_xpi_datlen (*(volatile uint32_t *)0x10009068)
#define reg_xpi_datbit (*(volatile uint32_t *)0x1000906C)
#define reg_xpi_hlvlen (*(volatile uint32_t *)0x10009070)
#define reg_xpi_txdata (*(volatile uint32_t *)0x10009074)
#define reg_xpi_rxdata (*(volatile uint32_t *)0x10009078)
#define reg_xpi_start (*(volatile uint32_t *)0x1000907C)
#define reg_xpi_status (*(volatile uint32_t *)0x10009080)
#define reg_xpi_cfgidx RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x00))
#define reg_xpi_accmd RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x04))
#define reg_xpi_mmstad RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x08))
#define reg_xpi_mmoffst RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x0C))
#define reg_xpi_mode RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x10))
#define reg_xpi_nss RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x14))
#define reg_xpi_clkdiv RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x18))
#define reg_xpi_rdwr RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x1C))
#define reg_xpi_revdat RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x20))
#define reg_xpi_txupb RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x24))
#define reg_xpi_txlowb RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x28))
#define reg_xpi_rxupb RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x2C))
#define reg_xpi_rxlowb RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x30))
#define reg_xpi_flush RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x34))
#define reg_xpi_cmdtyp RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x38))
#define reg_xpi_cmdlen RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x3C))
#define reg_xpi_cmddat RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x40))
#define reg_xpi_adrtyp RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x44))
#define reg_xpi_adrlen RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x48))
#define reg_xpi_adrdat RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x4C))
#define reg_xpi_alttyp RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x50))
#define reg_xpi_altlen RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x54))
#define reg_xpi_altdat RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x58))
#define reg_xpi_tdulen RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x5C))
#define reg_xpi_rdulen RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x60))
#define reg_xpi_dattyp RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x64))
#define reg_xpi_datlen RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x68))
#define reg_xpi_datbit RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x6C))
#define reg_xpi_hlvlen RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x70))
#define reg_xpi_txdata RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x74))
#define reg_xpi_rxdata RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x78))
#define reg_xpi_start RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x7C))
#define reg_xpi_status RS_SOC_REG32(RS_SOC_NMI_XPI_BASE, UINT32_C(0x80))
// dma(32b xfer, hardware trigger by I2S fifo, QSPI fifo)
#define reg_dma_mode (*(volatile uint32_t *)0x1000A000)
#define reg_dma_srcaddr (*(volatile uint32_t *)0x1000A004)
#define reg_dma_srcincr (*(volatile uint32_t *)0x1000A008)
#define reg_dma_dstaddr (*(volatile uint32_t *)0x1000A00C)
#define reg_dma_dstincr (*(volatile uint32_t *)0x1000A010)
#define reg_dma_xferlen (*(volatile uint32_t *)0x1000A014)
#define reg_dma_start (*(volatile uint32_t *)0x1000A018)
#define reg_dma_stop (*(volatile uint32_t *)0x1000A01C)
#define reg_dma_reset (*(volatile uint32_t *)0x1000A020)
#define reg_dma_status (*(volatile uint32_t *)0x1000A024)
#define reg_dma_fsm (*(volatile uint32_t *)0x1000A028)
#define reg_dma_mode RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x00))
#define reg_dma_srcaddr RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x04))
#define reg_dma_srcincr RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x08))
#define reg_dma_dstaddr RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x0C))
#define reg_dma_dstincr RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x10))
#define reg_dma_xferlen RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x14))
#define reg_dma_start RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x18))
#define reg_dma_stop RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x1C))
#define reg_dma_reset RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x20))
#define reg_dma_status RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x24))
#define reg_dma_fsm RS_SOC_REG32(RS_SOC_NMI_DMA_BASE, UINT32_C(0x28))
// sys ctrl
#define reg_sysctrl_coresel (*(volatile uint32_t *)0x1000B000)
#define reg_sysctrl_ipsel (*(volatile uint32_t *)0x1000B004)
#define reg_sysctrl_i2csel (*(volatile uint32_t *)0x1000B008)
#define reg_sysctrl_qspicsel (*(volatile uint32_t *)0x1000B00C)
#define RS_SOC_SYSCTRL_REG32(offset) RS_SOC_REG32(RS_SOC_NMI_SYSCTRL_BASE, (offset))
#define reg_sysctrl_coresel RS_SOC_REG32(RS_SOC_NMI_SYSCTRL_BASE, UINT32_C(0x00))
#define reg_sysctrl_ipsel RS_SOC_REG32(RS_SOC_NMI_SYSCTRL_BASE, UINT32_C(0x04))
#define reg_sysctrl_i2csel RS_SOC_REG32(RS_SOC_NMI_SYSCTRL_BASE, UINT32_C(0x08))
#define reg_sysctrl_qspicsel RS_SOC_REG32(RS_SOC_NMI_SYSCTRL_BASE, UINT32_C(0x0C))
/* Status: bit 0 pending (W1C), bit 1 write, bits 3:2 reason (1 unmapped, 2 reserved). */
#define reg_sysctrl_bus_fault_status RS_SOC_SYSCTRL_REG32(RS_SOC_SYSCTRL_FAULT_STATUS_OFFSET)
#define reg_sysctrl_bus_fault_addr RS_SOC_SYSCTRL_REG32(RS_SOC_SYSCTRL_FAULT_ADDR_OFFSET)
#define reg_sysctrl_bus_fault_count RS_SOC_SYSCTRL_REG32(RS_SOC_SYSCTRL_FAULT_COUNT_OFFSET)
#define RS_SOC_BUS_FAULT_PENDING UINT32_C(0x00000001)
#define RS_SOC_BUS_FAULT_WRITE UINT32_C(0x00000002)
#define RS_SOC_BUS_FAULT_REASON_MASK UINT32_C(0x0000000C)
#define RS_SOC_BUS_FAULT_REASON_UNMAPPED UINT32_C(0x00000004)
#define RS_SOC_BUS_FAULT_REASON_RESERVED UINT32_C(0x00000008)
// clint
#define reg_clint_mtimel (*(volatile uint32_t *)0x1000C000)
#define reg_clint_mtimeh (*(volatile uint32_t *)0x1000C004)
#define reg_clint_mtimecmpl (*(volatile uint32_t *)0x1000C008)
#define reg_clint_mtimecmph (*(volatile uint32_t *)0x1000C00C)
#define reg_clint_msip (*(volatile uint32_t *)0x1000C010)
#define reg_clint_clkdiv (*(volatile uint32_t *)0x1000C014)
#define reg_clint_mtimel RS_SOC_REG32(RS_SOC_NMI_CLINT_BASE, UINT32_C(0x00))
#define reg_clint_mtimeh RS_SOC_REG32(RS_SOC_NMI_CLINT_BASE, UINT32_C(0x04))
#define reg_clint_mtimecmpl RS_SOC_REG32(RS_SOC_NMI_CLINT_BASE, UINT32_C(0x08))
#define reg_clint_mtimecmph RS_SOC_REG32(RS_SOC_NMI_CLINT_BASE, UINT32_C(0x0C))
#define reg_clint_msip RS_SOC_REG32(RS_SOC_NMI_CLINT_BASE, UINT32_C(0x10))
#define reg_clint_clkdiv RS_SOC_REG32(RS_SOC_NMI_CLINT_BASE, UINT32_C(0x14))
// sdram
#define reg_sdram_clkdiv (*(volatile uint32_t *)0x1000D000)
#define reg_sdram_cfg (*(volatile uint32_t *)0x1000D004)
#define reg_sdram_clkdiv RS_SOC_REG32(RS_SOC_NMI_SDRAM_BASE, UINT32_C(0x00))
#define reg_sdram_cfg RS_SOC_REG32(RS_SOC_NMI_SDRAM_BASE, UINT32_C(0x04))
// dvp
#define reg_dvp_recven (*(volatile uint32_t *)0x1000E000)
#define reg_dvp_rxdata (*(volatile uint32_t *)0x1000E004)
#define reg_dvp_status (*(volatile uint32_t *)0x1000E008)
// sdio
#define reg_sdio_cfg (*(volatile uint32_t *)0x1000F000)
// opipsram
#define reg_opipsram_cfg (*(volatile uint32_t *)0x10010000)
#define reg_dvp_recven RS_SOC_REG32(RS_SOC_NMI_DVP_BASE, UINT32_C(0x00))
#define reg_dvp_rxdata RS_SOC_REG32(RS_SOC_NMI_DVP_BASE, UINT32_C(0x04))
#define reg_dvp_status RS_SOC_REG32(RS_SOC_NMI_DVP_BASE, UINT32_C(0x08))
// i2c1
#define reg_i2c1_clkdiv (*(volatile uint32_t *)0x10011000)
#define reg_i2c1_devaddr (*(volatile uint32_t *)0x10011004)
#define reg_i2c1_regaddr (*(volatile uint32_t *)0x10011008)
#define reg_i2c1_txdata (*(volatile uint32_t *)0x1001100C)
#define reg_i2c1_rxdata (*(volatile uint32_t *)0x10011010)
#define reg_i2c1_xfer (*(volatile uint32_t *)0x10011014)
#define reg_i2c1_cfg (*(volatile uint32_t *)0x10011018)
#define reg_i2c1_status (*(volatile uint32_t *)0x1001101C)
// ga
#define reg_ga_cfg (*(volatile uint32_t *)0x10012000)
// apu
#define reg_apu_cfg (*(volatile uint32_t *)0x10013000)
#define reg_i2c1_clkdiv RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x00))
#define reg_i2c1_devaddr RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x04))
#define reg_i2c1_regaddr RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x08))
#define reg_i2c1_txdata RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x0C))
#define reg_i2c1_rxdata RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x10))
#define reg_i2c1_xfer RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x14))
#define reg_i2c1_cfg RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x18))
#define reg_i2c1_status RS_SOC_REG32(RS_SOC_NMI_I2C1_BASE, UINT32_C(0x1C))
// archinfo
#define reg_archinfo_sys (*(volatile uint32_t *)0x20000000)
#define reg_archinfo_idl (*(volatile uint32_t *)0x20000004)
#define reg_archinfo_idh (*(volatile uint32_t *)0x20000008)
#define reg_archinfo_sys RS_SOC_REG32(RS_SOC_APB_ARCHINFO_BASE, UINT32_C(0x00))
#define reg_archinfo_idl RS_SOC_REG32(RS_SOC_APB_ARCHINFO_BASE, UINT32_C(0x04))
#define reg_archinfo_idh RS_SOC_REG32(RS_SOC_APB_ARCHINFO_BASE, UINT32_C(0x08))
// rng
#define reg_rng_ctrl (*(volatile uint32_t *)0x20001000)
#define reg_rng_seed (*(volatile uint32_t *)0x20001004)
#define reg_rng_val (*(volatile uint32_t *)0x20001008)
#define reg_rng_ctrl RS_SOC_REG32(RS_SOC_APB_RNG_BASE, UINT32_C(0x00))
#define reg_rng_seed RS_SOC_REG32(RS_SOC_APB_RNG_BASE, UINT32_C(0x04))
#define reg_rng_val RS_SOC_REG32(RS_SOC_APB_RNG_BASE, UINT32_C(0x08))
// uart
#define reg_uart1_lcr (*(volatile uint32_t *)0x20002000)
#define reg_uart1_div (*(volatile uint32_t *)0x20002004)
#define reg_uart1_trx (*(volatile uint32_t *)0x20002008)
#define reg_uart1_fcr (*(volatile uint32_t *)0x2000200c)
#define reg_uart1_lsr (*(volatile uint32_t *)0x20002010)
#define reg_uart1_lcr RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x00))
#define reg_uart1_div RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x04))
#define reg_uart1_trx RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x08))
#define reg_uart1_fcr RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x0C))
#define reg_uart1_lsr RS_SOC_REG32(RS_SOC_APB_UART1_BASE, UINT32_C(0x10))
// pwm
#define reg_pwm_ctrl (*(volatile uint32_t *)0x20003000)
#define reg_pwm_pscr (*(volatile uint32_t *)0x20003004)
#define reg_pwm_cnt (*(volatile uint32_t *)0x20003008)
#define reg_pwm_cmp (*(volatile uint32_t *)0x2000300c)
#define reg_pwm_cr0 (*(volatile uint32_t *)0x20003010)
#define reg_pwm_cr1 (*(volatile uint32_t *)0x20003014)
#define reg_pwm_cr2 (*(volatile uint32_t *)0x20003018)
#define reg_pwm_cr3 (*(volatile uint32_t *)0x2000301c)
#define reg_pwm_stat (*(volatile uint32_t *)0x20003020)
#define reg_pwm_ctrl RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x00))
#define reg_pwm_pscr RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x04))
#define reg_pwm_cnt RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x08))
#define reg_pwm_cmp RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x0C))
#define reg_pwm_cr0 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x10))
#define reg_pwm_cr1 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x14))
#define reg_pwm_cr2 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x18))
#define reg_pwm_cr3 RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x1C))
#define reg_pwm_stat RS_SOC_REG32(RS_SOC_APB_PWM_BASE, UINT32_C(0x20))
// ps2
#define reg_ps2_ctrl (*(volatile uint32_t *)0x20004000)
#define reg_ps2_data (*(volatile uint32_t *)0x20004004)
#define reg_ps2_stat (*(volatile uint32_t *)0x20004008)
#define reg_ps2_ctrl RS_SOC_REG32(RS_SOC_APB_PS2_BASE, UINT32_C(0x00))
#define reg_ps2_data RS_SOC_REG32(RS_SOC_APB_PS2_BASE, UINT32_C(0x04))
#define reg_ps2_stat RS_SOC_REG32(RS_SOC_APB_PS2_BASE, UINT32_C(0x08))
// rtc
#define reg_rtc_ctrl (*(volatile uint32_t *)0x20005000)
#define reg_rtc_pscr (*(volatile uint32_t *)0x20005004)
#define reg_rtc_cnt (*(volatile uint32_t *)0x20005008)
#define reg_rtc_alrm (*(volatile uint32_t *)0x2000500C)
#define reg_rtc_ista (*(volatile uint32_t *)0x20005010)
#define reg_rtc_ssta (*(volatile uint32_t *)0x20005014)
#define reg_rtc_ctrl RS_SOC_REG32(RS_SOC_APB_RTC_BASE, UINT32_C(0x00))
#define reg_rtc_pscr RS_SOC_REG32(RS_SOC_APB_RTC_BASE, UINT32_C(0x04))
#define reg_rtc_cnt RS_SOC_REG32(RS_SOC_APB_RTC_BASE, UINT32_C(0x08))
#define reg_rtc_alrm RS_SOC_REG32(RS_SOC_APB_RTC_BASE, UINT32_C(0x0C))
#define reg_rtc_ista RS_SOC_REG32(RS_SOC_APB_RTC_BASE, UINT32_C(0x10))
#define reg_rtc_ssta RS_SOC_REG32(RS_SOC_APB_RTC_BASE, UINT32_C(0x14))
// wdg
#define reg_wdg_ctrl (*(volatile uint32_t *)0x20006000)
#define reg_wdg_pscr (*(volatile uint32_t *)0x20006004)
#define reg_wdg_cnt (*(volatile uint32_t *)0x20006008)
#define reg_wdg_cmp (*(volatile uint32_t *)0x2000600C)
#define reg_wdg_stat (*(volatile uint32_t *)0x20006010)
#define reg_wdg_key (*(volatile uint32_t *)0x20006014)
#define reg_wdg_feed (*(volatile uint32_t *)0x20006018)
#define reg_wdg_ctrl RS_SOC_REG32(RS_SOC_APB_WDG_BASE, UINT32_C(0x00))
#define reg_wdg_pscr RS_SOC_REG32(RS_SOC_APB_WDG_BASE, UINT32_C(0x04))
#define reg_wdg_cnt RS_SOC_REG32(RS_SOC_APB_WDG_BASE, UINT32_C(0x08))
#define reg_wdg_cmp RS_SOC_REG32(RS_SOC_APB_WDG_BASE, UINT32_C(0x0C))
#define reg_wdg_stat RS_SOC_REG32(RS_SOC_APB_WDG_BASE, UINT32_C(0x10))
#define reg_wdg_key RS_SOC_REG32(RS_SOC_APB_WDG_BASE, UINT32_C(0x14))
#define reg_wdg_feed RS_SOC_REG32(RS_SOC_APB_WDG_BASE, UINT32_C(0x18))
// crc
#define reg_crc_ctrl (*(volatile uint32_t *)0x20007000)
#define reg_crc_init (*(volatile uint32_t *)0x20007004)
#define reg_crc_xorv (*(volatile uint32_t *)0x20007008)
#define reg_crc_data (*(volatile uint32_t *)0x2000700C)
#define reg_crc_stat (*(volatile uint32_t *)0x20007010)
#define reg_crc_ctrl RS_SOC_REG32(RS_SOC_APB_CRC_BASE, UINT32_C(0x00))
#define reg_crc_init RS_SOC_REG32(RS_SOC_APB_CRC_BASE, UINT32_C(0x04))
#define reg_crc_xorv RS_SOC_REG32(RS_SOC_APB_CRC_BASE, UINT32_C(0x08))
#define reg_crc_data RS_SOC_REG32(RS_SOC_APB_CRC_BASE, UINT32_C(0x0C))
#define reg_crc_stat RS_SOC_REG32(RS_SOC_APB_CRC_BASE, UINT32_C(0x10))
// tim3
#define reg_tim3_ctrl (*(volatile uint32_t *)0x20008000)
#define reg_tim3_pscr (*(volatile uint32_t *)0x20008004)
#define reg_tim3_cnt (*(volatile uint32_t *)0x20008008)
#define reg_tim3_cmp (*(volatile uint32_t *)0x2000800C)
#define reg_tim3_stat (*(volatile uint32_t *)0x20008010)
// user ip design(example)
#define reg_user_ip_reg0 (*(volatile uint32_t *)0x2000F000)
#define reg_user_ip_reg1 (*(volatile uint32_t *)0x2000F004)
#define reg_user_ip_reg2 (*(volatile uint32_t *)0x2000F008)
#define reg_user_ip_reg3 (*(volatile uint32_t *)0x2000F00C)
#define reg_user_ip_reg4 (*(volatile uint32_t *)0x2000F010)
#define reg_user_ip_reg5 (*(volatile uint32_t *)0x2000F014)
#define reg_user_ip_reg6 (*(volatile uint32_t *)0x2000F018)
// ... user custom area ...
#define reg_tim3_ctrl RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x00))
#define reg_tim3_pscr RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x04))
#define reg_tim3_cnt RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x08))
#define reg_tim3_cmp RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x0C))
#define reg_tim3_stat RS_SOC_REG32(RS_SOC_APB_TMR_BASE, UINT32_C(0x10))
#ifdef IP_MDD
#define reg_user_ip_reg0 RS_SOC_REG32(RS_SOC_APB_USER_IP_BASE, UINT32_C(0x00))
#define reg_user_ip_reg1 RS_SOC_REG32(RS_SOC_APB_USER_IP_BASE, UINT32_C(0x04))
#define reg_user_ip_reg2 RS_SOC_REG32(RS_SOC_APB_USER_IP_BASE, UINT32_C(0x08))
#define reg_user_ip_reg3 RS_SOC_REG32(RS_SOC_APB_USER_IP_BASE, UINT32_C(0x0C))
#define reg_user_ip_reg4 RS_SOC_REG32(RS_SOC_APB_USER_IP_BASE, UINT32_C(0x10))
#define reg_user_ip_reg5 RS_SOC_REG32(RS_SOC_APB_USER_IP_BASE, UINT32_C(0x14))
#define reg_user_ip_reg6 RS_SOC_REG32(RS_SOC_APB_USER_IP_BASE, UINT32_C(0x18))
#endif
#endif
+1 -7
View File
@@ -1,12 +1,6 @@
ENTRY( _start )
MEMORY
{
FLASH (rxai!w) : ORIGIN = 0x00000000, LENGTH = 16M
SRAM (wxa!ri) : ORIGIN = 0x30000000, LENGTH = 128K
PSRAM (wxa!ri) : ORIGIN = 0x40000000, LENGTH = 8M
/* PSRAM (wxa!ri) : ORIGIN = 0x40000000, LENGTH = 64K */ /* for debug */
}
INCLUDE memory_regions.ld
SECTIONS {
.init :
+1 -7
View File
@@ -1,12 +1,6 @@
ENTRY( _start )
MEMORY
{
FLASH (rxai!w) : ORIGIN = 0x00000000, LENGTH = 16M
SRAM (wxa!ri) : ORIGIN = 0x30000000, LENGTH = 128K
SDRAM (wxa!ri) : ORIGIN = 0x38000000, LENGTH = 32M
PSRAM (wxa!ri) : ORIGIN = 0x40000000, LENGTH = 8M
}
INCLUDE memory_regions.ld
SECTIONS {
.init :
+1 -6
View File
@@ -1,11 +1,6 @@
ENTRY( _start )
MEMORY
{
FLASH (rxai!w) : ORIGIN = 0x00000000, LENGTH = 16M
SRAM (wxa!ri) : ORIGIN = 0x30000000, LENGTH = 128K
PSRAM (wxa!ri) : ORIGIN = 0x40000000, LENGTH = 8M
}
INCLUDE memory_regions.ld
SECTIONS {
.init :
+1 -6
View File
@@ -1,11 +1,6 @@
ENTRY( _start )
MEMORY
{
FLASH (rxai!w) : ORIGIN = 0x00000000, LENGTH = 16M
SRAM (wxa!ri) : ORIGIN = 0x30000000, LENGTH = 128K
PSRAM (wxa!ri) : ORIGIN = 0x40000000, LENGTH = 8M
}
INCLUDE memory_regions.ld
SECTIONS {
.init :
+9 -15
View File
@@ -9,9 +9,8 @@
#include <retrosoc/lib/string.h>
#include <retrosoc/service/shell.h>
#include <retrosoc/service/booter.h>
// HACK:
#if defined(CORE_MDD) || defined(IP_MDD)
#include <../../rtl/mini/mpw/.build/user_design_info.h>
#include <user_design_info.h>
#endif
void rs_app_info(void) {
@@ -90,18 +89,14 @@ void rs_app_info(void) {
printf("Inst/Memory Address Range:\n");
printf(" QSPI Flash: @[0x%08x-0x%08x] %3d MiB\n", SPFS_MEM_START,
SPFS_MEM_START + SPFS_MEM_OFFST - 1, SPFS_MEM_OFFST / 1024 / 1024);
printf(" NMI IP MMIO: @[0x%08x-0x%08x] %3d MiB\n", NMI_MEM_START,
NMI_MEM_START + NMI_MEM_OFFST - 1, NMI_MEM_OFFST / 1024 / 1024);
printf(" APB IP MMIO: @[0x%08x-0x%08x] %3d MiB\n", APB_MEM_START,
APB_MEM_START + APB_MEM_OFFST - 1, APB_MEM_OFFST / 1024 / 1024);
#if RS_SOC_HAS_SRAM
printf(" On-chip RAM: @[0x%08x-0x%08x] %3d KiB\n", SRAM_MEM_START,
SRAM_MEM_START + SRAM_MEM_OFFST - 1, SRAM_MEM_OFFST / 1024);
#endif
printf(" Off-chip SDRAM: @[0x%08x-0x%08x] %3d MiB\n", SDRAM_MEM_START,
SDRAM_MEM_START + SDRAM_MEM_OFFST - 1, SDRAM_MEM_OFFST / 1024 / 1024);
printf(" Off-chip PSRAM: @[0x%08x-0x%08x] %3d MiB(%dx8MiB)\n", PSRAM_MEM_START,
PSRAM_MEM_START + PSRAM_MEM_OFFST - 1, 8 * PSRAM_NUM, PSRAM_NUM);
printf(" Off-chip OPIPSRAM: @[0x%08x-0x%08x] %3d MiB\n", OPIPSRAM_MEM_START,
OPIPSRAM_MEM_START + OPIPSRAM_MEM_OFFST - 1, OPIPSRAM_MEM_OFFST / 1024 / 1024);
printf(" Off-chip PSRAM: @[0x%08x-0x%08x] %3d MiB\n", PSRAM_MEM_START,
PSRAM_MEM_START + PSRAM_MEM_OFFST - 1, PSRAM_MEM_OFFST / 1024 / 1024);
printf(" XPI MMIO: @[0x%08x-0x%08x] %3d MiB\n", XPI_MEM_START,
XPI_MEM_START + XPI_MEM_OFFST - 1, XPI_MEM_OFFST / 1024 / 1024);
printf(" SPISD MMIO: @[0x%08x-0x%08x] %3d GiB\n\n", TF_CARD_START,
@@ -123,11 +118,7 @@ void rs_app_info(void) {
printf(" 1 x CLINT @%p\n", (void *)&reg_clint_mtimel);
printf(" 1 x SDRAM @%p\n", (void *)&reg_sdram_clkdiv);
printf(" 1 x DVP @%p\n", (void *)&reg_dvp_recven);
printf(" 1 x SDIO @%p\n", (void *)&reg_sdio_cfg);
printf(" 1 x OPIPSRAM @%p\n", (void *)&reg_opipsram_cfg);
printf(" 1 x I2C1 @%p\n", (void *)&reg_i2c1_clkdiv);
printf(" 1 x GA* @%p\n", (void *)&reg_ga_cfg);
printf(" 1 x APU* @%p\n", (void *)&reg_apu_cfg);
printf(" 1 x ARCHINFO @%p\n", (void *)&reg_archinfo_sys);
printf(" 1 x RNG @%p\n", (void *)&reg_rng_ctrl);
printf(" 1 x UART1(ADV) @%p\n", (void *)&reg_uart1_lcr);
@@ -137,7 +128,10 @@ void rs_app_info(void) {
printf(" 1 x WDG @%p\n", (void *)&reg_wdg_ctrl);
printf(" 1 x CRC @%p\n", (void *)&reg_crc_ctrl);
printf(" 1 x TIMER3(ADV) @%p\n", (void *)&reg_tim3_ctrl);
printf(" 1 x USER_IP(4KiB) @%p\n\n", (void *)&reg_user_ip_reg0);
#ifdef IP_MDD
printf(" 1 x USER_IP(4KiB) @%p\n", (void *)&reg_user_ip_reg0);
#endif
printf("\n");
printf("#############################################################\n");
printf("#############################################################\n");
}
+20 -20
View File
@@ -69,15 +69,15 @@ module nmi2apb (
assign crc.pprot = '0;
assign tmr.pprot = '0;
assign archinfo.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_ARCHINFO_START);
assign rng.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_RNG_START);
assign uart.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_UART_START);
assign pwm.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_PWM_START);
assign ps2.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_PS2_START);
assign rtc.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_RTC_START);
assign wdg.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_WDG_START);
assign crc.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_CRC_START);
assign tmr.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_TMR_START);
assign archinfo.psel = s_xfer_valid && `SOC_ADDR_IS_APB_ARCHINFO(nmi.addr);
assign rng.psel = s_xfer_valid && `SOC_ADDR_IS_APB_RNG(nmi.addr);
assign uart.psel = s_xfer_valid && `SOC_ADDR_IS_APB_UART1(nmi.addr);
assign pwm.psel = s_xfer_valid && `SOC_ADDR_IS_APB_PWM(nmi.addr);
assign ps2.psel = s_xfer_valid && `SOC_ADDR_IS_APB_PS2(nmi.addr);
assign rtc.psel = s_xfer_valid && `SOC_ADDR_IS_APB_RTC(nmi.addr);
assign wdg.psel = s_xfer_valid && `SOC_ADDR_IS_APB_WDG(nmi.addr);
assign crc.psel = s_xfer_valid && `SOC_ADDR_IS_APB_CRC(nmi.addr);
assign tmr.psel = s_xfer_valid && `SOC_ADDR_IS_APB_TMR(nmi.addr);
assign archinfo.penable = s_fsm_q == FSM_ENAB;
assign rng.penable = s_fsm_q == FSM_ENAB;
@@ -122,7 +122,7 @@ module nmi2apb (
`ifdef IP_MDD
assign user_ip.paddr = nmi.addr;
assign user_ip.pprot = '0;
assign user_ip.psel = s_xfer_valid && (nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_USR_START);
assign user_ip.psel = s_xfer_valid && `SOC_ADDR_IS_APB_USER_IP(nmi.addr);
assign user_ip.penable = s_fsm_q == FSM_ENAB;
assign user_ip.pwrite = |nmi.wstrb;
assign user_ip.pwdata = nmi.wdata;
@@ -161,17 +161,17 @@ module nmi2apb (
// Capture slave-select one-hot at FSM_SETP for cleaner response mux
// verilog_format: off
assign s_psel_comb[0] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_ARCHINFO_START;
assign s_psel_comb[1] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_RNG_START;
assign s_psel_comb[2] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_UART_START;
assign s_psel_comb[3] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_PWM_START;
assign s_psel_comb[4] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_PS2_START;
assign s_psel_comb[5] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_RTC_START;
assign s_psel_comb[6] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_WDG_START;
assign s_psel_comb[7] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_CRC_START;
assign s_psel_comb[8] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_TMR_START;
assign s_psel_comb[0] = `SOC_ADDR_IS_APB_ARCHINFO(nmi.addr);
assign s_psel_comb[1] = `SOC_ADDR_IS_APB_RNG(nmi.addr);
assign s_psel_comb[2] = `SOC_ADDR_IS_APB_UART1(nmi.addr);
assign s_psel_comb[3] = `SOC_ADDR_IS_APB_PWM(nmi.addr);
assign s_psel_comb[4] = `SOC_ADDR_IS_APB_PS2(nmi.addr);
assign s_psel_comb[5] = `SOC_ADDR_IS_APB_RTC(nmi.addr);
assign s_psel_comb[6] = `SOC_ADDR_IS_APB_WDG(nmi.addr);
assign s_psel_comb[7] = `SOC_ADDR_IS_APB_CRC(nmi.addr);
assign s_psel_comb[8] = `SOC_ADDR_IS_APB_TMR(nmi.addr);
`ifdef IP_MDD
assign s_psel_comb[9] = nmi.addr[31:28] == `APB_IP_START && nmi.addr[15:8] == `APB_USR_START;
assign s_psel_comb[9] = `SOC_ADDR_IS_APB_USER_IP(nmi.addr);
`endif
assign s_psel_d = (s_fsm_q == FSM_IDLE && s_mem_valid_re) ? s_psel_comb : s_psel_q;
+2 -2
View File
@@ -125,8 +125,8 @@ module nmi_psram (
// verilog_format: on
assign s_mem_sel = nmi.addr[31:24] == `PSRAM_START;
assign s_cfg_reg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_PSRAM_START;
assign s_mem_sel = `SOC_ADDR_IS_PSRAM(nmi.addr);
assign s_cfg_reg_sel = `SOC_ADDR_IS_NMI_PSRAM(nmi.addr);
assign nmi.ready = s_mem_sel ? s_mem_ready : 1'b1;
always_comb begin
nmi.rdata = '0;
+1 -1
View File
@@ -62,7 +62,7 @@ module nmi_sdram (
nmi_if u_mem_nmi_if ();
// nmi mux
assign s_sdram_reg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_SDRAM_START;
assign s_sdram_reg_sel = `SOC_ADDR_IS_NMI_SDRAM(nmi.addr);
assign u_reg_nmi_if.valid = nmi.valid && s_sdram_reg_sel;
assign u_reg_nmi_if.addr = nmi.addr;
assign u_reg_nmi_if.wdata = nmi.wdata;
+1 -1
View File
@@ -46,7 +46,7 @@ module nmi_spisd (
nmi_if u_cache_byp_nmi_if ();
// verilog_format: off
assign s_cfg_reg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_SPISD_START;
assign s_cfg_reg_sel = `SOC_ADDR_IS_NMI_SPISD(nmi.addr);
assign u_cfg_nmi_if.valid = nmi.valid && s_cfg_reg_sel;
assign u_cfg_nmi_if.addr = nmi.addr;
assign u_cfg_nmi_if.wdata = nmi.wdata;
+70
View File
@@ -16,11 +16,15 @@
`define NATV_SYSCTRL_IPSEL 8'h04 // WR/RD
`define NATV_SYSCTRL_I2CSEL 8'h08 // WR/RD
`define NATV_SYSCTRL_QSPISEL 8'h0C // WR/RD
`define NATV_SYSCTRL_FAULT_STATUS `SOC_SYSCTRL_FAULT_STATUS_OFFSET // W1C/RD
`define NATV_SYSCTRL_FAULT_ADDR `SOC_SYSCTRL_FAULT_ADDR_OFFSET // RD
`define NATV_SYSCTRL_FAULT_COUNT `SOC_SYSCTRL_FAULT_COUNT_OFFSET // RD
// verilog_format: on
`endif
`include "mdd_config.svh"
`include "mmap_define.svh"
interface sysctrl_if ();
logic [`USER_CORESEL_WIDTH-1:0] core_sel_i;
@@ -35,6 +39,10 @@ module nmi_sysctrl (
// verilog_format: off
input logic clk_i,
input logic rst_n_i,
input logic fault_valid_i,
input logic [31:0] fault_addr_i,
input logic [3:0] fault_wstrb_i,
input logic fault_reserved_i,
nmi_if.slave nmi,
sysctrl_if.dut sysctrl
// verilog_format: on
@@ -52,6 +60,12 @@ module nmi_sysctrl (
logic s_sysctrl_i2csel_d, s_sysctrl_i2csel_q;
logic s_sysctrl_qspisel_en;
logic s_sysctrl_qspisel_d, s_sysctrl_qspisel_q;
logic s_fault_status_clear;
logic s_fault_pending_d, s_fault_pending_q;
logic s_fault_write_d, s_fault_write_q;
logic [1:0] s_fault_reason_d, s_fault_reason_q;
logic [31:0] s_fault_addr_d, s_fault_addr_q;
logic [31:0] s_fault_count_d, s_fault_count_q;
assign s_nmi_wr_hdshk = nmi.valid && (~s_nmi_ready_q) && (|nmi.wstrb);
assign s_nmi_rd_hdshk = nmi.valid && (~s_nmi_ready_q) && (~(|nmi.wstrb));
@@ -100,6 +114,59 @@ module nmi_sysctrl (
s_sysctrl_qspisel_q
);
assign s_fault_status_clear = s_nmi_wr_hdshk &&
nmi.addr[7:0] == `NATV_SYSCTRL_FAULT_STATUS &&
nmi.wstrb[0] && nmi.wdata[0];
always_comb begin
s_fault_pending_d = s_fault_pending_q;
s_fault_write_d = s_fault_write_q;
s_fault_reason_d = s_fault_reason_q;
s_fault_addr_d = s_fault_addr_q;
s_fault_count_d = s_fault_count_q;
if (s_fault_status_clear) begin
s_fault_pending_d = 1'b0;
end
if (fault_valid_i) begin
s_fault_pending_d = 1'b1;
s_fault_write_d = |fault_wstrb_i;
s_fault_reason_d = fault_reserved_i ? 2'd2 : 2'd1;
s_fault_addr_d = fault_addr_i;
if (~(&s_fault_count_q)) begin
s_fault_count_d = s_fault_count_q + 32'd1;
end
end
end
dffr #(1) u_fault_pending_dffr (
clk_i,
rst_n_i,
s_fault_pending_d,
s_fault_pending_q
);
dffr #(1) u_fault_write_dffr (
clk_i,
rst_n_i,
s_fault_write_d,
s_fault_write_q
);
dffr #(2) u_fault_reason_dffr (
clk_i,
rst_n_i,
s_fault_reason_d,
s_fault_reason_q
);
dffr #(32) u_fault_addr_dffr (
clk_i,
rst_n_i,
s_fault_addr_d,
s_fault_addr_q
);
dffr #(32) u_fault_count_dffr (
clk_i,
rst_n_i,
s_fault_count_d,
s_fault_count_q
);
assign s_nmi_ready_d = nmi.valid && (~s_nmi_ready_q);
dffr #(1) u_nmi_ready_dffr (
clk_i,
@@ -117,6 +184,9 @@ module nmi_sysctrl (
`NATV_SYSCTRL_IPSEL: s_nmi_rdata_d = {{(32 - `USER_IPSEL_WIDTH) {1'b0}}, s_sysctrl_ipsel_q};
`NATV_SYSCTRL_I2CSEL: s_nmi_rdata_d = {31'd0, s_sysctrl_i2csel_q};
`NATV_SYSCTRL_QSPISEL: s_nmi_rdata_d = {31'd0, s_sysctrl_qspisel_q};
`NATV_SYSCTRL_FAULT_STATUS: s_nmi_rdata_d = {28'd0, s_fault_reason_q, s_fault_write_q, s_fault_pending_q};
`NATV_SYSCTRL_FAULT_ADDR: s_nmi_rdata_d = s_fault_addr_q;
`NATV_SYSCTRL_FAULT_COUNT: s_nmi_rdata_d = s_fault_count_q;
default: s_nmi_rdata_d = s_nmi_rdata_q;
endcase
// verilog_format: on
+1 -1
View File
@@ -107,7 +107,7 @@ module nmi_xpi (
// nmi mux
assign s_xpi_mm_sel = nmi.addr[31:28] == `FLASH_START || nmi.addr[31:28] == `XPI_MEM_START;
assign s_xpi_mm_sel = `SOC_ADDR_IS_FLASH(nmi.addr) || `SOC_ADDR_IS_XPI(nmi.addr);
assign u_reg_nmi_if.valid = nmi.valid && (~s_xpi_mm_sel);
assign u_reg_nmi_if.addr = nmi.addr;
assign u_reg_nmi_if.wdata = nmi.wdata;
+21 -3
View File
@@ -1,4 +1,12 @@
GENERATED_FL_DIR := $(FLOW_FILELIST_DIR)
MEMORY_MAP_SOURCE := $(RTL_PATH)/memory_map.json
MEMORY_MAP_SCRIPT := $(RTL_PATH)/script/generate_memory_map.py
MEMORY_MAP_DIR := $(VARIANT_ROOT)/generated/memory_map
MEMORY_MAP_STAMP := $(MEMORY_MAP_DIR)/.stamp
MEMORY_MAP_RTL_DIR := $(MEMORY_MAP_DIR)/rtl
MEMORY_MAP_C_DIR := $(MEMORY_MAP_DIR)/include
MEMORY_MAP_LINKER_DIR := $(MEMORY_MAP_DIR)/linker
MEMORY_MAP_FILELIST := $(MEMORY_MAP_DIR)/memory_map.fl
MPW_STAMP := $(CACHE_ROOT)/stamps/mpw-$(LOCK_DIGEST).prepared
MPW_OUTPUT_DIR := $(VARIANT_ROOT)/generated/mpw/$(SIM_TOOL_NAME)
MPW_VARIANT_STAMP := $(MPW_OUTPUT_DIR)/.stamp
@@ -25,8 +33,18 @@ $(MPW_VARIANT_STAMP): $(MPW_STAMP) $(ROOT_PATH)/scripts/generate_mpw.py
gen_mpw_code: $(MPW_VARIANT_STAMP)
$(MEMORY_MAP_STAMP): $(MEMORY_MAP_SOURCE) $(MEMORY_MAP_SCRIPT)
python3 $(MEMORY_MAP_SCRIPT) --map $(MEMORY_MAP_SOURCE) \
--output-dir $(MEMORY_MAP_DIR) --have-sram-if $(HAVE_SRAM_IF) --ip $(IP)
@touch $@
memory-map: $(MEMORY_MAP_STAMP)
check-memory-map:
python3 $(MEMORY_MAP_SCRIPT) --map $(MEMORY_MAP_SOURCE) --check
$(FILELIST_STAMP): $(FILELIST_TEMPLATES) $(RTL_PATH)/script/generate_filelist.py \
$(RTL_PATH)/script/filelist.py
$(RTL_PATH)/script/filelist.py $(MEMORY_MAP_STAMP)
python3 $(RTL_PATH)/script/generate_filelist.py \
--output-dir $(GENERATED_FL_DIR) \
$(foreach define,$(DEF_LIST),--define $(define))
@@ -53,7 +71,7 @@ NET_FLIST += -f $(GENERATED_FL_DIR)/sys_def.fl
NET_FLIST += -f $(GENERATED_FL_DIR)/commonip.fl
NET_FLIST += -f $(GENERATED_FL_DIR)/inc.fl
RTL_FLIST := $(NET_FLIST)
RTL_FLIST := -f $(MEMORY_MAP_FILELIST) $(NET_FLIST)
RTL_FLIST += -f $(GENERATED_FL_DIR)/clusterip.fl
RTL_FLIST += -f $(GENERATED_FL_DIR)/ip.fl
RTL_FLIST += -f $(GENERATED_FL_DIR)/tech.fl
@@ -81,4 +99,4 @@ else ifeq ($(SIMU), IVERILOG)
include $(RTL_PATH)/mk/iverilog.mk
endif
.PHONY: gen_mpw_code generate_filelist firmware
.PHONY: gen_mpw_code generate_filelist memory-map check-memory-map firmware
+43
View File
@@ -0,0 +1,43 @@
{
"schema_version": 1,
"cpu_reset": "0x00000000",
"regions": [
{"symbol": "FLASH", "base": "0x00000000", "size": "0x01000000", "route": "native", "kind": "active", "public": true, "linker": "FLASH"},
{"symbol": "NMI_GPIO", "base": "0x10000000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_UART0", "base": "0x10001000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_TIM0", "base": "0x10002000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_TIM1", "base": "0x10003000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_PSRAM", "base": "0x10004000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_SPISD", "base": "0x10005000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_I2C0", "base": "0x10006000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_I2S", "base": "0x10007000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_ONEWIRE", "base": "0x10008000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_XPI", "base": "0x10009000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_DMA", "base": "0x1000A000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_SYSCTRL", "base": "0x1000B000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_CLINT", "base": "0x1000C000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_SDRAM", "base": "0x1000D000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_DVP", "base": "0x1000E000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_SDIO", "base": "0x1000F000", "size": "0x00001000", "route": "reserved", "kind": "reserved", "public": false},
{"symbol": "NMI_OPIPSRAM", "base": "0x10010000", "size": "0x00001000", "route": "reserved", "kind": "reserved", "public": false},
{"symbol": "NMI_I2C1", "base": "0x10011000", "size": "0x00001000", "route": "native", "kind": "active", "public": true},
{"symbol": "NMI_GA", "base": "0x10012000", "size": "0x00001000", "route": "reserved", "kind": "reserved", "public": false},
{"symbol": "NMI_APU", "base": "0x10013000", "size": "0x00001000", "route": "reserved", "kind": "reserved", "public": false},
{"symbol": "APB_ARCHINFO", "base": "0x20000000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_RNG", "base": "0x20001000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_UART1", "base": "0x20002000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_PWM", "base": "0x20003000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_PS2", "base": "0x20004000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_RTC", "base": "0x20005000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_WDG", "base": "0x20006000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_CRC", "base": "0x20007000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_TMR", "base": "0x20008000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true},
{"symbol": "APB_USER_IP", "base": "0x2000F000", "size": "0x00001000", "route": "apb", "kind": "active", "public": true, "requires_ip": "MDD"},
{"symbol": "SRAM", "base": "0x30000000", "size": "0x00020000", "route": "ram", "kind": "active", "public": true, "linker": "SRAM"},
{"symbol": "SDRAM", "base": "0x38000000", "size": "0x02000000", "route": "native", "kind": "active", "public": true, "linker": "SDRAM"},
{"symbol": "PSRAM", "base": "0x40000000", "size": "0x00800000", "route": "native", "kind": "active", "public": true, "linker": "PSRAM"},
{"symbol": "OPIPSRAM", "base": "0x48000000", "size": "0x08000000", "route": "reserved", "kind": "reserved", "public": false},
{"symbol": "XPI", "base": "0x50000000", "size": "0x10000000", "route": "native", "kind": "active", "public": true},
{"symbol": "SPISD", "base": "0x60000000", "size": "0x40000000", "route": "native", "kind": "active", "public": true}
]
}
+4 -1
View File
@@ -110,10 +110,12 @@ CRT_SRCS += $(ROOT_PATH)/crt/arch/riscv/libgcc/mulsi3.c
endif
INC_PATH := -I$(SW_BUILD_DIR)/include \
-I$(MEMORY_MAP_C_DIR) \
-I$(ROOT_PATH)/crt/include \
$(addprefix -I,$(APP_INC_DIRS))
SRC_PATH := $(CRT_SRCS) $(APP_SRCS)
LDS_PATH := $(ROOT_PATH)/crt/linker/$(LINK_TYPE).lds
MEMORY_REGIONS_LD := $(MEMORY_MAP_LINKER_DIR)/memory_regions.ld
VERSION_HEADER := $(SW_BUILD_DIR)/include/socver.h
FIRMWARE_ELF := $(SW_BUILD_DIR)/firmware
ASM_FIRMWARE_NAME ?= retrosoc_asm
@@ -135,10 +137,11 @@ asm: $(MPW_VARIANT_STAMP)
cp $(SW_BUILD_DIR)/asm/hello-asm.bin $(SW_BUILD_DIR)/$(ASM_FIRMWARE_NAME).bin
cp $(SW_BUILD_DIR)/asm/hello-asm.txt $(SW_BUILD_DIR)/$(ASM_FIRMWARE_NAME)_all.txt
$(FIRMWARE_ELF): $(MPW_VARIANT_STAMP) $(VERSION_HEADER) $(SRC_PATH) $(SW_HEADERS) $(LDS_PATH) \
$(FIRMWARE_ELF): $(MPW_VARIANT_STAMP) $(MEMORY_MAP_STAMP) $(VERSION_HEADER) $(SRC_PATH) $(SW_HEADERS) $(LDS_PATH) \
$(ROOT_PATH)/rtl/mini/mk/software.mk
@mkdir -p $(SW_BUILD_DIR)
cd $(SW_BUILD_DIR) && $(CP) -P -o $(LINK_TYPE).lds $(LDS_PATH)
cp $(MEMORY_REGIONS_LD) $(SW_BUILD_DIR)/memory_regions.ld
cd $(SW_BUILD_DIR) && $(CC) $(CFLAGS) $(INC_PATH) -o $(@F) $(SRC_PATH)
cd $(SW_BUILD_DIR) && $(OBJC) -O verilog $(@F) $(FIRMWARE_NAME).hex
cd $(SW_BUILD_DIR) && $(OBJC) -O binary $(@F) $(FIRMWARE_NAME).bin
+243
View File
@@ -0,0 +1,243 @@
#!/usr/bin/env python3
"""Generate RTL, SDK and linker address-map artifacts from one JSON source."""
from __future__ import annotations
import argparse
import json
import os
import tempfile
from pathlib import Path
from typing import Any
MAX_ADDRESS = 1 << 32
VALID_ROUTES = {"native", "apb", "ram", "reserved"}
VALID_KINDS = {"active", "reserved"}
def parse_integer(value: Any, field: str) -> int:
if isinstance(value, int):
return value
if isinstance(value, str):
try:
return int(value, 0)
except ValueError as error:
raise ValueError(f"{field} must be an integer: {value!r}") from error
raise ValueError(f"{field} must be an integer")
def read_map(path: Path) -> tuple[int, list[dict[str, Any]]]:
with path.open(encoding="utf-8") as source:
document = json.load(source)
if document.get("schema_version") != 1:
raise ValueError("schema_version must be 1")
cpu_reset = parse_integer(document.get("cpu_reset"), "cpu_reset")
regions = document.get("regions")
if not isinstance(regions, list) or not regions:
raise ValueError("regions must be a non-empty list")
normalized: list[dict[str, Any]] = []
symbols: set[str] = set()
for index, region in enumerate(regions):
if not isinstance(region, dict):
raise ValueError(f"regions[{index}] must be an object")
symbol = region.get("symbol")
if not isinstance(symbol, str) or not symbol or not symbol.replace("_", "").isalnum():
raise ValueError(f"regions[{index}].symbol must be an uppercase identifier")
if symbol != symbol.upper() or symbol in symbols:
raise ValueError(f"regions[{index}].symbol must be unique and uppercase")
symbols.add(symbol)
route = region.get("route")
kind = region.get("kind")
if route not in VALID_ROUTES or kind not in VALID_KINDS:
raise ValueError(f"regions[{index}] has invalid route or kind")
if (route == "reserved") != (kind == "reserved"):
raise ValueError(f"regions[{index}] reserved route and kind must agree")
requires_ip = region.get("requires_ip")
if requires_ip is not None and requires_ip != "MDD":
raise ValueError(f"regions[{index}].requires_ip must be MDD when present")
base = parse_integer(region.get("base"), f"regions[{index}].base")
size = parse_integer(region.get("size"), f"regions[{index}].size")
if base < 0 or size <= 0 or base + size > MAX_ADDRESS:
raise ValueError(f"regions[{index}] exceeds the 32-bit address space")
if base % 4 != 0 or size % 4 != 0:
raise ValueError(f"regions[{index}] must be 32-bit aligned")
normalized.append(
{
"symbol": symbol,
"base": base,
"size": size,
"end": base + size - 1,
"route": route,
"kind": kind,
"public": region.get("public", False) is True,
"linker": region.get("linker"),
"requires_ip": requires_ip,
}
)
previous: dict[str, Any] | None = None
for region in sorted(normalized, key=lambda item: item["base"]):
if previous is not None and region["base"] <= previous["end"]:
raise ValueError(f"address-map overlap: {previous['symbol']} and {region['symbol']}")
previous = region
return cpu_reset, normalized
def hex32(value: int) -> str:
return f"32'h{value:08X}"
def c_hex32(value: int) -> str:
return f"UINT32_C(0x{value:08X})"
def range_expression(symbol: str) -> str:
return f"((addr) >= `SOC_ADDR_{symbol}_BASE && (addr) <= `SOC_ADDR_{symbol}_END)"
def join_or(expressions: list[str]) -> str:
return " || \\\n ".join(expressions) if expressions else "1'b0"
def render_rtl(cpu_reset: int, regions: list[dict[str, Any]]) -> str:
lines = [
"// Generated by rtl/mini/script/generate_memory_map.py; do not edit.",
"`ifndef RETROSOC_GENERATED_MMAP_DEFINE_SVH",
"`define RETROSOC_GENERATED_MMAP_DEFINE_SVH",
"",
f"`define SOC_CPU_RESET_ADDR {hex32(cpu_reset)}",
"`define SOC_IRQ_START_ADDR `SOC_CPU_RESET_ADDR",
"// Compatibility aliases for managed MPW cores.",
"`define CPU_RESET_ADDR `SOC_CPU_RESET_ADDR",
"`define IRQ_START_ADDR `SOC_IRQ_START_ADDR",
"",
]
for region in regions:
symbol = region["symbol"]
lines += [
f"`define SOC_ADDR_{symbol}_BASE {hex32(region['base'])}",
f"`define SOC_ADDR_{symbol}_END {hex32(region['end'])}",
f"`define SOC_ADDR_IS_{symbol}(addr) {range_expression(symbol)}",
]
lines.append("")
for route in ("native", "apb", "ram", "reserved"):
selected = [
f"`SOC_ADDR_IS_{region['symbol']}(addr)"
for region in regions
if region["route"] == route
]
lines.append(f"`define SOC_ADDR_IS_{route.upper()}(addr) ({join_or(selected)})")
lines += [
"",
"`define SOC_SYSCTRL_FAULT_STATUS_OFFSET 32'h00000010",
"`define SOC_SYSCTRL_FAULT_ADDR_OFFSET 32'h00000014",
"`define SOC_SYSCTRL_FAULT_COUNT_OFFSET 32'h00000018",
"",
"`endif",
"",
]
return "\n".join(lines)
def render_c(cpu_reset: int, regions: list[dict[str, Any]], have_sram_if: str) -> str:
lines = [
"/* Generated by rtl/mini/script/generate_memory_map.py; do not edit. */",
"#ifndef RETROSOC_GENERATED_MEMORY_MAP_H",
"#define RETROSOC_GENERATED_MEMORY_MAP_H",
"",
"#include <stdint.h>",
"",
f"#define RS_SOC_CPU_RESET_ADDR {c_hex32(cpu_reset)}",
f"#define RS_SOC_HAS_SRAM {1 if have_sram_if == 'YES' else 0}U",
"",
]
for region in regions:
if not region["public"]:
continue
symbol = region["symbol"]
lines += [
f"#define RS_SOC_{symbol}_BASE {c_hex32(region['base'])}",
f"#define RS_SOC_{symbol}_SIZE {c_hex32(region['size'])}",
f"#define RS_SOC_{symbol}_END {c_hex32(region['end'])}",
]
lines += [
"",
"#define RS_SOC_SYSCTRL_FAULT_STATUS_OFFSET UINT32_C(0x00000010)",
"#define RS_SOC_SYSCTRL_FAULT_ADDR_OFFSET UINT32_C(0x00000014)",
"#define RS_SOC_SYSCTRL_FAULT_COUNT_OFFSET UINT32_C(0x00000018)",
"",
"#endif",
"",
]
return "\n".join(lines)
def render_linker(regions: list[dict[str, Any]]) -> str:
lines = [
"/* Generated by rtl/mini/script/generate_memory_map.py; do not edit. */",
"MEMORY",
"{",
]
for region in regions:
linker = region["linker"]
if linker is None:
continue
attributes = "rx" if linker == "FLASH" else "wxa!ri"
lines.append(
f" {linker} ({attributes}) : ORIGIN = 0x{region['base']:08X}, "
f"LENGTH = 0x{region['size']:08X}"
)
lines += ["}", ""]
return "\n".join(lines)
def atomic_write(path: Path, content: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
if path.exists() and path.read_text(encoding="utf-8") == content:
return
descriptor, temporary_name = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
try:
with os.fdopen(descriptor, "w", encoding="utf-8", newline="\n") as output:
output.write(content)
os.replace(temporary_name, path)
except BaseException:
Path(temporary_name).unlink(missing_ok=True)
raise
def generate(map_path: Path, output_dir: Path, have_sram_if: str, ip: str) -> None:
cpu_reset, regions = read_map(map_path)
enabled_regions = [
region for region in regions if region["requires_ip"] is None or region["requires_ip"] == ip
]
atomic_write(output_dir / "rtl" / "mmap_define.svh", render_rtl(cpu_reset, enabled_regions))
atomic_write(output_dir / "memory_map.fl", f"+incdir+{output_dir / 'rtl'}\n")
atomic_write(
output_dir / "include" / "retrosoc" / "generated" / "memory_map.h",
render_c(cpu_reset, enabled_regions, have_sram_if),
)
atomic_write(output_dir / "linker" / "memory_regions.ld", render_linker(enabled_regions))
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--map", required=True, type=Path)
parser.add_argument("--output-dir", type=Path)
parser.add_argument("--have-sram-if", choices=("YES", "NO"), default="NO")
parser.add_argument("--ip", choices=("NONE", "MDD"), default="NONE")
parser.add_argument("--check", action="store_true", help="validate only; write nothing")
arguments = parser.parse_args()
try:
if arguments.check:
read_map(arguments.map)
else:
if arguments.output_dir is None:
parser.error("--output-dir is required unless --check is used")
generate(arguments.map, arguments.output_dir, arguments.have_sram_if, arguments.ip)
except (OSError, ValueError, json.JSONDecodeError) as error:
parser.error(str(error))
return 0
if __name__ == "__main__":
raise SystemExit(main())
+21 -21
View File
@@ -20,11 +20,15 @@ module bus (
nmi_if.slave core_nmi,
nmi_if.slave dma_nmi,
nmi_if.master natv_nmi,
nmi_if.master apb_nmi
nmi_if.master apb_nmi,
output logic fault_valid_o,
output logic [31:0] fault_addr_o,
output logic [3:0] fault_wstrb_o,
output logic fault_reserved_o
// verilog_format: on
);
logic s_natv_sel, s_apb_sel, s_ram_sel;
logic s_natv_sel, s_apb_sel, s_ram_sel, s_fault_sel;
logic s_ram_valid, s_ram_ready;
logic s_mstr_lock_d, s_mstr_lock_q;
logic s_mstr_id_d, s_mstr_id_q;
@@ -84,40 +88,36 @@ module bus (
u_mstr_rgsl_nmi_if
);
// bus mux — hierarchical address decode (2-level)
// bus mux — address ownership comes from the generated address map.
// verilog_format: off
logic s_natv_hi_sel;
// Level 1: fast 4-bit decode on addr[31:28]
assign s_natv_hi_sel = u_mstr_rgsl_nmi_if.addr[31:28] == `FLASH_START ||
u_mstr_rgsl_nmi_if.addr[31:28] == `NMI_IP_START ||
u_mstr_rgsl_nmi_if.addr[31:28] == `SPISD_START0 ||
u_mstr_rgsl_nmi_if.addr[31:28] == `SPISD_START1 ||
u_mstr_rgsl_nmi_if.addr[31:28] == `SPISD_START2 ||
u_mstr_rgsl_nmi_if.addr[31:28] == `SPISD_START3;
// Level 2: memory-mapped ranges that need wider compare
assign s_natv_sel = s_natv_hi_sel ||
(u_mstr_rgsl_nmi_if.addr[31:24] >= `SDRAM_START &&
u_mstr_rgsl_nmi_if.addr[31:24] <= `SDRAM_END) ||
u_mstr_rgsl_nmi_if.addr[31:24] == `PSRAM_START ||
u_mstr_rgsl_nmi_if.addr[31:24] == `OPIPSRAM_START;
assign s_natv_sel = `SOC_ADDR_IS_NATIVE(u_mstr_rgsl_nmi_if.addr);
assign natv_nmi.valid = u_mstr_rgsl_nmi_if.valid && s_natv_sel;
assign natv_nmi.addr = u_mstr_rgsl_nmi_if.addr;
assign natv_nmi.wdata = u_mstr_rgsl_nmi_if.wdata;
assign natv_nmi.wstrb = u_mstr_rgsl_nmi_if.wstrb;
assign s_apb_sel = u_mstr_rgsl_nmi_if.addr[31:28] == `APB_IP_START;
assign s_apb_sel = `SOC_ADDR_IS_APB(u_mstr_rgsl_nmi_if.addr);
assign apb_nmi.valid = u_mstr_rgsl_nmi_if.valid && s_apb_sel;
assign apb_nmi.addr = u_mstr_rgsl_nmi_if.addr;
assign apb_nmi.wdata = u_mstr_rgsl_nmi_if.wdata;
assign apb_nmi.wstrb = u_mstr_rgsl_nmi_if.wstrb;
`ifdef HAVE_SRAM_IF
assign s_ram_sel = u_mstr_rgsl_nmi_if.addr[31:24] >= `SRAM_START && u_mstr_rgsl_nmi_if.addr[31:24] <= `SRAM_END;
assign s_ram_sel = `SOC_ADDR_IS_RAM(u_mstr_rgsl_nmi_if.addr);
assign s_ram_valid = u_mstr_rgsl_nmi_if.valid && s_ram_sel;
assign ram.addr = u_mstr_rgsl_nmi_if.addr[16:2];
assign ram.wdata = u_mstr_rgsl_nmi_if.wdata;
assign ram.wstrb = s_ram_valid ? u_mstr_rgsl_nmi_if.wstrb : '0;
`else
assign s_ram_sel = 1'b0;
`endif
assign s_fault_sel = u_mstr_rgsl_nmi_if.valid &&
~(s_natv_sel || s_apb_sel || s_ram_sel);
assign fault_valid_o = s_fault_sel;
assign fault_addr_o = u_mstr_rgsl_nmi_if.addr;
assign fault_wstrb_o = u_mstr_rgsl_nmi_if.wstrb;
assign fault_reserved_o = `SOC_ADDR_IS_RESERVED(u_mstr_rgsl_nmi_if.addr);
// verilog_format: on
`ifdef HAVE_SRAM_MACRO
@@ -133,10 +133,10 @@ module bus (
`ifdef HAVE_SRAM_IF
assign u_mstr_rgsl_nmi_if.ready = (natv_nmi.valid && natv_nmi.ready) ||
(apb_nmi.valid && apb_nmi.ready) ||
s_ram_ready;
s_ram_ready || s_fault_sel;
`else
assign u_mstr_rgsl_nmi_if.ready = (natv_nmi.valid && natv_nmi.ready) ||
(apb_nmi.valid && apb_nmi.ready);
(apb_nmi.valid && apb_nmi.ready) || s_fault_sel;
`endif
+3 -3
View File
@@ -31,8 +31,8 @@ module core_wrapper (
.ENABLE_FAST_MUL(1),
.ENABLE_DIV (1),
.ENABLE_IRQ (0),
.PROGADDR_RESET (`CPU_RESET_ADDR),
.PROGADDR_IRQ (`IRQ_START_ADDR)
.PROGADDR_RESET (`SOC_CPU_RESET_ADDR),
.PROGADDR_IRQ (`SOC_IRQ_START_ADDR)
) u_picorv32 (
.clk (clk_i),
.resetn (rst_n_i),
@@ -72,7 +72,7 @@ module core_wrapper (
// verilog_format: on
hazard3_cpu_1port #(
.RESET_VECTOR (`CPU_RESET_ADDR),
.RESET_VECTOR (`SOC_CPU_RESET_ADDR),
.MTVEC_INIT (32'h0000_0000),
.EXTENSION_A (1),
.EXTENSION_C (1),
+91 -86
View File
@@ -34,6 +34,10 @@ module ip_nmi_wrapper (
sdio_if.dut sdio,
opipsram_if.dut opipsram,
i2c_if.dut i2c1,
input logic fault_valid_i,
input logic [31:0] fault_addr_i,
input logic [3:0] fault_wstrb_i,
input logic fault_reserved_i,
// irq
output logic [9:0] irq_o
// verilog_format: on
@@ -83,107 +87,104 @@ module ip_nmi_wrapper (
assign u_dma_hw_trg_if.qspi_tx_proc = ~s_dma_xpi_tx_stall;
assign u_dma_hw_trg_if.qspi_rx_proc = ~s_dma_xpi_rx_stall;
// gpio
assign u_gpio_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_GPIO_START);
assign u_gpio_nmi_if.addr = nmi.addr;
assign u_gpio_nmi_if.wdata = nmi.wdata;
assign u_gpio_nmi_if.wstrb = nmi.wstrb;
assign u_gpio_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_GPIO(nmi.addr);
assign u_gpio_nmi_if.addr = nmi.addr;
assign u_gpio_nmi_if.wdata = nmi.wdata;
assign u_gpio_nmi_if.wstrb = nmi.wstrb;
// uart
assign u_uart_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_UART_START);
assign u_uart_nmi_if.addr = nmi.addr;
assign u_uart_nmi_if.wdata = nmi.wdata;
assign u_uart_nmi_if.wstrb = nmi.wstrb;
assign u_uart_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_UART0(nmi.addr);
assign u_uart_nmi_if.addr = nmi.addr;
assign u_uart_nmi_if.wdata = nmi.wdata;
assign u_uart_nmi_if.wstrb = nmi.wstrb;
// tim0
assign u_tim0_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_TIM0_START);
assign u_tim0_nmi_if.addr = nmi.addr;
assign u_tim0_nmi_if.wdata = nmi.wdata;
assign u_tim0_nmi_if.wstrb = nmi.wstrb;
assign u_tim0_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_TIM0(nmi.addr);
assign u_tim0_nmi_if.addr = nmi.addr;
assign u_tim0_nmi_if.wdata = nmi.wdata;
assign u_tim0_nmi_if.wstrb = nmi.wstrb;
// tim1
assign u_tim1_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_TIM1_START);
assign u_tim1_nmi_if.addr = nmi.addr;
assign u_tim1_nmi_if.wdata = nmi.wdata;
assign u_tim1_nmi_if.wstrb = nmi.wstrb;
assign u_tim1_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_TIM1(nmi.addr);
assign u_tim1_nmi_if.addr = nmi.addr;
assign u_tim1_nmi_if.wdata = nmi.wdata;
assign u_tim1_nmi_if.wstrb = nmi.wstrb;
// psram
assign s_psram_cfg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_PSRAM_START;
assign s_psram_mem_sel = nmi.addr[31:24] >= `PSRAM_START && nmi.addr[31:24] <= `PSRAM_END;
assign u_psram_nmi_if.valid = nmi.valid && (s_psram_mem_sel || s_psram_cfg_sel);
assign u_psram_nmi_if.addr = nmi.addr;
assign u_psram_nmi_if.wdata = nmi.wdata;
assign u_psram_nmi_if.wstrb = nmi.wstrb;
assign s_psram_cfg_sel = `SOC_ADDR_IS_NMI_PSRAM(nmi.addr);
assign s_psram_mem_sel = `SOC_ADDR_IS_PSRAM(nmi.addr);
assign u_psram_nmi_if.valid = nmi.valid && (s_psram_mem_sel || s_psram_cfg_sel);
assign u_psram_nmi_if.addr = nmi.addr;
assign u_psram_nmi_if.wdata = nmi.wdata;
assign u_psram_nmi_if.wstrb = nmi.wstrb;
// spisd
assign s_spisd_cfg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_SPISD_START;
assign u_spisd_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `SPISD_START0 ||
nmi.addr[31:28] == `SPISD_START1 ||
nmi.addr[31:28] == `SPISD_START2 ||
nmi.addr[31:28] == `SPISD_START3 || s_spisd_cfg_sel);
assign u_spisd_nmi_if.addr = nmi.addr;
assign u_spisd_nmi_if.wdata = nmi.wdata;
assign u_spisd_nmi_if.wstrb = nmi.wstrb;
assign s_spisd_cfg_sel = `SOC_ADDR_IS_NMI_SPISD(nmi.addr);
assign u_spisd_nmi_if.valid = nmi.valid && (`SOC_ADDR_IS_SPISD(nmi.addr) || s_spisd_cfg_sel);
assign u_spisd_nmi_if.addr = nmi.addr;
assign u_spisd_nmi_if.wdata = nmi.wdata;
assign u_spisd_nmi_if.wstrb = nmi.wstrb;
// i2c0
assign u_i2c0_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_I2C0_START);
assign u_i2c0_nmi_if.addr = nmi.addr;
assign u_i2c0_nmi_if.wdata = nmi.wdata;
assign u_i2c0_nmi_if.wstrb = nmi.wstrb;
assign u_i2c0_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_I2C0(nmi.addr);
assign u_i2c0_nmi_if.addr = nmi.addr;
assign u_i2c0_nmi_if.wdata = nmi.wdata;
assign u_i2c0_nmi_if.wstrb = nmi.wstrb;
// i2s
assign u_i2s_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_I2S_START);
assign u_i2s_nmi_if.addr = nmi.addr;
assign u_i2s_nmi_if.wdata = nmi.wdata;
assign u_i2s_nmi_if.wstrb = nmi.wstrb;
assign u_i2s_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_I2S(nmi.addr);
assign u_i2s_nmi_if.addr = nmi.addr;
assign u_i2s_nmi_if.wdata = nmi.wdata;
assign u_i2s_nmi_if.wstrb = nmi.wstrb;
// onewire
assign u_onewire_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_ONEWIRE_START);
assign u_onewire_nmi_if.addr = nmi.addr;
assign u_onewire_nmi_if.wdata = nmi.wdata;
assign u_onewire_nmi_if.wstrb = nmi.wstrb;
assign u_onewire_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_ONEWIRE(nmi.addr);
assign u_onewire_nmi_if.addr = nmi.addr;
assign u_onewire_nmi_if.wdata = nmi.wdata;
assign u_onewire_nmi_if.wstrb = nmi.wstrb;
// xpi
assign s_xpi_cfg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_XPI_START;
assign s_xpi_mem_sel = nmi.addr[31:28] == `FLASH_START || nmi.addr[31:28] == `XPI_MEM_START;
assign u_xpi_nmi_if.valid = nmi.valid && (s_xpi_cfg_sel || s_xpi_mem_sel);
assign u_xpi_nmi_if.addr = nmi.addr;
assign u_xpi_nmi_if.wdata = nmi.wdata;
assign u_xpi_nmi_if.wstrb = nmi.wstrb;
assign s_xpi_cfg_sel = `SOC_ADDR_IS_NMI_XPI(nmi.addr);
assign s_xpi_mem_sel = `SOC_ADDR_IS_FLASH(nmi.addr) || `SOC_ADDR_IS_XPI(nmi.addr);
assign u_xpi_nmi_if.valid = nmi.valid && (s_xpi_cfg_sel || s_xpi_mem_sel);
assign u_xpi_nmi_if.addr = nmi.addr;
assign u_xpi_nmi_if.wdata = nmi.wdata;
assign u_xpi_nmi_if.wstrb = nmi.wstrb;
// dma
assign u_dma_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_DMA_START);
assign u_dma_nmi_if.addr = nmi.addr;
assign u_dma_nmi_if.wdata = nmi.wdata;
assign u_dma_nmi_if.wstrb = nmi.wstrb;
assign u_dma_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_DMA(nmi.addr);
assign u_dma_nmi_if.addr = nmi.addr;
assign u_dma_nmi_if.wdata = nmi.wdata;
assign u_dma_nmi_if.wstrb = nmi.wstrb;
// sysctrl
assign u_sysctrl_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_SYSCTRL_START);
assign u_sysctrl_nmi_if.addr = nmi.addr;
assign u_sysctrl_nmi_if.wdata = nmi.wdata;
assign u_sysctrl_nmi_if.wstrb = nmi.wstrb;
assign u_sysctrl_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_SYSCTRL(nmi.addr);
assign u_sysctrl_nmi_if.addr = nmi.addr;
assign u_sysctrl_nmi_if.wdata = nmi.wdata;
assign u_sysctrl_nmi_if.wstrb = nmi.wstrb;
// clint
assign u_clint_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_CLINT_START);
assign u_clint_nmi_if.addr = nmi.addr;
assign u_clint_nmi_if.wdata = nmi.wdata;
assign u_clint_nmi_if.wstrb = nmi.wstrb;
assign u_clint_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_CLINT(nmi.addr);
assign u_clint_nmi_if.addr = nmi.addr;
assign u_clint_nmi_if.wdata = nmi.wdata;
assign u_clint_nmi_if.wstrb = nmi.wstrb;
// sdram
assign s_sdram_cfg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_SDRAM_START;
assign s_sdram_mem_sel = nmi.addr[31:24] >= `SDRAM_START && nmi.addr[31:24] <= `SDRAM_END;
assign u_sdram_nmi_if.valid = nmi.valid && (s_sdram_cfg_sel || s_sdram_mem_sel);
assign u_sdram_nmi_if.addr = nmi.addr;
assign u_sdram_nmi_if.wdata = nmi.wdata;
assign u_sdram_nmi_if.wstrb = nmi.wstrb;
assign s_sdram_cfg_sel = `SOC_ADDR_IS_NMI_SDRAM(nmi.addr);
assign s_sdram_mem_sel = `SOC_ADDR_IS_SDRAM(nmi.addr);
assign u_sdram_nmi_if.valid = nmi.valid && (s_sdram_cfg_sel || s_sdram_mem_sel);
assign u_sdram_nmi_if.addr = nmi.addr;
assign u_sdram_nmi_if.wdata = nmi.wdata;
assign u_sdram_nmi_if.wstrb = nmi.wstrb;
// dvp
assign u_dvp_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_DVP_START);
assign u_dvp_nmi_if.addr = nmi.addr;
assign u_dvp_nmi_if.wdata = nmi.wdata;
assign u_dvp_nmi_if.wstrb = nmi.wstrb;
assign u_dvp_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_DVP(nmi.addr);
assign u_dvp_nmi_if.addr = nmi.addr;
assign u_dvp_nmi_if.wdata = nmi.wdata;
assign u_dvp_nmi_if.wstrb = nmi.wstrb;
// sdio
assign u_sdio_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[15:8] == `NMI_SDIO_START);
assign u_sdio_nmi_if.addr = nmi.addr;
assign u_sdio_nmi_if.wdata = nmi.wdata;
assign u_sdio_nmi_if.wstrb = nmi.wstrb;
assign u_sdio_nmi_if.valid = 1'b0;
assign u_sdio_nmi_if.addr = nmi.addr;
assign u_sdio_nmi_if.wdata = nmi.wdata;
assign u_sdio_nmi_if.wstrb = nmi.wstrb;
// opipsram
assign s_opipsram_cfg_sel = nmi.addr[31:28] == `NMI_IP_START && nmi.addr[19:16] == 4'd1 && nmi.addr[15:8] == `NMI_OPIPSRAM_START;
assign s_opipsram_mem_sel = nmi.addr[31:24] >= `OPIPSRAM_START && nmi.addr[31:24] <= `OPIPSRAM_END;
assign u_opipsram_nmi_if.valid = nmi.valid && (s_opipsram_mem_sel || s_opipsram_cfg_sel);
assign u_opipsram_nmi_if.addr = nmi.addr;
assign s_opipsram_cfg_sel = 1'b0;
assign s_opipsram_mem_sel = 1'b0;
assign u_opipsram_nmi_if.valid = 1'b0;
assign u_opipsram_nmi_if.addr = nmi.addr;
assign u_opipsram_nmi_if.wdata = nmi.wdata;
assign u_opipsram_nmi_if.wstrb = nmi.wstrb;
// i2c1
assign u_i2c1_nmi_if.valid = nmi.valid && (nmi.addr[31:28] == `NMI_IP_START && nmi.addr[19:16] == 4'd1 && nmi.addr[15:8] == `NMI_I2C1_START);
assign u_i2c1_nmi_if.addr = nmi.addr;
assign u_i2c1_nmi_if.wdata = nmi.wdata;
assign u_i2c1_nmi_if.wstrb = nmi.wstrb;
assign u_i2c1_nmi_if.valid = nmi.valid && `SOC_ADDR_IS_NMI_I2C1(nmi.addr);
assign u_i2c1_nmi_if.addr = nmi.addr;
assign u_i2c1_nmi_if.wdata = nmi.wdata;
assign u_i2c1_nmi_if.wstrb = nmi.wstrb;
// verilog_format: off
// Registered one-hot slave select for response mux (breaks comb fanin)
@@ -374,10 +375,14 @@ module ip_nmi_wrapper (
);
nmi_sysctrl u_nmi_sysctrl (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.nmi (u_sysctrl_nmi_if),
.sysctrl(sysctrl)
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.fault_valid_i (fault_valid_i),
.fault_addr_i (fault_addr_i),
.fault_wstrb_i (fault_wstrb_i),
.fault_reserved_i(fault_reserved_i),
.nmi (u_sysctrl_nmi_if),
.sysctrl (sysctrl)
);
nmi_clint u_nmi_clint (
+2 -2
View File
@@ -26,8 +26,8 @@ module mgmt_core_wrapper (
.ENABLE_FAST_MUL(1),
.ENABLE_DIV (1),
.ENABLE_IRQ (0),
.PROGADDR_RESET (`CPU_RESET_ADDR),
.PROGADDR_IRQ (`IRQ_START_ADDR)
.PROGADDR_RESET (`SOC_CPU_RESET_ADDR),
.PROGADDR_IRQ (`SOC_IRQ_START_ADDR)
) u_picorv32 (
.clk (clk_i),
.resetn (rst_n_i),
-69
View File
@@ -1,69 +0,0 @@
// Copyright (c) 2023-2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// retroSoC is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
`ifndef INC_MMAP_DEFINE_SVH
`define INC_MMAP_DEFINE_SVH
`define CPU_RESET_ADDR 32'h0000_0000
// NOTE: need to set a right value for software!
`define IRQ_START_ADDR 32'h0000_0000
`define FLASH_START 4'h0
`define NMI_IP_START 4'h1
`define APB_IP_START 4'h2
`define SRAM_START 8'h30
`define SRAM_END 8'h37
`define SDRAM_START 8'h38
`define SDRAM_END 8'h3F
`define PSRAM_START 8'h40
`define PSRAM_END 8'h47
`define OPIPSRAM_START 8'h48
`define OPIPSRAM_END 8'h4F
`define XPI_MEM_START 4'h5
`define SPISD_START0 4'h6
`define SPISD_START1 4'h7
`define SPISD_START2 4'h8
`define SPISD_START3 4'h9
// NMI IP REG ADDR
`define NMI_GPIO_START 8'h00
`define NMI_UART_START 8'h10
`define NMI_TIM0_START 8'h20
`define NMI_TIM1_START 8'h30
`define NMI_PSRAM_START 8'h40
`define NMI_SPISD_START 8'h50
`define NMI_I2C0_START 8'h60
`define NMI_I2S_START 8'h70
`define NMI_ONEWIRE_START 8'h80
`define NMI_XPI_START 8'h90
`define NMI_DMA_START 8'hA0
`define NMI_SYSCTRL_START 8'hB0
`define NMI_CLINT_START 8'hC0
`define NMI_SDRAM_START 8'hD0
`define NMI_DVP_START 8'hE0
`define NMI_SDIO_START 8'hF0
// new cycle
`define NMI_OPIPSRAM_START 8'h00
`define NMI_I2C1_START 8'h10
`define NMI_GA_START 8'h20
`define NMI_APU_START 8'h30
// APB IP REG ADDR
`define APB_ARCHINFO_START 8'h00
`define APB_RNG_START 8'h10
`define APB_UART_START 8'h20
`define APB_PWM_START 8'h30
`define APB_PS2_START 8'h40
`define APB_RTC_START 8'h50
`define APB_WDG_START 8'h60
`define APB_CRC_START 8'h70
`define APB_TMR_START 8'h80
`define APB_USR_START 8'hF0
`endif
+40 -28
View File
@@ -67,6 +67,10 @@ module retrosoc (
logic [31:0] s_irq;
logic [ 9:0] s_nmi_irq;
logic [ 6:0] s_apb_irq;
logic s_bus_fault_valid;
logic [31:0] s_bus_fault_addr;
logic [ 3:0] s_bus_fault_wstrb;
logic s_bus_fault_reserved;
`ifdef CORE_MDD
assign u_sysctrl_if.core_sel_i = core_sel_i;
@@ -371,42 +375,50 @@ module retrosoc (
bus u_bus (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.clk_i (clk_i),
.rst_n_i (rst_n_i),
`ifdef HAVE_SRAM_IF
.ram (ram),
.ram (ram),
`endif
// master
.core_nmi(u_core_nmi_if),
.dma_nmi (u_dma_nmi_if),
.core_nmi (u_core_nmi_if),
.dma_nmi (u_dma_nmi_if),
// slave
.natv_nmi(u_nmi_nmi_if),
.apb_nmi (u_apb_nmi_if)
.natv_nmi (u_nmi_nmi_if),
.apb_nmi (u_apb_nmi_if),
.fault_valid_o (s_bus_fault_valid),
.fault_addr_o (s_bus_fault_addr),
.fault_wstrb_o (s_bus_fault_wstrb),
.fault_reserved_o(s_bus_fault_reserved)
);
ip_nmi_wrapper u_ip_nmi_wrapper (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.clk_aud_i (clk_aud_i),
.rst_aud_n_i(rst_aud_n_i),
.nmi (u_nmi_nmi_if),
.gpio (u_gpio_if),
.uart (uart0),
.psram (u_psram_if),
.spisd (u_spisd_if),
.i2c0 (u_i2c0_if),
.i2s (u_i2s_if),
.onewire (u_onewire_if),
.xpi (xpi),
.dma_nmi (u_dma_nmi_if),
.sysctrl (u_sysctrl_if),
.sdram (sdram),
.dvp (u_dvp_if),
.sdio (u_sdio_if),
.opipsram (u_opipsram_if),
.i2c1 (u_i2c1_if),
.irq_o (s_nmi_irq)
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.clk_aud_i (clk_aud_i),
.rst_aud_n_i (rst_aud_n_i),
.nmi (u_nmi_nmi_if),
.gpio (u_gpio_if),
.uart (uart0),
.psram (u_psram_if),
.spisd (u_spisd_if),
.i2c0 (u_i2c0_if),
.i2s (u_i2s_if),
.onewire (u_onewire_if),
.xpi (xpi),
.dma_nmi (u_dma_nmi_if),
.sysctrl (u_sysctrl_if),
.sdram (sdram),
.dvp (u_dvp_if),
.sdio (u_sdio_if),
.opipsram (u_opipsram_if),
.i2c1 (u_i2c1_if),
.fault_valid_i (s_bus_fault_valid),
.fault_addr_i (s_bus_fault_addr),
.fault_wstrb_i (s_bus_fault_wstrb),
.fault_reserved_i(s_bus_fault_reserved),
.irq_o (s_nmi_irq)
);
+17 -1
View File
@@ -6,6 +6,7 @@ from __future__ import annotations
import argparse
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
@@ -37,7 +38,20 @@ def main() -> int:
root = args.root.resolve()
with tempfile.TemporaryDirectory(prefix="retrosoc-c-tests-") as temporary_directory:
executable = Path(temporary_directory) / "runtime_tests"
temporary_root = Path(temporary_directory)
memory_map_root = temporary_root / "memory_map"
subprocess.run(
[
sys.executable,
str(root / "rtl/mini/script/generate_memory_map.py"),
"--map",
str(root / "rtl/mini/memory_map.json"),
"--output-dir",
str(memory_map_root),
],
check=True,
)
executable = temporary_root / "runtime_tests"
command = [
compiler,
"-std=c11",
@@ -46,6 +60,8 @@ def main() -> int:
"-Werror",
"-fno-builtin",
"-I",
str(memory_map_root / "include"),
"-I",
str(root / "crt/include"),
"-I",
str(root / "app/media/include"),
+77
View File
@@ -0,0 +1,77 @@
`timescale 1ns / 1ps
module bus_fault_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic fault_valid_o;
logic [31:0] fault_addr_o;
logic [ 3:0] fault_wstrb_o;
logic fault_reserved_o;
nmi_if core_nmi ();
nmi_if dma_nmi ();
nmi_if natv_nmi ();
nmi_if apb_nmi ();
always #5 clk_i = ~clk_i;
assign natv_nmi.ready = 1'b1;
assign natv_nmi.rdata = 32'hCAFE_BABE;
assign apb_nmi.ready = 1'b1;
assign apb_nmi.rdata = 32'h1234_5678;
bus u_bus (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.core_nmi (core_nmi),
.dma_nmi (dma_nmi),
.natv_nmi (natv_nmi),
.apb_nmi (apb_nmi),
.fault_valid_o (fault_valid_o),
.fault_addr_o (fault_addr_o),
.fault_wstrb_o (fault_wstrb_o),
.fault_reserved_o(fault_reserved_o)
);
task automatic expect_fault(input logic [31:0] address, input logic [3:0] write_strobes,
input logic reserved);
begin
@(negedge clk_i);
core_nmi.addr = address;
core_nmi.wdata = 32'hA5A5_5A5A;
core_nmi.wstrb = write_strobes;
core_nmi.valid = 1'b1;
while (!fault_valid_o) @(posedge clk_i);
if (fault_addr_o !== address || fault_wstrb_o !== write_strobes ||
fault_reserved_o !== reserved || natv_nmi.valid || apb_nmi.valid) begin
$fatal(1, "unexpected fault response for address %h", address);
end
while (!core_nmi.ready) @(posedge clk_i);
if (core_nmi.rdata !== 32'd0) begin
$fatal(1, "fault response data must be zero");
end
@(negedge clk_i);
core_nmi.valid = 1'b0;
while (fault_valid_o) @(posedge clk_i);
end
endtask
initial begin
core_nmi.valid = 1'b0;
core_nmi.addr = '0;
core_nmi.wdata = '0;
core_nmi.wstrb = '0;
dma_nmi.valid = 1'b0;
dma_nmi.addr = '0;
dma_nmi.wdata = '0;
dma_nmi.wstrb = '0;
repeat (2) @(posedge clk_i);
rst_n_i = 1'b1;
expect_fault(32'h1000_F000, 4'hF, 1'b1);
expect_fault(32'hA000_0000, 4'h0, 1'b0);
$display("bus fault responder test passed");
$finish;
end
endmodule
+86
View File
@@ -0,0 +1,86 @@
`timescale 1ns / 1ps
module sysctrl_fault_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic fault_valid_i = 1'b0;
logic [31:0] fault_addr_i = '0;
logic [ 3:0] fault_wstrb_i = '0;
logic fault_reserved_i = 1'b0;
nmi_if nmi ();
sysctrl_if sysctrl ();
always #5 clk_i = ~clk_i;
nmi_sysctrl u_sysctrl (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.fault_valid_i (fault_valid_i),
.fault_addr_i (fault_addr_i),
.fault_wstrb_i (fault_wstrb_i),
.fault_reserved_i(fault_reserved_i),
.nmi (nmi),
.sysctrl (sysctrl)
);
task automatic read_register(input logic [31:0] address, output logic [31:0] data);
begin
@(negedge clk_i);
nmi.addr = address;
nmi.wdata = '0;
nmi.wstrb = '0;
nmi.valid = 1'b1;
while (!nmi.ready) @(posedge clk_i);
data = nmi.rdata;
@(negedge clk_i);
nmi.valid = 1'b0;
while (nmi.ready) @(posedge clk_i);
end
endtask
task automatic write_register(input logic [31:0] address, input logic [31:0] data);
begin
@(negedge clk_i);
nmi.addr = address;
nmi.wdata = data;
nmi.wstrb = 4'hF;
nmi.valid = 1'b1;
while (!nmi.ready) @(posedge clk_i);
@(negedge clk_i);
nmi.valid = 1'b0;
while (nmi.ready) @(posedge clk_i);
end
endtask
logic [31:0] read_data;
initial begin
nmi.valid = 1'b0;
nmi.addr = '0;
nmi.wdata = '0;
nmi.wstrb = '0;
sysctrl.core_sel_i = '0;
repeat (2) @(posedge clk_i);
rst_n_i = 1'b1;
@(negedge clk_i);
fault_valid_i = 1'b1;
fault_addr_i = 32'h1000_F000;
fault_wstrb_i = 4'hF;
fault_reserved_i = 1'b1;
@(negedge clk_i);
fault_valid_i = 1'b0;
read_register(32'h1000_B010, read_data);
if (read_data !== 32'h0000_000B) $fatal(1, "fault status was not recorded");
read_register(32'h1000_B014, read_data);
if (read_data !== 32'h1000_F000) $fatal(1, "fault address was not recorded");
read_register(32'h1000_B018, read_data);
if (read_data !== 32'h0000_0001) $fatal(1, "fault count was not incremented");
write_register(32'h1000_B010, 32'h0000_0001);
read_register(32'h1000_B010, read_data);
if (read_data !== 32'h0000_000A) $fatal(1, "fault W1C did not clear pending");
$display("sysctrl fault registers test passed");
$finish;
end
endmodule
+179
View File
@@ -0,0 +1,179 @@
"""Tests for the canonical Mini SoC address-map generator."""
from __future__ import annotations
import json
import shutil
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
GENERATOR = ROOT / "rtl/mini/script/generate_memory_map.py"
MEMORY_MAP = ROOT / "rtl/mini/memory_map.json"
def generate(output_dir: Path, *, ip: str = "NONE", sram: str = "NO") -> None:
subprocess.run(
[
sys.executable,
str(GENERATOR),
"--map",
str(MEMORY_MAP),
"--output-dir",
str(output_dir),
"--have-sram-if",
sram,
"--ip",
ip,
],
check=True,
)
def test_generated_artifacts_share_the_capacity_baseline(tmp_path: Path) -> None:
generate(tmp_path, sram="YES")
rtl = (tmp_path / "rtl/mmap_define.svh").read_text(encoding="utf-8")
header = (tmp_path / "include/retrosoc/generated/memory_map.h").read_text(encoding="utf-8")
linker = (tmp_path / "linker/memory_regions.ld").read_text(encoding="utf-8")
assert "`define SOC_ADDR_PSRAM_END 32'h407FFFFF" in rtl
assert "`define SOC_ADDR_XPI_END 32'h5FFFFFFF" in rtl
assert "`define CPU_RESET_ADDR `SOC_CPU_RESET_ADDR" in rtl
assert "`define SOC_ADDR_IS_RESERVED(addr)" in rtl
assert "RS_SOC_PSRAM_SIZE UINT32_C(0x00800000)" in header
assert "RS_SOC_SDRAM_SIZE UINT32_C(0x02000000)" in header
assert "RS_SOC_SPISD_SIZE UINT32_C(0x40000000)" in header
assert "RS_SOC_NMI_SDIO_BASE" not in header
assert "RS_SOC_OPIPSRAM_BASE" not in header
assert "RS_SOC_HAS_SRAM 1U" in header
assert "PSRAM (wxa!ri) : ORIGIN = 0x40000000, LENGTH = 0x00800000" in linker
def test_user_ip_is_emitted_only_for_the_matching_profile(tmp_path: Path) -> None:
none_output = tmp_path / "none"
mdd_output = tmp_path / "mdd"
generate(none_output)
generate(mdd_output, ip="MDD")
none_rtl = (none_output / "rtl/mmap_define.svh").read_text(encoding="utf-8")
mdd_header = (mdd_output / "include/retrosoc/generated/memory_map.h").read_text(
encoding="utf-8"
)
assert "SOC_ADDR_APB_USER_IP_BASE" not in none_rtl
assert "RS_SOC_APB_USER_IP_BASE" in mdd_header
def test_map_validation_rejects_overlaps(tmp_path: Path) -> None:
document = json.loads(MEMORY_MAP.read_text(encoding="utf-8"))
document["regions"][1]["base"] = document["regions"][0]["base"]
invalid_map = tmp_path / "overlap.json"
invalid_map.write_text(json.dumps(document), encoding="utf-8")
result = subprocess.run(
[sys.executable, str(GENERATOR), "--map", str(invalid_map), "--check"],
text=True,
capture_output=True,
)
assert result.returncode != 0
assert "address-map overlap" in result.stderr
def test_bus_fault_responder_handles_reserved_and_unmapped_addresses(tmp_path: Path) -> None:
iverilog = shutil.which("iverilog")
vvp = shutil.which("vvp")
if iverilog is None or vvp is None:
return
generate(tmp_path)
simulation = tmp_path / "bus_fault_tb"
source_list = tmp_path / "bus_fault.fl"
source_list.write_text(
"\n".join(
[
"+define+SV_ASSRT_DISABLE",
f"+incdir+{tmp_path / 'rtl'}",
f"+incdir+{ROOT / 'rtl/clusterip/common/rtl'}",
str(ROOT / "rtl/clusterip/common/rtl/interface/nmi_if.sv"),
str(ROOT / "rtl/clusterip/common/rtl/utils/register.sv"),
str(ROOT / "rtl/ip/native/nmi_regslice.sv"),
str(ROOT / "rtl/mini/top/bus.sv"),
str(ROOT / "tests/rtl/bus_fault_tb.sv"),
"",
]
),
encoding="utf-8",
)
converted = tmp_path / "bus_fault_tb.v"
subprocess.run(
[
sys.executable,
str(ROOT / "rtl/mini/script/convt_sv2v.py"),
"-f",
str(source_list),
"--output",
str(converted),
],
check=True,
)
subprocess.run(
[
iverilog,
"-g2012",
"-s",
"bus_fault_tb",
"-o",
str(simulation),
str(converted),
],
check=True,
)
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
assert "bus fault responder test passed" in result.stdout
def test_sysctrl_fault_registers_record_and_clear_pending(tmp_path: Path) -> None:
iverilog = shutil.which("iverilog")
vvp = shutil.which("vvp")
if iverilog is None or vvp is None:
return
generate(tmp_path)
source_list = tmp_path / "sysctrl_fault.fl"
source_list.write_text(
"\n".join(
[
"+define+SV_ASSRT_DISABLE",
f"+incdir+{tmp_path / 'rtl'}",
f"+incdir+{ROOT / 'rtl/mini/top'}",
f"+incdir+{ROOT / 'rtl/clusterip/common/rtl'}",
str(ROOT / "rtl/clusterip/common/rtl/interface/nmi_if.sv"),
str(ROOT / "rtl/clusterip/common/rtl/utils/register.sv"),
str(ROOT / "rtl/ip/native/sysctrl.sv"),
str(ROOT / "tests/rtl/sysctrl_fault_tb.sv"),
"",
]
),
encoding="utf-8",
)
converted = tmp_path / "sysctrl_fault_tb.v"
subprocess.run(
[
sys.executable,
str(ROOT / "rtl/mini/script/convt_sv2v.py"),
"-f",
str(source_list),
"--output",
str(converted),
],
check=True,
)
simulation = tmp_path / "sysctrl_fault_tb"
subprocess.run(
[iverilog, "-g2012", "-s", "sysctrl_fault_tb", "-o", str(simulation), str(converted)],
check=True,
)
result = subprocess.run([vvp, str(simulation)], text=True, capture_output=True, check=True)
assert "sysctrl fault registers test passed" in result.stdout