mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: refactor test scripts to update paths and improve organization
- Updated paths in test files to reflect new directory structure for RTL and script files. - Changed references from rtl/mini to rtl/ip and scripts/rtl where applicable. - Added a new test file for Tiny product isolation, ensuring independent ABI and bus acceptance. - Enhanced tests for memory map generation and protocol contracts for Tiny architecture. - Ensured that all tests are aligned with the latest directory structure and naming conventions.
This commit is contained in:
194 files changed
+5532
-447
No files matched your search
@@ -22,7 +22,7 @@ truth wins.
|
||||
records approved Required-rule deviations.
|
||||
- [crt/README.md](crt/README.md) defines the freestanding RISC-V runtime and
|
||||
SDK layout; [app/README.md](app/README.md) defines application composition.
|
||||
- `Makefile`, `rtl/mini/mk/software.mk`, committed `configs/*.mk`, and the
|
||||
- `Makefile`, `rtl/mk/software.mk`, committed `configs/*.mk`, and the
|
||||
GitHub workflows define the active build and regression behavior.
|
||||
- `quality/embedded_c_policy.json`, `quality/warnings/`, and
|
||||
`quality/metrics/policy.json` define the active quality policy.
|
||||
@@ -77,7 +77,9 @@ README that states its ownership, source of truth, and validation expectations.
|
||||
`bringup`, `debug`, and `shell`; each profile is declared in
|
||||
`app/apps/<name>/app.mk`. The `debug` application is an RTL debug-transport
|
||||
acceptance image, not a user-facing firmware profile.
|
||||
- Do not add new dependencies on `crt/inc`, retired `tiny` names, or legacy
|
||||
- Tiny is a distinct wired MCU product under `rtl/tiny`; `SOC=TINY` selects its
|
||||
IHP130 profile and AXI4/APB4 integration.
|
||||
- Do not add new dependencies on `crt/inc`, retired SDK `tiny` names, or legacy
|
||||
`rs_*.h`/`tiny*.h` include paths.
|
||||
- Treat `app/coremark/coremark-main`, `app/fatfs/ff16`, `app/lvgl/lvgl-main`,
|
||||
and managed ports as third-party or managed code. Update them through their
|
||||
|
||||
@@ -29,7 +29,7 @@ $(error HAVE_DEBUG has been removed; the Hazard3 Debug Module is always enabled)
|
||||
endif
|
||||
|
||||
SOC ?= MINI
|
||||
MINI_MODE ?= PRODUCT
|
||||
MINI_MODE ?= $(if $(filter MINI,$(SOC)),PRODUCT,NONE)
|
||||
SIMU ?= VCS
|
||||
SYNTH ?= NONE
|
||||
SYNTH_RECIPE ?= balanced
|
||||
@@ -44,7 +44,7 @@ SRAM_SIZE_KIB ?= $(if $(filter ICS55,$(PDK)),128,32)
|
||||
PDK_BEHAV ?= NO
|
||||
HAVE_SVA ?= NO
|
||||
APU_ENABLE_P7 ?= NO
|
||||
HAVE_HP ?= YES
|
||||
HAVE_HP ?= $(if $(filter TINY,$(SOC)),NO,YES)
|
||||
HP_CONFIG ?= rv32imafdc_zicbom_max
|
||||
BUILD_RELEASE ?= NO
|
||||
JTAG_IDCODE ?= DEADBEEF
|
||||
@@ -65,7 +65,7 @@ RTL_SIM_TIMEOUT ?= -1
|
||||
SIM_FIRMWARE_NAME ?= $(FIRMWARE_NAME)
|
||||
SIM_SUCCESS_MARKER ?= SIM_TEST_PASS
|
||||
|
||||
RTL_PATH := $(ROOT_PATH)/rtl/mini
|
||||
RTL_PATH := $(ROOT_PATH)/rtl/$(shell printf '%s' '$(SOC)' | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
RTL_TOP ?= retrosoc_tb
|
||||
|
||||
@@ -212,8 +212,8 @@ else
|
||||
FLOW_FILELIST_DIR := $(SIM_BUILD_ROOT)/filelists
|
||||
endif
|
||||
|
||||
VALID_SOC := MINI
|
||||
VALID_MINI_MODE := PRODUCT MPW
|
||||
VALID_SOC := MINI TINY
|
||||
VALID_MINI_MODE := PRODUCT MPW NONE
|
||||
VALID_SIMU := VCS VERILATOR IVERILOG
|
||||
VALID_SYNTH := NONE YOSYS
|
||||
VALID_SYNTH_RECIPE := balanced area speed
|
||||
@@ -276,11 +276,18 @@ $(error NPU_P5_ACCEPTANCE and NPU_P6_ACCEPTANCE are mutually exclusive)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(SOC),MINI)
|
||||
ifeq ($(MINI_MODE),NONE)
|
||||
$(error SOC=MINI requires MINI_MODE=PRODUCT or MPW)
|
||||
endif
|
||||
ifeq ($(MINI_MODE),PRODUCT)
|
||||
ifneq ($(HAVE_HP),YES)
|
||||
$(error MINI_MODE=PRODUCT requires HAVE_HP=YES)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
include $(ROOT_PATH)/rtl/tiny/mk/config.mk
|
||||
endif
|
||||
|
||||
MISSING_LOCAL_RTL_FILES := $(filter-out $(wildcard $(LOCAL_RTL_FILES)),$(LOCAL_RTL_FILES))
|
||||
ifneq ($(strip $(MISSING_LOCAL_RTL_FILES)),)
|
||||
@@ -389,7 +396,9 @@ ifeq ($(APU_ENABLE_P7), YES)
|
||||
DEF_LIST += +define+APU_ENABLE_P7
|
||||
endif
|
||||
|
||||
ifeq ($(MINI_MODE), PRODUCT)
|
||||
ifeq ($(SOC), TINY)
|
||||
DEF_LIST += +define+RETROSOC_SOC__TINY
|
||||
else ifeq ($(MINI_MODE), PRODUCT)
|
||||
DEF_LIST += +define+MINI_PRODUCT
|
||||
else
|
||||
DEF_LIST += +define+MINI_MPW
|
||||
@@ -399,8 +408,10 @@ ifeq ($(SYNTH), YOSYS)
|
||||
DEF_LIST += +define+SYNTHESIS
|
||||
endif
|
||||
|
||||
include rtl/mini/Makefile
|
||||
include $(RTL_PATH)/Makefile
|
||||
ifeq ($(SOC),MINI)
|
||||
include rtl/mini/mk/formal.mk
|
||||
endif
|
||||
|
||||
ifeq ($(SIMU),IVERILOG)
|
||||
PERF_LOG ?= $(IVERILOG_BEHV_DIR)/sim.log
|
||||
@@ -410,9 +421,11 @@ endif
|
||||
|
||||
ifeq ($(SYNTH), YOSYS)
|
||||
include physical/smoke/syn/yosys/yosys.mk
|
||||
ifeq ($(SOC),MINI)
|
||||
include physical/smoke/syn/yosys/ga2d_block.mk
|
||||
include physical/smoke/syn/yosys/apu_block.mk
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(STA), OPENSTA)
|
||||
include physical/smoke/sta/opensta/opensta.mk
|
||||
@@ -440,7 +453,7 @@ crypto-p0-report: manifest
|
||||
apu-block-filelist apu-block-synth apu-block-sta apu-block-report apu-block-evidence apu-block-clean \
|
||||
pin-map check-pin-map soc-topology check-soc-topology user-extensions check-user-extensions \
|
||||
check-clock-reset-domains tech-cell-test rtl-lint check-rtl-lint \
|
||||
formal formal-bus formal-rib-adapter formal-rib2apb formal-gpio formal-ws2812 formal-uart formal-i2c formal-timer formal-dvp formal-i2s formal-onchip-ram formal-opipsram formal-dma formal-apu formal-apu-kws formal-apu-p9 formal-gateway-a formal-sdio formal-clean formal-doctor \
|
||||
formal formal-bus formal-rib-adapter formal-rib2apb formal-gpio formal-ws2812 formal-uart formal-i2c formal-timer formal-dvp formal-i2s formal-onchip-ram formal-opipsram formal-dma formal-apu formal-apu-kws formal-apu-p9 formal-gateway-a formal-sdio formal-clean formal-doctor \
|
||||
rtl-style-check-all rtl-readiness-check rtl-readiness-check-all vexii-generate
|
||||
.NOTPARALLEL: setup
|
||||
|
||||
@@ -571,7 +584,7 @@ config:
|
||||
doctor:
|
||||
@python3 $(ROOT_PATH)/scripts/doctor.py \
|
||||
--root $(ROOT_PATH) --simu $(SIMU) --synth $(SYNTH) --sta $(STA) \
|
||||
--pdk $(PDK) --have-sram-macro $(HAVE_SRAM_MACRO) \
|
||||
--pdk $(PDK) --soc $(SOC) --have-sram-macro $(HAVE_SRAM_MACRO) \
|
||||
--formal $(FORMAL) --lock $(LOCK_FILE)
|
||||
|
||||
benchmark-report: firmware
|
||||
@@ -593,7 +606,13 @@ hp-performance-check:
|
||||
--lp $(LP_COREMARK_REPORT) --hp $(HP_COREMARK_REPORT) \
|
||||
--minimum-ratio $(HP_PERF_MIN_RATIO) --output $(META_DIR)/lp-hp-performance.json
|
||||
|
||||
ifeq ($(SOC),TINY)
|
||||
setup: setup-tiny
|
||||
setup-tiny:
|
||||
python3 $(ROOT_PATH)/scripts/setup_tiny.py
|
||||
else
|
||||
setup: setup-mpw setup-vexiiriscv setup-clusterip setup-ip setup-pdk setup-app
|
||||
endif
|
||||
|
||||
setup-regression:
|
||||
$(MAKE) CONFIG=configs/ci/ihp130.mk setup
|
||||
@@ -1091,19 +1110,22 @@ commercial-package: $(MPW_VARIANT_DEP) $(FILELIST_STAMP) manifest
|
||||
--variant-root $(VARIANT_ROOT) --output-dir $(VARIANT_ROOT)/commercial/input
|
||||
|
||||
regress-smoke:
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite smoke --pdk IHP130
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite smoke --pdk IHP130 $(if $(filter TINY,$(SOC)),--soc TINY)
|
||||
|
||||
regress-rtl:
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite rtl --pdk IHP130
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite rtl --pdk IHP130 $(if $(filter TINY,$(SOC)),--soc TINY)
|
||||
|
||||
regress-pr:
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite pr --pdk IHP130 $(if $(filter YES,$(REGRESS_NETSIM_BOOT_ONLY)),--netsim-boot-only)
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite pr --pdk IHP130 $(if $(filter TINY,$(SOC)),--soc TINY) $(if $(filter YES,$(REGRESS_NETSIM_BOOT_ONLY)),--netsim-boot-only)
|
||||
ifneq ($(SOC),TINY)
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite pr --pdk GF180 $(if $(filter YES,$(REGRESS_NETSIM_BOOT_ONLY)),--netsim-boot-only)
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite pr --pdk SKY130 $(if $(filter YES,$(REGRESS_NETSIM_BOOT_ONLY)),--netsim-boot-only)
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite pr --pdk ICS55 $(if $(filter YES,$(REGRESS_NETSIM_BOOT_ONLY)),--netsim-boot-only)
|
||||
|
||||
endif
|
||||
|
||||
regress-nightly:
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite nightly
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite nightly $(if $(filter TINY,$(SOC)),--soc TINY)
|
||||
|
||||
sim-asm: asm
|
||||
$(MAKE) SIM_FIRMWARE_NAME=$(ASM_FIRMWARE_NAME) sim
|
||||
@@ -20,11 +20,13 @@ An open-source RISC-V SoC platform, from SystemVerilog RTL and firmware to repro
|
||||
|
||||
## Platform overview
|
||||
|
||||
**Mini is the active implementation.** The product configuration combines a
|
||||
low-power (LP) management hart and a high-performance (HP) application hart.
|
||||
The separate Mini MPW profile retains the legacy selectable-core integration.
|
||||
[Tiny, Std, and Pro](docs/soc-family-positioning.md) are product-roadmap targets,
|
||||
not additional supported build profiles.
|
||||
**Mini and Tiny have independent integration flows.** Mini combines a
|
||||
low-power Hazard3 management hart and a VexiiRiscv application hart; its separate
|
||||
MPW profile retains selectable-core compatibility. [Tiny](docs/ip/tiny-soc.md)
|
||||
is a wired MCU with one Hazard3 RV32IMC hart, 128 KiB SRAM, AXI4/APB4 and no
|
||||
wireless IP. Tiny first targets IHP130; [Std and Pro](docs/soc-family-positioning.md)
|
||||
remain roadmap products. Qualification is determined by each profile's retained
|
||||
verification and physical reports.
|
||||
|
||||
| Area | Mini platform |
|
||||
| --- | --- |
|
||||
@@ -96,6 +98,20 @@ Keep `firmware sim` in the same Make invocation so both use one build variant.
|
||||
Outputs live under `build/<profile>-<YYYY-MM-DD-HH-MM>-<config-hash>/`.
|
||||
Check the flow logs and result JSON; UART startup text alone is not a pass.
|
||||
|
||||
### Build and simulate Tiny
|
||||
|
||||
```sh
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk setup
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk doctor
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk firmware sim
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk SIMU=IVERILOG firmware sim
|
||||
```
|
||||
|
||||
Tiny uses its own source lists and product maps under `rtl/tiny`. Its firmware
|
||||
loads into on-chip SRAM without PSRAM/SDRAM initialization. The first release
|
||||
uses a fixed 24 MHz clock and disables atomic instructions. Wireless, external
|
||||
RAM, HP cores, accelerators and advanced low-power modes remain deferred.
|
||||
|
||||
## Configurations and common flows
|
||||
|
||||
Start from a [committed profile](configs/README.md). These are selected entry
|
||||
@@ -103,6 +119,7 @@ points, not the complete profile or application inventory.
|
||||
|
||||
| Profile | Purpose |
|
||||
| --- | --- |
|
||||
| [IHP130 Tiny](configs/ci/ihp130-tiny.mk) | Single-hart wired MCU, 128 KiB SRAM, pin-level Flash boot and automated acceptance. |
|
||||
| [IHP130 Mini](configs/ci/ihp130.mk) | Manual bring-up with 32 KiB macro-backed SRAM. |
|
||||
| [GF180](configs/ci/gf180.mk) / [SKY130](configs/ci/sky130.mk) | Alternative PDK profiles with 32 KiB macro-backed SRAM. |
|
||||
| [ICS55](configs/ci/ics55.mk) | Regression-compatible profile with SRAM and PLL disabled. |
|
||||
|
||||
@@ -162,3 +162,10 @@ make regress-nightly
|
||||
|
||||
See the [repository README](../README.md) for prerequisites, supported
|
||||
configurations, and build artifact locations.
|
||||
|
||||
For `SOC=TINY`, `bringup` and `ci_smoke` use the MCU acceptance composition. It
|
||||
boots through XPI into SRAM, checks CPU C/A behavior and bus exceptions, DMA
|
||||
(including UART requests), interrupts, RTC, GPIO, UART1 and I2C error completion,
|
||||
then verifies watchdog reset by completing after the next NOR boot. It uses
|
||||
SYSCTRL terminal status. The small `asm/tiny_boot.S` image separately qualifies
|
||||
the synthesized SRAM/pad path; it is not a replacement for the full RTL test.
|
||||
@@ -0,0 +1,3 @@
|
||||
APP_SRCS += $(ROOT_PATH)/app/apps/ci_smoke/tiny.c
|
||||
APP_CFLAGS += -Os
|
||||
APP_SRCS += $(ROOT_PATH)/app/apps/ci_smoke/mcu_acceptance.S
|
||||
@@ -0,0 +1,31 @@
|
||||
/* Copyright (c) 2026 Yuchi Miao; SPDX-License-Identifier: MulanPSL-2.0 */
|
||||
.section .text
|
||||
.balign 4
|
||||
.global rs_mcu_compressed_probe
|
||||
.type rs_mcu_compressed_probe,@function
|
||||
rs_mcu_compressed_probe:
|
||||
.option push
|
||||
.option rvc
|
||||
c.li a0, 21
|
||||
c.slli a0, 1
|
||||
c.jr ra
|
||||
.option pop
|
||||
.size rs_mcu_compressed_probe, .-rs_mcu_compressed_probe
|
||||
|
||||
.balign 4
|
||||
.global rs_mcu_atomic_probe
|
||||
.type rs_mcu_atomic_probe,@function
|
||||
rs_mcu_atomic_probe:
|
||||
/* lr.w a0,(a0): must trap because the Tiny A extension is disabled. */
|
||||
.word 0x1005252f
|
||||
ret
|
||||
.size rs_mcu_atomic_probe, .-rs_mcu_atomic_probe
|
||||
|
||||
.balign 4
|
||||
.global rs_mcu_unmapped_probe
|
||||
.type rs_mcu_unmapped_probe,@function
|
||||
rs_mcu_unmapped_probe:
|
||||
li a0, 0x38000000
|
||||
lw a0, 0(a0)
|
||||
ret
|
||||
.size rs_mcu_unmapped_probe, .-rs_mcu_unmapped_probe
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef RETROSOC_MCU_ACCEPTANCE_H
|
||||
#define RETROSOC_MCU_ACCEPTANCE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t rs_mcu_compressed_probe(void);
|
||||
void rs_mcu_atomic_probe(uint32_t *address);
|
||||
void rs_mcu_unmapped_probe(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,278 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <retrosoc/arch/riscv/system_base.h>
|
||||
#include <retrosoc/core/archinfo.h>
|
||||
#include <retrosoc/core/irq.h>
|
||||
#include <retrosoc/core/soc.h>
|
||||
#include <retrosoc/generated/irq_metadata.h>
|
||||
#include <retrosoc/hal/clint.h>
|
||||
#include <retrosoc/hal/dma.h>
|
||||
#include <retrosoc/hal/gpio.h>
|
||||
#include <retrosoc/hal/i2c.h>
|
||||
#include <retrosoc/hal/onchip_sram.h>
|
||||
#include <retrosoc/hal/pwm.h>
|
||||
#include <retrosoc/hal/rtc.h>
|
||||
#include <retrosoc/hal/sysctrl.h>
|
||||
#include <retrosoc/hal/timer.h>
|
||||
#include <retrosoc/hal/uart.h>
|
||||
#include <retrosoc/hal/watchdog.h>
|
||||
#include <retrosoc/lib/printf.h>
|
||||
|
||||
#include "mcu_acceptance.h"
|
||||
|
||||
static _Alignas(64) uint32_t rs_mcu_source[80];
|
||||
static _Alignas(64) uint32_t rs_mcu_destination[80];
|
||||
static volatile uint32_t rs_mcu_irq_count;
|
||||
static volatile uint32_t rs_mcu_exception_count;
|
||||
static volatile bool rs_mcu_handler_failed;
|
||||
|
||||
static void rs_mcu_finish(bool pass, uint8_t code) {
|
||||
printf("Tiny acceptance %s code=%u\n", pass ? "passed" : "failed", code);
|
||||
rs_sysctrl_write_test_status(pass, code);
|
||||
/* The terminal status must retain the first accepted full-word write. */
|
||||
rs_sysctrl_write_test_status(!pass, UINT8_C(255));
|
||||
for (;;) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rs_mcu_exception(uintptr_t mcause, uintptr_t stack_pointer) {
|
||||
volatile uint32_t *const frame = (volatile uint32_t *)stack_pointer;
|
||||
|
||||
if ((mcause != UINT32_C(2)) && (mcause != UINT32_C(5))) {
|
||||
rs_mcu_handler_failed = true;
|
||||
}
|
||||
++rs_mcu_exception_count;
|
||||
/* system_irq.S saves MEPC in slot 11 of the RV32 trap frame. Both test
|
||||
* instructions are explicitly 32 bits; normal exceptions do not use this handler. */
|
||||
frame[11] += UINT32_C(4);
|
||||
}
|
||||
|
||||
static void rs_mcu_timer_irq(uintptr_t mcause, uintptr_t stack_pointer) {
|
||||
(void)mcause;
|
||||
(void)stack_pointer;
|
||||
++rs_mcu_irq_count;
|
||||
if (rs_timer_interrupt_clear(RS_TIMER_0, RS_TIMER_INTERRUPT_ALL) != RS_OK) {
|
||||
rs_mcu_handler_failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rs_mcu_dma(void) {
|
||||
rs_dma_config_t config = {
|
||||
.kind = RS_DMA_KIND_MM_TO_MM,
|
||||
.request = RS_DMA_REQUEST_SOFTWARE,
|
||||
.source = (uintptr_t)rs_mcu_source,
|
||||
.destination = (uintptr_t)rs_mcu_destination,
|
||||
.byte_count = UINT32_C(259),
|
||||
.width = RS_DMA_WIDTH_32,
|
||||
.source_increment = true,
|
||||
.destination_increment = true,
|
||||
.priority = 0U,
|
||||
.burst_beats = 16U,
|
||||
};
|
||||
|
||||
for (uint32_t index = 0U; index < 80U; ++index) {
|
||||
rs_mcu_source[index] = UINT32_C(0xa519c300) ^ index;
|
||||
rs_mcu_destination[index] = UINT32_C(0xcccccccc);
|
||||
}
|
||||
if ((rs_dma_configure(4U, &config) != RS_EINVAL) ||
|
||||
(rs_dma_configure(RS_DMA_CHANNEL_BULK, &config) != RS_OK) ||
|
||||
(rs_dma_start(RS_DMA_CHANNEL_BULK) != RS_OK) ||
|
||||
(rs_dma_wait(RS_DMA_CHANNEL_BULK, RS_TIMEOUT_DEFAULT) != RS_OK)) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t index = 0U; index < 64U; ++index) {
|
||||
if (rs_mcu_source[index] != rs_mcu_destination[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (rs_mcu_destination[64] !=
|
||||
((rs_mcu_source[64] & UINT32_C(0x00ffffff)) | UINT32_C(0xcc000000))) {
|
||||
return false;
|
||||
}
|
||||
config.kind = RS_DMA_KIND_MM_TO_STREAM;
|
||||
config.request = RS_DMA_REQUEST_I2S_TX;
|
||||
return rs_dma_config_validate(0U, &config) != RS_OK;
|
||||
}
|
||||
|
||||
static bool rs_mcu_interrupts(void) {
|
||||
uint32_t timeout = UINT32_C(20000);
|
||||
|
||||
if ((rs_irq_enable_external(RS_SOC_EXT_IRQ_TIMER0, rs_mcu_timer_irq) != RS_OK) ||
|
||||
(rs_timer_interrupt_enable(RS_TIMER_0, RS_TIMER_INTERRUPT_TIMEOUT) != RS_OK) ||
|
||||
(rs_timer_interrupt_test(RS_TIMER_0, RS_TIMER_INTERRUPT_TIMEOUT) != RS_OK)) {
|
||||
return false;
|
||||
}
|
||||
__RV_CSR_SET(CSR_MSTATUS, MSTATUS_MIE);
|
||||
while ((rs_mcu_irq_count == 0U) && (timeout != 0U)) {
|
||||
--timeout;
|
||||
}
|
||||
__RV_CSR_CLEAR(CSR_MSTATUS, MSTATUS_MIE);
|
||||
return (rs_mcu_irq_count == 1U) && !rs_mcu_handler_failed &&
|
||||
(rs_irq_disable_external(RS_SOC_EXT_IRQ_TIMER0) == RS_OK);
|
||||
}
|
||||
|
||||
static bool rs_mcu_io(void) {
|
||||
const rs_gpio_config_t output = {
|
||||
.mode = RS_GPIO_MODE_OUTPUT,
|
||||
.pull = RS_GPIO_PULL_NONE,
|
||||
.trigger = RS_GPIO_TRIGGER_NONE,
|
||||
.output_high = false,
|
||||
};
|
||||
const rs_uart_config_t loopback = {
|
||||
.source_clock_hz = RS_CPU_CLOCK_HZ,
|
||||
.baud_rate = UART_BPS,
|
||||
.data_bits = 8U,
|
||||
.stop_bits = 1U,
|
||||
.parity = RS_UART_PARITY_NONE,
|
||||
.rx_watermark = 1U,
|
||||
.rx_timeout_bits = 16U,
|
||||
.tx_enable = true,
|
||||
.rx_enable = true,
|
||||
.loopback_enable = true,
|
||||
};
|
||||
const uint32_t transmit[4] = {UINT32_C(0x54), UINT32_C(0x49), UINT32_C(0x4e), UINT32_C(0x59)};
|
||||
uint32_t receive[4] = {0U};
|
||||
rs_uart_timing_t timing;
|
||||
bool high;
|
||||
uint32_t timeout = UINT32_C(10000);
|
||||
uint8_t payload = UINT8_C(0x55);
|
||||
const rs_i2c_transfer_t transfer = {
|
||||
.address = UINT16_C(0x50),
|
||||
.tx_data = &payload,
|
||||
.tx_length = 1U,
|
||||
};
|
||||
rs_i2c_status_t status;
|
||||
|
||||
if ((rs_gpio_configure(15U, &output) != RS_OK) || (rs_gpio_write(15U, true) != RS_OK) ||
|
||||
(rs_gpio_read(15U, &high) != RS_OK) || !high || (rs_gpio_write(15U, false) != RS_OK) ||
|
||||
(rs_gpio_read(15U, &high) != RS_OK) || high) {
|
||||
return false;
|
||||
}
|
||||
if ((rs_uart_configure(&loopback, RS_TIMEOUT_DEFAULT) != RS_OK) ||
|
||||
(rs_uart_write_dma(transmit, 4U, RS_TIMEOUT_DEFAULT) != RS_OK) ||
|
||||
(rs_uart_read_dma(receive, 4U, RS_TIMEOUT_DEFAULT) != RS_OK)) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t index = 0U; index < 4U; ++index) {
|
||||
if (transmit[index] != receive[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((rs_uart_init(RS_CPU_CLOCK_HZ, UART_BPS) != RS_OK) ||
|
||||
(rs_uart_timing_calculate(RS_CPU_CLOCK_HZ, UART_BPS, &timing) != RS_OK)) {
|
||||
return false;
|
||||
}
|
||||
/* UART1 uses the same register ABI; the current shared high-level UART
|
||||
* API selects UART0. Exercise UART1 PIO and its internal loopback here. */
|
||||
RS_SOC_REG32(RS_SOC_APB4_UART1_BASE, UINT32_C(0x00)) = timing.baud_integer;
|
||||
RS_SOC_REG32(RS_SOC_APB4_UART1_BASE, UINT32_C(0x04)) = timing.baud_fraction;
|
||||
RS_SOC_REG32(RS_SOC_APB4_UART1_BASE, UINT32_C(0x08)) = UINT32_C(3);
|
||||
RS_SOC_REG32(RS_SOC_APB4_UART1_BASE, UINT32_C(0x0c)) = UINT32_C(7);
|
||||
RS_SOC_REG32(RS_SOC_APB4_UART1_BASE, UINT32_C(0x10)) = UINT32_C(0x5a);
|
||||
while (((RS_SOC_REG32(RS_SOC_APB4_UART1_BASE, UINT32_C(0x18)) & UINT32_C(0x40)) != 0U) &&
|
||||
(timeout != 0U)) {
|
||||
--timeout;
|
||||
}
|
||||
if ((timeout == 0U) || ((RS_SOC_REG32(RS_SOC_APB4_UART1_BASE, UINT32_C(0x14)) &
|
||||
UINT32_C(0xff)) != UINT32_C(0x5a))) {
|
||||
return false;
|
||||
}
|
||||
/* There is no slave on the pulled-up acceptance board: a real address
|
||||
* transaction must terminate as NACK rather than stick waiting on the bus. */
|
||||
for (uint32_t bus = 0U; bus < 2U; ++bus) {
|
||||
const rs_i2c_bus_t instance = (bus == 0U) ? RS_I2C_BUS_0 : RS_I2C_BUS_1;
|
||||
if ((rs_i2c_init(instance, RS_CPU_CLOCK_HZ, UINT32_C(100000)) != RS_OK) ||
|
||||
(rs_i2c_transfer(instance, &transfer, RS_TIMEOUT_DEFAULT) != RS_EIO) ||
|
||||
(rs_i2c_get_status(instance, &status) != RS_OK) ||
|
||||
((status.errors & RS_I2C_ERROR_ADDR_NACK) == 0U)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rs_mcu_rtc(void) {
|
||||
const rs_rtc_config_t config = {
|
||||
.second_cycles = UINT32_C(4096),
|
||||
.calibration_ppm = 0,
|
||||
.interrupt_enable = 0U,
|
||||
.wake_enable = 0U,
|
||||
.enable = true,
|
||||
};
|
||||
const rs_rtc_time_t value = {.seconds = UINT64_C(1234), .subsecond = 0U};
|
||||
rs_rtc_time_t observed;
|
||||
|
||||
return (rs_rtc_probe() == RS_OK) && (rs_rtc_configure(&config, RS_TIMEOUT_DEFAULT) == RS_OK) &&
|
||||
(rs_rtc_set_time(&value, RS_TIMEOUT_DEFAULT) == RS_OK) &&
|
||||
(rs_rtc_get_time(&observed, RS_TIMEOUT_DEFAULT) == RS_OK) &&
|
||||
(observed.seconds >= value.seconds);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
rs_archinfo_t info;
|
||||
rs_onchip_sram_info_t memory;
|
||||
rs_sysctrl_fault_status_t fault;
|
||||
rs_watchdog_status_t watchdog;
|
||||
uint64_t before;
|
||||
uint64_t after;
|
||||
const rs_watchdog_config_t watchdog_config = {
|
||||
.prescale_divider = 1U,
|
||||
.timeout_ticks = UINT32_C(20000),
|
||||
.window_min_ticks = 0U,
|
||||
.early_warning_ticks = 0U,
|
||||
.window_enable = false,
|
||||
.early_warning_enable = false,
|
||||
.debug_freeze_enable = true,
|
||||
};
|
||||
|
||||
if (rs_uart_init(RS_CPU_CLOCK_HZ, UART_BPS) != RS_OK) {
|
||||
rs_mcu_finish(false, 1U);
|
||||
}
|
||||
printf("Hello retroSoC! Tiny MCU\n");
|
||||
if (rs_watchdog_get_status(&watchdog, RS_TIMEOUT_DEFAULT) != RS_OK) {
|
||||
rs_mcu_finish(false, 2U);
|
||||
}
|
||||
if (watchdog.reset_count != 0U) {
|
||||
rs_mcu_finish(true, 0U);
|
||||
}
|
||||
if ((rs_archinfo_read(&info) != RS_OK) || (rs_archinfo_validate_build(&info) != RS_OK) ||
|
||||
(info.soc_id != RS_SOC_ID) || (info.topology != UINT32_C(0x20200001)) ||
|
||||
(rs_onchip_sram_probe(&memory) != RS_OK) || (memory.memory_bytes != UINT32_C(131072)) ||
|
||||
(memory.data_bytes != 4U) || (memory.bank_count != 32U)) {
|
||||
rs_mcu_finish(false, 3U);
|
||||
}
|
||||
if ((rs_mcu_compressed_probe() != 42U) || ((__RV_CSR_READ(CSR_MISA) & UINT32_C(1)) != 0U) ||
|
||||
(rs_irq_register_exception(2U, rs_mcu_exception) != RS_OK) ||
|
||||
(rs_irq_register_exception(5U, rs_mcu_exception) != RS_OK)) {
|
||||
rs_mcu_finish(false, 4U);
|
||||
}
|
||||
rs_mcu_atomic_probe(rs_mcu_source);
|
||||
rs_mcu_unmapped_probe();
|
||||
if ((rs_mcu_exception_count != 2U) || rs_mcu_handler_failed ||
|
||||
(rs_sysctrl_get_fault_status(&fault) != RS_OK) || !fault.pending ||
|
||||
(fault.address != UINT32_C(0x38000000)) || (rs_sysctrl_clear_fault() != RS_OK)) {
|
||||
rs_mcu_finish(false, 5U);
|
||||
}
|
||||
if (!rs_mcu_dma()) {
|
||||
rs_mcu_finish(false, 6U);
|
||||
}
|
||||
if ((rs_clint_get_time(&before) != RS_OK) || (rs_clint_get_time(&after) != RS_OK) ||
|
||||
(after <= before) || !rs_mcu_interrupts()) {
|
||||
rs_mcu_finish(false, 7U);
|
||||
}
|
||||
if (!rs_mcu_rtc() || (rs_pwm_probe() != RS_OK) ||
|
||||
(rs_sysctrl_set_hp_release(true) != RS_ENOTSUP)) {
|
||||
rs_mcu_finish(false, 8U);
|
||||
}
|
||||
if (!rs_mcu_io()) {
|
||||
rs_mcu_finish(false, 10U);
|
||||
}
|
||||
printf("Tiny CPU/DMA/IRQ/RTC/I/O passed; exercising watchdog reset\n");
|
||||
if ((rs_watchdog_configure(&watchdog_config) != RS_OK) ||
|
||||
(rs_watchdog_start(RS_TIMEOUT_DEFAULT) != RS_OK)) {
|
||||
rs_mcu_finish(false, 9U);
|
||||
}
|
||||
for (;;) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
APP_SRCS += $(ROOT_PATH)/app/apps/ci_smoke/tiny.c
|
||||
APP_CFLAGS += -Os
|
||||
APP_SRCS += $(ROOT_PATH)/app/apps/ci_smoke/mcu_acceptance.S
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Copyright (c) 2026 Yuchi Miao; SPDX-License-Identifier: MulanPSL-2.0 */
|
||||
#include "retrosoc/generated/memory_map.h"
|
||||
|
||||
/* Small gate-level acceptance image. Executes through the real XPI pins,
|
||||
* checks both ends of SRAM and byte strobes, then checks APB/UART/SYSCTRL.
|
||||
* The full SDK/application acceptance runs separately in both RTL simulators. */
|
||||
.section .text
|
||||
.global _start
|
||||
_start:
|
||||
li t0, RS_SOC_SRAM_BASE
|
||||
li t1, 0x12345678
|
||||
sw t1, 0(t0)
|
||||
lw t2, 0(t0)
|
||||
bne t1, t2, failed
|
||||
li t0, RS_SOC_SRAM_END - 3
|
||||
sw t1, 0(t0)
|
||||
li t2, 0xab
|
||||
sb t2, 1(t0)
|
||||
lw t2, 0(t0)
|
||||
li t1, 0x1234ab78
|
||||
bne t1, t2, failed
|
||||
|
||||
li s0, RS_SOC_APB4_UART0_BASE
|
||||
li t0, 26
|
||||
sw t0, 0(s0)
|
||||
li t0, 11
|
||||
sw t0, 4(s0)
|
||||
li t0, 3
|
||||
sw t0, 8(s0)
|
||||
sw t0, 12(s0)
|
||||
la s1, message
|
||||
print_loop:
|
||||
lbu s2, 0(s1)
|
||||
beqz s2, passed
|
||||
wait_uart:
|
||||
lw t0, 24(s0)
|
||||
andi t0, t0, 32
|
||||
bnez t0, wait_uart
|
||||
sw s2, 16(s0)
|
||||
addi s1, s1, 1
|
||||
j print_loop
|
||||
passed:
|
||||
/* Let the serial output drain before setting the terminal verdict. */
|
||||
lw t0, 24(s0)
|
||||
andi t0, t0, 4
|
||||
bnez t0, passed
|
||||
li t0, RS_SOC_APB4_SYSCTRL_BASE
|
||||
li t1, 0x80000001
|
||||
sw t1, RS_SOC_SYSCTRL_TEST_STATUS_OFFSET(t0)
|
||||
halt:
|
||||
j halt
|
||||
failed:
|
||||
li t0, RS_SOC_APB4_SYSCTRL_BASE
|
||||
li t1, 0x80000100
|
||||
sw t1, RS_SOC_SYSCTRL_TEST_STATUS_OFFSET(t0)
|
||||
j halt
|
||||
message:
|
||||
.asciz "Hello retroSoC! Tiny netlist boot\n"
|
||||
@@ -52,3 +52,12 @@ macro must select either this mode or a qualified macro timing model.
|
||||
|
||||
For supported profiles and commands, see the root [README](../README.md) and
|
||||
[agent contract](../AGENTS.md).
|
||||
|
||||
## Tiny MCU
|
||||
|
||||
`ci/ihp130-tiny.mk` selects `SOC=TINY`, one RV32IMC Hazard3 (A disabled),
|
||||
128 KiB SRAM, AXI32/APB4, four DMA channels and the wired peripheral subset.
|
||||
The profile uses 24 MHz, `HAVE_HP=NO`, `MINI_MODE=NONE`, CSR-enabled RV32IM
|
||||
firmware and `ld2_all_sram`. Both `bringup` and `ci_smoke` select Tiny acceptance
|
||||
firmware. Icarus and Verilator use the same pin-level Flash model. Other PDKs,
|
||||
wireless, external RAM and HP applications are rejected by the Tiny config gate.
|
||||
@@ -0,0 +1,18 @@
|
||||
SOC := TINY
|
||||
MINI_MODE := NONE
|
||||
PDK := IHP130
|
||||
SIMU := VERILATOR
|
||||
HAVE_PLL := NO
|
||||
HAVE_SRAM_IF := YES
|
||||
HAVE_SRAM_MACRO := YES
|
||||
SRAM_SIZE_KIB := 128
|
||||
HAVE_HP := NO
|
||||
HAVE_SVA := NO
|
||||
EXT_CLK_HZ := 24000000
|
||||
AUD_CLK_HZ := 24000000
|
||||
CLINT_TIMEBASE_HZ := 1000000
|
||||
ISA := RV32IM
|
||||
HAVE_CSR := YES
|
||||
APP := bringup
|
||||
LINK_TYPE := ld2_all_sram
|
||||
RTL_TOP := retrosoc_tiny_tb
|
||||
+15
-1
@@ -160,7 +160,7 @@ on it.
|
||||
## Build Integration
|
||||
|
||||
The central software build assembles the runtime sources in
|
||||
[`../rtl/mini/mk/software.mk`](../rtl/mini/mk/software.mk). It selects the
|
||||
[`../rtl/mk/software.mk`](../rtl/mk/software.mk). It selects the
|
||||
RISC-V ISA, optional CSR interrupt support, linker layout, and the application
|
||||
profile. Applications add their own sources after the common runtime is
|
||||
selected.
|
||||
@@ -219,3 +219,17 @@ hardware validation.
|
||||
|
||||
For the complete firmware, simulation, synthesis, and timing flow, see the
|
||||
[repository README](../README.md).
|
||||
|
||||
## Product composition
|
||||
|
||||
Tiny uses the same `rs_` SDK and selects its generated memory, IRQ and capability
|
||||
headers through the committed profile. The generated memory-map header includes
|
||||
Tiny capability metadata, so public DMA headers report four channels without
|
||||
requiring an application to reproduce private compiler flags. Unavailable IP
|
||||
drivers are omitted; Tiny SYSCTRL rejects unsupported lifecycle/PLL operations
|
||||
before MMIO. Startup skips external-RAM initialization and loads into SRAM.
|
||||
|
||||
`<retrosoc/hal/watchdog.h>` provides `rs_watchdog_configure`, `rs_watchdog_start`,
|
||||
`rs_watchdog_service`, `rs_watchdog_get_status` and `rs_watchdog_clear_reset_cause`,
|
||||
with SDK status values and bounded command waits. These wrappers preserve the
|
||||
locked watchdog register ABI.
|
||||
@@ -17,6 +17,7 @@ _start:
|
||||
/* Direct Mode: All exceptions set pc to BASE */
|
||||
csrc CSR_MTVEC, 0x3
|
||||
#endif
|
||||
#ifndef RS_SOC_TINY
|
||||
# wait psram reset done
|
||||
la a0, _flash_wait_start
|
||||
la a1, 2000
|
||||
@@ -25,6 +26,8 @@ wait_psram_reset:
|
||||
addi a0, a0, 4
|
||||
blt a0, a1, wait_psram_reset
|
||||
|
||||
#endif
|
||||
|
||||
# ===== Startup Stage 1 =====
|
||||
# init the regfile
|
||||
# zero-initialize register file
|
||||
@@ -68,6 +71,7 @@ wait_psram_reset:
|
||||
# when code LMA is different with VMA
|
||||
# test: using psram before loading
|
||||
|
||||
#ifndef RS_SOC_TINY
|
||||
# Define the addresses
|
||||
.equ GPIO_ALT_ENABLE, RS_SOC_APB4_GPIO_ADMIN_BASE + 0x34
|
||||
.equ GPIO_ALT_SELECT, RS_SOC_APB4_GPIO_ADMIN_BASE + 0x38
|
||||
@@ -98,6 +102,8 @@ PSRAM_READY_WAIT:
|
||||
andi t1, t1, PSRAM_READY
|
||||
beqz t1, PSRAM_READY_WAIT
|
||||
|
||||
#endif
|
||||
|
||||
app_loader_start:
|
||||
la a0, _ram_lma
|
||||
la a1, _ram_vma
|
||||
|
||||
@@ -77,11 +77,15 @@
|
||||
#define RS_DMA_ERROR_READ UINT32_C(0x00000040)
|
||||
#define RS_DMA_ERROR_STREAM_LAST UINT32_C(0x00000100)
|
||||
|
||||
#define RS_DMA_CHANNEL_COUNT 8U
|
||||
#define RS_DMA_CHANNEL_HP 6U
|
||||
#define RS_DMA_CHANNEL_RESERVED 7U
|
||||
#define RS_DMA_MAX_BURST_BEATS 16U
|
||||
#define RS_DMA_DATA_WIDTH_BITS 32U
|
||||
#ifdef RS_SOC_TINY
|
||||
#define RS_DMA_CHANNEL_COUNT 4U
|
||||
#else
|
||||
#define RS_DMA_CHANNEL_COUNT 8U
|
||||
#endif
|
||||
#define RS_DMA_CHANNEL_HP 6U
|
||||
#define RS_DMA_CHANNEL_RESERVED 7U
|
||||
#define RS_DMA_MAX_BURST_BEATS 16U
|
||||
#define RS_DMA_DATA_WIDTH_BITS 32U
|
||||
|
||||
#define RS_DMA_CHANNEL_OFFSET(channel, offset) \
|
||||
(RS_DMA_CH_BASE + ((uint32_t)(channel)*RS_DMA_CH_STRIDE) + (offset))
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
#ifndef RETROSOC_WDG_H
|
||||
#define RETROSOC_WDG_H
|
||||
|
||||
#include <wdg.h>
|
||||
|
||||
#include <retrosoc/core/status.h>
|
||||
|
||||
typedef wdg_config_t rs_watchdog_config_t;
|
||||
typedef wdg_snapshot_t rs_watchdog_status_t;
|
||||
|
||||
rs_status_t rs_watchdog_configure(const rs_watchdog_config_t *config);
|
||||
rs_status_t rs_watchdog_start(rs_timeout_t timeout);
|
||||
rs_status_t rs_watchdog_service(rs_timeout_t timeout);
|
||||
rs_status_t rs_watchdog_get_status(rs_watchdog_status_t *status, rs_timeout_t timeout);
|
||||
rs_status_t rs_watchdog_clear_reset_cause(rs_timeout_t timeout);
|
||||
|
||||
void ip_wdg_test(int argc, char **argv);
|
||||
#endif
|
||||
@@ -39,7 +39,20 @@ rs_status_t rs_archinfo_validate_build(const rs_archinfo_t *info) {
|
||||
.config_id = ARCHINFO_INTEGRATION_CONFIG_ID,
|
||||
};
|
||||
|
||||
#ifdef RS_SOC_TINY
|
||||
if ((info == NULL) || (info->soc_id != RS_SOC_ID) ||
|
||||
(info->component_id != ARCHINFO_COMPONENT_ID_VALUE) ||
|
||||
(info->ip_version != ARCHINFO_IP_VERSION_VALUE) ||
|
||||
(((info->capability & ARCHINFO_CAPABILITY_ABI_MASK) >> ARCHINFO_CAPABILITY_ABI_SHIFT) !=
|
||||
ARCHINFO_ABI_VERSION) ||
|
||||
(expectation.check_build_id && (info->build_id != expectation.build_id)) ||
|
||||
(info->config_id != expectation.config_id)) {
|
||||
return RS_EFORMAT;
|
||||
}
|
||||
return RS_OK;
|
||||
#else
|
||||
return rs_archinfo_status(archinfo_validate(info, &expectation));
|
||||
#endif
|
||||
}
|
||||
|
||||
rs_status_t rs_archinfo_read_device_id(uint32_t device_id[4]) {
|
||||
|
||||
@@ -18,6 +18,11 @@ static bool rs_dma_address_valid(uintptr_t address, uint32_t byte_count, bool in
|
||||
}
|
||||
|
||||
static bool rs_dma_request_valid(const rs_dma_config_t *config) {
|
||||
#ifdef RS_SOC_TINY
|
||||
if (config->kind != RS_DMA_KIND_MM_TO_MM) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
switch (config->kind) {
|
||||
case RS_DMA_KIND_MM_TO_MM:
|
||||
return (config->request == RS_DMA_REQUEST_SOFTWARE) ||
|
||||
@@ -91,6 +96,11 @@ rs_status_t rs_dma_tcd_validate(uint32_t channel, const rs_dma_tcd_t *tcd) {
|
||||
kind = (tcd->control >> RS_DMA_TCD_KIND_SHIFT) & UINT32_C(0x7);
|
||||
request = (tcd->control >> RS_DMA_TCD_REQUEST_SHIFT) & UINT32_C(0xF);
|
||||
burst = (tcd->control >> RS_DMA_TCD_BURST_SHIFT) & UINT32_C(0x1F);
|
||||
#ifdef RS_SOC_TINY
|
||||
if (kind != (uint32_t)RS_DMA_KIND_MM_TO_MM) {
|
||||
return RS_ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
if ((kind > (uint32_t)RS_DMA_KIND_STREAM_TO_MM) ||
|
||||
(request > (uint32_t)RS_DMA_REQUEST_CRYPTO_OUT) || (burst > RS_DMA_MAX_BURST_BEATS) ||
|
||||
((tcd->source & UINT32_C(0x3)) != UINT32_C(0)) ||
|
||||
|
||||
+2
-2
@@ -454,7 +454,7 @@ rs_status_t rs_i2c_write_dma(rs_i2c_bus_t bus, uint16_t address, bool ten_bit_ad
|
||||
const uint32_t channel = (bus == RS_I2C_BUS_0) ? RS_DMA_CHANNEL_I2C0 : RS_DMA_CHANNEL_I2C1;
|
||||
const rs_dma_request_t request =
|
||||
(bus == RS_I2C_BUS_0) ? RS_DMA_REQUEST_I2C0_TX : RS_DMA_REQUEST_I2C1_TX;
|
||||
rs_dma_config_t dma_config;
|
||||
rs_dma_config_t dma_config = {0};
|
||||
|
||||
if (!rs_i2c_bus_valid(bus) || (data == NULL) || (workspace == NULL) || (length == 0U) ||
|
||||
(length > RS_I2C_DMA_MAX_BYTES)) {
|
||||
@@ -499,7 +499,7 @@ rs_status_t rs_i2c_read_dma(rs_i2c_bus_t bus, uint16_t address, bool ten_bit_add
|
||||
const uint32_t channel = (bus == RS_I2C_BUS_0) ? RS_DMA_CHANNEL_I2C0 : RS_DMA_CHANNEL_I2C1;
|
||||
const rs_dma_request_t request =
|
||||
(bus == RS_I2C_BUS_0) ? RS_DMA_REQUEST_I2C0_RX : RS_DMA_REQUEST_I2C1_RX;
|
||||
rs_dma_config_t dma_config;
|
||||
rs_dma_config_t dma_config = {0};
|
||||
|
||||
if (!rs_i2c_bus_valid(bus) || (data == NULL) || (workspace == NULL) || (length == 0U) ||
|
||||
(length > RS_I2C_DMA_MAX_BYTES)) {
|
||||
|
||||
@@ -86,6 +86,12 @@ static rs_status_t rs_sysctrl_perf_offsets(rs_sysctrl_perf_counter_t counter, ui
|
||||
return RS_EINVAL;
|
||||
}
|
||||
|
||||
#ifdef RS_SOC_TINY
|
||||
if ((counter != RS_SYSCTRL_PERF_MGMT_WAIT) && (counter != RS_SYSCTRL_PERF_DMA_WAIT)) {
|
||||
return RS_ENOTSUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (counter) {
|
||||
case RS_SYSCTRL_PERF_MGMT_WAIT:
|
||||
*low_offset = RS_SYSCTRL_PERF_MGMT_WAIT_LO_OFFSET;
|
||||
@@ -215,6 +221,9 @@ rs_status_t rs_sysctrl_clear_user_core_config_error(void) {
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_get_pll_config(uint8_t *selection) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
if (selection == NULL) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
@@ -224,6 +233,9 @@ rs_status_t rs_sysctrl_get_pll_config(uint8_t *selection) {
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_set_pll_config(uint8_t selection) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
if (((uint32_t)selection & ~RS_SYSCTRL_PLL_SELECTION_MASK) != 0U) {
|
||||
return RS_EINVAL;
|
||||
}
|
||||
@@ -232,16 +244,25 @@ rs_status_t rs_sysctrl_set_pll_config(uint8_t selection) {
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_apply_pll_config(void) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
*rs_sysctrl_register(RS_SYSCTRL_PLL_CMD_OFFSET) = RS_SYSCTRL_PLL_CMD_APPLY;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_clear_pll_error(void) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
*rs_sysctrl_register(RS_SYSCTRL_PLL_CMD_OFFSET) = RS_SYSCTRL_PLL_CMD_CLEAR_ERROR;
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_get_pll_status(rs_sysctrl_pll_status_t *status) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
uint32_t value;
|
||||
|
||||
if (status == NULL) {
|
||||
@@ -282,6 +303,9 @@ rs_status_t rs_sysctrl_clear_fault(void) {
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_set_hp_release(bool release) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
rs_sysctrl_hp_status_t status;
|
||||
|
||||
if ((rs_sysctrl_get_hp_status(&status) != RS_OK) || !status.present) {
|
||||
@@ -295,6 +319,9 @@ rs_status_t rs_sysctrl_set_hp_release(bool release) {
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_get_hp_status(rs_sysctrl_hp_status_t *status) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
uint32_t value;
|
||||
|
||||
if (status == NULL) {
|
||||
@@ -311,6 +338,9 @@ rs_status_t rs_sysctrl_get_hp_status(rs_sysctrl_hp_status_t *status) {
|
||||
}
|
||||
|
||||
rs_status_t rs_sysctrl_select_hp_debug(bool select_hp) {
|
||||
#ifdef RS_SOC_TINY
|
||||
return RS_ENOTSUP;
|
||||
#endif
|
||||
rs_sysctrl_hp_status_t status;
|
||||
uint32_t value;
|
||||
|
||||
|
||||
+2
-2
@@ -279,7 +279,7 @@ rs_status_t rs_uart_irq_test(uint32_t mask) {
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_write_dma(const uint32_t *words, size_t count, rs_timeout_t timeout) {
|
||||
rs_dma_config_t config;
|
||||
rs_dma_config_t config = {0};
|
||||
size_t index;
|
||||
rs_status_t status;
|
||||
|
||||
@@ -314,7 +314,7 @@ rs_status_t rs_uart_write_dma(const uint32_t *words, size_t count, rs_timeout_t
|
||||
}
|
||||
|
||||
rs_status_t rs_uart_read_dma(uint32_t *words, size_t count, rs_timeout_t timeout) {
|
||||
rs_dma_config_t config;
|
||||
rs_dma_config_t config = {0};
|
||||
rs_status_t status;
|
||||
|
||||
if ((words == NULL) || (count == 0U) || (count > (UINT32_MAX / sizeof(*words)))) {
|
||||
|
||||
@@ -7,6 +7,41 @@
|
||||
|
||||
#define RS_WDG_COMMAND_TIMEOUT UINT32_C(1024)
|
||||
|
||||
static rs_status_t rs_watchdog_status(wdg_status_t status) {
|
||||
switch (status) {
|
||||
case WDG_STATUS_OK:
|
||||
return RS_OK;
|
||||
case WDG_STATUS_INVALID_ARGUMENT:
|
||||
return RS_EINVAL;
|
||||
case WDG_STATUS_TIMEOUT:
|
||||
return RS_ETIMEOUT;
|
||||
case WDG_STATUS_INCOMPATIBLE:
|
||||
return RS_EFORMAT;
|
||||
default:
|
||||
return RS_EIO;
|
||||
}
|
||||
}
|
||||
|
||||
rs_status_t rs_watchdog_configure(const rs_watchdog_config_t *config) {
|
||||
return rs_watchdog_status(wdg_configure((uintptr_t)RS_SOC_APB4_WDG_BASE, config));
|
||||
}
|
||||
|
||||
rs_status_t rs_watchdog_start(rs_timeout_t timeout) {
|
||||
return rs_watchdog_status(wdg_start((uintptr_t)RS_SOC_APB4_WDG_BASE, timeout));
|
||||
}
|
||||
|
||||
rs_status_t rs_watchdog_service(rs_timeout_t timeout) {
|
||||
return rs_watchdog_status(wdg_service((uintptr_t)RS_SOC_APB4_WDG_BASE, timeout));
|
||||
}
|
||||
|
||||
rs_status_t rs_watchdog_get_status(rs_watchdog_status_t *status, rs_timeout_t timeout) {
|
||||
return rs_watchdog_status(wdg_snapshot((uintptr_t)RS_SOC_APB4_WDG_BASE, status, timeout));
|
||||
}
|
||||
|
||||
rs_status_t rs_watchdog_clear_reset_cause(rs_timeout_t timeout) {
|
||||
return rs_watchdog_status(wdg_clear_reset_cause((uintptr_t)RS_SOC_APB4_WDG_BASE, timeout));
|
||||
}
|
||||
|
||||
void ip_wdg_test(int argc, char **argv) {
|
||||
static const wdg_config_t config = {
|
||||
.prescale_divider = 1U,
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
This directory contains repository-level engineering policy that supplements
|
||||
the root README and subsystem guides.
|
||||
|
||||
- [Tiny MCU](ip/tiny-soc.md) defines the independent wired Tiny product, AXI4/APB4, SRAM-only startup and IHP130 acceptance.
|
||||
|
||||
- [Contributing](../CONTRIBUTING.md) describes community discussion, development,
|
||||
review, validation evidence, and maintainer responsibilities.
|
||||
- [git-workflow.md](git-workflow.md) defines branch and commit conventions,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
| Tier | Profile | Automated coverage |
|
||||
| --- | --- | --- |
|
||||
| Pull request | `configs/ci/ihp130-tiny.mk` | Tiny firmware, Verilator/Icarus, lint; local Yosys, netlist and OpenSTA |
|
||||
| Smoke | `configs/ci/ihp130.mk` | strict Verilator RTL lint, firmware, Verilator SVA compilation, Icarus assembly self-test |
|
||||
| Pull request | `configs/ci/ihp130.mk` | strict Verilator RTL lint, firmware, Verilator, Icarus |
|
||||
| Pull request | `configs/ci/ihp130-debug.mk` | Verilator remote-bitbang JTAG DTM, Debug Module, OpenOCD, and GDB acceptance |
|
||||
|
||||
@@ -4,6 +4,8 @@ This directory owns architecture, register ABI, software contract, and
|
||||
verification documentation for self-owned retroSoC peripheral IP and platform
|
||||
extension interfaces.
|
||||
|
||||
- [Tiny MCU](tiny-soc.md) defines the independent wired Tiny product, AXI4/APB4, SRAM-only startup and IHP130 acceptance.
|
||||
|
||||
- [timer.md](timer.md) defines the dual APB4 general timer.
|
||||
- [sysctrl.md](sysctrl.md) defines the APB4 SystemCtrl register ABI, control-plane contracts, HAL, and verification.
|
||||
- [resource-controller.md](resource-controller.md) defines root-managed resource ownership, IRQ routing, and cache-maintenance handoff.
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
# Tiny MCU Verification Record
|
||||
|
||||
This record accompanies the [frozen Tiny contract](tiny-soc.md). It describes
|
||||
local implementation evidence from 2026-09-25, not a release or silicon signoff.
|
||||
The working tree is uncommitted and the readiness status remains `prototype`.
|
||||
|
||||
## Configuration and artifact roots
|
||||
|
||||
The selected profile is `configs/ci/ihp130-tiny.mk`: IHP130, 128 KiB SRAM,
|
||||
24 MHz, RV32IM firmware on an RV32IMC hart with A disabled. Runs below used
|
||||
`BUILD_TIMESTAMP=2026-09-25-12-00`:
|
||||
|
||||
- Default `bringup`: `build/ihp130-tiny-2026-09-25-12-00-d6009644a134/`.
|
||||
- `APP=ci_smoke`: `build/ihp130-tiny-2026-09-25-12-00-044d45791ef7/`.
|
||||
- `APP=ci_smoke HAVE_SVA=YES`:
|
||||
`build/ihp130-tiny-2026-09-25-12-00-6874f2ffdf11/`.
|
||||
|
||||
Configuration digests identify settings and the dependency lock, not a clean
|
||||
source revision. A release requires rerunning from its reviewed commit.
|
||||
|
||||
## Functional and quality checks
|
||||
|
||||
| Check | Evidence/boundary |
|
||||
| --- | --- |
|
||||
| Tiny maps and source isolation | Generated address, IRQ, pad and clock/reset inputs validate; source closure excludes Mini product RTL, RIB/RIBP and HP generation. |
|
||||
| AXI fabric, both simulators | Directed tests cover competing CPU/DMA requests, W-before-AW, delayed W, response backpressure, ID/RLAST, 16-beat bursts, 4 KiB crossing, alignment, reserved regions and continued operation after errors. |
|
||||
| Tiny SYSCTRL, both simulators | APB tests cover unsupported controls, partial terminal writes, sticky first status, counter snapshots, first-fault retention, W1C, RTC wake and reset. |
|
||||
| Verilator full firmware | `SIM_TEST_PASS`; the CI composition also passes with SVA enabled. Pin-level NOR, compressed instructions, disabled atomics, load faults, SRAM discovery, memory/UART DMA, external timer IRQ, CLINT time, RTC, GPIO, UART1 loopback, I2C NACK and watchdog reboot are exercised. |
|
||||
| Icarus full firmware | Final expanded CI firmware passes at 3,705,751 cycles, matching the SVA-enabled Verilator run. |
|
||||
| Icarus synthesized boot | `netsim-boot` passes at 29,362 cycles using the compact assembly image. Covers pin-level NOR, SRAM first/last words, byte writes, UART and terminal status; does not establish full C-firmware gate-level coverage. |
|
||||
| SDK gates | C formatting, embedded-C policy and host tests pass, including Tiny channel/endpoint rejection compiled from the real DMA validator. No new Required-rule MISRA deviation is recorded; these partial checks do not certify MISRA conformance. |
|
||||
| Focused Python tests | 112 tests passed across Tiny, address/pad generation and build/regression tooling. Shared debug-reset and SRAM/DMA register-parity checks also pass. After fixing parameterization/publication compatibility and preparing the existing MPW/device-model inputs, all 54 non-reference failures selected for rerun pass. |
|
||||
| RTL policy | Changed RTL formatting, full owned RTL style audit and readiness metadata pass. Global formatting limitations are listed below. |
|
||||
| Reproducibility | Dependency lock validation, Ruff, PR/nightly dry-runs and `git diff --check` pass. Tiny source packaging exports the Tiny top, actual filelist and its core timing SDC. |
|
||||
|
||||
The full-firmware verdict is authoritative only when both the tool result and
|
||||
`result-sim-check.json` pass. UART text alone is not sufficient. Assembly netlist
|
||||
acceptance uses the same strict terminal marker policy.
|
||||
|
||||
## Synthesis and timing
|
||||
|
||||
For the CI composition, Yosys completed with the IHP130 technology libraries
|
||||
and 32 `tc_sram_1024x32` banks. The `balanced` report records 207,739 cells and
|
||||
9,798,326.725198 square micrometers of library area. The area includes the
|
||||
instantiated memory/pad hierarchy and is not a placed die-area estimate.
|
||||
|
||||
OpenSTA completed with the selected slow library corner and the 41.666666667 ns
|
||||
system clock. Reported setup WNS is **-455.18 ns**, setup TNS is
|
||||
**-13,049,600 ns**, and hold WNS/TNS are zero. The worst path starts at the
|
||||
synchronized system-reset register and reaches peripheral FIFO storage through
|
||||
the high-fanout reset distribution. This is an open physical/timing issue;
|
||||
24 MHz is a functional target, not a timing-qualified operating point.
|
||||
|
||||
Reports reside under the CI variant's `syn/yosys/rpt/` and `sta/opensta/`.
|
||||
The metric collector understands the Tiny top and timestamp-prefixed Yosys JSON
|
||||
reports. Metrics remain in `observe` mode; no warning or metric baseline has
|
||||
been edited to accept this feature.
|
||||
|
||||
## Commands and remaining coverage
|
||||
|
||||
The build/verification commands were run with the profile and timestamp above:
|
||||
|
||||
```sh
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk doctor firmware sim
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk APP=ci_smoke HAVE_SVA=YES firmware sim
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk APP=ci_smoke SIMU=IVERILOG firmware sim
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk APP=ci_smoke SYNTH=YOSYS synth
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk APP=ci_smoke SIMU=IVERILOG netsim-boot
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk APP=ci_smoke STA=OPENSTA sta
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk metrics package
|
||||
make sw-format-check sw-policy-check sw-host-test rtl-style-check-all rtl-readiness-check
|
||||
python3 -m pytest -q tests/test_tiny.py tests/test_memory_map.py tests/test_pin_map.py tests/test_script_tools.py
|
||||
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --netsim-boot-only
|
||||
```
|
||||
|
||||
The combined IHP130 regression stops in its Mini phase because the locked
|
||||
VexiiRiscv checkout is absent. Tiny can be selected independently with
|
||||
`--soc TINY`, or `make CONFIG=configs/ci/ihp130-tiny.mk regress-pr`.
|
||||
The initial full Pytest run completed with 1,234 passed, 26 failed, 19 skipped
|
||||
and 71 errors. Parameterization/format-sensitive expectations and the Mini
|
||||
publication's constant/cast parsing were corrected; the affected cases were
|
||||
rerun successfully. MPW/device-model inputs and a writable test ccache resolved
|
||||
additional environment failures. The remaining 16 cases require the absent
|
||||
locked FLAC corpus, MLPerf Tiny models or TensorFlow oracle sources. These are
|
||||
not Tiny setup dependencies. The full suite was not rerun after the focused
|
||||
corrections; it is not reported as a clean full-suite pass.
|
||||
|
||||
The initial run, focused results, combined-regression failure and remaining
|
||||
reference-input case list are retained under the CI variant's
|
||||
`meta/validation/`.
|
||||
Global RTL/Make formatting checks encounter existing APU/accelerator files
|
||||
outside this change. Changed-file formatting is checked independently.
|
||||
|
||||
Remaining qualification includes reset-tree/timing closure, placement/routing,
|
||||
PVT/MMMC, CDC/RDC signoff, silicon and power measurements, full C netlist
|
||||
acceptance, a Tiny-specific external OpenOCD session, positive external I2C
|
||||
slave transactions and comprehensive pad-level PWM/RTC coverage. Wireless,
|
||||
retention, secure boot and other PDKs remain explicit deferred features.
|
||||
|
||||
## Shared-path migration follow-up
|
||||
|
||||
Mini now references the canonical shared RTL, `scripts/rtl` helpers and
|
||||
`rtl/mk/software.mk` directly. The 21 Mini compatibility links and seven Tiny
|
||||
helper links have been removed. Filelists, simulator/formal/synthesis rules,
|
||||
Python imports, tests, publication tooling and ownership documents use the new
|
||||
paths. No Git file-type changes remain. Historical warning baselines are
|
||||
unchanged.
|
||||
|
||||
The resolved Mini `commonip.fl`, `ip.fl` and `top.fl` retain the same 299
|
||||
unique sources in the same order. `netlist_support.fl` retains its two sources;
|
||||
`inc.fl` adds `rtl/ip/core`. All relocated shared RTL content hashes match the
|
||||
pre-migration snapshot. This follow-up changes paths, not RTL behavior or the
|
||||
public hardware/software interface.
|
||||
|
||||
Validation after removing the links:
|
||||
|
||||
- 245 focused tests passed: 144 build/generator/topology/style/Tiny tests,
|
||||
96 publication/LibreLane tests and five debug-reset/SRAM simulations.
|
||||
Full-suite collection succeeds with 1,356 tests; the full suite was not
|
||||
rerun because of the reference-input gaps documented above.
|
||||
- Mini `configs/ci/ihp130.mk` address/pad/topology/clock-reset checks and firmware
|
||||
build pass. Its Verilator compile reaches HP generation and stops because
|
||||
the locked VexiiRiscv checkout is missing; full Mini simulation and the
|
||||
combined regression remain unverified.
|
||||
- Tiny `configs/ci/ihp130-tiny.mk`, `APP=ci_smoke HAVE_SVA=YES`, firmware and
|
||||
Verilator simulation pass again at 3,705,751 cycles. Full Icarus, synthesis
|
||||
and STA were not repeated for this path-only follow-up.
|
||||
- Eleven Python CLI entrypoints work outside the repository directory.
|
||||
Mini SRAM formal filelist generation, `sv2v` conversion, filelist combination
|
||||
and dependency generation pass using the canonical shared paths, including
|
||||
the relocated SRAM header. Formal proofs were not rerun.
|
||||
- Ruff, owned RTL style, readiness metadata, 251 local Markdown links and
|
||||
`git diff --check` pass. The Make formatter still reports existing EOF and
|
||||
formal-command indentation differences in APU/GA2D/formal fragments; those
|
||||
unrelated differences were preserved.
|
||||
|
||||
Run logs, exact commands and path snapshots are retained under
|
||||
`build/ihp130-2026-09-25-12-00-9903b3d112b7/meta/validation/shared-path-migration/`.
|
||||
No C register/API change or additional MISRA deviation belongs to this
|
||||
follow-up; the SDK gates from the implementation record above were not rerun.
|
||||
|
||||
## Next review
|
||||
|
||||
```text
|
||||
Use $retrosoc-mini-feature-review in review mode for feature tiny-soc. Review the current worktree diff against docs/ip/tiny-soc.md and docs/ip/tiny-soc-verification.md. Verify Tiny isolation, default Mini compatibility, AXI/APB/error/reset behavior and the SDK ABI. Treat the observed reset-fanout timing deficit and missing APU/NPU/VexiiRiscv inputs as explicit qualification gaps; do not claim timing closure or alter warning/metric baselines.
|
||||
```
|
||||
@@ -0,0 +1,193 @@
|
||||
# retroSoC Tiny MCU Contract
|
||||
|
||||
## Purpose and research boundary
|
||||
|
||||
This contract freezes the approved Tiny wired-MCU first release. Tiny owns its
|
||||
integration in `rtl/tiny`; Mini remains a separate product. The committed
|
||||
`configs/ci/ihp130-tiny.mk` profile is the reproducible implementation boundary.
|
||||
The design was approved on 2026-09-25. Source presence does not establish
|
||||
verification, timing closure, silicon qualification, or low-power performance.
|
||||
|
||||
The [RP2350](https://www.raspberrypi.com/products/rp2350/) is a Hazard3-based MCU
|
||||
reference for software, SRAM, and deterministic I/O. Its dual-core, security,
|
||||
USB, and PIO features are not Tiny requirements. The
|
||||
[CAST SRAM controller](https://www.cast-inc.com/peripherals/memory-controllers/sram-ctrl)
|
||||
illustrates native AXI synchronous SRAM and documented verification delivery;
|
||||
no commercial implementation or qualification is reused.
|
||||
|
||||
## Requirements and non-goals
|
||||
|
||||
- TINY-001: one Hazard3 hart, RV32IMC with A disabled, mandatory debug support;
|
||||
existing RV32IM firmware remains the default compiler target.
|
||||
- TINY-002: native 32-bit AXI4 data and APB4 control. The CPU's native AHB-Lite
|
||||
terminates at a direct AXI adapter. No RIB/RIBP source or interface is part of
|
||||
Tiny's compilation or elaboration closure.
|
||||
- TINY-003: 128 KiB technology-backed SRAM, XPI NOR boot, no external RAM
|
||||
dependency. Reset vector is `0x00000000`; SRAM begins at `0x30000000`.
|
||||
- TINY-004: 32 GPIO, two UARTs, two I2C controllers, two general timers,
|
||||
CLINT, four DMA channels, PWM, RTC, watchdog, SYSCTRL and architecture info.
|
||||
- TINY-005: IHP130, 24 MHz system clock, no PLL, 1 MHz CLINT timebase. CPU,
|
||||
AXI, APB, RTC and watchdog share the system clock.
|
||||
- TINY-006: Tiny must build independently of MPW, HP CPU generation and
|
||||
multimedia inputs. Shared SDK APIs retain the `rs_` namespace.
|
||||
- TINY-007: no wireless IP, radio-specific host integration, or wireless stack.
|
||||
|
||||
Deferred: RV32 A atomics, RTOS ports, authenticated boot, retention/power gating,
|
||||
independent sleep clock, 256–512 KiB SRAM, USB, SDIO, standalone general SPI,
|
||||
I2S, CAN, ADC, multimedia accelerators and other PDK qualification. XPI retains
|
||||
the existing four-chip-select interface; initial pin-level acceptance uses NOR
|
||||
on NSS0. The unpopulated chip selects are not qualified device configurations.
|
||||
|
||||
## Selected architecture and interfaces
|
||||
|
||||
`retrosoc_tiny` integrates the CPU, two-master fabric, SRAM, XPI and one APB
|
||||
island. `retrosoc_tiny_asic` owns technology pads; `retrosoc_tiny_tb` owns device
|
||||
models and terminal verdicts. Product maps, filelists and bindings belong to
|
||||
Tiny; reusable core/debug, memory and bus utilities belong to shared RTL IP.
|
||||
|
||||
AXI has 32-bit addresses/data and one-bit ID/USER. CPU and DMA share one
|
||||
globally active read or write transaction. Round-robin ownership changes only
|
||||
after B or RLAST handshake; accepted W traffic cannot change owners. Backpressure
|
||||
must preserve VALID payloads. Memory accepts naturally aligned 1/2/4-byte INCR
|
||||
transactions of 1–16 beats within a target and 4 KiB page. MMIO accepts one-beat
|
||||
FIXED/INCR accesses. Unsupported size/burst/lock/alignment or crossing returns
|
||||
SLVERR; absent regions return DECERR. Rejected reads return the advertised
|
||||
number of response beats; rejected writes drain their accepted data before B.
|
||||
|
||||
APB uses full setup/access phases, PSTRB and PSLVERR. Registers retain their
|
||||
existing IP offset, access and reset contracts. A missing peripheral has no
|
||||
successful decode. GPIO alternate functions retain the selected Mini mappings;
|
||||
unsupported alternate functions drive neither pads nor peripheral requests.
|
||||
UART TX/RX and XPI have dedicated pins.
|
||||
|
||||
## DMA and interrupt contract
|
||||
|
||||
DMA retains the V2 manual register ABI, direct and TCD modes, 32-bit transfers,
|
||||
up-to-16-beat memory bursts and existing completion/error/W1C/abort semantics.
|
||||
Four channels are available: 0 UART0, 1 I2C0, 2 I2C1, 3 bulk/XPI. UART1 uses
|
||||
PIO/IRQ. Stream endpoints and requests for omitted devices are unsupported and
|
||||
must fail validation rather than wait indefinitely. Capability discovery and
|
||||
SDK range checks must agree with hardware.
|
||||
|
||||
CLINT software/timer occupy core bits 0/1. Reused external sources keep Mini
|
||||
core-bit numbering: UART0 2, timer0 3, timer1 4, I2C0 7, XPI 9, PWM 11,
|
||||
RTC 13, watchdog 14, GPIO 18, I2C1 19, DMA 20, UART1 26. The vector has 32
|
||||
bits (30 Hazard3 external inputs); all omitted sources are zero.
|
||||
|
||||
## Register and software ABI
|
||||
|
||||
Tiny maps reuse the addresses of implemented Mini peripherals, Flash alias and
|
||||
XPI aperture. Generated outputs contain address/IRQ/capability metadata and
|
||||
linker regions, not new generated IP register definitions. SVH/C register pairs
|
||||
remain handwritten and checked for parity. Hardware identity must describe Tiny,
|
||||
one MCU hart, 128 KiB SRAM and actual capabilities.
|
||||
|
||||
Tiny SYSCTRL preserves fault capture, performance enable/clear and TEST_STATUS
|
||||
at the existing offsets. The first full-word TEST_STATUS write with bit 31 set
|
||||
is sticky until system reset; bit 0 is pass and bits 15:8 are the result code.
|
||||
Unsupported Mini lifecycle/clock controls fail safely; they do not enable HP or
|
||||
user-core behavior. Unavailable IP drivers are omitted from the Tiny firmware composition.
|
||||
Unsupported SYSCTRL lifecycle/PLL operations and DMA channel/endpoint requests
|
||||
return an error before MMIO. GPIO alternate modes follow the Tiny pin map.
|
||||
|
||||
The `bringup` and `ci_smoke` applications select product-specific entrypoints.
|
||||
Startup skips PSRAM setup on Tiny and uses `ld2_all_sram`: code/data copy from
|
||||
Flash into SRAM, with SRAM BSS and stack. IRQ/CSR support is enabled. Public
|
||||
headers remain under `<retrosoc/...>`; retired `tiny*.h` paths are not restored.
|
||||
|
||||
## Clock, reset and lifecycle
|
||||
|
||||
External reset is asynchronously asserted and synchronously released. Watchdog
|
||||
reset restarts the system. Debug hart reset waits for the CPU AXI adapter to
|
||||
be idle; it must not abandon an accepted transaction. JTAG and asynchronous
|
||||
external inputs retain the approved Common synchronizer/handshake boundaries.
|
||||
There is no cross-domain system bus or dynamic clock switching in this release.
|
||||
RTC/WDG run at the configured system frequency and provide no independent
|
||||
deep-sleep guarantee. SRAM contents are not initialized by reset.
|
||||
|
||||
## Errors, observability and security
|
||||
|
||||
Decode/protocol faults complete with AXI errors and feed sticky SYSCTRL fault
|
||||
information. DMA records errors and supports bounded software waits and abort.
|
||||
Counters and terminal-test status permit firmware and simulation diagnosis.
|
||||
Watchdog provides whole-system recovery from a nonresponsive target; this
|
||||
release makes no unrestricted AXI liveness, secure-boot, production-entropy,
|
||||
isolation, or safety-certification claim.
|
||||
|
||||
## Development order and acceptance
|
||||
|
||||
### TINY-P0 — Freeze Tiny MCU Contract
|
||||
|
||||
Record the approved requirements here and update document indexes. Acceptance:
|
||||
reviewable specification, valid links and `git diff --check`.
|
||||
|
||||
### TINY-P1 — Product Selection and Shared Infrastructure
|
||||
|
||||
Add SOC=TINY, the committed profile, dependency selection and shared build/IP
|
||||
boundaries. Preserve Mini defaults. Acceptance: configuration/generator tests,
|
||||
dependency lock validation, no implicit Tiny dependency on Mini product RTL.
|
||||
|
||||
### TINY-P2 — AXI4/APB4 Tiny RTL
|
||||
|
||||
Implement the hierarchy and contracts above. Acceptance: lint, standalone AXI,
|
||||
APB, memory, reset and IRQ checks; no RIB/RIBP in the resolved source closure.
|
||||
|
||||
### TINY-P3 — SDK Boot and System Verification
|
||||
|
||||
Implement generated capabilities, SRAM-only startup, HAL selection and firmware.
|
||||
Acceptance: both simulators boot through pin-level NOR and emit SIM_TEST_PASS;
|
||||
test SRAM boundaries, DMA, peripherals, IRQ, disabled A, C instructions and debug.
|
||||
|
||||
### TINY-P4 — IHP130 Qualification and Documentation
|
||||
|
||||
Add Tiny to IHP130 regression without replacing Mini coverage. Run format/style,
|
||||
lint, software policy/host tests, Ruff, Pytest, firmware and supported regressions.
|
||||
Run Yosys, Icarus netlist and OpenSTA; archive macro mapping, area, cell count,
|
||||
24 MHz timing and warnings under the configuration's build variant. Check docs
|
||||
and example commands. Record unrun/failed gates explicitly; do not promote
|
||||
warning baselines or metrics policy as part of this feature.
|
||||
|
||||
## Reproducible commands and current evidence
|
||||
|
||||
Use the committed profile, and preserve one `BUILD_TIMESTAMP` when commands
|
||||
must share artifacts:
|
||||
|
||||
```sh
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk setup doctor
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk firmware sim
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk SIMU=IVERILOG firmware sim
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk SYNTH=YOSYS synth
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk SIMU=IVERILOG netsim-boot
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk STA=OPENSTA sta
|
||||
make CONFIG=configs/ci/ihp130-tiny.mk metrics package
|
||||
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc TINY --dry-run
|
||||
```
|
||||
|
||||
`netsim-boot` runs the dedicated `app/asm/tiny_boot.S` gate-level image. It checks
|
||||
pin-level NOR boot, both ends of physical SRAM, a byte-lane write, UART and the
|
||||
SYSCTRL terminal result. It requires `SIM_TEST_PASS`; this is separate from the
|
||||
complete SDK/IRQ/DMA/watchdog acceptance in both RTL simulators. `netsim` retains
|
||||
the full firmware option. The shared SRAM IP's capability register describes
|
||||
the IP's native superset; end-to-end requests must obey Tiny's narrower fabric
|
||||
contract above.
|
||||
|
||||
Tiny uses two-cycle AHB ERROR completion so Hazard3 can trap AXI failures. The
|
||||
shared core/bridge parameters retain Mini's existing default behavior. Tiny
|
||||
ArchInfo reports SOC_ID `0x54494e59`, topology `0x20200001`, and FEATURES0
|
||||
`0x00007ffe`: bits 1/2 SRAM interface/macro, 3 AXI, 4 APB, 5 DMA, 6 UART,
|
||||
7 I2C, 8 PWM, 9 RTC, 10 watchdog, 11 GPIO, 12 CLINT, 13 timers and 14 XPI.
|
||||
Bit 0 (PLL) is zero. Tiny FAULT_DETAIL contains the raw AXI response (2/3),
|
||||
FAULT_STATUS reason is 1 for decode and 2 for slave/protocol errors,
|
||||
and FAULT_MASTER uses 0 for CPU and 1 for DMA; no RIB encoding is exported.
|
||||
The public watchdog API is `rs_watchdog_*` with `rs_status_t` and bounded waits.
|
||||
|
||||
The [verification record](tiny-soc-verification.md) distinguishes successful
|
||||
functional checks from missing reference inputs and physical closure. The
|
||||
product remains `prototype`: negative pre-layout reset-fanout timing must not
|
||||
be presented as a qualified 24 MHz implementation.
|
||||
|
||||
## Commercial delivery gaps
|
||||
|
||||
Current-revision verification and physical reports govern readiness. Reusable
|
||||
VIP, coverage closure, full CDC/RDC, DFT/MBIST, PVT/MMMC, post-layout timing,
|
||||
power characterization, regulatory and silicon qualification remain separate.
|
||||
@@ -32,8 +32,10 @@ and reviewed evidence for the applicable rules.
|
||||
- Use `rs_status_t` for fallible operations. Prefer bounded string/format APIs
|
||||
and timeout-based register waits. Dynamic allocation is not permitted in
|
||||
self-owned embedded C.
|
||||
- New `tiny` identifiers, legacy include paths, and prohibited library calls
|
||||
- Retired `tiny`-prefixed SDK identifiers, legacy include paths, and prohibited library calls
|
||||
are not allowed outside the compatibility files explicitly listed by policy.
|
||||
The Tiny product name in prose/string literals and `RS_SOC_TINY` product
|
||||
selection do not restore those retired SDK interfaces.
|
||||
|
||||
The standard is referenced by name and category only. Consult the licensed
|
||||
MISRA publication for the complete rule text and applicability guidance; do
|
||||
|
||||
@@ -10,7 +10,7 @@ validated without changing functional behavior.
|
||||
The owned profile in
|
||||
[`rtl/rtl_style_manifest.json`](../rtl/rtl_style_manifest.json) is the source
|
||||
of truth for the reviewed source set. It includes `rtl/ip/**` and
|
||||
`rtl/mini/top/**`, but excludes managed, generated, PDK, formal, device-model,
|
||||
`rtl/mini/top/**` and `rtl/tiny/top/**`, but excludes managed, generated, PDK, formal, device-model,
|
||||
and third-party sources.
|
||||
|
||||
[`rtl/rtl_style_audit.json`](../rtl/rtl_style_audit.json) records the exact
|
||||
|
||||
@@ -10,7 +10,7 @@ differ: retroSoC uses `clk_i` and `rst_n_i`, not `rst_ni`.
|
||||
|
||||
## 1. Scope and rule levels
|
||||
|
||||
The owned profile applies to `rtl/ip/**` and `rtl/mini/top/**`. Formal,
|
||||
The owned profile applies to `rtl/ip/**`, `rtl/mini/top/**`, and `rtl/tiny/top/**`. Formal,
|
||||
device-model, PDK, generated, managed, and third-party sources use the profiles
|
||||
declared in [`rtl/rtl_style_manifest.json`](../rtl/rtl_style_manifest.json).
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
## Status and Scope
|
||||
|
||||
This document defines the intended Tiny, Mini, Std, and Pro product ladder.
|
||||
It is a product roadmap, not a statement of implemented repository support.
|
||||
The current build system accepts only `SOC=MINI`, and the committed Mini
|
||||
profiles remain the executable source of truth.
|
||||
Tiny and Mini have executable build profiles; Std and Pro remain roadmap
|
||||
targets. Committed product profiles and retained validation evidence define
|
||||
implemented support. Tiny first targets IHP130 as a wired MCU.
|
||||
|
||||
Mini is the family anchor. It establishes the common product model: an open
|
||||
RISC-V SoC in which a small, always-available Hazard3 management core owns
|
||||
@@ -14,8 +14,8 @@ add application processors and accelerators without transferring final
|
||||
lifecycle control to Linux. Tiny reduces this model to an MCU-class device and
|
||||
does not require a separate application processor.
|
||||
|
||||
All frequencies, memory sizes, bus widths, accelerator rates, and software
|
||||
features below are product targets. They require separate RTL integration,
|
||||
Except for the explicitly identified executable baselines, frequencies, memory
|
||||
sizes, bus widths, accelerator rates, and software features below are product targets. They require separate RTL integration,
|
||||
driver enablement, verification, and physical qualification before they can be
|
||||
advertised for a device or PDK.
|
||||
|
||||
@@ -47,45 +47,36 @@ nodes, protocol bridges, and smart-home edge endpoints. It is MCU-first: boot
|
||||
latency, sleep behavior, deterministic I/O, security, package cost, and usable
|
||||
energy per event take precedence over Linux compatibility.
|
||||
|
||||
Tiny has two productization profiles:
|
||||
The first executable product is **Tiny-MCU**, an independent wired MCU
|
||||
integration in `rtl/tiny`, selected with `configs/ci/ihp130-tiny.mk`. It has no
|
||||
wireless IP, wireless protocol stack, or radio-specific companion integration.
|
||||
Tiny-Connect, BLE, IEEE 802.15.4 and Wi-Fi are deferred product research.
|
||||
|
||||
- **Tiny-MCU** contains no radio and targets wired control or products that do
|
||||
not need connectivity on every unit.
|
||||
- **Tiny-Connect** provides Bluetooth Low Energy and IEEE 802.15.4 capability.
|
||||
The open digital-RTL baseline should expose a qualified SPI or SDIO host,
|
||||
interrupt, reset, wake, and power-sequencing interface to a certified radio.
|
||||
On-die or co-packaged RF becomes a product option only after suitable RF IP,
|
||||
analog integration, PDK support, and regulatory qualification exist.
|
||||
### First-release Architecture
|
||||
|
||||
Wi-Fi 6 is an optional upper Tiny-Connect SKU rather than a baseline
|
||||
requirement. This avoids imposing its RF, memory, and active-power costs on
|
||||
802.15.4 and Bluetooth endpoint products.
|
||||
|
||||
### Recommended Architecture
|
||||
|
||||
| Area | Product target |
|
||||
| Area | Tiny MCU baseline |
|
||||
| --- | --- |
|
||||
| CPU | One Hazard3 RV32IMAC core at 64-160 MHz, subject to PDK qualification |
|
||||
| On-chip memory | 256-512 KiB banked SRAM, boot ROM, and 8-32 KiB retention SRAM |
|
||||
| Code storage | QSPI flash with execute-in-place and authenticated recovery boot |
|
||||
| Memory model | No MMU and no external DRAM dependency |
|
||||
| Interconnect | 32-bit RIB; bounded `INCR4` support for DMA and XIP, without a full AXI4 fabric |
|
||||
| Software | Freestanding SDK, bare metal, and Zephyr- or FreeRTOS-class RTOS ports |
|
||||
| Low power | Clock gating, switchable SRAM banks, RTC/event wake, retention, and a separately measured deep-sleep state |
|
||||
| Security | Immutable boot root, signed boot, OTP key material, PMP, TRNG, and symmetric/hash acceleration |
|
||||
| Edge I/O | UART, SPI, I2C, PWM, ADC, I2S/PDM, USB full speed, and CAN FD selected by package profile |
|
||||
| CPU | One Hazard3 RV32IMC hart; A extension disabled until atomic bus semantics are qualified |
|
||||
| On-chip memory | 128 KiB macro-backed SRAM; 256–512 KiB and retention SRAM deferred |
|
||||
| Code storage | XPI NOR boot, loaded into SRAM; authenticated recovery boot deferred |
|
||||
| Memory model | No MMU, HP hart, or external DRAM/PSRAM dependency |
|
||||
| Interconnect | 32-bit AXI4 data plane and APB4 control; no RIB/RIBP |
|
||||
| Software | Existing freestanding SDK, RV32IM compiler target, CSR/IRQ-enabled acceptance firmware |
|
||||
| Clock/reset | 24 MHz system clock, no PLL, 1 MHz CLINT timebase, watchdog and JTAG reset |
|
||||
| Edge I/O | 32 GPIO, two UARTs, two I2C controllers, two timers, four DMA channels, PWM, RTC, watchdog and XPI |
|
||||
|
||||
No power-current number should be published until it is measured on a
|
||||
qualified physical implementation with the wake sources and retention state
|
||||
specified. Tiny's acceptance criteria should include sleep-to-active latency,
|
||||
energy per sensing/reporting cycle, and certified-radio interoperability, not
|
||||
only CPU benchmarks.
|
||||
The normative [Tiny MCU contract](ip/tiny-soc.md) defines the AXI subset,
|
||||
address/interrupt ABI, startup, errors and phased acceptance. Independent
|
||||
low-power clocks, clock/power gating, retention, secure boot, RTOS ports, USB,
|
||||
SDIO, standalone general SPI, CAN and ADC remain future work. No measured
|
||||
frequency ceiling, power-current, wake-latency or security claim follows from
|
||||
this initial functional profile.
|
||||
|
||||
### Commercial Reference Points
|
||||
|
||||
| Commercial SoC | Relevant axis | Position relative to Tiny |
|
||||
| --- | --- | --- |
|
||||
| [Espressif ESP32-H2](https://www.espressif.com/en/products/socs/esp32-h2) | Low-power RV32 MCU with Bluetooth LE and IEEE 802.15.4 | Primary Tiny-Connect endpoint and Thread/Zigbee market reference |
|
||||
| [Espressif ESP32-H2](https://www.espressif.com/en/products/socs/esp32-h2) | Low-power RV32 MCU with Bluetooth LE and IEEE 802.15.4 | Deferred Tiny-Connect research reference |
|
||||
| [Espressif ESP32-C6](https://www.espressif.com/en/products/socs/esp32-c6) | RV32 high- and low-power cores with Wi-Fi 6, Bluetooth LE, and IEEE 802.15.4 | Upper connectivity reference; RF and protocol integration are well beyond a radio-companion Tiny baseline |
|
||||
| [Raspberry Pi RP2350](https://www.raspberrypi.com/products/rp2350/) | Dual Hazard3 option, 520 KiB SRAM, security, USB, and programmable I/O | Closest open-core MCU and deterministic-I/O reference, without integrated radio |
|
||||
| [ST STM32U5](https://www.st.com/en/microcontrollers-microprocessors/stm32u5-series.html) | Ultra-low-power secure MCU family with large embedded memory and graphics options | Energy-efficiency, security, and industrial MCU ecosystem reference rather than an ISA-equivalent peer |
|
||||
@@ -414,7 +405,7 @@ software quality.
|
||||
|
||||
| Tier | Claim gate |
|
||||
| --- | --- |
|
||||
| Tiny | Measured active and sleep power, bounded wake latency, secure-boot validation, and qualified edge-connectivity operation |
|
||||
| Tiny | First release: wired-MCU boot, AXI/APB/DMA/IRQ and IHP130 evidence; future low-power/security claims require separate measurements and qualification |
|
||||
| Mini | Repeatable Linux boot, at least 64 MiB usable main memory, native memory bursts, and management-controlled start/stop recovery |
|
||||
| Std | Full AXI4 ordering tests, coherent accelerator traffic, 1080p60 graphical desktop, audio playback, and NPU inference under concurrent DMA load |
|
||||
| Pro | Four-hart coherent SMP stress, RV64 distribution boot, more-than-4-GiB memory validation, and concurrent GPU/NPU/video operation |
|
||||
|
||||
@@ -12,7 +12,7 @@ from typing import Any
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from rtl.mini.pin_map.generate_pin_map import read_map # noqa: E402
|
||||
from scripts.rtl.generate_pin_map import read_map # noqa: E402
|
||||
from scripts.check_clock_reset_domains import validate # noqa: E402
|
||||
from scripts.setup_helpers import atomic_write # noqa: E402
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ from pathlib import Path
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from librelane.flows import Flow # noqa: E402
|
||||
from rtl.mini.pin_map.generate_pin_map import IHP130_POWER_PAD_COUNTS # noqa: E402
|
||||
from scripts.rtl.generate_pin_map import IHP130_POWER_PAD_COUNTS # noqa: E402
|
||||
from scripts.setup_helpers import atomic_write # noqa: E402
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from rtl.mini.pin_map.generate_pin_map import ( # noqa: E402
|
||||
from scripts.rtl.generate_pin_map import ( # noqa: E402
|
||||
IHP130_POWER_PAD_COUNTS,
|
||||
Pad,
|
||||
ihp130_pad_instance,
|
||||
|
||||
@@ -11,7 +11,7 @@ from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from rtl.mini.pin_map.generate_pin_map import Pad, ihp130_pad_instance, read_map # noqa: E402
|
||||
from scripts.rtl.generate_pin_map import Pad, ihp130_pad_instance, read_map # noqa: E402
|
||||
from scripts.check_clock_reset_domains import validate # noqa: E402
|
||||
from scripts.setup_helpers import atomic_write # noqa: E402
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from typing import Any
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from rtl.mini.pin_map.generate_pin_map import read_map # noqa: E402
|
||||
from scripts.rtl.generate_pin_map import read_map # noqa: E402
|
||||
from scripts.check_clock_reset_domains import validate # noqa: E402
|
||||
from scripts.setup_helpers import atomic_write # noqa: E402
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
OPENSTA ?= sta
|
||||
OPENSTA_TOP ?= $(if $(filter TINY,$(SOC)),retrosoc_tiny_asic,retrosoc_asic)
|
||||
OPENSTA_THREADS ?= $(JOBS)
|
||||
OPENSTA_NETLIST ?= $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v
|
||||
OPENSTA_REPORT ?= $(STA_BUILD_ROOT)/retrosoc_sta.log
|
||||
@@ -8,8 +9,8 @@ OPENSTA_METRICS ?= $(STA_BUILD_ROOT)/timing_metrics.rpt
|
||||
OPENSTA_CONFIG ?= $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.config
|
||||
OPENSTA_SDC ?= $(STA_BUILD_ROOT)/retrosoc_core.sdc
|
||||
OPENSTA_SDC_GEN := $(ROOT_PATH)/physical/smoke/sta/opensta/generate_sdc.py
|
||||
OPENSTA_DOMAIN_MAP := $(ROOT_PATH)/rtl/mini/integration/clock_reset_domains.json
|
||||
OPENSTA_PIN_MAP := $(ROOT_PATH)/rtl/mini/pin_map/pin_map.json
|
||||
OPENSTA_DOMAIN_MAP := $(RTL_PATH)/integration/clock_reset_domains.json
|
||||
OPENSTA_PIN_MAP := $(RTL_PATH)/pin_map/pin_map.json
|
||||
|
||||
include $(ROOT_PATH)/physical/smoke/sta/opensta/pdk_timing.mk
|
||||
|
||||
@@ -36,7 +37,7 @@ sta: $(OPENSTA_SDC) | manifest
|
||||
}
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool opensta --log $(OPENSTA_LOG) \
|
||||
--result $(STA_BUILD_ROOT)/result-sta.json \
|
||||
--env OPENSTA_NETLIST=$(OPENSTA_NETLIST) --env OPENSTA_LIBERTY=$(OPENSTA_LIBERTY) \
|
||||
--env OPENSTA_TOP=$(OPENSTA_TOP) --env OPENSTA_NETLIST=$(OPENSTA_NETLIST) --env OPENSTA_LIBERTY=$(OPENSTA_LIBERTY) \
|
||||
--env 'OPENSTA_LINK_LIBS=$(OPENSTA_LINK_LIBS)' --env 'OPENSTA_SRAM_LIBS=$(OPENSTA_SRAM_LIBS)' \
|
||||
--env OPENSTA_SDC=$(OPENSTA_SDC) --env OPENSTA_REPORT=$(OPENSTA_REPORT) \
|
||||
--env OPENSTA_METRICS=$(OPENSTA_METRICS) -- \
|
||||
|
||||
@@ -14,7 +14,11 @@ if {[info exists ::env(OPENSTA_SRAM_LIBS)] && $::env(OPENSTA_SRAM_LIBS) ne ""} {
|
||||
}
|
||||
}
|
||||
read_verilog $::env(OPENSTA_NETLIST)
|
||||
link_design retrosoc_asic
|
||||
set top_design retrosoc_asic
|
||||
if {[info exists ::env(OPENSTA_TOP)] && $::env(OPENSTA_TOP) ne ""} {
|
||||
set top_design $::env(OPENSTA_TOP)
|
||||
}
|
||||
link_design $top_design
|
||||
read_sdc $::env(OPENSTA_SDC)
|
||||
|
||||
report_checks -path_delay min_max -sort_by_slack -slack_max 0.0 -group_path_count 1000 -endpoint_path_count 1000 > $::env(OPENSTA_REPORT)
|
||||
|
||||
@@ -18,10 +18,9 @@ from pathlib import Path
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[4]
|
||||
SCRIPT_DIR = REPO_ROOT / "rtl/mini/script"
|
||||
sys.path.insert(0, str(SCRIPT_DIR))
|
||||
from filelist import FileList, parse_filelists, write_filelist # noqa: E402
|
||||
from generate_filelist import generate_all # noqa: E402
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
from scripts.rtl.filelist import FileList, parse_filelists, write_filelist # noqa: E402
|
||||
from rtl.mini.script.generate_filelist import generate_all # noqa: E402
|
||||
|
||||
|
||||
APU_SOURCE_MARKERS = ("/ip/multimedia/apu_", "/ip/multimedia/apb4_apu.sv")
|
||||
|
||||
@@ -13,13 +13,10 @@ from pathlib import Path
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[4]
|
||||
SCRIPT_DIR = REPO_ROOT / "rtl/mini/script"
|
||||
INTEGRATION_DIR = REPO_ROOT / "rtl/mini/integration"
|
||||
sys.path.insert(0, str(SCRIPT_DIR))
|
||||
sys.path.insert(0, str(INTEGRATION_DIR))
|
||||
from filelist import FileList, atomic_write, parse_filelists # noqa: E402
|
||||
from generate_filelist import generate_all # noqa: E402
|
||||
from generate_user_extensions import generate as generate_user_extensions # noqa: E402
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
from scripts.rtl.filelist import FileList, atomic_write, parse_filelists # noqa: E402
|
||||
from rtl.mini.script.generate_filelist import generate_all # noqa: E402
|
||||
from rtl.mini.integration.generate_user_extensions import generate as generate_user_extensions # noqa: E402
|
||||
|
||||
|
||||
INCLUDE_RE = re.compile(r'^\s*`include\s+"([^"]+)"')
|
||||
@@ -69,6 +66,20 @@ def configured_filelist(
|
||||
*,
|
||||
require_files: bool = True,
|
||||
) -> FileList:
|
||||
if getattr(args, "soc", "MINI") == "TINY":
|
||||
directory = getattr(args, "source_filelist_dir", None)
|
||||
if directory is None:
|
||||
raise ValueError("Tiny export requires --source-filelist-dir")
|
||||
names = ("def.fl", "inc.fl", "commonip.fl", "clusterip.fl", "ip.fl",
|
||||
"tech.fl", "core_hazard3.fl", "top.fl")
|
||||
filelist = parse_filelists((directory / name for name in names), require_files=require_files)
|
||||
if "+define+RETROSOC_SOC__TINY" not in filelist.defines:
|
||||
raise ValueError("Tiny export requires Tiny source lists")
|
||||
if "+define+SYNTHESIS" not in filelist.defines:
|
||||
filelist.defines.append("+define+SYNTHESIS")
|
||||
return filelist
|
||||
if args.dynamic_core_filelist is None or args.dynamic_ip_filelist is None:
|
||||
raise ValueError("Mini export requires dynamic core and IP filelists")
|
||||
names: list[str | Path] = []
|
||||
for name in (
|
||||
"memory_map_filelist",
|
||||
@@ -271,7 +282,7 @@ def metadata_file(value: str) -> tuple[Path, Path]:
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Export configured retroSoC RTL sources")
|
||||
parser.add_argument("mode", choices=("tar", "sv"))
|
||||
parser.add_argument("--soc", default="MINI", choices=("MINI",))
|
||||
parser.add_argument("--soc", default="MINI", choices=("MINI", "TINY"))
|
||||
parser.add_argument("--pdk", default="IHP130", choices=("IHP130", "ICS55", "SKY130", "GF180"))
|
||||
parser.add_argument("--simu", default="VCS", choices=("VCS", "VERILATOR", "IVERILOG"))
|
||||
parser.add_argument("--have-pll", action="store_true")
|
||||
@@ -285,18 +296,19 @@ def parse_args() -> argparse.Namespace:
|
||||
parser.add_argument(
|
||||
"--dynamic-core-filelist",
|
||||
type=Path,
|
||||
required=True,
|
||||
required=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--dynamic-ip-filelist",
|
||||
type=Path,
|
||||
required=True,
|
||||
required=False,
|
||||
)
|
||||
parser.add_argument("--memory-map-filelist", type=Path)
|
||||
parser.add_argument("--soc-topology-filelist", type=Path)
|
||||
parser.add_argument("--user-extensions-filelist", type=Path)
|
||||
parser.add_argument("--pin-map-filelist", type=Path)
|
||||
parser.add_argument("--archinfo-incdir", type=Path)
|
||||
parser.add_argument("--source-filelist-dir", type=Path)
|
||||
parser.add_argument("--librelane-safe", action="store_true")
|
||||
parser.add_argument("--metadata-file", type=metadata_file, action="append", default=[])
|
||||
parser.add_argument("--output-dir", type=Path, default=REPO_ROOT / "export")
|
||||
@@ -312,15 +324,16 @@ def main() -> int:
|
||||
with tempfile.TemporaryDirectory(prefix="retrosoc-filelists-") as temporary:
|
||||
generated_dir = Path(temporary)
|
||||
user_extensions_dir = generated_dir / "user_extensions"
|
||||
generate_all(generated_dir, build_defines(args))
|
||||
if args.user_extensions_filelist is None:
|
||||
if args.soc == "MINI":
|
||||
generate_all(generated_dir, build_defines(args))
|
||||
if args.soc == "MINI" and args.user_extensions_filelist is None:
|
||||
generate_user_extensions(
|
||||
REPO_ROOT / "rtl/mini/integration/user_extensions.json",
|
||||
user_extensions_dir,
|
||||
)
|
||||
filelist = configured_filelist(args, generated_dir, user_extensions_dir)
|
||||
if args.mode == "sv":
|
||||
output = export_dir / "retrosoc_asic_sources.sv"
|
||||
output = export_dir / ("retrosoc_tiny_asic_sources.sv" if args.soc == "TINY" else "retrosoc_asic_sources.sv")
|
||||
write_single_sv(filelist, output, librelane_safe=args.librelane_safe)
|
||||
else:
|
||||
output = write_tar(filelist, export_dir, args.soc, dict(args.metadata_file))
|
||||
|
||||
@@ -98,7 +98,7 @@ APU_BLOCK_STA_RESULT := $(APU_BLOCK_STA)/result-sta.json
|
||||
APU_BLOCK_SYN_RESULT := $(APU_BLOCK_SYN)/result-synth.json
|
||||
|
||||
$(APU_BLOCK_FL): $(APU_BLOCK_EXPORTER) $(FILELIST_TEMPLATES) \
|
||||
$(RTL_PATH)/script/generate_filelist.py $(RTL_PATH)/script/filelist.py
|
||||
$(RTL_PATH)/script/generate_filelist.py $(ROOT_PATH)/scripts/rtl/filelist.py
|
||||
@mkdir -p $(APU_BLOCK_FL_DIR)
|
||||
python3 $(APU_BLOCK_EXPORTER) --output-dir $(APU_BLOCK_FL_DIR) \
|
||||
$(foreach define,$(DEF_LIST),--define $(define))
|
||||
|
||||
@@ -48,7 +48,7 @@ endif
|
||||
# active DEF_LIST but without the SoC generated-include chain, so the block
|
||||
# flow does not depend on the HP/pin-map generation stamps.
|
||||
$(GA2D_BLOCK_FL_DIR)/.stamp: $(RTL_PATH)/script/generate_filelist.py \
|
||||
$(RTL_PATH)/script/filelist.py \
|
||||
$(ROOT_PATH)/scripts/rtl/filelist.py \
|
||||
$(sort $(wildcard $(ROOT_PATH)/rtl/filelist/pdk_*.fl) \
|
||||
$(wildcard $(RTL_PATH)/filelist/*.fl) $(RTL_PATH)/lint.msg)
|
||||
$(FLOW_PYTHON) $(RTL_PATH)/script/generate_filelist.py \
|
||||
@@ -57,11 +57,11 @@ $(GA2D_BLOCK_FL_DIR)/.stamp: $(RTL_PATH)/script/generate_filelist.py \
|
||||
@touch $@
|
||||
|
||||
$(GA2D_BLOCK_FLIST): $(GA2D_BLOCK_FL_DIR)/.stamp $(MEMORY_MAP_STAMP)
|
||||
@python3 $(RTL_PATH)/script/comb.py \
|
||||
@python3 $(ROOT_PATH)/scripts/rtl/comb.py \
|
||||
-f $(GA2D_BLOCK_FL_DIR)/def.fl \
|
||||
-f $(MEMORY_MAP_FILELIST) \
|
||||
-f $(GA2D_BLOCK_FL_DIR)/ga2d_block.fl --output $@
|
||||
@python3 $(RTL_PATH)/script/filelist_deps.py -f $@ \
|
||||
@python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py -f $@ \
|
||||
--extra $(MEMORY_MAP_FILELIST) \
|
||||
--target $(GA2D_BLOCK_NETLIST) --output $(GA2D_BLOCK_DEPFILE)
|
||||
|
||||
|
||||
@@ -19,18 +19,19 @@
|
||||
|
||||
# Directories
|
||||
# directory of the path to the last called Makefile (this one)
|
||||
YOSYS_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST)))))
|
||||
YOSYS_BUILD := $(SYN_BUILD_ROOT)
|
||||
YOSYS_OUT := $(YOSYS_BUILD)/out
|
||||
YOSYS_TMP := $(YOSYS_BUILD)/tmp
|
||||
YOSYS_RPT := $(YOSYS_BUILD)/rpt
|
||||
YOSYS_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST)))))
|
||||
YOSYS_BUILD := $(SYN_BUILD_ROOT)
|
||||
YOSYS_OUT := $(YOSYS_BUILD)/out
|
||||
YOSYS_TMP := $(YOSYS_BUILD)/tmp
|
||||
YOSYS_RPT := $(YOSYS_BUILD)/rpt
|
||||
YOSYS_TIMEOUT ?= 10800
|
||||
|
||||
include $(YOSYS_DIR)/synth_config.mk
|
||||
|
||||
ifeq ($(origin YOSYS_TARGET_PERIOD_PS),undefined)
|
||||
YOSYS_TARGET_PERIOD_PS := $(shell python3 $(ROOT_PATH)/scripts/yosys_period.py \
|
||||
--domains $(ROOT_PATH)/rtl/mini/integration/clock_reset_domains.json)
|
||||
--domains $(RTL_PATH)/integration/clock_reset_domains.json \
|
||||
--domain $(if $(filter TINY,$(SOC)),system,hp))
|
||||
ifeq ($(strip $(YOSYS_TARGET_PERIOD_PS)),)
|
||||
$(error Failed to derive YOSYS_TARGET_PERIOD_PS from the clock/reset inventory)
|
||||
endif
|
||||
@@ -49,8 +50,8 @@ YOSYS_SCRIPTS := $(wildcard $(YOSYS_DIR)/script/*) $(YOSYS_DIR)/synth_config.mk
|
||||
-include $(YOSYS_DEPFILE)
|
||||
|
||||
$(SV_FLIST): $(MPW_VARIANT_STAMP) $(FILELIST_STAMP)
|
||||
@python3 $(RTL_PATH)/script/comb.py $(RTL_FLIST) --output $(SV_FLIST)
|
||||
@python3 $(RTL_PATH)/script/filelist_deps.py $(RTL_FLIST) --target $(NETLIST) \
|
||||
@python3 $(ROOT_PATH)/scripts/rtl/comb.py $(RTL_FLIST) --output $(SV_FLIST)
|
||||
@python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py $(RTL_FLIST) --target $(NETLIST) \
|
||||
--output $(YOSYS_DEPFILE)
|
||||
|
||||
gen_synth_filelist: $(SV_FLIST)
|
||||
|
||||
@@ -146,9 +146,9 @@ def collect_data(config: dict[str, Any], *, check_snapshot: bool = True) -> dict
|
||||
product = profiles["profile"]
|
||||
if product.get("MINI_MODE") != "PRODUCT" or product.get("HAVE_HP") != "YES":
|
||||
raise ValueError("datasheet requires the reviewed dual-hart PRODUCT profile")
|
||||
address = load_generator("datasheet_memory", "rtl/mini/address_map/generate_memory_map.py")
|
||||
address = load_generator("datasheet_memory", "scripts/rtl/generate_memory_map.py")
|
||||
topology = load_generator("datasheet_topology", "rtl/mini/integration/generate_soc_topology.py")
|
||||
pinmap = load_generator("datasheet_pins", "rtl/mini/pin_map/generate_pin_map.py")
|
||||
pinmap = load_generator("datasheet_pins", "scripts/rtl/generate_pin_map.py")
|
||||
reset, regions, _ = address.read_map(ROOT / MAP, int(product["SRAM_SIZE_KIB"]))
|
||||
_, _, _, gpio, _, _, irqs, policies = topology.read_topology(ROOT / TOPOLOGY, ROOT / MAP)
|
||||
pads, _ = pinmap.read_map(ROOT / PINS)
|
||||
|
||||
@@ -20,7 +20,7 @@ def check_examples(compiler: str) -> int:
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(ROOT / "rtl/mini/address_map/generate_memory_map.py"),
|
||||
str(ROOT / "scripts/rtl/generate_memory_map.py"),
|
||||
"--map",
|
||||
str(ROOT / "rtl/mini/address_map/memory_map.json"),
|
||||
"--output-dir",
|
||||
|
||||
@@ -8451,13 +8451,13 @@
|
||||
],
|
||||
"sources": [
|
||||
"rtl/mini/top/retrosoc.sv",
|
||||
"rtl/mini/top/onchip_ram.sv"
|
||||
"rtl/ip/memory/onchip_ram.sv"
|
||||
],
|
||||
"instance_source": {
|
||||
"file": "rtl/mini/top/retrosoc.sv",
|
||||
"name": "u_onchip_ram",
|
||||
"module": "onchip_ram",
|
||||
"declaration_file": "rtl/mini/top/onchip_ram.sv"
|
||||
"declaration_file": "rtl/ip/memory/onchip_ram.sv"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -8495,7 +8495,7 @@
|
||||
}
|
||||
],
|
||||
"sources": [
|
||||
"rtl/mini/top/onchip_ram.sv"
|
||||
"rtl/ip/memory/onchip_ram.sv"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -8562,11 +8562,11 @@
|
||||
"style": "direct",
|
||||
"bindings": [
|
||||
{
|
||||
"file": "rtl/mini/top/onchip_ram.sv",
|
||||
"file": "rtl/ip/memory/onchip_ram.sv",
|
||||
"text": ".data_i(s_mem_wdata[31:0])"
|
||||
},
|
||||
{
|
||||
"file": "rtl/mini/top/onchip_ram.sv",
|
||||
"file": "rtl/ip/memory/onchip_ram.sv",
|
||||
"text": ".data_i(s_mem_wdata[63:32])"
|
||||
}
|
||||
],
|
||||
@@ -10929,13 +10929,13 @@
|
||||
],
|
||||
"sources": [
|
||||
"rtl/mini/top/retrosoc.sv",
|
||||
"rtl/mini/top/onchip_ram.sv"
|
||||
"rtl/ip/memory/onchip_ram.sv"
|
||||
],
|
||||
"instance_source": {
|
||||
"file": "rtl/mini/top/retrosoc.sv",
|
||||
"name": "u_onchip_ram",
|
||||
"module": "onchip_ram",
|
||||
"declaration_file": "rtl/mini/top/onchip_ram.sv"
|
||||
"declaration_file": "rtl/ip/memory/onchip_ram.sv"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1430,10 +1430,10 @@
|
||||
"sram": {
|
||||
"document": "docs/ip/onchip-sram.md",
|
||||
"defines": [
|
||||
"rtl/mini/top/onchip_ram_define.svh"
|
||||
"rtl/ip/memory/onchip_ram_define.svh"
|
||||
],
|
||||
"rtl": [
|
||||
"rtl/mini/top/onchip_ram_reg.sv"
|
||||
"rtl/ip/memory/onchip_ram_reg.sv"
|
||||
],
|
||||
"parameters": {
|
||||
"Present": 1,
|
||||
|
||||
@@ -58,7 +58,7 @@ the existing non-coherent buffer protocol. LP and HP configuration differences d
|
||||
two harts into a symmetric cache-coherent SMP platform.
|
||||
#block(above:rhythm.metadata-before,below:rhythm.metadata-after,breakable:false)[
|
||||
#set text(size:9pt)
|
||||
#source("rtl/mini/top/mgmt_core_wrapper.sv",title:"LP instance") ·
|
||||
#source("rtl/ip/core/mgmt_core_wrapper.sv",title:"LP instance") ·
|
||||
#source("scripts/vexiiriscv/GenerateRetroSocHp.scala",title:"HP configuration/PMA") ·
|
||||
#source("scripts/generate_vexiiriscv.py",title:"Artifact manifest") ·
|
||||
#source("app/ports/linux/linux/retrosoc_hp.dts",title:"HP platform properties")
|
||||
|
||||
@@ -41,7 +41,7 @@ The debug replacement sets the stack and calls main, without the generic PSRAM i
|
||||
relocation or BSS loop. The XPI flash-loader replacement sets the stack, clears BSS and calls
|
||||
main; if main returns it executes EBREAK and loops. Those compact entries are tied to their
|
||||
application/linker assumptions and do not establish a universal alternative startup sequence.
|
||||
#source-note("rtl/mini/mk/software.mk",title:"Generic CRT, conditional IRQ objects and application CRT replacement")
|
||||
#source-note("rtl/mk/software.mk",title:"Generic CRT, conditional IRQ objects and application CRT replacement")
|
||||
#source-note("crt/arch/riscv/startup.S",title:"Actual generic LP entry and PSRAM-ready loop")
|
||||
#source-note("app/apps/debug/startup.S",title:"Dedicated debug entry")
|
||||
#source-note("app/apps/xpi_flash_loader/startup.S",title:"Dedicated SRAM flash-loader entry")
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"rtl/mini/top/apb4_periph.sv",
|
||||
"rtl/mini/top/apb4_system.sv",
|
||||
"rtl/mini/top/memory_pad_mux.sv",
|
||||
"rtl/mini/top/mgmt_debug_wrapper.sv",
|
||||
"rtl/ip/core/mgmt_debug_wrapper.sv",
|
||||
"rtl/mini/top/retrosoc.sv",
|
||||
"rtl/mini/top/soc_clock_reset_subsystem.sv",
|
||||
"rtl/mini/top/soc_data_plane.sv"
|
||||
@@ -168,7 +168,7 @@
|
||||
"ips": [],
|
||||
"rotate": false,
|
||||
"clock": {
|
||||
"file": "rtl/mini/top/mgmt_debug_wrapper.sv",
|
||||
"file": "rtl/ip/core/mgmt_debug_wrapper.sv",
|
||||
"name": "u_jtag_rst_sync",
|
||||
"module": "rst_sync",
|
||||
"port": "clk_i",
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
"crt/include/retrosoc/hal/onchip_sram.h",
|
||||
"docs/ip/onchip-sram.md",
|
||||
"publications/examples/sram.c",
|
||||
"rtl/mini/top/onchip_ram_reg.sv"
|
||||
"rtl/ip/memory/onchip_ram_reg.sv"
|
||||
],
|
||||
"tests": [
|
||||
"tests/test_onchip_sram_register_parity.py"
|
||||
@@ -1159,7 +1159,7 @@
|
||||
"applies_to": "Reviewed generic LP CRT; dedicated debug and XPI-loader startups have separate initialization contracts.",
|
||||
"sources": [
|
||||
"crt/arch/riscv/startup.S",
|
||||
"rtl/mini/mk/software.mk"
|
||||
"rtl/mk/software.mk"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -3385,7 +3385,7 @@
|
||||
"rtl/managed/clusterip/common/rtl/utils/register.sv",
|
||||
"rtl/mini/top/clock_config_controller.sv",
|
||||
"rtl/mini/top/hp_lifecycle_controller.sv",
|
||||
"rtl/mini/top/mgmt_core_wrapper.sv",
|
||||
"rtl/ip/core/mgmt_core_wrapper.sv",
|
||||
"rtl/mini/top/resource_controller.sv",
|
||||
"rtl/mini/top/soc_clock_reset_subsystem.sv",
|
||||
"scripts/generate_vexiiriscv.py",
|
||||
@@ -5213,7 +5213,7 @@
|
||||
"crt/src/service/test.c",
|
||||
"publications/datasheets/mini.json",
|
||||
"rtl/mini/integration/soc_topology.json",
|
||||
"rtl/mini/mk/software.mk",
|
||||
"rtl/mk/software.mk",
|
||||
"scripts/build_hp_linux.py",
|
||||
"scripts/regress.py",
|
||||
"crt/src/hal/hp_mailbox.c",
|
||||
@@ -5225,17 +5225,17 @@
|
||||
"bindings": [
|
||||
{
|
||||
"id": "csr-selection",
|
||||
"file": "rtl/mini/mk/software.mk",
|
||||
"file": "rtl/mk/software.mk",
|
||||
"text": "ifeq ($(HAVE_CSR),YES)\nDEF_VAL += -DCSR_ENABLE\nendif"
|
||||
},
|
||||
{
|
||||
"id": "irq-objects",
|
||||
"file": "rtl/mini/mk/software.mk",
|
||||
"file": "rtl/mk/software.mk",
|
||||
"text": "ifeq ($(HAVE_CSR),YES)\nCRT_SRCS += $(ROOT_PATH)/crt/arch/riscv/system_irq.S\nCRT_SRCS += $(ROOT_PATH)/crt/src/core/system_irq_handler.c\nCRT_SRCS += $(ROOT_PATH)/crt/src/core/irq.c"
|
||||
},
|
||||
{
|
||||
"id": "app-override",
|
||||
"file": "rtl/mini/mk/software.mk",
|
||||
"file": "rtl/mk/software.mk",
|
||||
"text": "ifneq ($(strip $(APP_CRT_SRCS)),)\nCRT_SRCS := $(APP_CRT_SRCS)\nendif"
|
||||
},
|
||||
{
|
||||
@@ -6151,8 +6151,8 @@
|
||||
"rtl/mini/top/fabric_monitor.sv",
|
||||
"rtl/mini/top/hp_subsystem.sv",
|
||||
"rtl/mini/top/memory_pad_mux.sv",
|
||||
"rtl/mini/top/mgmt_debug_wrapper.sv",
|
||||
"rtl/mini/top/onchip_ram.sv",
|
||||
"rtl/ip/core/mgmt_debug_wrapper.sv",
|
||||
"rtl/ip/memory/onchip_ram.sv",
|
||||
"rtl/mini/top/rcu.sv",
|
||||
"rtl/mini/top/resource_controller.sv",
|
||||
"rtl/mini/top/retrosoc.sv",
|
||||
|
||||
@@ -34,7 +34,12 @@ def lp_parameters(text: str) -> dict[str, str]:
|
||||
matches = re.findall(r"\bhazard3_cpu_1port\s*#\s*\((.*?)\)\s+u_hazard3_cpu_1port\s*\(", without_comments(text), re.S)
|
||||
if len(matches) != 1:
|
||||
raise ValueError("LP instance missing or ambiguous")
|
||||
return unique_pairs(re.findall(r"\.([A-Z][A-Z0-9_]*)\s*\(([^()]*)\)", matches[0]), "LP")
|
||||
parameters = unique_pairs(re.findall(r"\.([A-Z][A-Z0-9_]*)\s*\(([^()]*)\)", matches[0]), "LP")
|
||||
# The fixed Mini integration uses the shared wrapper's Boolean feature
|
||||
# defaults. Keep configurable integer expressions (notably IRQ count) intact.
|
||||
defaults = dict(re.findall(r"parameter\s+bit\s+(\w+)\s*=\s*1'b([01])", without_comments(text)))
|
||||
return {name: defaults.get(value, value) if name.startswith("EXTENSION_") else value
|
||||
for name, value in parameters.items()}
|
||||
|
||||
|
||||
def hp_parameters(text: str) -> tuple[dict[str, str], list[str]]:
|
||||
@@ -109,7 +114,7 @@ def validate_details(spec: dict, ids: set[str], root: Path, active_limits: set[s
|
||||
|
||||
def collect_details(root: Path, spec: dict, ids: set[str], active_limits: set[str]) -> dict:
|
||||
validate_details(spec, ids, root, active_limits)
|
||||
lp = lp_parameters((root / "rtl/mini/top/mgmt_core_wrapper.sv").read_text(encoding="utf-8"))
|
||||
lp = lp_parameters((root / "rtl/ip/core/mgmt_core_wrapper.sv").read_text(encoding="utf-8"))
|
||||
hp_source = (root / "scripts/vexiiriscv/GenerateRetroSocHp.scala").read_text(encoding="utf-8")
|
||||
hp, hp_isa = hp_parameters(hp_source)
|
||||
for required, actual, name in ((spec["cpu"]["lp_fields"], lp, "LP"), (spec["cpu"]["hp_fields"], hp, "HP")):
|
||||
|
||||
@@ -111,11 +111,11 @@ def buffer_budget(kind: str, *, width=0, height=0, rate=0, bits=0, milliseconds=
|
||||
"total_bytes": stride * count, "dma_supported": supported}
|
||||
|
||||
|
||||
def constants(text: str, prefix: str, rtl=False) -> dict[str, int]:
|
||||
def constants(text: str, prefix: str, rtl=False, *, exclude: frozenset[str] = frozenset()) -> dict[str, int]:
|
||||
text = re.sub(r"/\*.*?\*/|//[^\n]*", "", text, flags=re.S)
|
||||
pattern = (rf"\b({prefix}\w+)\s*=\s*\d+'d(\d+)\s*;" if rtl else
|
||||
rf"\b({prefix}\w+)\s*(?:=\s*|\s+)(\d+)(?:U)?(?=\s*[,;\n])")
|
||||
pairs = re.findall(pattern, text)
|
||||
pairs = [(name, value) for name, value in re.findall(pattern, text) if name not in exclude]
|
||||
if len({name for name, _ in pairs}) != len(pairs):
|
||||
raise ValueError(f"duplicate constant: {prefix}")
|
||||
return {name: int(value) for name, value in pairs}
|
||||
@@ -194,8 +194,10 @@ def collect_programming(root: Path, spec: dict, ids: set[str], revision: str) ->
|
||||
sdk_text = (root / "crt/include/retrosoc/hal/dma.h").read_text()
|
||||
sdk = constants(sdk_text, "RS_DMA_REQUEST_")
|
||||
channels = constants(sdk_text, "RS_DMA_CHANNEL_")
|
||||
channels.update(constants((root / "crt/include/retrosoc/hal/dma_regs.h").read_text(), "RS_DMA_CHANNEL_"))
|
||||
channels.pop("RS_DMA_CHANNEL_COUNT")
|
||||
# Capacity is selected by product; it is not a named channel allocation.
|
||||
# Keep the Mini publication's role inventory independent of Tiny's count.
|
||||
channels.update(constants((root / "crt/include/retrosoc/hal/dma_regs.h").read_text(),
|
||||
"RS_DMA_CHANNEL_", exclude=frozenset({"RS_DMA_CHANNEL_COUNT"})))
|
||||
if {r["symbol"] for r in spec["channels"]} != set(channels):
|
||||
raise ValueError("DMA channel allocation coverage mismatch")
|
||||
for row in result["dma_routes"]:
|
||||
|
||||
@@ -21,6 +21,22 @@ LITERAL = re.compile(r"(?P<w>\d+)?'[sS]?(?P<base>[hHbBdDoO])(?P<digits>[0-9a-fA-
|
||||
def number(expression: str, constants: dict[str, int] | None = None) -> int:
|
||||
constants = constants or {}
|
||||
expression = " ".join(expression.split()).replace("`", "")
|
||||
# Preserve sized-cast truncation and unwrap a complete parenthesized
|
||||
# expression before looking for an SV conditional at its top level.
|
||||
while expression.startswith("(") and expression.endswith(")"):
|
||||
depth = 0
|
||||
enclosed = True
|
||||
for index, character in enumerate(expression):
|
||||
depth += (character == "(") - (character == ")")
|
||||
if depth == 0 and index != len(expression) - 1:
|
||||
enclosed = False
|
||||
break
|
||||
if not enclosed or depth != 0:
|
||||
break
|
||||
expression = expression[1:-1].strip()
|
||||
sized_cast = re.fullmatch(r"(\d+)'\(([^()]*)\)", expression)
|
||||
if sized_cast:
|
||||
return number(sized_cast[2], constants) & ((1 << int(sized_cast[1])) - 1)
|
||||
expression = LITERAL.sub(
|
||||
lambda m: str(
|
||||
int(m["digits"].replace("_", ""), {"h": 16, "b": 2, "d": 10, "o": 8}[m["base"].lower()])
|
||||
@@ -151,7 +167,7 @@ def parse_definitions(paths: list[str], extra: dict[str, int]) -> tuple[dict, di
|
||||
"line": text.count("\n", 0, match.start()) + 1,
|
||||
}
|
||||
for match in re.finditer(
|
||||
r"\b(?:localparam|parameter)\s+(?:(?:int(?:\s+unsigned)?|logic(?:\s*\[[^]]+\])?|\w+_t)\s+)?"
|
||||
r"\b(?:localparam|parameter)\s+(?:(?:int(?:\s+unsigned)?|bit|logic(?:\s*\[[^]]+\])?|\w+_t)\s+)?"
|
||||
r"(\w+)\s*=\s*([^;\n]+)",
|
||||
text,
|
||||
):
|
||||
@@ -165,7 +181,7 @@ def parse_definitions(paths: list[str], extra: dict[str, int]) -> tuple[dict, di
|
||||
},
|
||||
)
|
||||
for match in re.finditer(
|
||||
r"\blocalparam\s+(?:int(?:\s+unsigned)?|logic(?:\s*\[[^]]+\])?|\w+_t)\s+(\w+)\s*=\s*([^;]+);",
|
||||
r"\blocalparam\s+(?:int(?:\s+unsigned)?|bit|logic(?:\s*\[[^]]+\])?|\w+_t)\s+(\w+)\s*=\s*([^;]+);",
|
||||
text,
|
||||
):
|
||||
definitions[match[1]] = {
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
# RTL Design and Simulation
|
||||
|
||||
This directory contains retroSoC SystemVerilog RTL, CPU/IP integration,
|
||||
peripheral and technology wrappers, filelists, testbench support, and the Mini
|
||||
peripheral and technology wrappers, filelists, testbench support, and the Mini/Tiny
|
||||
SoC build entry points.
|
||||
|
||||
`mini/` is the active SoC integration flow. `managed/` contains locked or
|
||||
`mini/` and `tiny/` own independent product integrations. Tiny is the single-hart
|
||||
AXI32/APB4 wired MCU described in [its contract](../docs/ip/tiny-soc.md). `managed/` contains locked or
|
||||
vendored integration inputs, `ip/` contains self-owned IP and experiments, and
|
||||
`model/` contains committed device simulation models with preserved upstream
|
||||
notices. `filelist/` selects PDK-specific RTL sources; `tech/` contains
|
||||
|
||||
+7
-4
@@ -1,11 +1,14 @@
|
||||
# RIB and Experimental IP
|
||||
# Shared RTL IP
|
||||
|
||||
This directory owns project RTL IP.
|
||||
|
||||
Self-owned IP is grouped by function: interconnect, util, memory, storage,
|
||||
serial, USB, multimedia, and peripheral. The Mini SoC selects active sources
|
||||
explicitly in rtl/mini/filelist/ip.fl, whose source order is part of
|
||||
the build contract.
|
||||
serial, USB, multimedia, and peripheral. Mini and Tiny select active sources
|
||||
explicitly in their product filelists.
|
||||
Source order is part of the build contract. Shared Hazard3/debug wrappers are
|
||||
in `core`, AXI adapters in `interconnect`, and native AXI SRAM in `memory`.
|
||||
Both products reference these shared files directly in their own filelists.
|
||||
Tiny does not select any RIB/RIBP module.
|
||||
|
||||
experimental contains retained inactive RTL. It is not included by any active
|
||||
filelist and must not become a build dependency without an explicit integration
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
`include "mmap_define.svh"
|
||||
|
||||
module mgmt_core_wrapper #(
|
||||
parameter int ExternalIrqCount = 30
|
||||
parameter int ExternalIrqCount = 30,
|
||||
parameter bit EnableAtomics = 1'b1,
|
||||
parameter bit TwoCycleBusErrors = 1'b0
|
||||
) (
|
||||
// verilog_format: off -- preserve reviewed column alignment
|
||||
input logic clk_i,
|
||||
@@ -58,7 +60,7 @@ module mgmt_core_wrapper #(
|
||||
.hclk(clk_i),
|
||||
.hresetn(s_core_rst_n)
|
||||
);
|
||||
ahbl2axi4 u_ahbl2axi4 (
|
||||
ahbl2axi4 #(.TwoCycleErrors(TwoCycleBusErrors)) u_ahbl2axi4 (
|
||||
.ahbl (u_ahbl_if),
|
||||
.axi4 (axi4),
|
||||
.idle_o(s_ahbl_idle)
|
||||
@@ -103,7 +105,7 @@ module mgmt_core_wrapper #(
|
||||
hazard3_cpu_1port #(
|
||||
.RESET_VECTOR (`SOC_CPU_RESET_ADDR),
|
||||
.MTVEC_INIT (32'h0000_0000),
|
||||
.EXTENSION_A (1),
|
||||
.EXTENSION_A (EnableAtomics),
|
||||
.EXTENSION_C (1),
|
||||
.EXTENSION_E (0),
|
||||
.EXTENSION_M (1),
|
||||
File renamed without changes.
File renamed without changes.
@@ -11,7 +11,9 @@
|
||||
|
||||
`include "axi4_define.svh"
|
||||
|
||||
module ahbl2axi4 (
|
||||
module ahbl2axi4 #(
|
||||
parameter bit TwoCycleErrors = 1'b0
|
||||
) (
|
||||
ahbl_if.slave ahbl,
|
||||
axi4_if.master axi4,
|
||||
output logic idle_o
|
||||
@@ -27,6 +29,7 @@ module ahbl2axi4 (
|
||||
localparam logic [2:0] FSM_WRITE_RESP = 3'd2;
|
||||
localparam logic [2:0] FSM_READ = 3'd3;
|
||||
localparam logic [2:0] FSM_READ_RESP = 3'd4;
|
||||
localparam logic [2:0] FSM_ERROR_RESP = 3'd5;
|
||||
|
||||
logic [2:0] s_fsm_d, s_fsm_q;
|
||||
logic [31:0] s_addr_d, s_addr_q;
|
||||
@@ -37,15 +40,22 @@ module ahbl2axi4 (
|
||||
logic [ 3:0] s_wstrb;
|
||||
logic [31:0] s_wdata;
|
||||
logic s_terminal;
|
||||
logic s_axi_err;
|
||||
logic s_resp_valid;
|
||||
|
||||
assign idle_o = s_fsm_q == FSM_IDLE;
|
||||
assign s_terminal = ((s_fsm_q == FSM_WRITE_RESP) && axi4.bvalid) ||
|
||||
((s_fsm_q == FSM_READ_RESP) && axi4.rvalid);
|
||||
assign s_resp_valid = ((s_fsm_q == FSM_WRITE_RESP) && axi4.bvalid) ||
|
||||
((s_fsm_q == FSM_READ_RESP) && axi4.rvalid);
|
||||
assign s_axi_err = s_resp_valid &&
|
||||
(((s_fsm_q == FSM_WRITE_RESP) && (axi4.bresp != `AXI4_RESP_OKAY)) ||
|
||||
((s_fsm_q == FSM_READ_RESP) && (axi4.rresp != `AXI4_RESP_OKAY)));
|
||||
// In compliant mode, the AXI terminal error is consumed during the first
|
||||
// AHB ERROR cycle (HREADY=0). The saved state supplies the final ERROR cycle
|
||||
// (HREADY=1), allowing Hazard3 to squash a following pipelined access.
|
||||
assign s_terminal = (s_resp_valid && !(TwoCycleErrors && s_axi_err)) ||
|
||||
(s_fsm_q == FSM_ERROR_RESP);
|
||||
assign ahbl.hready = (s_fsm_q == FSM_IDLE) || s_terminal;
|
||||
assign ahbl.hresp = s_terminal &&
|
||||
(((s_fsm_q == FSM_WRITE_RESP) && (axi4.bresp != `AXI4_RESP_OKAY)) ||
|
||||
((s_fsm_q == FSM_READ_RESP) && (axi4.rresp != `AXI4_RESP_OKAY))) ?
|
||||
AHBL_RESP_ERROR : AHBL_RESP_OKAY;
|
||||
assign ahbl.hresp = (s_axi_err || (s_fsm_q == FSM_ERROR_RESP)) ? AHBL_RESP_ERROR : AHBL_RESP_OKAY;
|
||||
assign ahbl.hrdata = axi4.rdata;
|
||||
|
||||
always_comb begin
|
||||
@@ -155,6 +165,9 @@ module ahbl2axi4 (
|
||||
FSM_READ: begin
|
||||
if (axi4.arvalid && axi4.arready) s_fsm_d = FSM_READ_RESP;
|
||||
end
|
||||
FSM_WRITE_RESP, FSM_READ_RESP: begin
|
||||
if (TwoCycleErrors && s_axi_err) s_fsm_d = FSM_ERROR_RESP;
|
||||
end
|
||||
default: begin
|
||||
end
|
||||
endcase
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -9,11 +9,13 @@
|
||||
// See the Mulan PSL v2 for more details.
|
||||
|
||||
module apb4_dma #(
|
||||
parameter int AddrWidth = 32,
|
||||
parameter int DataWidth = 32,
|
||||
parameter int NumChannels = 4,
|
||||
parameter int MaxBurstBeats = 16,
|
||||
parameter int FifoDepth = 16
|
||||
parameter int AddrWidth = 32,
|
||||
parameter int DataWidth = 32,
|
||||
parameter int NumChannels = 4,
|
||||
parameter int MaxBurstBeats = 16,
|
||||
parameter int FifoDepth = 16,
|
||||
parameter logic [15:0] RequestMask = 16'h3fff,
|
||||
parameter bit EnableStreams = 1'b1
|
||||
) (
|
||||
// verilog_format: off -- integration ports retain established peripheral endpoint names.
|
||||
input logic clk_i,
|
||||
@@ -72,7 +74,8 @@ module apb4_dma #(
|
||||
dma_reg #(
|
||||
.NumChannels (NumChannels),
|
||||
.DataWidth (DataWidth),
|
||||
.MaxBurstBeats(MaxBurstBeats)
|
||||
.MaxBurstBeats(MaxBurstBeats),
|
||||
.EnableStreams(EnableStreams)
|
||||
) u_dma_reg (
|
||||
.clk_i (clk_i),
|
||||
.rst_n_i (rst_n_i),
|
||||
@@ -119,6 +122,8 @@ module apb4_dma #(
|
||||
);
|
||||
|
||||
dma_core #(
|
||||
.RequestMask (RequestMask),
|
||||
.EnableStreams(EnableStreams),
|
||||
.AddrWidth (AddrWidth),
|
||||
.DataWidth (DataWidth),
|
||||
.NumChannels (NumChannels),
|
||||
|
||||
@@ -12,13 +12,15 @@
|
||||
`include "axi4_define.svh"
|
||||
|
||||
module dma_core #(
|
||||
parameter int AddrWidth = 32,
|
||||
parameter int DataWidth = 32,
|
||||
parameter int NumChannels = 4,
|
||||
parameter int ChannelIndexWidth = (NumChannels > 1) ? $clog2(NumChannels) : 1,
|
||||
parameter int MaxBurstBeats = 16,
|
||||
parameter int FifoDepth = 16,
|
||||
parameter bit EnableCrc = 1'b1
|
||||
parameter int AddrWidth = 32,
|
||||
parameter int DataWidth = 32,
|
||||
parameter int NumChannels = 4,
|
||||
parameter int ChannelIndexWidth = (NumChannels > 1) ? $clog2(NumChannels) : 1,
|
||||
parameter int MaxBurstBeats = 16,
|
||||
parameter int FifoDepth = 16,
|
||||
parameter bit EnableCrc = 1'b1,
|
||||
parameter logic [15:0] RequestMask = 16'h3fff,
|
||||
parameter bit EnableStreams = 1'b1
|
||||
) (
|
||||
// verilog_format: off -- channel vectors are kept aligned with the register-bank ABI.
|
||||
input logic clk_i,
|
||||
@@ -447,7 +449,9 @@ module dma_core #(
|
||||
|
||||
s_start_valid[channel] = 1'b1;
|
||||
s_start_err_code[channel] = DMA_ERROR_CONFIG;
|
||||
if ((s_cfg_width[channel] != DMA_WIDTH_32) || (s_cfg_byte_count[channel] == 32'd0) ||
|
||||
if (!RequestMask[s_cfg_request[channel]] ||
|
||||
(!EnableStreams && (s_cfg_kind[channel] != DMA_KIND_MM_TO_MM)) ||
|
||||
(s_cfg_width[channel] != DMA_WIDTH_32) || (s_cfg_byte_count[channel] == 32'd0) ||
|
||||
(s_cfg_burst[channel] == 5'd0) ||
|
||||
(s_cfg_burst[channel] > 5'(MaxBurstBeats))) begin
|
||||
s_start_valid[channel] = 1'b0;
|
||||
@@ -1268,7 +1272,9 @@ module dma_core #(
|
||||
|
||||
if (s_tcd_parse_q) begin
|
||||
s_tcd_parse_q <= 1'b0;
|
||||
if (s_err_q[s_tcd_read_owner_q] ||
|
||||
if (!RequestMask[s_tcd_word7_q[s_tcd_read_owner_q][15:12]] ||
|
||||
(!EnableStreams && (s_tcd_word7_q[s_tcd_read_owner_q][10:8] != DMA_KIND_MM_TO_MM)) ||
|
||||
s_err_q[s_tcd_read_owner_q] ||
|
||||
(s_tcd_word7_q[s_tcd_read_owner_q][0] == 1'b0) ||
|
||||
(s_tcd_word3_q[s_tcd_read_owner_q] == 32'd0) ||
|
||||
(s_tcd_word1_q[s_tcd_read_owner_q][1:0] != 2'b00) ||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
module dma_reg #(
|
||||
parameter int NumChannels = 4,
|
||||
parameter bit EnableStreams = 1'b1,
|
||||
parameter int ChannelIndexWidth = (NumChannels > 1) ? $clog2(NumChannels) : 1,
|
||||
parameter int DataWidth = 32,
|
||||
parameter int MaxBurstBeats = 16
|
||||
@@ -350,7 +351,15 @@ module dma_reg #(
|
||||
`APB4_DMA__IP_ID: s_read_data = IpId;
|
||||
`APB4_DMA__IP_VERSION: s_read_data = IpVersion;
|
||||
`APB4_DMA__CAPABILITY:
|
||||
s_read_data = {1'b0, 3'd3, 4'(MaxBurstBeats), 8'(DataWidth), 8'(NumChannels), 7'd0, 1'b1};
|
||||
s_read_data = {
|
||||
1'b0,
|
||||
(EnableStreams ? 3'd3 : 3'd0),
|
||||
4'(MaxBurstBeats),
|
||||
8'(DataWidth),
|
||||
8'(NumChannels),
|
||||
7'd0,
|
||||
1'b1
|
||||
};
|
||||
`APB4_DMA__GLOBAL_CTRL: s_read_data = 32'd0;
|
||||
`APB4_DMA__GLOBAL_STATUS: s_read_data = {31'd0, |busy_i};
|
||||
`APB4_DMA__IRQ_STATE: s_read_data = {{(32 - NumChannels) {1'b0}}, s_irq_state};
|
||||
|
||||
File renamed without changes.
@@ -10,7 +10,9 @@
|
||||
|
||||
`include "xpi_define.svh"
|
||||
|
||||
`ifdef SIMU_VERILATOR
|
||||
`ifdef RETROSOC_SOC__TINY
|
||||
`define APB4_XPI_CORE_MODULE xpi_core
|
||||
`elsif SIMU_VERILATOR
|
||||
`define APB4_XPI_CORE_MODULE xpi_core_verilator
|
||||
`else
|
||||
`define APB4_XPI_CORE_MODULE xpi_core
|
||||
|
||||
File renamed without changes.
File renamed without changes.
+4
-4
@@ -1,6 +1,6 @@
|
||||
GENERATED_FL_DIR := $(FLOW_FILELIST_DIR)
|
||||
MEMORY_MAP_SOURCE := $(RTL_PATH)/address_map/memory_map.json
|
||||
MEMORY_MAP_SCRIPT := $(RTL_PATH)/address_map/generate_memory_map.py
|
||||
MEMORY_MAP_SCRIPT := $(ROOT_PATH)/scripts/rtl/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
|
||||
@@ -8,7 +8,7 @@ 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
|
||||
PIN_MAP_SOURCE := $(RTL_PATH)/pin_map/pin_map.json
|
||||
PIN_MAP_SCRIPT := $(RTL_PATH)/pin_map/generate_pin_map.py
|
||||
PIN_MAP_SCRIPT := $(ROOT_PATH)/scripts/rtl/generate_pin_map.py
|
||||
PIN_MAP_DIR := $(VARIANT_ROOT)/generated/pin_map
|
||||
PIN_MAP_STAMP := $(PIN_MAP_DIR)/.stamp
|
||||
PIN_MAP_FILELIST := $(PIN_MAP_DIR)/pin_map.fl
|
||||
@@ -132,7 +132,7 @@ check-clock-reset-domains:
|
||||
$(FLOW_PYTHON) $(CLOCK_RESET_DOMAINS_SCRIPT) --map $(CLOCK_RESET_DOMAINS_SOURCE) --root $(ROOT_PATH)
|
||||
|
||||
$(FILELIST_STAMP): $(FILELIST_TEMPLATES) $(RTL_PATH)/script/generate_filelist.py $(LOCAL_RTL_FILES) \
|
||||
$(RTL_PATH)/script/filelist.py $(MEMORY_MAP_STAMP) $(PIN_MAP_STAMP) $(SOC_TOPOLOGY_STAMP) \
|
||||
$(ROOT_PATH)/scripts/rtl/filelist.py $(MEMORY_MAP_STAMP) $(PIN_MAP_STAMP) $(SOC_TOPOLOGY_STAMP) \
|
||||
$(USER_EXTENSIONS_STAMP) $(ARCHINFO_METADATA_STAMP) \
|
||||
$(if $(filter MPW,$(MINI_MODE)),$(MPW_VARIANT_STAMP)) \
|
||||
$(if $(filter YES,$(HAVE_HP)),$(HP_GENERATED_STAMP))
|
||||
@@ -146,7 +146,7 @@ $(FILELIST_STAMP): $(FILELIST_TEMPLATES) $(RTL_PATH)/script/generate_filelist.py
|
||||
generate_filelist: $(FILELIST_STAMP)
|
||||
|
||||
# software
|
||||
include $(RTL_PATH)/mk/software.mk
|
||||
include $(ROOT_PATH)/rtl/mk/software.mk
|
||||
|
||||
#====================== filelist ======================
|
||||
ifeq ($(PDK), IHP130)
|
||||
|
||||
+10
-4
@@ -1,8 +1,12 @@
|
||||
# Mini SoC Integration
|
||||
|
||||
This directory is the active Mini SoC integration boundary.
|
||||
This directory is the Mini SoC integration boundary. Tiny owns a separate
|
||||
[MCU integration](../tiny/README.md). Shared CPU/debug, memory, bus helpers and
|
||||
software build logic are owned outside Mini. Filelists, build rules and tests
|
||||
reference their canonical shared paths directly.
|
||||
|
||||
- address_map contains the canonical address-map input and generator.
|
||||
- address_map contains the canonical Mini address-map input. Its generator
|
||||
lives in `scripts/rtl/generate_memory_map.py`.
|
||||
- core contains self-owned Mini core wrappers.
|
||||
- dv contains behavioural testbench, device models, and Verilator harness
|
||||
sources.
|
||||
@@ -10,8 +14,10 @@ This directory is the active Mini SoC integration boundary.
|
||||
behavioral/synthesis Common source set; `netlist_support.fl` is the explicit
|
||||
allowlist of testbench dependencies not already present in a synthesized
|
||||
netlist.
|
||||
- mk contains simulator and software make fragments.
|
||||
- script contains filelist, address-map, conversion, and setup helpers.
|
||||
- mk contains Mini simulator and formal make fragments; shared firmware rules
|
||||
live in `rtl/mk/software.mk`.
|
||||
- script contains Mini filelist generation and simulator-binding helpers.
|
||||
Shared parsing/conversion helpers live in `scripts/rtl`.
|
||||
- top contains SoC integration RTL, including `apb4_system` for the APB4
|
||||
platform block and `apb4_periph` for the APB4 peripheral container.
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Canonical Address Map
|
||||
|
||||
memory_map.json is the sole source for Mini SoC address ranges. Its generator
|
||||
`memory_map.json` is the sole source for Mini SoC address ranges. The shared
|
||||
[generator](../../../scripts/rtl/generate_memory_map.py)
|
||||
emits RTL include definitions, SDK headers, linker memory regions, and the
|
||||
filelist include path into the selected build variant.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/clusterip/common/rtl/interface/ram_if.sv
|
||||
/top/rib_if.sv
|
||||
/clusterip/common/rtl/utils/register.sv
|
||||
/top/soc_common_fifo.sv
|
||||
/ip/util/soc_common_fifo.sv
|
||||
/clusterip/common/rtl/utils/spill_register.sv
|
||||
/clusterip/common/rtl/stream/round_robin_arbiter.sv
|
||||
/clusterip/common/rtl/utils/lfsr.sv
|
||||
@@ -20,7 +20,7 @@
|
||||
/clusterip/common/rtl/cdc/cdc_sync.sv
|
||||
/clusterip/common/rtl/cdc/cdc_rst_ctrlr.sv
|
||||
/clusterip/common/rtl/cdc/cdc_2phase.sv
|
||||
/top/soc_common_cdc.sv
|
||||
/ip/util/soc_common_cdc.sv
|
||||
/clusterip/common/rtl/clkrst/clk_int_div.sv
|
||||
/clusterip/common/rtl/clock/safe_clock_mux.sv
|
||||
/clusterip/common/rtl/clkrst/rst_sync.sv
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
+incdir+/clusterip/rtc/rtl
|
||||
+incdir+/clusterip/wdg/rtl
|
||||
+incdir+/clusterip/crc/rtl
|
||||
+incdir+/ip/core
|
||||
+incdir+/ip/interconnect
|
||||
+incdir+/ip/util
|
||||
+incdir+/ip/memory
|
||||
|
||||
+10
-10
@@ -1,11 +1,11 @@
|
||||
/top/apb4_if_bridge.sv
|
||||
/ip/interconnect/apb4_if_bridge.sv
|
||||
/top/apb4_async_bridge.sv
|
||||
/top/gpio_pad_bridge.sv
|
||||
/ip/peripheral/gpio_pad_bridge.sv
|
||||
/top/memory_pad_mux.sv
|
||||
/top/ribp2rib.sv
|
||||
/top/rib2ribp.sv
|
||||
/top/rib2apb.sv
|
||||
/top/axi4_connector.sv
|
||||
/ip/interconnect/axi4_connector.sv
|
||||
/top/axi4_master_idle.sv
|
||||
/top/axi4_mgmt_router.sv
|
||||
/top/axi4_async_bridge.sv
|
||||
@@ -18,9 +18,9 @@
|
||||
/top/fabric_monitor.sv
|
||||
/top/soc_data_plane.sv
|
||||
/top/data_plane_fault_cdc.sv
|
||||
/top/axi4_error_slave.sv
|
||||
/ip/interconnect/axi4_error_slave.sv
|
||||
/top/rib2axi4.sv
|
||||
/top/ahbl2axi4.sv
|
||||
/ip/interconnect/ahbl2axi4.sv
|
||||
/top/axi42apb4_system.sv
|
||||
/top/axi42apb4_periph.sv
|
||||
/top/axi4_word_bridge.sv
|
||||
@@ -33,8 +33,8 @@
|
||||
/top/retrosoc.sv
|
||||
/top/retrosoc_asic.sv
|
||||
/top/retrosoc_core.sv
|
||||
/top/onchip_ram_reg.sv
|
||||
/top/onchip_ram.sv
|
||||
/ip/memory/onchip_ram_reg.sv
|
||||
/ip/memory/onchip_ram.sv
|
||||
/top/resource_controller.sv
|
||||
/top/apb4_periph.sv
|
||||
/top/apb4_system.sv
|
||||
@@ -46,10 +46,10 @@
|
||||
/top/clock_frequency_monitor.sv
|
||||
/top/soc_clock_gate.sv
|
||||
/top/soc_clock_reset_subsystem.sv
|
||||
/top/mgmt_debug_reset.sv
|
||||
/ip/core/mgmt_debug_reset.sv
|
||||
/top/hp_lifecycle_controller.sv
|
||||
/top/mgmt_debug_wrapper.sv
|
||||
/top/mgmt_core_wrapper.sv
|
||||
/ip/core/mgmt_debug_wrapper.sv
|
||||
/ip/core/mgmt_core_wrapper.sv
|
||||
/top/hp_core_wrapper.sv
|
||||
/top/hp_subsystem.sv
|
||||
/top/user_core_design.sv
|
||||
|
||||
@@ -10,10 +10,9 @@ from pathlib import Path
|
||||
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
ROOT = SCRIPT_DIR.parents[2]
|
||||
FILELIST_DIR = ROOT / "rtl/mini/script"
|
||||
sys.path.insert(0, str(FILELIST_DIR))
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from filelist import FileList, write_filelist # noqa: E402
|
||||
from scripts.rtl.filelist import FileList, write_filelist # noqa: E402
|
||||
|
||||
|
||||
COMMON_RTL = ROOT / "rtl/managed/clusterip/common/rtl"
|
||||
@@ -249,8 +248,8 @@ def source_files(target: str) -> list[Path]:
|
||||
COMMON_RTL / "utils/register.sv",
|
||||
COMMON_RTL / "utils/xchecker.sv",
|
||||
ROOT / "rtl/tech/tc_sram.sv",
|
||||
TOP / "onchip_ram_reg.sv",
|
||||
TOP / "onchip_ram.sv",
|
||||
ROOT / "rtl/ip/memory/onchip_ram_reg.sv",
|
||||
ROOT / "rtl/ip/memory/onchip_ram.sv",
|
||||
SCRIPT_DIR / "onchip_ram_formal.sv",
|
||||
]
|
||||
if target == "opipsram":
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"reset": "s_jtag_trst_n_sync",
|
||||
"reset_source": "jtag_trst_n_i",
|
||||
"reset_primitive": "rst_sync",
|
||||
"path": "rtl/mini/top/mgmt_debug_wrapper.sv",
|
||||
"path": "rtl/ip/core/mgmt_debug_wrapper.sv",
|
||||
"instance": "u_jtag_rst_sync",
|
||||
"sta": {"source_port": "jtag_tck_i_pad", "object_type": "port", "period_ns": 100.0, "async_group": "jtag"}
|
||||
},
|
||||
|
||||
@@ -178,8 +178,8 @@ FORMAL_SOURCE_FILES := $(RTL_PATH)/formal/bus_formal.sv \
|
||||
$(ROOT_PATH)/rtl/ip/memory/psram_pkg.sv \
|
||||
$(ROOT_PATH)/rtl/ip/memory/psram_axi4.sv \
|
||||
$(ROOT_PATH)/rtl/ip/memory/psram_phy.sv \
|
||||
$(RTL_PATH)/top/onchip_ram_reg.sv \
|
||||
$(RTL_PATH)/top/onchip_ram.sv \
|
||||
$(ROOT_PATH)/rtl/ip/memory/onchip_ram_reg.sv \
|
||||
$(ROOT_PATH)/rtl/ip/memory/onchip_ram.sv \
|
||||
$(ROOT_PATH)/rtl/tech/tc_sram.sv \
|
||||
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/utils/register.sv \
|
||||
$(ROOT_PATH)/rtl/managed/clusterip/common/rtl/utils/xchecker.sv \
|
||||
@@ -242,11 +242,11 @@ $(FORMAL_DIR)/%/formal.fl: $(FORMAL_FILELIST_GENERATOR) $(FORMAL_SOURCE_FILES) \
|
||||
--memory-map-dir $(MEMORY_MAP_DIR) --soc-topology-dir $(SOC_TOPOLOGY_DIR) \
|
||||
--user-extensions-dir $(USER_EXTENSIONS_DIR)
|
||||
|
||||
$(FORMAL_DIR)/%/design.v: $(FORMAL_DIR)/%/formal.fl $(RTL_PATH)/script/convt_sv2v.py \
|
||||
$(RTL_PATH)/script/filelist.py $(FORMAL_SOURCE_FILES)
|
||||
$(FORMAL_DIR)/%/design.v: $(FORMAL_DIR)/%/formal.fl $(ROOT_PATH)/scripts/rtl/convt_sv2v.py \
|
||||
$(ROOT_PATH)/scripts/rtl/filelist.py $(FORMAL_SOURCE_FILES)
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool formal-sv2v \
|
||||
--log $(@D)/sv2v.log --result $(@D)/result-sv2v.json \
|
||||
-- python3 $(RTL_PATH)/script/convt_sv2v.py -f $< --output $@
|
||||
-- python3 $(ROOT_PATH)/scripts/rtl/convt_sv2v.py -f $< --output $@
|
||||
|
||||
$(FORMAL_DIR)/%/prove.sby: $(FORMAL_DIR)/%/design.v \
|
||||
$(FORMAL_SBY_GENERATOR)
|
||||
|
||||
@@ -36,8 +36,8 @@ IVERILOG_SIM_OPTS := +sim_timeout=$(RTL_SIM_TIMEOUT) +wave_$(WAVE)
|
||||
|
||||
$(CONVERTED_SOC): $(if $(filter MPW,$(MINI_MODE)),$(MPW_VARIANT_STAMP)) $(FILELIST_STAMP)
|
||||
@mkdir -p $(@D)
|
||||
python3 $(RTL_PATH)/script/convt_sv2v.py $(RTL_FLIST) --output $@
|
||||
python3 $(RTL_PATH)/script/filelist_deps.py $(RTL_FLIST) --target $@ \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/convt_sv2v.py $(RTL_FLIST) --output $@
|
||||
python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py $(RTL_FLIST) --target $@ \
|
||||
--output $(CONVERTED_DEPFILE)
|
||||
|
||||
$(IVERILOG_BEHV_FLIST): $(FILELIST_STAMP) $(CONVERTED_SOC) $(IVERILOG_FILELIST_GEN)
|
||||
@@ -88,7 +88,7 @@ $(IVERILOG_BEHV_SIMV): $(IVERILOG_BEHV_FLIST)
|
||||
--log $(IVERILOG_BEHV_DIR)/compile.log --result $(IVERILOG_BEHV_DIR)/result-compile.json \
|
||||
--cwd $(IVERILOG_BEHV_DIR) -- $(IVERILOG) $(IVERILOG_COMMON_OPTS) \
|
||||
$(IVERILOG_TIME_OPTS) -f $< -o simv -s $(RTL_TOP)
|
||||
python3 $(RTL_PATH)/script/filelist_deps.py -f $(IVERILOG_BEHV_FLIST) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py -f $(IVERILOG_BEHV_FLIST) \
|
||||
--target $@ --output $(IVERILOG_BEHV_DEPFILE)
|
||||
|
||||
$(IVERILOG_NETL_SIMV): $(IVERILOG_NETL_FLIST)
|
||||
@@ -97,7 +97,7 @@ $(IVERILOG_NETL_SIMV): $(IVERILOG_NETL_FLIST)
|
||||
--log $(IVERILOG_NETL_DIR)/compile.log --result $(IVERILOG_NETL_DIR)/result-compile.json \
|
||||
--cwd $(IVERILOG_NETL_DIR) -- $(IVERILOG) $(IVERILOG_COMMON_OPTS) \
|
||||
$(IVERILOG_TIME_OPTS) -f $< -o simv -s $(RTL_TOP)
|
||||
python3 $(RTL_PATH)/script/filelist_deps.py -f $(IVERILOG_NETL_FLIST) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py -f $(IVERILOG_NETL_FLIST) \
|
||||
--target $@ --output $(IVERILOG_NETL_DEPFILE)
|
||||
|
||||
$(IVERILOG_POST_SIMV): $(IVERILOG_POST_FLIST)
|
||||
@@ -106,7 +106,7 @@ $(IVERILOG_POST_SIMV): $(IVERILOG_POST_FLIST)
|
||||
--log $(IVERILOG_POST_DIR)/compile.log --result $(IVERILOG_POST_DIR)/result-compile.json \
|
||||
--cwd $(IVERILOG_POST_DIR) -- $(IVERILOG) $(IVERILOG_COMMON_OPTS) \
|
||||
$(IVERILOG_POST_OPTS) -f $< -o simv -s $(RTL_TOP) -s retrosoc_sdf_annotator
|
||||
python3 $(RTL_PATH)/script/filelist_deps.py -f $(IVERILOG_POST_FLIST) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py -f $(IVERILOG_POST_FLIST) \
|
||||
--target $@ --output $(IVERILOG_POST_DEPFILE)
|
||||
|
||||
comp: $(IVERILOG_BEHV_SIMV)
|
||||
@@ -114,7 +114,7 @@ netcomp: $(IVERILOG_NETL_SIMV)
|
||||
postcomp: $(IVERILOG_POST_SIMV)
|
||||
|
||||
sim: comp
|
||||
python3 $(RTL_PATH)/script/prepare_norflash.py --sim-dir $(IVERILOG_BEHV_DIR) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/prepare_norflash.py --sim-dir $(IVERILOG_BEHV_DIR) \
|
||||
--firmware $(SW_BUILD_DIR)/$(SIM_FIRMWARE_NAME).hex
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool iverilog-sim \
|
||||
--log $(IVERILOG_BEHV_DIR)/sim.log --result $(IVERILOG_BEHV_DIR)/result-sim.json \
|
||||
@@ -123,7 +123,7 @@ sim: comp
|
||||
--result $(IVERILOG_BEHV_DIR)/result-sim-check.json --require '$(SIM_SUCCESS_MARKER)'
|
||||
|
||||
netsim: netcomp
|
||||
python3 $(RTL_PATH)/script/prepare_norflash.py --sim-dir $(IVERILOG_NETL_DIR) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/prepare_norflash.py --sim-dir $(IVERILOG_NETL_DIR) \
|
||||
--firmware $(SW_BUILD_DIR)/$(SIM_FIRMWARE_NAME).hex
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool iverilog-sim \
|
||||
--log $(IVERILOG_NETL_DIR)/sim.log --result $(IVERILOG_NETL_DIR)/result-sim.json \
|
||||
@@ -132,7 +132,7 @@ netsim: netcomp
|
||||
--result $(IVERILOG_NETL_DIR)/result-sim-check.json --require '$(SIM_SUCCESS_MARKER)'
|
||||
|
||||
netsim-boot: netcomp
|
||||
python3 $(RTL_PATH)/script/prepare_norflash.py --sim-dir $(IVERILOG_NETL_DIR) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/prepare_norflash.py --sim-dir $(IVERILOG_NETL_DIR) \
|
||||
--firmware $(SW_BUILD_DIR)/$(SIM_FIRMWARE_NAME).hex
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool iverilog-sim \
|
||||
--log $(IVERILOG_NETL_DIR)/sim.log --result $(IVERILOG_NETL_DIR)/result-sim.json \
|
||||
@@ -142,7 +142,7 @@ netsim-boot: netcomp
|
||||
--result $(IVERILOG_NETL_DIR)/result-sim-check.json --require 'Hello retroSoC!'
|
||||
|
||||
postsim: postcomp
|
||||
python3 $(RTL_PATH)/script/prepare_norflash.py --sim-dir $(IVERILOG_POST_DIR) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/prepare_norflash.py --sim-dir $(IVERILOG_POST_DIR) \
|
||||
--firmware $(SW_BUILD_DIR)/$(SIM_FIRMWARE_NAME).hex
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool iverilog-sim \
|
||||
--log $(IVERILOG_POST_DIR)/sim.log --result $(IVERILOG_POST_DIR)/result-sim.json \
|
||||
|
||||
+2
-2
@@ -99,13 +99,13 @@ $(VCS_BEHV_SIMV) $(VCS_NETL_SIMV) $(VCS_POST_SIMV): $(MPW_VARIANT_DEP) $(FILELIS
|
||||
$(FLOW_PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool vcs --log $(DIR)/driver-compile.log \
|
||||
--result $(DIR)/result-compile.json --cwd $(DIR) -- \
|
||||
$(SIM_TOOL) $(COMMON_OPTS) $(OPTS) $(FLIST) -top $(RTL_TOP) $(COMP_LOG)
|
||||
$(FLOW_PYTHON) $(RTL_PATH)/script/filelist_deps.py $(DEPS_ARGS) --target $@ --output $(DEPFILE)
|
||||
$(FLOW_PYTHON) $(ROOT_PATH)/scripts/rtl/filelist_deps.py $(DEPS_ARGS) --target $@ --output $(DEPFILE)
|
||||
|
||||
$(VCS_NETL_SIMV): $(SYN_BUILD_ROOT)/out/retrosoc_asic_yosys.v
|
||||
$(VCS_POST_SIMV): $(ROOT_PATH)/physical/sdf/retrosoc_asic.v $(ROOT_PATH)/physical/sdf/retrosoc_asic_CTS_MIN.sdf.gz
|
||||
|
||||
sim netsim postsim:
|
||||
$(FLOW_PYTHON) $(RTL_PATH)/script/prepare_norflash.py --sim-dir $(DIR) \
|
||||
$(FLOW_PYTHON) $(ROOT_PATH)/scripts/rtl/prepare_norflash.py --sim-dir $(DIR) \
|
||||
--firmware $(SW_BUILD_DIR)/$(SIM_FIRMWARE_NAME).hex
|
||||
$(FLOW_PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool vcs-sim --stream-bytes \
|
||||
--log $(DIR)/driver-sim.log \
|
||||
|
||||
@@ -74,7 +74,7 @@ $(VERILATOR_STAMP): $(MPW_VARIANT_DEP) $(FILELIST_STAMP) $(VERILATOR_EXTRA_SOURC
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool verilator \
|
||||
--log $(BUILD_DIR)/verilating.log --result $(BUILD_DIR)/result-verilate.json \
|
||||
-- $(VERILATOR) $(VERILATOR_FLAGS)
|
||||
python3 $(RTL_PATH)/script/filelist_deps.py $(RTL_FLIST) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py $(RTL_FLIST) \
|
||||
$(foreach source,$(VERILATOR_EXTRA_SOURCES),--extra $(source)) \
|
||||
--target $@ --output $(VERILATOR_DEPFILE)
|
||||
@touch $@
|
||||
@@ -90,7 +90,7 @@ $(RTL_LINT_STAMP): $(MPW_VARIANT_DEP) $(FILELIST_STAMP) $(VERILATOR_EXTRA_SOURCE
|
||||
python3 $(ROOT_PATH)/scripts/run_flow.py --tool rtl-lint \
|
||||
--log $(RTL_LINT_DIR)/lint.log --result $(RTL_LINT_DIR)/result-rtl-lint.json \
|
||||
-- $(VERILATOR) $(RTL_LINT_FLAGS)
|
||||
python3 $(RTL_PATH)/script/filelist_deps.py $(RTL_FLIST) \
|
||||
python3 $(ROOT_PATH)/scripts/rtl/filelist_deps.py $(RTL_FLIST) \
|
||||
$(foreach source,$(VERILATOR_EXTRA_SOURCES),--extra $(source)) \
|
||||
--target $@ --output $(RTL_LINT_DEPFILE)
|
||||
@touch $@
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# Canonical SoC Pin Map
|
||||
|
||||
`pin_map.json` is the single source for the Mini SoC logical pad ABI and its
|
||||
ASIC, FPGA, Verilator, and RTL-testbench bindings. The generator emits
|
||||
ASIC, FPGA, Verilator, and RTL-testbench bindings. The shared
|
||||
[generator](../../../scripts/rtl/generate_pin_map.py) emits
|
||||
temporary SystemVerilog include files below the selected build variant; do not
|
||||
edit generated files.
|
||||
|
||||
|
||||
@@ -5,9 +5,12 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import gzip
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from filelist import atomic_write, parse_filelists, write_filelist
|
||||
REPO_ROOT = Path(__file__).resolve().parents[3]
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
from scripts.rtl.filelist import atomic_write, parse_filelists, write_filelist # noqa: E402
|
||||
|
||||
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
|
||||
@@ -4,9 +4,12 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from filelist import atomic_write
|
||||
REPO_ROOT = Path(__file__).resolve().parents[3]
|
||||
sys.path.insert(0, str(REPO_ROOT))
|
||||
from scripts.rtl.filelist import atomic_write # noqa: E402
|
||||
|
||||
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Shared RTL/SDK Build Rules
|
||||
|
||||
`software.mk` owns common compiler, linker and firmware artifact rules for Mini
|
||||
and Tiny. Product configuration and application source selection remain explicit.
|
||||
Both products include this canonical file directly. Changes require both
|
||||
product configuration tests, affected firmware builds, and SDK gates.
|
||||
@@ -142,6 +142,17 @@ CRT_SRCS := $(ROOT_PATH)/crt/arch/riscv/startup.S \
|
||||
$(ROOT_PATH)/crt/src/hal/user_ip.c \
|
||||
$(ROOT_PATH)/crt/src/hal/user_core.c
|
||||
|
||||
ifeq ($(SOC),TINY)
|
||||
DEF_VAL += -DRS_SOC_TINY
|
||||
CFLAGS += -DRS_SOC_TINY
|
||||
TINY_CRT_NAMES := startup.S clzsi2.c divdi3.c ffssi2.c udivdi3.c umoddi3.c \
|
||||
stdlib.c string.c console.c printf.c archinfo.c clint.c uart_math.c uart.c \
|
||||
gpio_math.c gpio.c timer_math.c timer.c pwm.c rtc.c wdg.c watchdog.c i2c_math.c i2c.c \
|
||||
dma_math.c dma.c onchip_sram.c xpi.c
|
||||
CRT_SRCS := $(foreach source,$(CRT_SRCS),$(if $(filter $(notdir $(source)),$(TINY_CRT_NAMES)),$(source)))
|
||||
CRT_SRCS += $(ROOT_PATH)/crt/src/hal/sysctrl.c
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_CSR),YES)
|
||||
CRT_SRCS += $(ROOT_PATH)/crt/arch/riscv/system_irq.S
|
||||
CRT_SRCS += $(ROOT_PATH)/crt/src/core/system_irq_handler.c
|
||||
@@ -154,7 +165,7 @@ APP_SRCS :=
|
||||
APP_INC_DIRS :=
|
||||
APP_CFLAGS :=
|
||||
APP_CRT_SRCS :=
|
||||
APP_MK := $(ROOT_PATH)/app/apps/$(APP)/app.mk
|
||||
APP_MK := $(ROOT_PATH)/app/apps/$(APP)/$(if $(filter TINY,$(SOC)),tiny.mk,app.mk)
|
||||
|
||||
ifeq ($(wildcard $(APP_MK)),)
|
||||
$(error Application profile not found: $(APP_MK))
|
||||
@@ -219,6 +230,11 @@ FORCE_VERSION:
|
||||
|
||||
upd_ver_info: $(VERSION_HEADER)
|
||||
|
||||
ifeq ($(SOC),TINY)
|
||||
asm: tiny-boot-image
|
||||
cp $(SW_BUILD_DIR)/tiny_boot.hex $(SW_BUILD_DIR)/$(ASM_FIRMWARE_NAME).hex
|
||||
cp $(SW_BUILD_DIR)/tiny_boot.bin $(SW_BUILD_DIR)/$(ASM_FIRMWARE_NAME).bin
|
||||
else
|
||||
asm: $(MPW_VARIANT_DEP) $(MEMORY_MAP_STAMP)
|
||||
@mkdir -p $(SW_BUILD_DIR)/asm
|
||||
$(MAKE) -C $(ROOT_PATH)/app/asm OUT_DIR=$(SW_BUILD_DIR)/asm \
|
||||
@@ -227,8 +243,10 @@ asm: $(MPW_VARIANT_DEP) $(MEMORY_MAP_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
|
||||
|
||||
endif
|
||||
|
||||
$(FIRMWARE_ELF): $(MPW_VARIANT_DEP) $(MEMORY_MAP_STAMP) $(SOC_TOPOLOGY_STAMP) $(SOC_IRQ_METADATA) $(USER_EXTENSIONS_STAMP) $(ARCHINFO_METADATA_STAMP) $(VERSION_HEADER) $(SRC_PATH) $(SW_HEADERS) $(LDS_PATH) \
|
||||
$(ROOT_PATH)/rtl/mini/mk/software.mk
|
||||
$(ROOT_PATH)/rtl/mk/software.mk $(APP_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
|
||||
@@ -5,7 +5,8 @@
|
||||
"name": "owned-rtl",
|
||||
"paths": [
|
||||
"rtl/ip",
|
||||
"rtl/mini/top"
|
||||
"rtl/mini/top",
|
||||
"rtl/tiny/top"
|
||||
],
|
||||
"status": "prototype",
|
||||
"baseline_revision": null,
|
||||
|
||||
+55
-45
@@ -96,12 +96,21 @@
|
||||
}
|
||||
],
|
||||
"inventory": {
|
||||
"rtl/ip/core": [
|
||||
"mgmt_core_wrapper.sv",
|
||||
"mgmt_debug_reset.sv",
|
||||
"mgmt_debug_wrapper.sv"
|
||||
],
|
||||
"rtl/ip/experimental": [
|
||||
"apb4_gpu.sv",
|
||||
"axi4f2ribp.sv",
|
||||
"wb2ribp.sv"
|
||||
],
|
||||
"rtl/ip/interconnect": [
|
||||
"ahbl2axi4.sv",
|
||||
"apb4_if_bridge.sv",
|
||||
"axi4_connector.sv",
|
||||
"axi4_error_slave.sv",
|
||||
"axi4l2ribp.sv",
|
||||
"ribp2ribp.sv",
|
||||
"ribp_regslice.sv"
|
||||
@@ -110,6 +119,9 @@
|
||||
"apb4_opipsram.sv",
|
||||
"apb4_psram.sv",
|
||||
"axi4_sdram.sv",
|
||||
"onchip_ram.sv",
|
||||
"onchip_ram_define.svh",
|
||||
"onchip_ram_reg.sv",
|
||||
"opipsram_axi4.sv",
|
||||
"opipsram_core.sv",
|
||||
"opipsram_define.svh",
|
||||
@@ -125,11 +137,11 @@
|
||||
"psram_phy.sv",
|
||||
"psram_pkg.sv",
|
||||
"psram_reg.sv",
|
||||
"sdram_axi4.sv",
|
||||
"sdram_clkgen.sv",
|
||||
"sdram_core.sv",
|
||||
"sdram_define.svh",
|
||||
"sdram_pkg.sv",
|
||||
"sdram_axi4.sv",
|
||||
"sdram_reg.sv"
|
||||
],
|
||||
"rtl/ip/multimedia": [
|
||||
@@ -142,8 +154,8 @@
|
||||
"apu_codec_sequencer.sv",
|
||||
"apu_codec_transport.sv",
|
||||
"apu_control_store.sv",
|
||||
"apu_dma.sv",
|
||||
"apu_define.svh",
|
||||
"apu_dma.sv",
|
||||
"apu_entropy_engine.sv",
|
||||
"apu_kernel_engine.sv",
|
||||
"apu_kws_apum_profile.svh",
|
||||
@@ -159,9 +171,9 @@
|
||||
"apu_primitive_dispatcher.sv",
|
||||
"apu_proof_memo.sv",
|
||||
"apu_reconstruction_engine.sv",
|
||||
"apu_reg.sv",
|
||||
"apu_resampler.sv",
|
||||
"apu_ring_scheduler.sv",
|
||||
"apu_reg.sv",
|
||||
"apu_stream_router.sv",
|
||||
"apu_transform_engine.sv",
|
||||
"axi4s_dvp.sv",
|
||||
@@ -171,8 +183,8 @@
|
||||
"ga2d_addr_gen.sv",
|
||||
"ga2d_axi4_master.sv",
|
||||
"ga2d_core.sv",
|
||||
"ga2d_dma.sv",
|
||||
"ga2d_define.svh",
|
||||
"ga2d_dma.sv",
|
||||
"ga2d_pixel.sv",
|
||||
"ga2d_pkg.sv",
|
||||
"ga2d_reg.sv",
|
||||
@@ -217,7 +229,6 @@
|
||||
],
|
||||
"rtl/ip/peripheral": [
|
||||
"apb4_clint.sv",
|
||||
"clock_ctrl_if.sv",
|
||||
"apb4_dma.sv",
|
||||
"apb4_gpio.sv",
|
||||
"apb4_hp_mailbox.sv",
|
||||
@@ -229,6 +240,7 @@
|
||||
"clint_if.sv",
|
||||
"clint_reg.sv",
|
||||
"clint_timebase.sv",
|
||||
"clock_ctrl_if.sv",
|
||||
"dma_axi4_master.sv",
|
||||
"dma_core.sv",
|
||||
"dma_define.svh",
|
||||
@@ -238,6 +250,7 @@
|
||||
"gpio_core.sv",
|
||||
"gpio_define.svh",
|
||||
"gpio_if.sv",
|
||||
"gpio_pad_bridge.sv",
|
||||
"gpio_reg.sv",
|
||||
"hp_mailbox_define.svh",
|
||||
"pll_ctrl_if.sv",
|
||||
@@ -250,6 +263,17 @@
|
||||
"timer_reg.sv",
|
||||
"user_gpio_if.sv"
|
||||
],
|
||||
"rtl/ip/security": [
|
||||
"apb4_crypto.sv",
|
||||
"crypto_aes_core.sv",
|
||||
"crypto_aes_engine.sv",
|
||||
"crypto_define.svh",
|
||||
"crypto_montgomery.sv",
|
||||
"crypto_pkg.sv",
|
||||
"crypto_rsa_core.sv",
|
||||
"crypto_sha2_core.sv",
|
||||
"crypto_sha2_engine.sv"
|
||||
],
|
||||
"rtl/ip/serial": [
|
||||
"apb4_i2c.sv",
|
||||
"apb4_i2c_define.svh",
|
||||
@@ -280,17 +304,6 @@
|
||||
"ws2812_if.sv",
|
||||
"ws2812_reg.sv"
|
||||
],
|
||||
"rtl/ip/security": [
|
||||
"apb4_crypto.sv",
|
||||
"crypto_aes_core.sv",
|
||||
"crypto_aes_engine.sv",
|
||||
"crypto_define.svh",
|
||||
"crypto_montgomery.sv",
|
||||
"crypto_pkg.sv",
|
||||
"crypto_rsa_core.sv",
|
||||
"crypto_sha2_core.sv",
|
||||
"crypto_sha2_engine.sv"
|
||||
],
|
||||
"rtl/ip/storage": [
|
||||
"apb4_sdio.sv",
|
||||
"apb4_spisd.sv",
|
||||
@@ -324,9 +337,6 @@
|
||||
"xpi_pkg.sv",
|
||||
"xpi_reg.sv"
|
||||
],
|
||||
"rtl/ip/util": [
|
||||
"async_fifo.sv"
|
||||
],
|
||||
"rtl/ip/usb": [
|
||||
"apb4_usb2.sv",
|
||||
"usb2_define.svh",
|
||||
@@ -345,53 +355,49 @@
|
||||
"usb2_ulpi_if.sv",
|
||||
"usb2_ulpi_link.sv"
|
||||
],
|
||||
"rtl/ip/util": [
|
||||
"async_fifo.sv",
|
||||
"soc_common_cdc.sv",
|
||||
"soc_common_fifo.sv"
|
||||
],
|
||||
"rtl/mini/top": [
|
||||
"ahbl2axi4.sv",
|
||||
"ahbl2ribp.sv",
|
||||
"apb4_if_bridge.sv",
|
||||
"apb4_async_bridge.sv",
|
||||
"apb4_periph.sv",
|
||||
"apb4_system.sv",
|
||||
"axi42apb4_system.sv",
|
||||
"axi42apb4.svh",
|
||||
"axi42apb4_periph.sv",
|
||||
"axi42apb4_state.svh",
|
||||
"axi42apb4_system.sv",
|
||||
"axi42ram.sv",
|
||||
"axi42ribp.sv",
|
||||
"axi42ribp_burst.sv",
|
||||
"axi4_bus.sv",
|
||||
"axi4_address_gate.sv",
|
||||
"axi4_async_bridge.sv",
|
||||
"axi4_connector.sv",
|
||||
"axi4_bus.sv",
|
||||
"axi4_data_crossbar.sv",
|
||||
"axi4_target_guard.sv",
|
||||
"axi4_downsizer_64to32.sv",
|
||||
"axi4_error_slave.sv",
|
||||
"axi4_id_prefix.sv",
|
||||
"axi4_interconnect.sv",
|
||||
"axi4_master_idle.sv",
|
||||
"axi4_mgmt_router.sv",
|
||||
"axi4_target_guard.sv",
|
||||
"axi4_upsizer_32to64.sv",
|
||||
"axi4_word_bridge.sv",
|
||||
"core_wrapper.sv",
|
||||
"clock_config_controller.sv",
|
||||
"clock_frequency_monitor.sv",
|
||||
"core_wrapper.sv",
|
||||
"data_plane_fault_cdc.sv",
|
||||
"extension_compat.sv",
|
||||
"extension_dma_master.sv",
|
||||
"extension_slot.sv",
|
||||
"extension_subsystem.sv",
|
||||
"fabric_monitor.sv",
|
||||
"gpio_pad_bridge.sv",
|
||||
"hp_axi4_mux3.sv",
|
||||
"hp_core_wrapper.sv",
|
||||
"hp_subsystem.sv",
|
||||
"hp_lifecycle_controller.sv",
|
||||
"mgmt_core_wrapper.sv",
|
||||
"mgmt_debug_reset.sv",
|
||||
"mgmt_debug_wrapper.sv",
|
||||
"hp_subsystem.sv",
|
||||
"memory_pad_mux.sv",
|
||||
"onchip_ram_define.svh",
|
||||
"onchip_ram_reg.sv",
|
||||
"onchip_ram.sv",
|
||||
"pll_rcu_controller.sv",
|
||||
"rcu.sv",
|
||||
"resource_controller.sv",
|
||||
@@ -412,24 +418,28 @@
|
||||
"soc_clock_config.svh",
|
||||
"soc_clock_gate.sv",
|
||||
"soc_clock_reset_subsystem.sv",
|
||||
"soc_common_cdc.sv",
|
||||
"soc_common_fifo.sv",
|
||||
"soc_data_plane.sv",
|
||||
"user_core_design.sv",
|
||||
"user_core_top.sv",
|
||||
"user_extensions.svh",
|
||||
"user_ip_design_template.sv",
|
||||
"user_ip_top.sv",
|
||||
"user_ip_wrapper.sv",
|
||||
"axi42apb4.svh",
|
||||
"axi42apb4_state.svh"
|
||||
"user_ip_wrapper.sv"
|
||||
],
|
||||
"rtl/tiny/top": [
|
||||
"retrosoc_tiny.sv",
|
||||
"retrosoc_tiny_asic.sv",
|
||||
"tiny_archinfo.sv",
|
||||
"tiny_axi42apb4.sv",
|
||||
"tiny_axi4_fabric.sv",
|
||||
"tiny_sysctrl.sv"
|
||||
]
|
||||
},
|
||||
"reviewed_boundaries": [
|
||||
{
|
||||
"paths": [
|
||||
"rtl/ip/experimental/axi4f2ribp.sv",
|
||||
"rtl/ip/experimental/apb4_gpu.sv",
|
||||
"rtl/ip/experimental/axi4f2ribp.sv",
|
||||
"rtl/ip/experimental/wb2ribp.sv"
|
||||
],
|
||||
"result": "inactive experimental source",
|
||||
@@ -471,16 +481,16 @@
|
||||
},
|
||||
{
|
||||
"paths": [
|
||||
"rtl/mini/top/onchip_ram.sv",
|
||||
"rtl/mini/top/onchip_ram_reg.sv"
|
||||
"rtl/ip/memory/onchip_ram.sv",
|
||||
"rtl/ip/memory/onchip_ram_reg.sv"
|
||||
],
|
||||
"result": "reviewed AXI and technology-memory boundary",
|
||||
"rationale": "AXI and APB state uses Common registers; the synchronous bank array retains the stable technology wrapper and PDK SRAM pin boundary."
|
||||
},
|
||||
{
|
||||
"paths": [
|
||||
"rtl/mini/top/soc_common_cdc.sv",
|
||||
"rtl/mini/top/soc_common_fifo.sv"
|
||||
"rtl/ip/util/soc_common_cdc.sv",
|
||||
"rtl/ip/util/soc_common_fifo.sv"
|
||||
],
|
||||
"result": "managed compatibility wrapper retained",
|
||||
"rationale": "The narrow self-owned wrappers preserve required Verilator filename behavior while including managed Common source."
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
"owned": {
|
||||
"roots": [
|
||||
"rtl/ip",
|
||||
"rtl/mini/top"
|
||||
"rtl/mini/top",
|
||||
"rtl/tiny/top"
|
||||
],
|
||||
"suffixes": [
|
||||
".sv",
|
||||
@@ -18,7 +19,8 @@
|
||||
"verification": {
|
||||
"roots": [
|
||||
"rtl/mini/formal",
|
||||
"rtl/mini/dv"
|
||||
"rtl/mini/dv",
|
||||
"rtl/tiny/dv"
|
||||
],
|
||||
"suffixes": [
|
||||
".sv",
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
export CCACHE_DIR := $(CACHE_ROOT)/ccache/verilator
|
||||
export CCACHE_TEMPDIR := $(CACHE_ROOT)/ccache/verilator/tmp
|
||||
|
||||
TINY_GENERATED_DIR := $(VARIANT_ROOT)/generated/tiny
|
||||
GENERATED_FL_DIR := $(FLOW_FILELIST_DIR)
|
||||
FILELIST_STAMP := $(GENERATED_FL_DIR)/.stamp
|
||||
MEMORY_MAP_DIR := $(TINY_GENERATED_DIR)/memory_map
|
||||
MEMORY_MAP_C_DIR := $(MEMORY_MAP_DIR)/include
|
||||
MEMORY_MAP_LINKER_DIR := $(MEMORY_MAP_DIR)/linker
|
||||
MEMORY_MAP_STAMP := $(FILELIST_STAMP)
|
||||
PIN_MAP_DIR := $(TINY_GENERATED_DIR)/pin_map
|
||||
SOC_TOPOLOGY_INCLUDE_DIR := $(TINY_GENERATED_DIR)/include
|
||||
SOC_TOPOLOGY_STAMP := $(FILELIST_STAMP)
|
||||
SOC_IRQ_METADATA := $(SOC_TOPOLOGY_INCLUDE_DIR)/retrosoc/generated/irq_metadata.h
|
||||
USER_EXTENSIONS_DIR := $(TINY_GENERATED_DIR)
|
||||
USER_EXTENSIONS_STAMP := $(FILELIST_STAMP)
|
||||
ARCHINFO_METADATA_DIR := $(TINY_GENERATED_DIR)/archinfo
|
||||
ARCHINFO_METADATA_SCRIPT := $(ROOT_PATH)/rtl/managed/clusterip/archinfo/scripts/generate_metadata.py
|
||||
ARCHINFO_METADATA_STAMP := $(ARCHINFO_METADATA_DIR)/.stamp
|
||||
TINY_MAPS := $(wildcard $(RTL_PATH)/address_map/*.json $(RTL_PATH)/pin_map/*.json $(RTL_PATH)/integration/*.json)
|
||||
TINY_TEMPLATES := $(wildcard $(RTL_PATH)/filelist/*.fl)
|
||||
TINY_TOOLS := $(ROOT_PATH)/scripts/generate_tiny.py $(wildcard $(ROOT_PATH)/scripts/rtl/*.py)
|
||||
|
||||
$(ARCHINFO_METADATA_STAMP): $(LOCK_FILE) $(wildcard $(ARCHINFO_METADATA_SCRIPT))
|
||||
@test -f $(ARCHINFO_METADATA_SCRIPT) || { echo "Run Tiny setup first" >&2; exit 1; }
|
||||
$(PYTHON) $(ARCHINFO_METADATA_SCRIPT) --repo-root $(ROOT_PATH) --lock $(LOCK_FILE) \
|
||||
--config-digest $(CONFIG_DIGEST) $(if $(filter YES,$(BUILD_RELEASE)),--release) \
|
||||
--output-sv $(ARCHINFO_METADATA_DIR)/archinfo_integration_metadata.svh \
|
||||
--output-c $(ARCHINFO_METADATA_DIR)/archinfo_integration_metadata.h
|
||||
@touch $@
|
||||
|
||||
$(FILELIST_STAMP): $(ROOT_PATH)/Makefile $(RTL_PATH)/Makefile $(TINY_MAPS) $(TINY_TEMPLATES) $(TINY_TOOLS) $(ARCHINFO_METADATA_STAMP)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/generate_tiny.py --output $(TINY_GENERATED_DIR) \
|
||||
--filelists $(GENERATED_FL_DIR) $(foreach define,$(DEF_LIST),--define $(define))
|
||||
@touch $@
|
||||
|
||||
$(SOC_IRQ_METADATA): $(FILELIST_STAMP)
|
||||
@test -f $@
|
||||
|
||||
generate_filelist memory-map pin-map soc-topology user-extensions: $(FILELIST_STAMP)
|
||||
archinfo-metadata: $(ARCHINFO_METADATA_STAMP)
|
||||
check-memory-map:
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/rtl/generate_memory_map.py --map $(RTL_PATH)/address_map/memory_map.json --check
|
||||
check-pin-map:
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/rtl/generate_pin_map.py --map $(RTL_PATH)/pin_map/pin_map.json --check
|
||||
check-soc-topology:
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/generate_tiny.py --check
|
||||
check-clock-reset-domains:
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/check_clock_reset_domains.py --map $(RTL_PATH)/integration/clock_reset_domains.json --root $(ROOT_PATH)
|
||||
|
||||
RTL_FILELISTS := $(addprefix $(GENERATED_FL_DIR)/,def.fl inc.fl commonip.fl clusterip.fl ip.fl tech.fl core_hazard3.fl top.fl)
|
||||
RTL_FLIST := $(foreach filelist,$(RTL_FILELISTS),-f $(filelist))
|
||||
PDK_FILELIST := $(GENERATED_FL_DIR)/pdk_ihp130.fl
|
||||
TINY_TB_FLIST := -f $(GENERATED_FL_DIR)/tb.fl
|
||||
TOP_DESIGN := retrosoc_tiny_asic
|
||||
RTL_NAME := retrosoc_tiny_asic
|
||||
OPENSTA_NETLIST := $(SYN_BUILD_ROOT)/out/$(RTL_NAME)_yosys.v
|
||||
OPENSTA_CONFIG := $(SYN_BUILD_ROOT)/out/$(RTL_NAME)_yosys.config
|
||||
NETLIST_PATH := $(OPENSTA_NETLIST)
|
||||
TINY_CONVERTED := $(SIM_BUILD_ROOT)/converted_soc.v
|
||||
TINY_DEPFILE := $(SIM_BUILD_ROOT)/sources.d
|
||||
TINY_LINT_LOG := $(VARIANT_ROOT)/lint/verilator/lint.log
|
||||
SOC_SIM_TIME ?= 1800
|
||||
TINY_SIM_TIMEOUT ?= 20000000
|
||||
VERILATOR ?= verilator
|
||||
IVERILOG ?= iverilog
|
||||
VVP ?= vvp
|
||||
|
||||
include $(ROOT_PATH)/rtl/mk/software.mk
|
||||
-include $(TINY_DEPFILE)
|
||||
|
||||
$(TINY_CONVERTED): $(FILELIST_STAMP)
|
||||
@mkdir -p $(@D)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/rtl/convt_sv2v.py $(RTL_FLIST) --output $@
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/rtl/filelist_deps.py $(RTL_FLIST) \
|
||||
--target $@ --output $(TINY_DEPFILE)
|
||||
|
||||
ifeq ($(SIMU),VERILATOR)
|
||||
$(SIM_BUILD_ROOT)/emu: $(FILELIST_STAMP) $(wildcard $(RTL_PATH)/dv/*.sv)
|
||||
@mkdir -p $(SIM_BUILD_ROOT) $(CCACHE_TEMPDIR)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool verilator \
|
||||
--log $(SIM_BUILD_ROOT)/compile.log --result $(SIM_BUILD_ROOT)/result-compile.json -- \
|
||||
$(VERILATOR) --binary --timing --assert -j $(JOBS) --top-module $(RTL_TOP) \
|
||||
-Wno-fatal --timescale 1ns/1ps --Mdir $(SIM_BUILD_ROOT)/obj_dir -o $(SIM_BUILD_ROOT)/emu \
|
||||
$(RTL_FLIST) -f $(PDK_FILELIST) $(TINY_TB_FLIST)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/rtl/filelist_deps.py $(RTL_FLIST) $(TINY_TB_FLIST) \
|
||||
--target $@ --output $(TINY_DEPFILE)
|
||||
comp: $(SIM_BUILD_ROOT)/emu
|
||||
TINY_RUN := timeout --foreground $(SOC_SIM_TIME)s $(SIM_BUILD_ROOT)/emu
|
||||
else
|
||||
$(SIM_BUILD_ROOT)/simv: $(TINY_CONVERTED) $(wildcard $(RTL_PATH)/dv/*.sv)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool iverilog \
|
||||
--log $(SIM_BUILD_ROOT)/compile.log --result $(SIM_BUILD_ROOT)/result-compile.json -- \
|
||||
$(IVERILOG) -g2012 -gno-specify -s $(RTL_TOP) -o $@ -f $(GENERATED_FL_DIR)/def.fl \
|
||||
-f $(GENERATED_FL_DIR)/inc.fl -f $(PDK_FILELIST) $(TINY_TB_FLIST) $(TINY_CONVERTED)
|
||||
comp: $(SIM_BUILD_ROOT)/simv
|
||||
TINY_RUN := $(VVP) $(SIM_BUILD_ROOT)/simv
|
||||
endif
|
||||
|
||||
rtl-lint: $(FILELIST_STAMP) | manifest
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool rtl-lint \
|
||||
--log $(TINY_LINT_LOG) --result $(VARIANT_ROOT)/lint/verilator/result-rtl-lint.json -- \
|
||||
$(VERILATOR) --lint-only --timing --assert --timescale 1ns/1ps --Wall -Wno-fatal \
|
||||
--top-module retrosoc_tiny_asic $(RTL_FLIST) -f $(PDK_FILELIST)
|
||||
check-rtl-lint: rtl-lint
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/analyze_warnings.py check --root $(ROOT_PATH) \
|
||||
--profile $(PROFILE_NAME) --variant-root $(VARIANT_ROOT) --tool rtl-lint \
|
||||
--output $(META_DIR)/rtl-lint-warnings.json
|
||||
|
||||
sim: comp firmware | manifest
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool $(SIM_TOOL_NAME)-sim \
|
||||
--log $(SIM_BUILD_ROOT)/sim.log --result $(SIM_BUILD_ROOT)/result-sim.json -- \
|
||||
$(TINY_RUN) +firmware=$(SW_BUILD_DIR)/$(SIM_FIRMWARE_NAME).hex +max_cycles=$(TINY_SIM_TIMEOUT)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/check_simulation.py --log $(SIM_BUILD_ROOT)/sim.log \
|
||||
--result $(SIM_BUILD_ROOT)/result-sim-check.json --require '$(SIM_SUCCESS_MARKER)'
|
||||
|
||||
netcomp: $(FILELIST_STAMP)
|
||||
@mkdir -p $(NETLIST_SIM_ROOT)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool iverilog \
|
||||
--log $(NETLIST_SIM_ROOT)/compile.log --result $(NETLIST_SIM_ROOT)/result-compile.json -- \
|
||||
$(IVERILOG) -g2012 -gno-specify -DRETROSOC_SOC__TINY_NETLIST -s $(RTL_TOP) -o $(NETLIST_SIM_ROOT)/simv \
|
||||
-f $(GENERATED_FL_DIR)/def.fl -f $(GENERATED_FL_DIR)/inc.fl -f $(PDK_FILELIST) \
|
||||
$(TINY_TB_FLIST) $(NETLIST_PATH)
|
||||
netsim: netcomp firmware | manifest
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool iverilog-sim \
|
||||
--log $(NETLIST_SIM_ROOT)/sim.log --result $(NETLIST_SIM_ROOT)/result-sim.json -- \
|
||||
$(VVP) $(NETLIST_SIM_ROOT)/simv +firmware=$(SW_BUILD_DIR)/$(SIM_FIRMWARE_NAME).hex +max_cycles=$(TINY_SIM_TIMEOUT)
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/check_simulation.py --log $(NETLIST_SIM_ROOT)/sim.log \
|
||||
--result $(NETLIST_SIM_ROOT)/result-sim-check.json --require '$(SIM_SUCCESS_MARKER)'
|
||||
|
||||
.PHONY: generate_filelist memory-map pin-map soc-topology user-extensions archinfo-metadata \
|
||||
check-memory-map check-pin-map check-soc-topology check-clock-reset-domains comp sim \
|
||||
rtl-lint check-rtl-lint netcomp netsim netsim-boot
|
||||
|
||||
TINY_BOOT_ELF := $(SW_BUILD_DIR)/tiny_boot.elf
|
||||
$(TINY_BOOT_ELF): $(ROOT_PATH)/app/asm/tiny_boot.S $(FILELIST_STAMP)
|
||||
@mkdir -p $(SW_BUILD_DIR)
|
||||
$(CC) -march=rv32im_zicsr -mabi=ilp32 -nostdlib -I$(MEMORY_MAP_C_DIR) -I$(SOC_TOPOLOGY_INCLUDE_DIR) \
|
||||
-Wl,-Ttext=0x0,--entry=_start,--build-id=none -o $@ $<
|
||||
$(OBJC) -O verilog $@ $(SW_BUILD_DIR)/tiny_boot.hex
|
||||
$(OBJC) -O binary $@ $(SW_BUILD_DIR)/tiny_boot.bin
|
||||
|
||||
tiny-boot-image: $(TINY_BOOT_ELF)
|
||||
netsim-boot: netcomp tiny-boot-image | manifest
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/run_flow.py --tool iverilog-sim \
|
||||
--log $(NETLIST_SIM_ROOT)/sim.log --result $(NETLIST_SIM_ROOT)/result-sim.json -- \
|
||||
$(VVP) $(NETLIST_SIM_ROOT)/simv +firmware=$(SW_BUILD_DIR)/tiny_boot.hex +max_cycles=100000
|
||||
$(PYTHON) $(ROOT_PATH)/scripts/check_simulation.py --log $(NETLIST_SIM_ROOT)/sim.log \
|
||||
--result $(NETLIST_SIM_ROOT)/result-sim-check.json --require 'SIM_TEST_PASS'
|
||||
|
||||
.PHONY: tiny-boot-image
|
||||
@@ -0,0 +1,27 @@
|
||||
# Tiny MCU Integration
|
||||
|
||||
Tiny is the independent single-Hazard3 wired MCU product. Its frozen contract
|
||||
is [Tiny MCU](../../docs/ip/tiny-soc.md). Use
|
||||
`make CONFIG=configs/ci/ihp130-tiny.mk setup` followed by
|
||||
`make CONFIG=configs/ci/ihp130-tiny.mk firmware sim`.
|
||||
|
||||
`top` owns product integration, `address_map`, `pin_map` and `integration` own
|
||||
canonical address, pad, IRQ and clock/reset inputs, `filelist` selects sources,
|
||||
`dv` owns product verification, and `mk` owns product configuration. Reusable
|
||||
RTL lives in `rtl/ip`; Common and Hazard3 remain locked managed inputs.
|
||||
No Tiny source list includes RIB/RIBP or Mini product RTL. Build rules invoke
|
||||
shared helpers in `scripts/rtl` directly; generated files belong only under
|
||||
the selected build variant.
|
||||
|
||||
The initial IHP130 profile has 128 KiB SRAM, 24 MHz AXI32/APB4, four DMA channels,
|
||||
and RV32IMC without atomics. Wireless, external RAM, HP cores and accelerators
|
||||
are outside this release. Run both Icarus and Verilator, the Tiny directed
|
||||
tests, and the IHP130 regression before claiming qualification. Synthesis and
|
||||
STA use the Tiny top and clock inventory, not Mini constraints.
|
||||
|
||||
`make CONFIG=configs/ci/ihp130-tiny.mk regress-pr` runs only Tiny's IHP130
|
||||
matrix. The regression runner also accepts `--soc TINY`; leaving it unset
|
||||
retains the combined Mini/Tiny IHP130 matrix. `netsim-boot` uses the compact
|
||||
assembly SRAM/pad test, while `netsim` uses the full SDK acceptance image.
|
||||
See the [verification record](../../docs/ip/tiny-soc-verification.md) for
|
||||
qualification boundaries and the observed reset-distribution timing deficit.
|
||||
@@ -0,0 +1,406 @@
|
||||
{
|
||||
"schema_version": 2,
|
||||
"cpu_reset": "0x00000000",
|
||||
"sysctrl_registers": [
|
||||
{
|
||||
"symbol": "CORESEL",
|
||||
"offset": "0x00"
|
||||
},
|
||||
{
|
||||
"symbol": "IPSEL",
|
||||
"offset": "0x04"
|
||||
},
|
||||
{
|
||||
"symbol": "PLL_CFG",
|
||||
"offset": "0x08"
|
||||
},
|
||||
{
|
||||
"symbol": "PLL_CMD",
|
||||
"offset": "0x0C"
|
||||
},
|
||||
{
|
||||
"symbol": "FAULT_STATUS",
|
||||
"offset": "0x10"
|
||||
},
|
||||
{
|
||||
"symbol": "FAULT_ADDR",
|
||||
"offset": "0x14"
|
||||
},
|
||||
{
|
||||
"symbol": "FAULT_COUNT",
|
||||
"offset": "0x18"
|
||||
},
|
||||
{
|
||||
"symbol": "PLL_STATUS",
|
||||
"offset": "0x1C"
|
||||
},
|
||||
{
|
||||
"symbol": "USER_CORE_RESET",
|
||||
"offset": "0x20"
|
||||
},
|
||||
{
|
||||
"symbol": "USER_CORE_STATUS",
|
||||
"offset": "0x24"
|
||||
},
|
||||
{
|
||||
"symbol": "FAULT_MASTER",
|
||||
"offset": "0x28"
|
||||
},
|
||||
{
|
||||
"symbol": "FAULT_DETAIL",
|
||||
"offset": "0x2C"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_CTRL",
|
||||
"offset": "0x40"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_MGMT_WAIT_LO",
|
||||
"offset": "0x44"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_MGMT_WAIT_HI",
|
||||
"offset": "0x48"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_USER_WAIT_LO",
|
||||
"offset": "0x4C"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_USER_WAIT_HI",
|
||||
"offset": "0x50"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_DMA_WAIT_LO",
|
||||
"offset": "0x54"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_DMA_WAIT_HI",
|
||||
"offset": "0x58"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_APB4_PERIPH_WAIT_LO",
|
||||
"offset": "0x5C"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_APB4_PERIPH_WAIT_HI",
|
||||
"offset": "0x60"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_APB4_SYSTEM_WAIT_LO",
|
||||
"offset": "0x64"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_APB4_SYSTEM_WAIT_HI",
|
||||
"offset": "0x68"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_SDRAM_WAIT_LO",
|
||||
"offset": "0x6C"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_SDRAM_WAIT_HI",
|
||||
"offset": "0x70"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_PSRAM_WAIT_LO",
|
||||
"offset": "0x74"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_PSRAM_WAIT_HI",
|
||||
"offset": "0x78"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_FLASH_WAIT_LO",
|
||||
"offset": "0x7C"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_FLASH_WAIT_HI",
|
||||
"offset": "0x80"
|
||||
},
|
||||
{
|
||||
"symbol": "TEST_STATUS",
|
||||
"offset": "0x84"
|
||||
},
|
||||
{
|
||||
"symbol": "RTC_WAKE_STATUS",
|
||||
"offset": "0x88"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_SDIO0_WAIT_LO",
|
||||
"offset": "0x8C"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_SDIO0_WAIT_HI",
|
||||
"offset": "0x90"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_SDIO1_WAIT_LO",
|
||||
"offset": "0x94"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_SDIO1_WAIT_HI",
|
||||
"offset": "0x98"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_USB2_WAIT_LO",
|
||||
"offset": "0x9C"
|
||||
},
|
||||
{
|
||||
"symbol": "PERF_USB2_WAIT_HI",
|
||||
"offset": "0xA0"
|
||||
},
|
||||
{
|
||||
"symbol": "HP_CTRL",
|
||||
"offset": "0xA4"
|
||||
},
|
||||
{
|
||||
"symbol": "HP_STATUS",
|
||||
"offset": "0xA8"
|
||||
},
|
||||
{
|
||||
"symbol": "DEBUG_SELECT",
|
||||
"offset": "0xAC"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_HP_REQ",
|
||||
"offset": "0xB0"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_HP_CURRENT",
|
||||
"offset": "0xB4"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_LP_CFG",
|
||||
"offset": "0xB8"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_PCLK_CFG",
|
||||
"offset": "0xBC"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_STATUS",
|
||||
"offset": "0xC0"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_FAULT",
|
||||
"offset": "0xC4"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_TIMEOUT",
|
||||
"offset": "0xC8"
|
||||
},
|
||||
{
|
||||
"symbol": "CLK_GATE",
|
||||
"offset": "0xCC"
|
||||
},
|
||||
{
|
||||
"symbol": "MEM_PAD_CTRL",
|
||||
"offset": "0xD0"
|
||||
},
|
||||
{
|
||||
"symbol": "MEM_PAD_STATUS",
|
||||
"offset": "0xD4"
|
||||
},
|
||||
{
|
||||
"symbol": "MEM_PAD_FAULT",
|
||||
"offset": "0xD8"
|
||||
}
|
||||
],
|
||||
"regions": [
|
||||
{
|
||||
"symbol": "FLASH",
|
||||
"base": "0x00000000",
|
||||
"size": "0x01000000",
|
||||
"route": "axi4",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"linker": "FLASH",
|
||||
"user_access": "ro",
|
||||
"burst": "incr16"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_GPIO",
|
||||
"base": "0x10000000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_UART0",
|
||||
"base": "0x10001000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_TIM0",
|
||||
"base": "0x10002000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_TIM1",
|
||||
"base": "0x10003000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_I2C0",
|
||||
"base": "0x10006000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_XPI",
|
||||
"base": "0x10009000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "none"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_DMA",
|
||||
"base": "0x1000A000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "none"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_SYSCTRL",
|
||||
"base": "0x1000B000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "none"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_CLINT",
|
||||
"base": "0x10020000",
|
||||
"size": "0x00010000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "none"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_I2C1",
|
||||
"base": "0x10011000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_GPIO_ADMIN",
|
||||
"base": "0x10014000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "none"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_SRAM",
|
||||
"base": "0x10017000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "none"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_UART1",
|
||||
"base": "0x10018000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_periph",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_ARCHINFO",
|
||||
"base": "0x20000000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_system",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "ro"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_PWM",
|
||||
"base": "0x20002000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_system",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_RTC",
|
||||
"base": "0x20004000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_system",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw"
|
||||
},
|
||||
{
|
||||
"symbol": "APB4_WDG",
|
||||
"base": "0x20005000",
|
||||
"size": "0x00001000",
|
||||
"route": "apb4_system",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "none"
|
||||
},
|
||||
{
|
||||
"symbol": "SRAM",
|
||||
"base": "0x30000000",
|
||||
"size": "0x00020000",
|
||||
"size_options": [
|
||||
"0x00001000",
|
||||
"0x00004000",
|
||||
"0x00008000",
|
||||
"0x00010000",
|
||||
"0x00020000"
|
||||
],
|
||||
"route": "ram",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"linker": "SRAM",
|
||||
"user_access": "rw",
|
||||
"burst": "incr16"
|
||||
},
|
||||
{
|
||||
"symbol": "XPI",
|
||||
"base": "0x50000000",
|
||||
"size": "0x10000000",
|
||||
"route": "axi4",
|
||||
"kind": "active",
|
||||
"public": true,
|
||||
"user_access": "rw",
|
||||
"burst": "incr16"
|
||||
}
|
||||
],
|
||||
"legacy_rib": false,
|
||||
"capability_header": "retrosoc/generated/soc_features.h"
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2026 Yuchi Miao
|
||||
// SPDX-License-Identifier: MulanPSL-2.0
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module retrosoc_tiny_tb;
|
||||
logic s_clk_driver = 1'b0;
|
||||
wire s_clk = s_clk_driver;
|
||||
logic s_reset_driver = 1'b0;
|
||||
wire s_rst_n = s_reset_driver;
|
||||
wire s_uart0_tx, s_uart1_tx;
|
||||
wire s_uart0_rx = 1'b1;
|
||||
wire s_uart1_rx = 1'b1;
|
||||
wire s_jtag_tck = 1'b0;
|
||||
wire s_jtag_tms = 1'b1;
|
||||
wire s_jtag_tdi = 1'b0;
|
||||
wire s_jtag_trst_n = s_rst_n;
|
||||
wire s_jtag_tdo;
|
||||
tri1 [31:0] s_gpio;
|
||||
wire s_xpi_sck;
|
||||
wire [ 3:0] s_xpi_nss;
|
||||
tri [ 3:0] s_xpi_data;
|
||||
integer s_cycles;
|
||||
integer s_max_cycles = 20000000;
|
||||
integer s_done_cycles = 0;
|
||||
logic [ 7:0] s_uart_byte;
|
||||
|
||||
`ifdef RETROSOC_SOC__TINY_NETLIST
|
||||
wire [7:0] s_test_code = {
|
||||
u_dut.s_test_code_7_,
|
||||
u_dut.s_test_code_6_,
|
||||
u_dut.s_test_code_5_,
|
||||
u_dut.s_test_code_4_,
|
||||
u_dut.s_test_code_3_,
|
||||
u_dut.s_test_code_2_,
|
||||
u_dut.s_test_code_1_,
|
||||
u_dut.s_test_code_0_
|
||||
};
|
||||
`else
|
||||
wire [7:0] s_test_code = u_dut.s_test_code;
|
||||
`endif
|
||||
|
||||
always #20.833333 s_clk_driver = !s_clk_driver;
|
||||
initial begin
|
||||
if ($value$plusargs("max_cycles=%d", s_max_cycles)) begin
|
||||
end
|
||||
repeat (20) @(posedge s_clk);
|
||||
@(negedge s_clk);
|
||||
s_reset_driver = 1'b1;
|
||||
for (s_cycles = 0; s_cycles < s_max_cycles; s_cycles = s_cycles + 1) begin
|
||||
@(posedge s_clk);
|
||||
if (u_dut.s_test_done) begin
|
||||
if (!u_dut.s_test_pass) $fatal(1, "SIM_TEST_FAIL code=%0d", s_test_code);
|
||||
s_done_cycles = s_done_cycles + 1;
|
||||
if (s_done_cycles == 128) begin
|
||||
$display("SIM_TEST_PASS Tiny cycles=%0d", s_cycles);
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
if (s_done_cycles != 128) $fatal(1, "SIM_TEST_TIMEOUT Tiny cycles=%0d", s_cycles);
|
||||
end
|
||||
|
||||
`ifdef RETROSOC_SOC__TINY_NETLIST
|
||||
// UART0 diagnostic output; SYSCTRL remains the authoritative test verdict.
|
||||
initial
|
||||
forever begin
|
||||
@(negedge s_uart0_tx);
|
||||
#1627.604;
|
||||
for (int bit_index = 0; bit_index < 8; bit_index++) begin
|
||||
s_uart_byte[bit_index] = s_uart0_tx;
|
||||
#1085.069;
|
||||
end
|
||||
$write("%c", s_uart_byte);
|
||||
end
|
||||
|
||||
`endif
|
||||
|
||||
retrosoc_tiny_asic u_dut (
|
||||
`include "retrosoc_asic_tb_bindings.svh"
|
||||
);
|
||||
tiny_qspi_nor u_flash (
|
||||
.sck_i (s_xpi_sck),
|
||||
.cs_n_i (s_xpi_nss[0]),
|
||||
.data_io(s_xpi_data)
|
||||
);
|
||||
endmodule
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright (c) 2026 Yuchi Miao
|
||||
// SPDX-License-Identifier: MulanPSL-2.0
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
// Pin-level 0xEB NOR model: 8 command bits, 24 quad address bits, 8 mode
|
||||
// bits and four dummy clocks. Unsupported commands fail closed. This model
|
||||
// verifies reset-read transport; program/erase and analog NOR timing are not
|
||||
// represented. Both simulators use exactly this same serial model.
|
||||
module tiny_qspi_nor (
|
||||
input logic sck_i,
|
||||
input logic cs_n_i,
|
||||
inout wire [3:0] data_io
|
||||
);
|
||||
typedef enum logic [2:0] {
|
||||
Command,
|
||||
Address,
|
||||
Mode,
|
||||
Dummy,
|
||||
Data
|
||||
} state_e;
|
||||
state_e s_state;
|
||||
logic [ 7:0] s_memory [0:16777215];
|
||||
logic [ 7:0] s_command;
|
||||
logic [23:0] s_address;
|
||||
logic [ 3:0] s_output;
|
||||
integer s_count;
|
||||
integer s_nibble;
|
||||
string s_firmware;
|
||||
|
||||
assign data_io = (!cs_n_i && (s_state == Data)) ? s_output : 4'bzzzz;
|
||||
initial begin
|
||||
s_state = Command;
|
||||
s_count = 0;
|
||||
s_command = '0;
|
||||
s_address = '0;
|
||||
if (!$value$plusargs("firmware=%s", s_firmware)) $fatal(1, "Missing +firmware hex image");
|
||||
$readmemh(s_firmware, s_memory);
|
||||
end
|
||||
always @(posedge sck_i or posedge cs_n_i) begin
|
||||
if (cs_n_i) begin
|
||||
s_state = Command;
|
||||
s_count = 0;
|
||||
s_command = '0;
|
||||
s_address = '0;
|
||||
end else begin
|
||||
case (s_state)
|
||||
Command: begin
|
||||
s_command = {s_command[6:0], data_io[0]};
|
||||
if (s_count == 7) begin
|
||||
if (s_command != 8'heb) $fatal(1, "Unsupported NOR command %02x", s_command);
|
||||
s_state = Address;
|
||||
s_count = 0;
|
||||
end else s_count = s_count + 1;
|
||||
end
|
||||
Address: begin
|
||||
s_address = {s_address[19:0], data_io};
|
||||
if (s_count == 5) begin
|
||||
s_state = Mode;
|
||||
s_count = 0;
|
||||
end else s_count = s_count + 1;
|
||||
end
|
||||
Mode: begin
|
||||
if (s_count == 1) begin
|
||||
s_state = Dummy;
|
||||
s_count = 0;
|
||||
end else s_count = s_count + 1;
|
||||
end
|
||||
Dummy: begin
|
||||
if (s_count == 3) s_state = Data;
|
||||
else s_count = s_count + 1;
|
||||
end
|
||||
Data: begin
|
||||
end
|
||||
default: $fatal(1, "Invalid NOR state");
|
||||
endcase
|
||||
end
|
||||
end
|
||||
always @(negedge sck_i or posedge cs_n_i) begin
|
||||
if (cs_n_i) begin
|
||||
s_nibble = 0;
|
||||
s_output = '0;
|
||||
end else if (s_state == Data) begin
|
||||
if ((s_nibble & 1) == 0) s_output = s_memory[s_address+(s_nibble/2)][7:4];
|
||||
else s_output = s_memory[s_address+(s_nibble/2)][3:0];
|
||||
s_nibble = s_nibble + 1;
|
||||
end else begin
|
||||
s_nibble = 0;
|
||||
s_output = '0;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,24 @@
|
||||
/clusterip/archinfo/rtl/archinfo_reg.sv
|
||||
/clusterip/archinfo/rtl/apb4_archinfo.sv
|
||||
/clusterip/pwm/rtl/pwm_pkg.sv
|
||||
/clusterip/pwm/rtl/pwm_tickgen.sv
|
||||
/clusterip/pwm/rtl/pwm_timer.sv
|
||||
/clusterip/pwm/rtl/pwm_channel.sv
|
||||
/clusterip/pwm/rtl/pwm_deadtime.sv
|
||||
/clusterip/pwm/rtl/pwm_carrier.sv
|
||||
/clusterip/pwm/rtl/pwm_capture.sv
|
||||
/clusterip/pwm/rtl/pwm_core.sv
|
||||
/clusterip/pwm/rtl/pwm_reg.sv
|
||||
/clusterip/pwm/rtl/pwm_if.sv
|
||||
/clusterip/pwm/rtl/apb4_pwm.sv
|
||||
/clusterip/rtc/rtl/rtc_pkg.sv
|
||||
/clusterip/rtc/rtl/rtc_if.sv
|
||||
/clusterip/rtc/rtl/rtc_tickgen.sv
|
||||
/clusterip/rtc/rtl/rtc_core.sv
|
||||
/clusterip/rtc/rtl/rtc_reg.sv
|
||||
/clusterip/rtc/rtl/apb4_rtc.sv
|
||||
/clusterip/wdg/rtl/wdg_pkg.sv
|
||||
/clusterip/wdg/rtl/wdg_if.sv
|
||||
/clusterip/wdg/rtl/wdg_core.sv
|
||||
/clusterip/wdg/rtl/wdg_reg.sv
|
||||
/clusterip/wdg/rtl/apb4_wdg.sv
|
||||
@@ -0,0 +1,22 @@
|
||||
/clusterip/common/rtl/interface/apb4_if.sv
|
||||
/clusterip/common/rtl/interface/apb4_pure_if.sv
|
||||
/clusterip/common/rtl/interface/ahbl_if.sv
|
||||
/clusterip/common/rtl/interface/axi4_if.sv
|
||||
/clusterip/common/rtl/interface/axi4_addr_gen.sv
|
||||
/clusterip/common/rtl/interface/axi4_stream_if.sv
|
||||
/clusterip/common/rtl/interface/ram_if.sv
|
||||
/clusterip/common/rtl/utils/register.sv
|
||||
/clusterip/common/rtl/utils/spill_register.sv
|
||||
/clusterip/common/rtl/stream/round_robin_arbiter.sv
|
||||
/clusterip/common/rtl/utils/lfsr.sv
|
||||
/clusterip/common/rtl/utils/bin2gray.sv
|
||||
/clusterip/common/rtl/utils/gray2bin.sv
|
||||
/clusterip/common/rtl/base/ecc_secded.sv
|
||||
/clusterip/common/rtl/utils/edge_det.sv
|
||||
/clusterip/common/rtl/cdc/cdc_sync.sv
|
||||
/clusterip/common/rtl/cdc/cdc_rst_ctrlr.sv
|
||||
/clusterip/common/rtl/cdc/cdc_2phase.sv
|
||||
/clusterip/common/rtl/clkrst/rst_sync.sv
|
||||
/clusterip/common/rtl/clkrst/counter.sv
|
||||
/ip/util/soc_common_fifo.sv
|
||||
/ip/util/soc_common_cdc.sv
|
||||
Loaded 100 of 194 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user