From 4f8d7bc699007445387cc9df7b3b958a5f675097 Mon Sep 17 00:00:00 2001 From: maksyuki Date: Sun, 9 Aug 2026 15:14:41 +0800 Subject: [PATCH] feat: add archinfo metadata generation and integration - Introduced scripts and makefile targets for generating architecture information metadata. - Updated the filelist generation to include archinfo metadata files. - Modified software.mk to include archinfo source files and headers. - Enhanced the ip_apb_wrapper and user_ip_wrapper to integrate archinfo components. - Updated tests to ensure stability and correct path expansions for generated files. - Removed unnecessary files from the clusterip filelist. --- Makefile | 8 +- README.md | 5 +- app/README.md | 2 +- app/apps/ci_smoke/main.c | 14 +- config/dependencies.lock.json | 2 +- crt/include/retrosoc/core/archinfo.h | 11 + crt/include/retrosoc/core/soc.h | 4 - crt/src/core/archinfo.c | 71 +++- crt/src/service/booter.c | 3 +- docs/engineering.md | 10 + docs/mini-soc-block-diagram.dot | 9 +- docs/mini-soc-block-diagram.svg | 489 ++++++++++++++------------- rtl/mini/Makefile | 18 +- rtl/mini/filelist/clusterip.fl | 1 - rtl/mini/formal/i2c_formal_props.sv | 2 + rtl/mini/mk/software.mk | 7 +- rtl/mini/script/generate_filelist.py | 12 +- rtl/mini/top/ip_apb_wrapper.sv | 113 ++++++- rtl/mini/top/user_ip_wrapper.sv | 20 +- tests/test_script_tools.py | 9 +- 20 files changed, 521 insertions(+), 289 deletions(-) diff --git a/Makefile b/Makefile index 1333341f..62c611a3 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ HAVE_SRAM_IF ?= NO HAVE_SRAM_MACRO ?= NO PDK_BEHAV ?= NO HAVE_SVA ?= NO +BUILD_RELEASE ?= NO JTAG_IDCODE ?= DEADBEEF EXT_CLK_HZ ?= 72000000 CLINT_TIMEBASE_HZ ?= 1000000 @@ -82,7 +83,7 @@ JOBS ?= $(shell count=$$(nproc 2>/dev/null || printf '1'); \ if [ "$$count" -gt "$(MAX_JOBS)" ]; then printf '%s' '$(MAX_JOBS)'; \ else printf '%s' "$$count"; fi) CONFIG_KEY_VARS := SOC PDK HAVE_PLL HAVE_SRAM_IF HAVE_SRAM_MACRO PDK_BEHAV HAVE_SVA \ - JTAG_IDCODE EXT_CLK_HZ CLINT_TIMEBASE_HZ ISA HAVE_CSR APP LINK_TYPE \ + BUILD_RELEASE JTAG_IDCODE EXT_CLK_HZ CLINT_TIMEBASE_HZ ISA HAVE_CSR APP LINK_TYPE \ COREMARK_MODE RTL_TOP FIRMWARE_NAME VARIANT_ID := $(strip $(shell $(VCS_SHELL_PYTHON) $(ROOT_PATH)/scripts/config_key.py \ --lock $(LOCK_FILE) --profile $(PROFILE_NAME) --timestamp $(BUILD_TIMESTAMP) \ @@ -90,8 +91,9 @@ VARIANT_ID := $(strip $(shell $(VCS_SHELL_PYTHON) $(ROOT_PATH)/scripts/c ifeq ($(VARIANT_ID),) $(error Failed to calculate build variant ID) endif -LOCK_DIGEST := $(strip $(shell $(VCS_SHELL_PYTHON) $(ROOT_PATH)/scripts/dependency_lock.py \ +LOCK_DIGEST := $(strip $(shell $(VCS_SHELL_PYTHON) $(ROOT_PATH)/scripts/dependency_lock.py \ --lock $(LOCK_FILE) --digest | tail -n 1)) +CONFIG_DIGEST := $(lastword $(subst -, ,$(VARIANT_ID))) export BUILD_TIMESTAMP VARIANT_ROOT := $(abspath $(BUILD_ROOT))/$(VARIANT_ID) SW_BUILD_DIR := $(VARIANT_ROOT)/sw @@ -131,6 +133,7 @@ $(call validate_value,HAVE_SRAM_IF,$(VALID_BOOL)) $(call validate_value,HAVE_SRAM_MACRO,$(VALID_BOOL)) $(call validate_value,PDK_BEHAV,$(VALID_BOOL)) $(call validate_value,HAVE_SVA,$(VALID_BOOL)) +$(call validate_value,BUILD_RELEASE,$(VALID_BOOL)) $(call validate_value,WAVE,$(VALID_BOOL)) $(call validate_value,FORMAL,$(VALID_BOOL)) $(call validate_value,VCS_USE_LSF,$(VALID_BOOL)) @@ -313,6 +316,7 @@ config: VCS_USE_LSF '$(VCS_USE_LSF)' PDK '$(PDK)' \ HAVE_PLL '$(HAVE_PLL)' HAVE_SRAM_IF '$(HAVE_SRAM_IF)' \ HAVE_SRAM_MACRO '$(HAVE_SRAM_MACRO)' PDK_BEHAV '$(PDK_BEHAV)' HAVE_SVA '$(HAVE_SVA)' \ + BUILD_RELEASE '$(BUILD_RELEASE)' \ JTAG_IDCODE '$(JTAG_IDCODE)' EXT_CLK_HZ '$(EXT_CLK_HZ)' \ CLINT_TIMEBASE_HZ '$(CLINT_TIMEBASE_HZ)' \ ISA '$(ISA)' HAVE_CSR '$(HAVE_CSR)' APP '$(APP)' \ diff --git a/README.md b/README.md index 08bba6c0..6613a3ca 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ under the [Mulan Permissive Software License, Version 2](LICENSE). `coremark`, `debug`, and `shell` applications. - Open-source behavioral simulation with Icarus Verilog and Verilator, synthesis with Yosys, netlist simulation with Icarus Verilog, and timing analysis with OpenSTA. +- Read-only ARCHINFO ABI V2 discovery for build/configuration provenance, SoC + topology, technology capabilities, and lifecycle-gated device identity. - Checksum-verified dependency and toolchain locks, structured flow results, warning baselines, metrics collection, SBOM generation, and checksummed release packages. @@ -73,7 +75,8 @@ user core. CI Verilator firmware simulations explicitly select the `ci_smoke` application, which checks UART, archinfo APB readback, and test-status -completion without the verbose startup report. The profiles retain `bringup` +completion without the verbose startup report. ARCHINFO checks include its V2 +ABI and the build/configuration identifiers generated for that variant. The profiles retain `bringup` as their default for manual diagnostics. To run the full report in Verilator, use: diff --git a/app/README.md b/app/README.md index 8a9575a1..764f6157 100644 --- a/app/README.md +++ b/app/README.md @@ -29,7 +29,7 @@ The build selects an application with `APP=`. The supported profiles are: | --- | --- | | `benchmark` | Fixed-workload memory and DMA baseline with machine-readable wait counters and readback checksums. | | `bringup` | Manual startup diagnostic that prints complete application and archinfo details. | -| `ci_smoke` | Fast deterministic CI smoke test for UART, archinfo APB readback, and test-status completion. | +| `ci_smoke` | Fast deterministic CI smoke test for UART, ARCHINFO V2 ABI/build identity, and test-status completion. | | `coremark` | SRAM-resident Hazard3 CoreMark measurement; use the committed quick or standard profile. | | `debug` | Minimal SRAM image used only by the Hazard3 OpenOCD/GDB acceptance flow. | | `shell` | Interactive application that adds shell services, board drivers, media, FatFs, CoreMark, and UserIP integration. | diff --git a/app/apps/ci_smoke/main.c b/app/apps/ci_smoke/main.c index 25f33b54..39d06f9b 100644 --- a/app/apps/ci_smoke/main.c +++ b/app/apps/ci_smoke/main.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -6,13 +7,12 @@ #include #include -static bool rs_ci_smoke_archinfo_matches_reset_values(void) { - const uint32_t archinfo_sys = reg_archinfo_sys; - const uint32_t archinfo_idl = reg_archinfo_idl; - const uint32_t archinfo_idh = reg_archinfo_idh; +static bool rs_ci_smoke_archinfo_v2(void) { + rs_archinfo_t info; + uint32_t device_id[4]; - return (archinfo_sys == UINT32_C(0x000F1010)) && (archinfo_idl == UINT32_C(0xFFFF2022)) && - (archinfo_idh == UINT32_C(0x00FFFFFF)); + return (rs_archinfo_read(&info) == RS_OK) && (rs_archinfo_validate_build(&info) == RS_OK) && + (rs_archinfo_read_device_id(device_id) == RS_ENOTSUP); } static bool rs_ci_smoke_clint_standard_map(void) { @@ -173,7 +173,7 @@ int main(void) { rs_test_finish(RS_TEST_FAILED, 7U); } - if (!rs_ci_smoke_archinfo_matches_reset_values()) { + if (!rs_ci_smoke_archinfo_v2()) { rs_test_finish(RS_TEST_FAILED, 1U); } printf("ci_smoke: archinfo passed\n"); diff --git a/config/dependencies.lock.json b/config/dependencies.lock.json index c6460913..bf6008f6 100644 --- a/config/dependencies.lock.json +++ b/config/dependencies.lock.json @@ -60,7 +60,7 @@ "submodules": ["libraries/sky130_fd_sc_hd/latest"], "license": "Apache-2.0" }, - "cluster_archinfo": {"url": "https://github.com/retroSoC/archinfo.git", "revision": "d65dd13c83a1176668bf5178004814a1551bf6ba", "destination": "rtl/managed/clusterip/archinfo", "license": "NOASSERTION"}, + "cluster_archinfo": {"url": "https://github.com/retroSoC/archinfo.git", "revision": "78505969a0afdbc887cdd9b36eda228b4afb616e", "destination": "rtl/managed/clusterip/archinfo", "license": "MulanPSL-2.0"}, "cluster_clint": {"url": "https://github.com/retroSoC/clint.git", "revision": "ce49f1a5501c0a9f18c0e3f358417648f3f2fb18", "destination": "rtl/managed/clusterip/clint", "license": "NOASSERTION"}, "cluster_common": {"url": "https://github.com/retroSoC/common.git", "revision": "16ee9a5cfdc1248f35f0993710e3cb89464c19d9", "destination": "rtl/managed/clusterip/common", "license": "NOASSERTION"}, "cluster_crc": {"url": "https://github.com/retroSoC/crc.git", "revision": "4654a63d06d487b5b9fe22af228c36c736b90bad", "destination": "rtl/managed/clusterip/crc", "license": "NOASSERTION"}, diff --git a/crt/include/retrosoc/core/archinfo.h b/crt/include/retrosoc/core/archinfo.h index 9df44645..a2e12adc 100644 --- a/crt/include/retrosoc/core/archinfo.h +++ b/crt/include/retrosoc/core/archinfo.h @@ -1,5 +1,16 @@ #ifndef RETROSOC_ARCHINFO_H #define RETROSOC_ARCHINFO_H +#include + +#include +#include + +typedef archinfo_snapshot_t rs_archinfo_t; + +rs_status_t rs_archinfo_read(rs_archinfo_t *info); +rs_status_t rs_archinfo_validate_build(const rs_archinfo_t *info); +rs_status_t rs_archinfo_read_device_id(uint32_t device_id[4]); void ip_archinfo_test(int argc, char **argv); + #endif diff --git a/crt/include/retrosoc/core/soc.h b/crt/include/retrosoc/core/soc.h index aae31624..7fdf3944 100644 --- a/crt/include/retrosoc/core/soc.h +++ b/crt/include/retrosoc/core/soc.h @@ -183,10 +183,6 @@ #define reg_dvp_recven RS_SOC_REG32(RS_SOC_RIBP_DVP_BASE, UINT32_C(0x00)) #define reg_dvp_rxdata RS_SOC_REG32(RS_SOC_RIBP_DVP_BASE, UINT32_C(0x04)) #define reg_dvp_status RS_SOC_REG32(RS_SOC_RIBP_DVP_BASE, UINT32_C(0x08)) -// archinfo -#define reg_archinfo_sys RS_SOC_REG32(RS_SOC_APB_ARCHINFO_BASE, UINT32_C(0x00)) -#define reg_archinfo_idl RS_SOC_REG32(RS_SOC_APB_ARCHINFO_BASE, UINT32_C(0x04)) -#define reg_archinfo_idh RS_SOC_REG32(RS_SOC_APB_ARCHINFO_BASE, UINT32_C(0x08)) // rng #define reg_rng_ctrl RS_SOC_REG32(RS_SOC_APB_RNG_BASE, UINT32_C(0x00)) #define reg_rng_seed RS_SOC_REG32(RS_SOC_APB_RNG_BASE, UINT32_C(0x04)) diff --git a/crt/src/core/archinfo.c b/crt/src/core/archinfo.c index 229c7b3c..4f80b831 100644 --- a/crt/src/core/archinfo.c +++ b/crt/src/core/archinfo.c @@ -1,12 +1,73 @@ +#include +#include +#include #include #include -#include + +static rs_status_t rs_archinfo_status(archinfo_status_t status) { + rs_status_t result; + + switch (status) { + case ARCHINFO_STATUS_OK: + result = RS_OK; + break; + case ARCHINFO_STATUS_INVALID_ARGUMENT: + result = RS_EINVAL; + break; + case ARCHINFO_STATUS_UNAVAILABLE: + result = RS_ENOTSUP; + break; + case ARCHINFO_STATUS_INCOMPATIBLE: + default: + result = RS_EFORMAT; + break; + } + + return result; +} + +rs_status_t rs_archinfo_read(rs_archinfo_t *info) { + return rs_archinfo_status(archinfo_read((uintptr_t)RS_SOC_APB_ARCHINFO_BASE, info)); +} + +rs_status_t rs_archinfo_validate_build(const rs_archinfo_t *info) { + const archinfo_build_expectation_t expectation = { + .check_build_id = + (ARCHINFO_INTEGRATION_BUILD_STATUS & ARCHINFO_BUILD_SOURCE_KNOWN_MASK) != 0U, + .check_config_id = true, + .build_id = ARCHINFO_INTEGRATION_BUILD_ID, + .config_id = ARCHINFO_INTEGRATION_CONFIG_ID, + }; + + return rs_archinfo_status(archinfo_validate(info, &expectation)); +} + +rs_status_t rs_archinfo_read_device_id(uint32_t device_id[4]) { + return rs_archinfo_status( + archinfo_read_device_id((uintptr_t)RS_SOC_APB_ARCHINFO_BASE, device_id)); +} void ip_archinfo_test(int argc, char **argv) { + rs_archinfo_t info; + rs_status_t status; + (void)argc; (void)argv; - printf("[APB IP] archinfo test\n"); - printf("[ARCHINFO SYS] %x\n", reg_archinfo_sys); - printf("[ARCHINFO IDL] %x\n", reg_archinfo_idl); - printf("[ARCHINFO IDH] %x\n", reg_archinfo_idh); + + status = rs_archinfo_read(&info); + if (status != RS_OK) { + printf("[ARCHINFO] read failed: %d\n", status); + return; + } + + printf("[APB IP] archinfo ABI V2\n"); + printf("[ARCHINFO COMPONENT] %x\n", info.component_id); + printf("[ARCHINFO SOC/REV] %x/%x\n", info.soc_id, info.soc_revision); + printf("[ARCHINFO BUILD] %x%x status=%x\n", (uint32_t)(info.build_id >> 32U), + (uint32_t)info.build_id, info.build_status); + printf("[ARCHINFO CONFIG] %x\n", info.config_id); + printf("[ARCHINFO CLOCK/SRAM] %u/%u\n", info.reference_clock_hz, info.sram_bytes); + printf("[ARCHINFO TOPOLOGY/FEATURES] %x/%x\n", info.topology, info.features0); + printf("[ARCHINFO TECHNOLOGY] %x\n", info.technology); + printf("[ARCHINFO VERSION/CAP] %x/%x\n", info.ip_version, info.capability); } diff --git a/crt/src/service/booter.c b/crt/src/service/booter.c index e6eab1d1..e8e7cee8 100644 --- a/crt/src/service/booter.c +++ b/crt/src/service/booter.c @@ -116,7 +116,8 @@ void rs_app_info(void) { printf(" 1 x DVP @%p\n", (void *)®_dvp_recven); printf(" 1 x I2C1 @%p\n", (void *)(uintptr_t)RS_SOC_RIBP_I2C1_BASE); - printf(" 1 x ARCHINFO @%p\n", (void *)®_archinfo_sys); + printf(" 1 x ARCHINFO @%p\n", + (void *)(uintptr_t)RS_SOC_APB_ARCHINFO_BASE); printf(" 1 x RNG @%p\n", (void *)®_rng_ctrl); printf(" 1 x UART1(ADV) @%p\n", (void *)®_uart1_lcr); printf(" 1 x PWM(4CHNL) @%p\n", (void *)®_pwm_ctrl); diff --git a/docs/engineering.md b/docs/engineering.md index aa7ab684..5a66b124 100644 --- a/docs/engineering.md +++ b/docs/engineering.md @@ -19,6 +19,15 @@ archinfo APB readback, and test-status completion within the CI time budget; `bringup` retains the full automatic application-information report for manual runs. +ARCHINFO ABI V2 exposes immutable build, configuration, topology, feature, and +technology identity. Its register specification, driver, standalone tests, and +formal properties are delivered by the +[archinfo IP repository](https://github.com/retroSoC/archinfo). The integration +generates matching RTL and C metadata headers from the source revision, +dependency lock, and canonical configuration digest. +Normal builds clear the release flag; an audited release flow sets +`BUILD_RELEASE=YES`, which is part of the canonical configuration digest. + OpenSTA runs a reproducible core-STA baseline for every CI PDK: IHP130 uses `slow_1p08V_125C`, GF180 uses `ss_125C_4v50`, ICS55 uses the H7CR `ss_1p08_125C` view, and SKY130 uses `ss_100C_1v40`. @@ -96,6 +105,7 @@ one timestamp to all of its child Make commands. ```text build// generated/mpw// + generated/archinfo/ generated/pin_map/ sw/ sim// diff --git a/docs/mini-soc-block-diagram.dot b/docs/mini-soc-block-diagram.dot index 126bb83d..fe96d527 100644 --- a/docs/mini-soc-block-diagram.dot +++ b/docs/mini-soc-block-diagram.dot @@ -152,7 +152,11 @@ digraph mini_soc_block_diagram { ]; apb_targets [ fillcolor="#E6F4EA", - label="APB target wrapper\nArchinfo, RNG, UART1, PWM, PS/2, RTC\nwatchdog, CRC, advanced timer and user IP" + label="APB target wrapper\nRNG, UART1, PWM, PS/2, RTC\nwatchdog, CRC, advanced timer and user IP" + ]; + archinfo [ + fillcolor="#E6F4EA", + label="ARCHINFO V2\nread-only build, topology and technology identity\nlifecycle-gated 128-bit device ID" ]; gpio_bridge [ fillcolor="#E5E7EB", @@ -169,7 +173,7 @@ digraph mini_soc_block_diagram { { rank=same; user_core; dma; } { rank=same; fault; fabric; sram; } { rank=same; ribp_adapter; apb_adapter; } - { rank=same; sysctrl; clint; ribp_targets; uart0; i2c_controllers; gpio_controller; timers; ws2812; apb_targets; } + { rank=same; sysctrl; clint; ribp_targets; uart0; i2c_controllers; gpio_controller; timers; ws2812; archinfo; apb_targets; } { rank=same; gpio_bridge; irq; } ext_clock -> rcu [label="clock / reset"]; @@ -199,6 +203,7 @@ digraph mini_soc_block_diagram { ribp_adapter -> gpio_controller [label="RIBP\nuser/admin"]; ribp_adapter -> timers [label="RIBP"]; ribp_adapter -> ws2812 [label="RIBP"]; + apb_adapter -> archinfo [label="APB"]; apb_adapter -> apb_targets [label="APB"]; ribp_targets -> gpio_controller [label="alternate functions"]; diff --git a/docs/mini-soc-block-diagram.svg b/docs/mini-soc-block-diagram.svg index 2b3df19e..e2b0ab9c 100644 --- a/docs/mini-soc-block-diagram.svg +++ b/docs/mini-soc-block-diagram.svg @@ -4,19 +4,19 @@ - + mini_soc_block_diagram retroSoC Mini SoC Architecture cluster_asic - + retrosoc_asic cluster_soc - + retrosoc @@ -44,475 +44,490 @@ ext_io - -External I/O and memory -GPIO, UART0, XPI Flash, SDRAM, PSRAM -SD card, I2C, I2S, DVP and WS2812 + +External I/O and memory +GPIO, UART0, XPI Flash, SDRAM, PSRAM +SD card, I2C, I2S, DVP and WS2812 ext_jtag - -Management JTAG -TCK, TMS, TDI, TRST_n, TDO + +Management JTAG +TCK, TMS, TDI, TRST_n, TDO jtag_dtm - -Hazard3 JTAG DTM -10 MHz asynchronous TCK domain + +Hazard3 JTAG DTM +10 MHz asynchronous TCK domain ext_jtag->jtag_dtm - - -JTAG pads + + +JTAG pads fabric - -RIB fabric -3-master round-robin arbitration -INCR1 / INCR4, access policy, fault reporting + +RIB fabric +3-master round-robin arbitration +INCR1 / INCR4, access policy, fault reporting rcu->fabric - - -system clock / reset + + +system clock / reset clint - -CLINT -standard 64 KiB register map -mtime, mtimecmp and MSIP + +CLINT +standard 64 KiB register map +mtime, mtimecmp and MSIP rcu->clint - - -1 MHz tick + + +1 MHz tick mgmt_core - -Management core -Fixed Hazard3, branch predictor -JTAG Debug Module always present + +Management core +Fixed Hazard3, branch predictor +JTAG Debug Module always present mgmt_adapter - -RIBP2RIB + +RIBP2RIB mgmt_core->mgmt_adapter - - -RIBP + + +RIBP debug_module - -Hazard3 Debug Module -abstract commands, no SBA -management-hart-only reset + +Hazard3 Debug Module +abstract commands, no SBA +management-hart-only reset jtag_dtm->debug_module - - -DMI, asynchronous CDC + + +DMI, asynchronous CDC debug_module->mgmt_core - - -halt, resume, abstract commands + + +halt, resume, abstract commands debug_module->mgmt_adapter - - -reset after bridge idle + + +reset after bridge idle timers - -General timers 0/1 -32-bit counter, 16-bit prescaler -periodic / one-shot, compare, debug freeze + +General timers 0/1 +32-bit counter, 16-bit prescaler +periodic / one-shot, compare, debug freeze debug_module->timers - - -halted + + +halted mgmt_adapter->fabric - - -RIB + + +RIB user_core - -Selected user core -C0-C5, one active -PicoRV32 at C5 + +Selected user core +C0-C5, one active +PicoRV32 at C5 user_core->fabric - - -RIB + + +RIB dma - -DMA -RIB master and RIBP target + +DMA +RIB master and RIBP target dma->fabric - - -RIB + + +RIB uart0 - -UART0 V2 -64-byte TX/RX FIFOs, fractional baud -framing/errors, IRQ2, DMA-paced + +UART0 V2 +64-byte TX/RX FIFOs, fractional baud +framing/errors, IRQ2, DMA-paced - + dma->uart0 - - -TX/RX data + + +TX/RX data i2c_controllers - -I2C0 / I2C1 V2 -16-entry command/RX FIFOs, Sm/Fm/Fm+ -7/10-bit, IRQ7/19, DMA-paced + +I2C0 / I2C1 V2 +16-entry command/RX FIFOs, Sm/Fm/Fm+ +7/10-bit, IRQ7/19, DMA-paced - + dma->i2c_controllers - - -DATA_CMD / RXDATA + + +DATA_CMD / RXDATA ws2812 - -WS2812 TX -24-bit MSB-first serializer -16-word FIFO, IRQ17, DMA-fed + +WS2812 TX +24-bit MSB-first serializer +16-word FIFO, IRQ17, DMA-fed - + dma->ws2812 - - -TXDATA writes + + +TXDATA writes fault - -Error slave -access and protocol faults + +Error slave +access and protocol faults fabric->fault - - - -invalid / denied + + + +invalid / denied sram - -On-chip SRAM -optional RIB2RAM path + +On-chip SRAM +optional RIB2RAM path fabric->sram - - -RIB + + +RIB ribp_adapter - -RIB2RIBP + +RIB2RIBP fabric->ribp_adapter - - -RIB + + +RIB apb_adapter - -RIB2APB -direct APB bridge + +RIB2APB +direct APB bridge fabric->apb_adapter - - -RIB + + +RIB sysctrl - -SYSCTRL -PLL, user-core select/reset/bus enable -fault and performance control + +SYSCTRL +PLL, user-core select/reset/bus enable +fault and performance control ribp_adapter->sysctrl - - -RIBP + + +RIBP ribp_adapter->clint - - -RIBP + + +RIBP ribp_targets - -RIBP target wrapper -XPI/Flash, SDRAM, PSRAM, SPI-SD and DVP -I2S + +RIBP target wrapper +XPI/Flash, SDRAM, PSRAM, SPI-SD and DVP +I2S ribp_adapter->ribp_targets - - -RIBP + + +RIBP ribp_adapter->uart0 - - -RIBP + + +RIBP ribp_adapter->i2c_controllers - - -RIBP + + +RIBP gpio_controller - -GPIO V2 -user + management RIBP windows -atomic I/O, filter, locks, IRQ18 + +GPIO V2 +user + management RIBP windows +atomic I/O, filter, locks, IRQ18 ribp_adapter->gpio_controller - - -RIBP -user/admin + + +RIBP +user/admin ribp_adapter->timers - - -RIBP + + +RIBP ribp_adapter->ws2812 - - -RIBP + + +RIBP apb_targets - -APB target wrapper -Archinfo, RNG, UART1, PWM, PS/2, RTC -watchdog, CRC, advanced timer and user IP + +APB target wrapper +RNG, UART1, PWM, PS/2, RTC +watchdog, CRC, advanced timer and user IP - + apb_adapter->apb_targets - - -APB + + +APB + + + +archinfo + +ARCHINFO V2 +read-only build, topology and technology identity +lifecycle-gated 128-bit device ID + + + +apb_adapter->archinfo + + +APB - + irq - -Interrupt aggregation -RIBP and APB target IRQs to management core + +Interrupt aggregation +RIBP and APB target IRQs to management core - + clint->irq - - -machine IRQ0 / IRQ1 + + +machine IRQ0 / IRQ1 - + ribp_targets->ext_io - - - -device interfaces + + + +device interfaces - + ribp_targets->gpio_controller - - -alternate functions + + +alternate functions - + uart0->ext_io - - - -UART pads + + + +UART pads - + uart0->irq - - -IRQ2 + + +IRQ2 - + i2c_controllers->gpio_controller - - -GPIO3/4 ALT1 -GPIO7/8 ALT0 + + +GPIO3/4 ALT1 +GPIO7/8 ALT0 - + i2c_controllers->irq - - -IRQ7 / IRQ19 + + +IRQ7 / IRQ19 - + gpio_bridge - -GPIO pad bridge -PDK capability-adapted controls + +GPIO pad bridge +PDK capability-adapted controls - + gpio_controller->gpio_bridge - - -pad control + + +pad control - + gpio_controller->irq - - -IRQ18 + + +IRQ18 - + timers->irq - - -IRQ3 / IRQ4 + + +IRQ3 / IRQ4 - + ws2812->gpio_bridge - - -GPIO2 ALT1 + + +GPIO2 ALT1 - + ws2812->irq - - -IRQ17 + + +IRQ17 - + apb_targets->gpio_controller - - -user_gpio + + +user_gpio - + gpio_bridge->ext_io - - - -pad control + + + +pad control diff --git a/rtl/mini/Makefile b/rtl/mini/Makefile index 25261bd9..d60af566 100644 --- a/rtl/mini/Makefile +++ b/rtl/mini/Makefile @@ -22,6 +22,11 @@ USER_EXTENSIONS_SCRIPT := $(RTL_PATH)/integration/generate_user_extensions.p USER_EXTENSIONS_DIR := $(VARIANT_ROOT)/generated/user_extensions USER_EXTENSIONS_STAMP := $(USER_EXTENSIONS_DIR)/.stamp USER_EXTENSIONS_FILELIST := $(USER_EXTENSIONS_DIR)/user_extensions.fl +ARCHINFO_METADATA_SCRIPT := $(ROOT_PATH)/rtl/managed/clusterip/archinfo/scripts/generate_metadata.py +ARCHINFO_METADATA_DIR := $(VARIANT_ROOT)/generated/archinfo +ARCHINFO_METADATA_STAMP := $(ARCHINFO_METADATA_DIR)/.stamp +ARCHINFO_METADATA_SV := $(ARCHINFO_METADATA_DIR)/archinfo_integration_metadata.svh +ARCHINFO_METADATA_C := $(ARCHINFO_METADATA_DIR)/archinfo_integration_metadata.h CLOCK_RESET_DOMAINS_SOURCE := $(RTL_PATH)/integration/clock_reset_domains.json CLOCK_RESET_DOMAINS_SCRIPT := $(ROOT_PATH)/scripts/check_clock_reset_domains.py MPW_STAMP := $(CACHE_ROOT)/stamps/mpw-$(LOCK_DIGEST).prepared @@ -96,14 +101,23 @@ user-extensions: $(USER_EXTENSIONS_STAMP) check-user-extensions: $(FLOW_PYTHON) $(USER_EXTENSIONS_SCRIPT) --map $(USER_EXTENSIONS_SOURCE) --check +$(ARCHINFO_METADATA_STAMP): $(ARCHINFO_METADATA_SCRIPT) $(LOCK_FILE) + $(FLOW_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_SV) --output-c $(ARCHINFO_METADATA_C) + @touch $@ + +archinfo-metadata: $(ARCHINFO_METADATA_STAMP) + 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 \ $(RTL_PATH)/script/filelist.py $(MEMORY_MAP_STAMP) $(PIN_MAP_STAMP) $(SOC_TOPOLOGY_STAMP) \ - $(USER_EXTENSIONS_STAMP) + $(USER_EXTENSIONS_STAMP) $(ARCHINFO_METADATA_STAMP) $(FLOW_PYTHON) $(RTL_PATH)/script/generate_filelist.py \ --output-dir $(GENERATED_FL_DIR) \ + --incdir $(ARCHINFO_METADATA_DIR) \ $(foreach define,$(DEF_LIST),--define $(define)) @touch $@ @@ -159,4 +173,4 @@ endif .PHONY: gen_mpw_code generate_filelist memory-map check-memory-map pin-map check-pin-map \ soc-topology check-soc-topology user-extensions check-user-extensions \ - check-clock-reset-domains firmware \ No newline at end of file + archinfo-metadata check-clock-reset-domains firmware \ No newline at end of file diff --git a/rtl/mini/filelist/clusterip.fl b/rtl/mini/filelist/clusterip.fl index 9ef063d3..1771e7d5 100644 --- a/rtl/mini/filelist/clusterip.fl +++ b/rtl/mini/filelist/clusterip.fl @@ -1,4 +1,3 @@ -/clusterip/archinfo/rtl/archinfo_reg_pkg.sv /clusterip/archinfo/rtl/archinfo_reg.sv /clusterip/archinfo/rtl/apb4_archinfo.sv /clusterip/rng/rtl/apb4_rng.sv diff --git a/rtl/mini/formal/i2c_formal_props.sv b/rtl/mini/formal/i2c_formal_props.sv index b54f9f0d..b17f1fbf 100644 --- a/rtl/mini/formal/i2c_formal_props.sv +++ b/rtl/mini/formal/i2c_formal_props.sv @@ -2,6 +2,7 @@ // retroSoC is licensed under Mulan PSL v2. module i2c_formal; + // verilog_format: off (* anyseq, gclk *) logic clk_i; wire rst_n_i; wire f_past_valid; @@ -29,6 +30,7 @@ module i2c_formal; wire tx_dma_stall; wire rx_dma_stall; wire irq; + // verilog_format: on i2c_formal_design u_design ( .clk_i (clk_i), diff --git a/rtl/mini/mk/software.mk b/rtl/mini/mk/software.mk index 31b50692..c45b54ac 100644 --- a/rtl/mini/mk/software.mk +++ b/rtl/mini/mk/software.mk @@ -61,6 +61,7 @@ CRT_SRCS := $(ROOT_PATH)/crt/arch/riscv/startup.S \ $(ROOT_PATH)/crt/src/lib/string.c \ $(ROOT_PATH)/crt/src/lib/console.c \ $(ROOT_PATH)/crt/src/lib/printf.c \ + $(ROOT_PATH)/rtl/managed/clusterip/archinfo/sw/src/archinfo.c \ $(ROOT_PATH)/crt/src/core/archinfo.c \ $(ROOT_PATH)/crt/src/service/bench.c \ $(ROOT_PATH)/crt/src/service/booter.c \ @@ -126,6 +127,8 @@ endif INC_PATH := -I$(SW_BUILD_DIR)/include \ -I$(MEMORY_MAP_C_DIR) \ -I$(USER_EXTENSIONS_DIR)/include \ + -I$(ARCHINFO_METADATA_DIR) \ + -I$(ROOT_PATH)/rtl/managed/clusterip/archinfo/sw/include \ -I$(ROOT_PATH)/crt/include \ $(addprefix -I,$(APP_INC_DIRS)) SRC_PATH := $(CRT_SRCS) $(APP_SRCS) @@ -136,6 +139,8 @@ FIRMWARE_ELF := $(SW_BUILD_DIR)/firmware ASM_FIRMWARE_NAME ?= retrosoc_asm SW_HEADERS := $(shell find $(ROOT_PATH)/crt/include $(ROOT_PATH)/app -type f \ \( -name '*.h' -o -name '*.hpp' \) 2>/dev/null) +SW_HEADERS += $(shell find $(ROOT_PATH)/rtl/managed/clusterip/archinfo/sw/include \ + -type f -name '*.h' 2>/dev/null) $(VERSION_HEADER): FORCE_VERSION $(ROOT_PATH)/crt/ver.py $(ROOT_PATH)/crt/ver.tmpl @mkdir -p $(dir $@) @@ -153,7 +158,7 @@ asm: $(MPW_VARIANT_STAMP) $(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 -$(FIRMWARE_ELF): $(MPW_VARIANT_STAMP) $(MEMORY_MAP_STAMP) $(USER_EXTENSIONS_STAMP) $(VERSION_HEADER) $(SRC_PATH) $(SW_HEADERS) $(LDS_PATH) \ +$(FIRMWARE_ELF): $(MPW_VARIANT_STAMP) $(MEMORY_MAP_STAMP) $(USER_EXTENSIONS_STAMP) $(ARCHINFO_METADATA_STAMP) $(VERSION_HEADER) $(SRC_PATH) $(SW_HEADERS) $(LDS_PATH) \ $(ROOT_PATH)/rtl/mini/mk/software.mk @mkdir -p $(SW_BUILD_DIR) cd $(SW_BUILD_DIR) && $(CP) -P -o $(LINK_TYPE).lds $(LDS_PATH) diff --git a/rtl/mini/script/generate_filelist.py b/rtl/mini/script/generate_filelist.py index 7bbd8e13..3d4d84e3 100644 --- a/rtl/mini/script/generate_filelist.py +++ b/rtl/mini/script/generate_filelist.py @@ -54,7 +54,9 @@ def expand_lint_config(content: str) -> str: return expanded -def generate_all(output_dir: Path, defines: list[str]) -> list[Path]: +def generate_all( + output_dir: Path, defines: list[str], incdirs: list[Path] | None = None +) -> list[Path]: output_dir.mkdir(parents=True, exist_ok=True) generated: list[Path] = [] @@ -92,7 +94,8 @@ def generate_all(output_dir: Path, defines: list[str]) -> list[Path]: generated.append(lint_destination) def_file = output_dir / "def.fl" - atomic_write(def_file, " ".join(defines) + "\n") + include_tokens = [f"+incdir+{path.resolve()}" for path in (incdirs or [])] + atomic_write(def_file, " ".join([*include_tokens, *defines]) + "\n") generated.append(def_file) return generated @@ -103,6 +106,9 @@ def parse_args() -> argparse.Namespace: "--output-dir", type=Path, default=DEFAULT_OUTPUT_DIR, help="output directory" ) parser.add_argument("--define", action="append", default=[], help="filelist +define+ token") + parser.add_argument( + "--incdir", action="append", default=[], type=Path, help="generated include directory" + ) return parser.parse_args() @@ -111,7 +117,7 @@ def main() -> int: invalid = [item for item in args.define if not item.startswith("+define+")] if invalid: raise SystemExit(f"invalid define token(s): {' '.join(invalid)}") - generated = generate_all(args.output_dir.resolve(), args.define) + generated = generate_all(args.output_dir.resolve(), args.define, args.incdir) print(f"generated {len(generated)} files in {args.output_dir.resolve()}") return 0 diff --git a/rtl/mini/top/ip_apb_wrapper.sv b/rtl/mini/top/ip_apb_wrapper.sv index f3114eb9..d5901079 100644 --- a/rtl/mini/top/ip_apb_wrapper.sv +++ b/rtl/mini/top/ip_apb_wrapper.sv @@ -14,6 +14,7 @@ `include "ps2_define.svh" `include "user_extensions.svh" `include "soc_irq_config.svh" +`include "archinfo_integration_metadata.svh" module ip_apb_wrapper ( // verilog_format: off @@ -32,33 +33,119 @@ module ip_apb_wrapper ( // verilog_format: on ); + localparam logic [7:0] ARCHINFO_MGMT_HART_COUNT = 8'd1; + localparam logic [7:0] ARCHINFO_USER_CORE_COUNT = `USER_CORE_COUNT; + localparam logic [7:0] ARCHINFO_GPIO_COUNT = 8'd32; + localparam logic [7:0] ARCHINFO_IRQ_COUNT = `SOC_IRQ_VECTOR_WIDTH; + localparam logic [31:0] ARCHINFO_TOPOLOGY = { + ARCHINFO_IRQ_COUNT, ARCHINFO_GPIO_COUNT, ARCHINFO_USER_CORE_COUNT, ARCHINFO_MGMT_HART_COUNT + }; + +`ifdef HAVE_PLL + localparam logic ARCHINFO_HAVE_PLL = 1'b1; +`else + localparam logic ARCHINFO_HAVE_PLL = 1'b0; +`endif +`ifdef HAVE_SRAM_IF + localparam logic ARCHINFO_HAVE_SRAM_IF = 1'b1; + localparam logic [31:0] ARCHINFO_SRAM_BYTES = 32'd131_072; +`else + localparam logic ARCHINFO_HAVE_SRAM_IF = 1'b0; + localparam logic [31:0] ARCHINFO_SRAM_BYTES = 32'd0; +`endif +`ifdef HAVE_SRAM_MACRO + localparam logic ARCHINFO_HAVE_SRAM_MACRO = 1'b1; +`else + localparam logic ARCHINFO_HAVE_SRAM_MACRO = 1'b0; +`endif + + localparam logic [31:0] ARCHINFO_FEATURES0 = + 32'h0000_FFF8 | {31'd0, ARCHINFO_HAVE_PLL} | + ({31'd0, ARCHINFO_HAVE_SRAM_IF} << 1) | ({31'd0, ARCHINFO_HAVE_SRAM_MACRO} << 2); + +`ifdef PDK_IHP130 + localparam logic [31:0] ARCHINFO_TECHNOLOGY = 32'h0201_0082; +`elsif PDK_GF180 + localparam logic [31:0] ARCHINFO_TECHNOLOGY = 32'h0202_00B4; +`elsif PDK_SKY130 + localparam logic [31:0] ARCHINFO_TECHNOLOGY = 32'h0203_0082; +`elsif PDK_ICS55 + localparam logic [31:0] ARCHINFO_TECHNOLOGY = 32'h0204_0037; +`else + localparam logic [31:0] ARCHINFO_TECHNOLOGY = 32'h0000_0000; +`endif + // Generated timed and pure scalar APB interfaces preserve FPGA compatibility. `include "soc_apb_interfaces.svh" // Low-frequency peripherals retain their dedicated interfaces. rtc_if u_rtc_if ( - clk_aud_i, - rst_aud_n_i + .rtc_clk_i (clk_aud_i), + .rtc_rst_n_i(rst_aud_n_i) ); - wdg_if u_wdg_if (clk_aud_i); - tmr_if u_tmr_if (clk_aud_i); + wdg_if u_wdg_if (.rtc_clk_i(clk_aud_i)); + tmr_if u_tmr_if (.exclk_i(clk_aud_i)); assign u_tmr_if.capch_i = tmr_capch_i; `include "soc_apb_bridges.svh" // verilog_format: off - apb4_archinfo u_apb4_archinfo (u_archinfo_apb_if); - apb4_rng u_apb4_rng (u_rng_apb_if); - apb4_uart #(.FIFO_DEPTH(32)) u_apb4_uart (u_uart1_apb_if, uart); - apb4_pwm u_apb4_pwm (u_pwm_apb_if, pwm); - apb4_ps2 u_apb4_ps2 (u_ps2_apb_if, ps2); - apb4_rtc u_apb4_rtc (u_rtc_apb_if, u_rtc_if); - apb4_wdg u_apb4_wdg (u_wdg_apb_if, u_wdg_if); - apb4_crc u_apb4_crc (u_crc_apb_if); - apb4_tmr u_apb4_tmr (u_tmr_apb_if, u_tmr_if); + apb4_archinfo #( + .VENDOR_ID (32'h0000_0000), + .SOC_REVISION (32'h0001_0000), + .BUILD_ID (`ARCHINFO_INTEGRATION_BUILD_ID), + .CONFIG_ID (`ARCHINFO_INTEGRATION_CONFIG_ID), + .BUILD_STATUS (`ARCHINFO_INTEGRATION_BUILD_STATUS), + .REFERENCE_CLOCK_HZ(`SOC_EXT_CLK_HZ), + .SRAM_BYTES (ARCHINFO_SRAM_BYTES), + .TOPOLOGY (ARCHINFO_TOPOLOGY), + .FEATURES0 (ARCHINFO_FEATURES0), + .TECHNOLOGY (ARCHINFO_TECHNOLOGY) + ) u_apb4_archinfo ( + .device_id_i (128'h0000_0000_0000_0000_0000_0000_0000_0000), + .device_id_valid_i (1'b0), + .device_id_read_enable_i(1'b0), + .apb4 (u_archinfo_apb_if) + ); // verilog_format: on + apb4_rng u_apb4_rng (.apb4(u_rng_apb_if)); + + apb4_uart #( + .FIFO_DEPTH(32) + ) u_apb4_uart ( + .apb4(u_uart1_apb_if), + .uart(uart) + ); + + apb4_pwm u_apb4_pwm ( + .apb4(u_pwm_apb_if), + .pwm (pwm) + ); + + apb4_ps2 u_apb4_ps2 ( + .apb4(u_ps2_apb_if), + .ps2 (ps2) + ); + + apb4_rtc u_apb4_rtc ( + .apb4(u_rtc_apb_if), + .rtc (u_rtc_if) + ); + + apb4_wdg u_apb4_wdg ( + .apb4(u_wdg_apb_if), + .wdg (u_wdg_if) + ); + + apb4_crc u_apb4_crc (.apb4(u_crc_apb_if)); + + apb4_tmr u_apb4_tmr ( + .apb4(u_tmr_apb_if), + .tmr (u_tmr_if) + ); + // Generated IRQ ownership and core-vector bit assignments are topology checked. `include "soc_apb_irq_bindings.svh" diff --git a/rtl/mini/top/user_ip_wrapper.sv b/rtl/mini/top/user_ip_wrapper.sv index 42b78a03..4fcf6274 100644 --- a/rtl/mini/top/user_ip_wrapper.sv +++ b/rtl/mini/top/user_ip_wrapper.sv @@ -20,11 +20,21 @@ module user_ip_wrapper ( // verilog_format: on ); - // verilog_format: off - apb4_if u_demo_apb4_if(clk_i, rst_n_i); - apb4_if u_user_apb4_if(clk_i, rst_n_i); - apb4_archinfo u_apb4_archinfo_ip(u_demo_apb4_if); - // verilog_format: on + apb4_if u_demo_apb4_if ( + .pclk (clk_i), + .presetn(rst_n_i) + ); + apb4_if u_user_apb4_if ( + .pclk (clk_i), + .presetn(rst_n_i) + ); + + apb4_archinfo u_apb4_archinfo_ip ( + .device_id_i (128'h0000_0000_0000_0000_0000_0000_0000_0000), + .device_id_valid_i (1'b0), + .device_id_read_enable_i(1'b0), + .apb4 (u_demo_apb4_if) + ); assign apb.pready = ~(|sel_i) ? u_demo_apb4_if.pready : u_user_apb4_if.pready; assign apb.prdata = ~(|sel_i) ? u_demo_apb4_if.prdata : u_user_apb4_if.prdata; diff --git a/tests/test_script_tools.py b/tests/test_script_tools.py index 526694eb..b06174ab 100644 --- a/tests/test_script_tools.py +++ b/tests/test_script_tools.py @@ -108,11 +108,14 @@ def test_nested_filelist_and_space_path_round_trip(tmp_path: Path) -> None: def test_generate_all_is_stable_and_expands_paths(tmp_path: Path) -> None: defines = ["+define+PDK_IHP130"] - generated = generate_all(tmp_path, defines) + generated_include = tmp_path / "archinfo metadata" + generated = generate_all(tmp_path, defines, [generated_include]) mtimes = {path: path.stat().st_mtime_ns for path in generated} - generate_all(tmp_path, defines) + generate_all(tmp_path, defines, [generated_include]) assert {path: path.stat().st_mtime_ns for path in generated} == mtimes - assert (tmp_path / "def.fl").read_text(encoding="utf-8") == " ".join(defines) + "\n" + assert (tmp_path / "def.fl").read_text(encoding="utf-8") == ( + f"+incdir+{generated_include.resolve()} " + " ".join(defines) + "\n" + ) cluster = (tmp_path / "clusterip.fl").read_text(encoding="utf-8") hazard3 = (tmp_path / "core_hazard3.fl").read_text(encoding="utf-8") assert str(ROOT / "rtl/managed/clusterip") in cluster