feat: refactor tests and update configurations for OpenC906 migration

- Adjusted slot assignments in  to reflect new peripheral mappings.
- Updated  to validate new OpenC906 configurations, including generator and profile checks.
- Modified  to reference the new Std-series VexiiRiscv generator.
- Changed cache maintenance instructions in  to align with C906 specifications.
- Revised assertions in  to account for internal unit removals.
- Updated  to reflect changes in peripheral interface counts and policies.
- Added new test file  to ensure preservation of the frozen HP configuration in the Std-series generator.
This commit is contained in:
maksyuki committed 2026-10-10 15:15:21 +08:00
1 parent 3e46cc80e2
commit 8d735aafbd
133 files changed
+8797 -2420

No files matched your search

+10
View File
@@ -1,5 +1,15 @@
# Third-party attribution
The Mini high-performance (HP) core is the pre-generated T-Head OpenC906 RTL
from [XUANTIE-RV/openc906](https://github.com/XUANTIE-RV/openc906), locked at
commit `b0c06eb1f8b3bae663bd8b87eac89ff48e68a57f` in
`dependencies/dependencies.lock.json` and installed below
`.cache/retrosoc/sources/openc906`. OpenC906 is licensed under Apache-2.0; its
copyright and license files remain in the locked checkout and are not copied
into this repository. The single retroSoC-controlled substitution is the
reviewed hart-ID override `rtl/mini/ip_overrides/aq_sysio_kid.v`, which
retains the upstream Apache-2.0 header.
The optional HP RT-Thread kernel is official RT-Thread v5.3.0, commit
`99428a1e7f7447955aa860f7c969273a12095b8f`, from
[RT-Thread/rt-thread](https://github.com/RT-Thread/rt-thread). It is licensed
+30 -19
View File
@@ -51,7 +51,6 @@ PDK_BEHAV ?= NO
HAVE_SVA ?= NO
APU_ENABLE_P7 ?= NO
HAVE_HP ?= $(if $(filter TINY,$(SOC)),NO,YES)
HP_CONFIG ?= rv64imafdc_zicbom_max
BUILD_RELEASE ?= NO
JTAG_IDCODE ?= DEADBEEF
EXT_CLK_HZ ?= 72000000
@@ -97,6 +96,7 @@ HP_COREMARK_REPORT ?=
BUILD_ROOT ?= $(ROOT_PATH)/build
CACHE_ROOT ?= $(ROOT_PATH)/.cache/retrosoc
VEXIIRISCV_ROOT ?= $(ROOT_PATH)/.cache/retrosoc/sources/vexiiriscv
OPENC906_ROOT ?= $(ROOT_PATH)/.cache/retrosoc/sources/openc906
SBT ?= sbt
BUILD_TIMESTAMP ?= $(shell date '+%Y-%m-%d-%H-%M')
BUILD_TIMESTAMP := $(BUILD_TIMESTAMP)
@@ -117,7 +117,7 @@ JOBS ?= $(shell count=$$(nproc 2>/dev/null || printf '1'); \
else printf '%s' "$$count"; fi)
LOCAL_RTL_FILES ?=
CONFIG_KEY_VARS := SOC MINI_MODE PDK HAVE_PLL HAVE_SRAM_IF HAVE_SRAM_MACRO SRAM_SIZE_KIB PDK_BEHAV HAVE_SVA APU_ENABLE_P7 \
HAVE_HP HP_CONFIG BUILD_RELEASE JTAG_IDCODE EXT_CLK_HZ AUD_CLK_HZ CLINT_TIMEBASE_HZ MGMT_CPU_CLK_HZ \
HAVE_HP BUILD_RELEASE JTAG_IDCODE EXT_CLK_HZ AUD_CLK_HZ CLINT_TIMEBASE_HZ MGMT_CPU_CLK_HZ \
ISA HAVE_CSR APP LINK_TYPE COREMARK_MODE RTL_TOP FIRMWARE_NAME
CONFIG_KEY_VARS += NPU_P5_ACCEPTANCE NPU_P6_ACCEPTANCE NPU_P6_WORKLOAD
# Preserve existing baseline keys; experimental software inputs have distinct variants.
@@ -142,8 +142,8 @@ SW_BUILD_DIR := $(VARIANT_ROOT)/sw
SIM_TOOL_NAME := $(shell printf '%s' '$(SIMU)' | tr '[:upper:]' '[:lower:]')
SIM_BUILD_ROOT := $(VARIANT_ROOT)/sim/$(SIM_TOOL_NAME)
META_DIR := $(VARIANT_ROOT)/meta
HP_GENERATED_DIR := $(VARIANT_ROOT)/generated/vexiiriscv
HP_GENERATED_RTL := $(HP_GENERATED_DIR)/vexii_riscv_hp_generated.v
HP_GENERATED_DIR := $(VARIANT_ROOT)/generated/openc906
HP_GENERATED_FL := $(HP_GENERATED_DIR)/openc906.fl
HP_GENERATED_MANIFEST := $(HP_GENERATED_DIR)/manifest.json
HP_GENERATED_STAMP := $(HP_GENERATED_DIR)/.stamp
APU_P5_DIR := $(VARIANT_ROOT)/apu/p5
@@ -243,7 +243,6 @@ VALID_SYNTH_RECIPE := balanced area speed
VALID_STA := NONE OPENSTA
VALID_PDK := ICS55 IHP130 SKY130 GF180
VALID_BOOL := YES NO
VALID_HP_CONFIG := rv64imafdc_zicbom_max
VALID_ISA := RV32E RV32I RV32IM
VALID_APP := benchmark bringup ci_smoke coremark debug hp_boot shell xpi_flash_loader apu_release
VALID_LINK_TYPE := xip jtag_sram ld2_all_sram ld2_sram ld2_psram ld2_sdram ld2_tiny_banked
@@ -269,7 +268,6 @@ $(call validate_value,PDK_BEHAV,$(VALID_BOOL))
$(call validate_value,HAVE_SVA,$(VALID_BOOL))
$(call validate_value,APU_ENABLE_P7,$(VALID_BOOL))
$(call validate_value,HAVE_HP,$(VALID_BOOL))
$(call validate_value,HP_CONFIG,$(VALID_HP_CONFIG))
$(call validate_value,BUILD_RELEASE,$(VALID_BOOL))
$(call validate_value,WAVE,$(VALID_BOOL))
$(call validate_value,FORMAL,$(VALID_BOOL))
@@ -522,7 +520,7 @@ crypto-p2-report: manifest
--netlist-root $(CRYPTO_P2_NETLIST_ROOT) --sta-root $(CRYPTO_P2_STA_ROOT) \
--physical-root $(CRYPTO_P2_PHYSICAL_ROOT)
.PHONY: help config doctor setup setup-regression setup-mpw setup-vexiiriscv setup-clusterip setup-ip setup-pdk setup-app setup-apu-reference setup-apu-kws-reference apu-p5-bundle apu-p5-corpus apu-p7-model apu-p9-coefficients apu-p9-evidence apu-p9-memory-ab setup-hp-linux hp-linux hp-bundle hp-linux-sim hp-smoke-bundle hp-smoke-sim hp-apu-bundle hp-apu-sim \
.PHONY: help config doctor setup setup-regression setup-mpw setup-vexiiriscv setup-openc906 setup-clusterip setup-ip setup-pdk setup-app setup-apu-reference setup-apu-kws-reference apu-p5-bundle apu-p5-corpus apu-p7-model apu-p9-coefficients apu-p9-evidence apu-p9-memory-ab setup-hp-linux hp-linux hp-bundle hp-linux-sim hp-smoke-bundle hp-smoke-sim hp-apu-bundle hp-apu-sim \
clean-all purge-cache manifest check-warnings metrics check-metrics package commercial-package \
regress-smoke regress-rtl regress-pr regress-nightly sim-asm format format-check sw-format sw-format-check mk-format \
mk-format-check rtl-format rtl-format-check rtl-style-check rtl-migrate-connections rtl-migrate-names sw-policy-check sw-host-test \
@@ -532,7 +530,7 @@ crypto-p2-report: manifest
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 \
rtl-style-check-all rtl-readiness-check rtl-readiness-check-all vexii-generate
rtl-style-check-all rtl-readiness-check rtl-readiness-check-all openc906-prepare std-vexii-generate
.NOTPARALLEL: setup
help:
@@ -607,7 +605,8 @@ help:
' soc-topology generate the selected internal SoC integration artifacts' \
' check-soc-topology validate the canonical internal SoC integration map' \
' user-extensions generate the selected scalar user-extension bindings' \
' vexii-generate generate the locked HP VexiiRiscv RTL below build/' \
' openc906-prepare emit the locked HP OpenC906 filelist below build/' \
' std-vexii-generate generate the Std-series VexiiRiscv RTL below build/ (Std asset)' \
' check-user-extensions validate the canonical user-extension map' \
' check-clock-reset-domains validate the root clock/reset and CDC inventory' \
' rtl-lint | check-rtl-lint run/check strict Verilator RTL lint warnings' \
@@ -655,7 +654,7 @@ config:
HAVE_PLL '$(HAVE_PLL)' HAVE_SRAM_IF '$(HAVE_SRAM_IF)' \
HAVE_SRAM_MACRO '$(HAVE_SRAM_MACRO)' SRAM_SIZE_KIB '$(SRAM_SIZE_KIB)' \
PDK_BEHAV '$(PDK_BEHAV)' HAVE_SVA '$(HAVE_SVA)' APU_ENABLE_P7 '$(APU_ENABLE_P7)' \
HAVE_HP '$(HAVE_HP)' HP_CONFIG '$(HP_CONFIG)' BUILD_RELEASE '$(BUILD_RELEASE)' \
HAVE_HP '$(HAVE_HP)' BUILD_RELEASE '$(BUILD_RELEASE)' \
JTAG_IDCODE '$(JTAG_IDCODE)' EXT_CLK_HZ '$(EXT_CLK_HZ)' AUD_CLK_HZ '$(AUD_CLK_HZ)' \
CLINT_TIMEBASE_HZ '$(CLINT_TIMEBASE_HZ)' MGMT_CPU_CLK_HZ '$(MGMT_CPU_CLK_HZ)' \
ISA '$(ISA)' HAVE_CSR '$(HAVE_CSR)' APP '$(APP)' \
@@ -691,7 +690,7 @@ setup: setup-tiny
setup-tiny:
python3 $(ROOT_PATH)/scripts/setup_tiny.py --pdk $(PDK)
else
setup: setup-mpw setup-vexiiriscv setup-clusterip setup-ip setup-pdk setup-app
setup: setup-mpw setup-openc906 setup-clusterip setup-ip setup-pdk setup-app
endif
setup-regression:
@@ -710,6 +709,9 @@ setup-mpw:
setup-vexiiriscv:
python3 $(ROOT_PATH)/scripts/setup_vexiiriscv.py
setup-openc906:
python3 $(ROOT_PATH)/scripts/setup_openc906.py
setup-clusterip:
python3 $(ROOT_PATH)/rtl/managed/clusterip/setup.py
@@ -1102,19 +1104,28 @@ npu-p5-lp-sim: firmware sim
--require 'NPU_P5_LP model=kws' --require 'SIM_TEST_PASS code=0'
ifeq ($(HAVE_HP),YES)
$(HP_GENERATED_STAMP): $(ROOT_PATH)/scripts/generate_vexiiriscv.py \
$(ROOT_PATH)/scripts/vexiiriscv/GenerateRetroSocHp.scala $(LOCK_FILE)
python3 $(ROOT_PATH)/scripts/generate_vexiiriscv.py \
--root $(ROOT_PATH) --source $(VEXIIRISCV_ROOT) --output $(HP_GENERATED_DIR) \
--manifest $(HP_GENERATED_MANIFEST) --lock $(LOCK_FILE) --sbt $(SBT)
$(HP_GENERATED_STAMP): $(ROOT_PATH)/scripts/generate_openc906.py \
$(ROOT_PATH)/rtl/mini/ip_overrides/aq_sysio_kid.v \
$(ROOT_PATH)/rtl/mini/ip_overrides/sysmap.h $(LOCK_FILE)
python3 $(ROOT_PATH)/scripts/generate_openc906.py \
--root $(ROOT_PATH) --source $(OPENC906_ROOT) --output $(HP_GENERATED_DIR) \
--manifest $(HP_GENERATED_MANIFEST) --lock $(LOCK_FILE)
@touch $@
vexii-generate: $(HP_GENERATED_STAMP)
openc906-prepare: $(HP_GENERATED_STAMP)
else
vexii-generate:
@printf '%s\n' 'HAVE_HP=NO; no VexiiRiscv RTL is required'
openc906-prepare:
@printf '%s\n' 'HAVE_HP=NO; no OpenC906 RTL is required'
endif
# Std-series asset: the VexiiRiscv generator no longer participates in the
# Mini build; it is preserved here for the future Std performance core.
STD_VEXII_DIR := $(VARIANT_ROOT)/generated/vexiiriscv
std-vexii-generate:
python3 $(ROOT_PATH)/scripts/generate_vexiiriscv.py \
--root $(ROOT_PATH) --source $(VEXIIRISCV_ROOT) --output $(STD_VEXII_DIR) \
--manifest $(STD_VEXII_DIR)/manifest.json --lock $(LOCK_FILE) --sbt $(SBT)
clean-all:
python3 $(ROOT_PATH)/scripts/clean.py --root $(ROOT_PATH) --path $(abspath $(BUILD_ROOT))
+2 -2
View File
@@ -19,7 +19,7 @@ An open-source RISC-V SoC platform, from SystemVerilog RTL and firmware to repro
## Platform overview
**Mini and Tiny have independent integration flows.** Mini combines a
low-power Hazard3 management hart and a VexiiRiscv application hart; its separate
low-power Hazard3 management hart and a T-Head OpenC906 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 defaults to ICS55 SAFE24 with a parked PLL and retains
@@ -34,7 +34,7 @@ multimedia inputs.
| Area | Mini platform |
| --- | --- |
| Compute | Hazard3 LP management hart; generated dual-issue VexiiRiscv HP application hart. Baseline profiles compile LP firmware for RV32IM and select an RV64IMAFDC HP core with Zicbom cache maintenance. |
| Compute | Hazard3 LP management hart; locked pre-generated T-Head OpenC906 HP application hart. Baseline profiles compile LP firmware for RV32IM and use the OpenC906 DEFAULT RV64GC configuration with T-Head custom cache-maintenance instructions. |
| Memory and interconnect | Native AXI4 data plane, APB4 control, configurable on-chip SRAM, SDRAM, PSRAM/OPI-PSRAM, and XPI flash integration. |
| Control and I/O | GPIO, timers, UART, I2C, I2S, PWM, RTC, watchdog, storage interfaces, DMA, interrupt routing, and fixed EXT-L/EXT-H extension slots. |
| Software | Freestanding C runtime and HAL, board support, diagnostic and shell applications, CoreMark, and HP boot/bundle tooling. |
+4 -2
View File
@@ -503,7 +503,8 @@ static void rs_npu_p6_clean_range(const void *pointer, uint32_t bytes) {
uintptr_t end = ((uintptr_t)pointer + bytes + UINT32_C(63)) & ~(uintptr_t)UINT32_C(63);
while (cursor < end) {
__asm__ volatile("cbo.clean 0(%0)" : : "r"(cursor) : "memory");
/* OpenC906 dcache.cva: clean the 64-byte D-cache line at cursor. */
__asm__ volatile(".insn r 0x0b, 0x0, 0x01, x0, %0, x5" : : "r"(cursor) : "memory");
cursor += UINT32_C(64);
}
}
@@ -513,7 +514,8 @@ static void rs_npu_p6_invalidate_range(const void *pointer, uint32_t bytes) {
uintptr_t end = ((uintptr_t)pointer + bytes + UINT32_C(63)) & ~(uintptr_t)UINT32_C(63);
while (cursor < end) {
__asm__ volatile("cbo.inval 0(%0)" : : "r"(cursor) : "memory");
/* OpenC906 dcache.iva: invalidate the 64-byte D-cache line at cursor. */
__asm__ volatile(".insn r 0x0b, 0x0, 0x01, x0, %0, x6" : : "r"(cursor) : "memory");
cursor += UINT32_C(64);
}
__asm__ volatile("fence r, r" : : : "memory");
+16 -14
View File
@@ -25,7 +25,7 @@
#define HP_MAILBOX_HP_DOORBELL UINT32_C(0x2C)
#define HP_MAILBOX_HP_INTR_STATE UINT32_C(0x40)
#define HP_CBO_LINE_BYTES UINT32_C(64)
#define HP_CACHE_LINE_BYTES UINT32_C(64)
#define HP_MAILBOX_BUDGET UINT32_C(0x08000000)
#define HP_JOB_BUDGET UINT32_C(0x08000000)
#define HP_JOB_TERMINAL \
@@ -77,24 +77,26 @@ static void hp_uart_puthex(uint32_t value) {
}
}
static void hp_cbo_clean(uint32_t address, uint32_t bytes) {
uint32_t cursor = address & ~(HP_CBO_LINE_BYTES - 1U);
static void hp_dcache_clean(uint32_t address, uint32_t bytes) {
uint32_t cursor = address & ~(HP_CACHE_LINE_BYTES - 1U);
const uint32_t end = address + bytes;
while (cursor < end) {
__asm__ volatile("cbo.clean 0(%0)" ::"r"(cursor) : "memory");
cursor += HP_CBO_LINE_BYTES;
/* OpenC906 dcache.cva: clean the 64-byte D-cache line at cursor. */
__asm__ volatile(".insn r 0x0b, 0x0, 0x01, x0, %0, x5" ::"r"(cursor) : "memory");
cursor += HP_CACHE_LINE_BYTES;
}
__asm__ volatile("fence rw, rw" ::: "memory");
}
static void hp_cbo_inval(uint32_t address, uint32_t bytes) {
uint32_t cursor = address & ~(HP_CBO_LINE_BYTES - 1U);
static void hp_dcache_inval(uint32_t address, uint32_t bytes) {
uint32_t cursor = address & ~(HP_CACHE_LINE_BYTES - 1U);
const uint32_t end = address + bytes;
while (cursor < end) {
__asm__ volatile("cbo.inval 0(%0)" ::"r"(cursor) : "memory");
cursor += HP_CBO_LINE_BYTES;
/* OpenC906 dcache.iva: invalidate the 64-byte D-cache line at cursor. */
__asm__ volatile(".insn r 0x0b, 0x0, 0x01, x0, %0, x6" ::"r"(cursor) : "memory");
cursor += HP_CACHE_LINE_BYTES;
}
__asm__ volatile("fence rw, rw" ::: "memory");
}
@@ -200,7 +202,7 @@ static bool hp_submit_wav(volatile rs_apu_release_page_t *page) {
!hp_range_in(page->output_address, page->output_capacity, write_base, write_limit)) {
return false;
}
hp_cbo_clean(page->wav_address, page->wav_bytes);
hp_dcache_clean(page->wav_address, page->wav_bytes);
*hp_reg(apu + RS_APU_ABI_JOB_CONTROL) = 0U;
*hp_reg(apu + RS_APU_ABI_JOB_INPUT_ADDRESS) = page->wav_address;
*hp_reg(apu + RS_APU_ABI_JOB_INPUT_LENGTH) = page->wav_bytes;
@@ -221,7 +223,7 @@ static bool hp_submit_wav(volatile rs_apu_release_page_t *page) {
if ((page->wav_status & (UINT32_C(1) << RS_APU_ABI_JOB_STATUS_DONE)) == 0U) {
return false;
}
hp_cbo_inval(page->output_address, page->wav_output_bytes);
hp_dcache_inval(page->output_address, page->wav_output_bytes);
page->wav_output_crc =
hp_crc32((volatile const uint8_t *)(uintptr_t)page->output_address, page->wav_output_bytes);
page->hp_steps |= RS_APU_RELEASE_STEP_WAV_DONE;
@@ -240,7 +242,7 @@ static bool hp_submit_kws(volatile rs_apu_release_page_t *page) {
}
*hp_reg(apu + RS_APU_ABI_KWS_CONTROL) = UINT32_C(3);
page->hp_steps |= RS_APU_RELEASE_STEP_KWS_ARM;
hp_cbo_clean(page->kws_address, page->kws_bytes);
hp_dcache_clean(page->kws_address, page->kws_bytes);
*hp_reg(apu + RS_APU_ABI_JOB_CONTROL) = UINT32_C(1);
*hp_reg(apu + RS_APU_ABI_JOB_INPUT_ADDRESS) = page->kws_address;
*hp_reg(apu + RS_APU_ABI_JOB_INPUT_LENGTH) = page->kws_bytes;
@@ -295,7 +297,7 @@ static void hp_publish(volatile rs_apu_release_page_t *page, uint32_t summary) {
page->hp_steps |= RS_APU_RELEASE_STEP_PUBLISH;
page->result_magic = RS_APU_RELEASE_RESULT_MAGIC;
hp_cbo_clean(RS_APU_RELEASE_PAGE_ADDRESS, RS_APU_RELEASE_PAGE_BYTES);
hp_dcache_clean(RS_APU_RELEASE_PAGE_ADDRESS, RS_APU_RELEASE_PAGE_BYTES);
mailbox[HP_MAILBOX_HP_EVENT / 4U] = RS_APU_RELEASE_EVENT_DONE;
mailbox[HP_MAILBOX_HP_ARG0 / 4U] = summary;
mailbox[HP_MAILBOX_HP_SEQUENCE / 4U] = RS_APU_RELEASE_MAILBOX_SEQUENCE;
@@ -340,7 +342,7 @@ void main(void) {
}
}
hp_milestone("MAILBOX");
hp_cbo_inval(RS_APU_RELEASE_PAGE_ADDRESS, RS_APU_RELEASE_PAGE_BYTES);
hp_dcache_inval(RS_APU_RELEASE_PAGE_ADDRESS, RS_APU_RELEASE_PAGE_BYTES);
page->hp_steps = RS_APU_RELEASE_STEP_MAILBOX;
if ((code != RS_APU_RELEASE_JOB_RUN) || (argument != RS_APU_RELEASE_PAGE_ADDRESS) ||
(page->magic != RS_APU_RELEASE_PAGE_MAGIC) ||
+1 -1
View File
@@ -1,7 +1,7 @@
# HP Linux Port
This directory owns the Buildroot external tree, device tree, kernel config,
and integration metadata for the fixed RV64 VexiiRiscv HP core. Linux,
and integration metadata for the fixed RV64GC T-Head OpenC906 HP core. Linux,
OpenSBI, Buildroot, toolchains, and all generated images remain below `.cache/`
or `build/` and are not tracked.
+23 -12
View File
@@ -18,15 +18,14 @@
timebase-frequency = <1000000>;
cpu@1 {
compatible = "spinal,vexiiriscv", "riscv";
compatible = "thead,c906", "riscv";
device_type = "cpu";
reg = <1>;
clock-frequency = <72000000>;
mmu-type = "riscv,sv39";
riscv,isa-base = "rv64i";
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicbom",
riscv,isa-extensions = "i", "m", "a", "f", "d", "c",
"zicsr", "zifencei";
riscv,cbom-block-size = <64>;
hp_cpu_intc: interrupt-controller {
compatible = "riscv,cpu-intc";
@@ -60,15 +59,27 @@
#size-cells = <1>;
ranges;
hp_aclint: timer@2000000 {
compatible = "sifive,clint0";
reg = <0x02000000 0x00010000>;
interrupts-extended = <&hp_cpu_intc 3>, <&hp_cpu_intc 7>;
/*
* Internal C906 CLINT (thead,c900-clint): decoded by the core
* BIU, not a SoC fabric slave. No memory-mapped mtime; software
* reads the time CSR. Interrupt order per hart: M-SW, M-timer,
* S-SW, S-timer.
*/
hp_clint: timer@c000000 {
compatible = "thead,c900-clint";
reg = <0x0c000000 0x00010000>;
interrupts-extended = <&hp_cpu_intc 3>, <&hp_cpu_intc 7>,
<&hp_cpu_intc 1>, <&hp_cpu_intc 5>;
};
hp_plic: interrupt-controller@c000000 {
compatible = "sifive,plic-1.0.0";
reg = <0x0c000000 0x04000000>;
/*
* Internal C906 PLIC (thead,c900-plic): decoded by the core
* BIU. SoC external source n is PLIC ID n+16; IDs 0-15 are
* reserved/internal.
*/
hp_plic: interrupt-controller@8000000 {
compatible = "thead,c900-plic";
reg = <0x08000000 0x04000000>;
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <1>;
@@ -80,7 +91,7 @@
compatible = "retrosoc,uart-v3";
reg = <0x10018000 0x1000>;
interrupt-parent = <&hp_plic>;
interrupts = <1>;
interrupts = <17>;
clock-frequency = <72000000>;
status = "okay";
};
@@ -89,7 +100,7 @@
compatible = "retrosoc,hp-mailbox-v1";
reg = <0x10019000 0x1000>;
interrupt-parent = <&hp_plic>;
interrupts = <2>;
interrupts = <18>;
#mbox-cells = <1>;
};
};
@@ -3,5 +3,4 @@
config PLATFORM_RETROSOC_HP
bool
select IPI_MSWI
select TIMER_MTIMER
default y
+45 -16
View File
@@ -1,13 +1,18 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright (c) 2026 Yuchi Miao */
#include <sbi/riscv_asm.h>
#include <sbi/riscv_encoding.h>
#include <sbi/riscv_io.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_platform.h>
#include <sbi/sbi_timer.h>
#include <sbi_utils/ipi/aclint_mswi.h>
#include <sbi_utils/timer/aclint_mtimer.h>
#define RETROSOC_HP_ACLINT_BASE 0x02000000UL
/* Internal C906 CLINT (thead,c900-clint), decoded by the core BIU. */
#define RETROSOC_HP_CLINT_BASE 0x0C000000UL
#define RETROSOC_HP_CLINT_MTIMECMP_LO 0x4000UL
#define RETROSOC_HP_CLINT_MTIMECMP_HI 0x4004UL
#define RETROSOC_HP_UART_BASE 0x10018000UL
#define RETROSOC_HP_UART_BAUD_INT 78U
#define RETROSOC_HP_UART_BAUD_FRAC 32U
@@ -30,21 +35,44 @@
static const u32 s_hart_index_to_id[] = {1U};
static struct aclint_mswi_data s_mswi = {
.addr = RETROSOC_HP_ACLINT_BASE,
.addr = RETROSOC_HP_CLINT_BASE,
.size = ACLINT_MSWI_SIZE,
.first_hartid = 0U,
.hart_count = 2U,
.first_hartid = 1U,
.hart_count = 1U,
};
static struct aclint_mtimer_data s_mtimer = {
.mtime_freq = 1000000UL,
.mtime_addr = RETROSOC_HP_ACLINT_BASE + 0xBFF8UL,
.mtime_size = ACLINT_DEFAULT_MTIME_SIZE,
.mtimecmp_addr = RETROSOC_HP_ACLINT_BASE + 0x4000UL,
.mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE,
.first_hartid = 0U,
.hart_count = 2U,
.has_64bit_mmio = false,
/* No memory-mapped mtime: the SoC drives mtime into the core. */
static u64 retrosoc_hp_timer_value(void) {
return csr_read(CSR_TIME);
}
static void retrosoc_hp_mtimecmp_write(u64 value) {
writel_relaxed((u32)-1, (void *)(RETROSOC_HP_CLINT_BASE + RETROSOC_HP_CLINT_MTIMECMP_LO));
writel_relaxed((u32)(value >> 32U),
(void *)(RETROSOC_HP_CLINT_BASE + RETROSOC_HP_CLINT_MTIMECMP_HI));
writel_relaxed((u32)value, (void *)(RETROSOC_HP_CLINT_BASE + RETROSOC_HP_CLINT_MTIMECMP_LO));
}
static void retrosoc_hp_timer_event_start(u64 next_event) {
retrosoc_hp_mtimecmp_write(next_event);
}
static void retrosoc_hp_timer_event_stop(void) {
retrosoc_hp_mtimecmp_write(~0ULL);
}
static int retrosoc_hp_timer_warm_init(void) {
retrosoc_hp_timer_event_stop();
return 0;
}
static struct sbi_timer_device s_timer = {
.name = "retrosoc-hp-c906-clint",
.timer_freq = 1000000UL,
.timer_value = retrosoc_hp_timer_value,
.timer_event_start = retrosoc_hp_timer_event_start,
.timer_event_stop = retrosoc_hp_timer_event_stop,
.warm_init = retrosoc_hp_timer_warm_init,
};
static void retrosoc_hp_uart_write(u32 offset, u32 value) {
@@ -93,7 +121,8 @@ static int retrosoc_hp_early_init(bool cold_boot) {
}
static int retrosoc_hp_timer_init(void) {
return aclint_mtimer_cold_init(&s_mtimer, NULL);
sbi_timer_set_device(&s_timer);
return 0;
}
static const struct sbi_platform_operations s_platform_operations = {
@@ -104,7 +133,7 @@ static const struct sbi_platform_operations s_platform_operations = {
const struct sbi_platform platform = {
.opensbi_version = OPENSBI_VERSION,
.platform_version = SBI_PLATFORM_VERSION(1U, 0U),
.name = "retroSoC RV64 HP",
.name = "retroSoC OpenC906 HP",
.features = SBI_PLATFORM_DEFAULT_FEATURES,
.hart_count = 1U,
.hart_stack_size = SBI_PLATFORM_DEFAULT_HART_STACK_SIZE,
+2 -1
View File
@@ -17,7 +17,8 @@ static void rs_hp_npu_clean_range(const void *pointer, uint32_t bytes) {
uintptr_t end = ((uintptr_t)pointer + bytes + UINT32_C(63)) & ~(uintptr_t)UINT32_C(63);
while (cursor < end) {
__asm__ volatile("cbo.clean 0(%0)" : : "r"(cursor) : "memory");
/* OpenC906 dcache.cva: clean the 64-byte D-cache line at cursor. */
__asm__ volatile(".insn r 0x0b, 0x0, 0x01, x0, %0, x5" : : "r"(cursor) : "memory");
cursor += UINT32_C(64);
}
}
+16 -8
View File
@@ -58,6 +58,10 @@
.equ GA2D_WAIT_POLLS, 0x00100000
_start:
# Enable the T-Head extended instruction set (mxstatus.theadisaee) so the
# C906 custom-0 cache maintenance instructions below decode legally.
li t0, 0x400000
csrs 0x7c0, t0
la sp, _stack_top
la t0, _bss_start
la t1, _bss_end
@@ -257,27 +261,31 @@ prepare_source_data:
mv ra, s0
ret
# C906 cache maintenance replaces the VexiiRiscv Zicbom ops: custom-0
# encodings dcache.cva (0x0250000b | rs1<<15, clean by VA) and dcache.iva
# (0x0260000b | rs1<<15, invalidate by VA) per the OpenC906 ID decoder and
# the XTheadCmo specification. Each shared buffer remains one 64-byte line.
clean_shared_lines:
la a0, hp_source_guard
cbo.clean 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x5
la a0, hp_source_line
cbo.clean 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x5
la a0, hp_destination_line
cbo.clean 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x5
la a0, hp_destination_guard
cbo.clean 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x5
fence rw, rw
ret
invalidate_shared_lines:
la a0, hp_source_guard
cbo.inval 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x6
la a0, hp_source_line
cbo.inval 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x6
la a0, hp_destination_line
cbo.inval 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x6
la a0, hp_destination_guard
cbo.inval 0(a0)
.insn r 0x0b, 0x0, 0x01, x0, a0, x6
fence r, r
ret
+3 -2
View File
@@ -6,8 +6,9 @@ dependency lock under `.cache/`; it is not edited or copied into project source.
SCons runs on a staged BSP below `build/<variant>/hp-rtthread/`.
Run `make setup-hp-rtthread`, then `make CONFIG=configs/ci/ihp130-rtthread.mk
SIMU=VERILATOR hp-rtthread-sim`. The test uses UART1, hart-1 CLINT and PLIC
machine context 0/source 2. Peripheral accesses remain 32 bits. Static threads
SIMU=VERILATOR hp-rtthread-sim`. The test uses UART1 and the internal C906
CLINT (time CSR plus MTIMECMP at 0x0C004000) and PLIC machine context 0 with
the mailbox doorbell at source 18. Peripheral accesses remain 32 bits. Static threads
exercise RV64 integer state, timer preemption, semaphore/message queue behavior,
timeouts, and an LP-to-HP mailbox interrupt. LP validates the final mailbox
response and owns SYSCTRL TEST_STATUS. A banner alone is not a pass.
+19 -20
View File
@@ -3,10 +3,12 @@
#include <rthw.h>
#define RS_RTT_UART UINT32_C(0x10018000)
#define RS_RTT_CLINT UINT32_C(0x02000000)
#define RS_RTT_PLIC UINT32_C(0x0C000000)
#define RS_RTT_MAILBOX UINT32_C(0x10019000)
#define RS_RTT_UART UINT32_C(0x10018000)
/* Internal C906 CLINT (MSIP@0x0, MTIMECMP@0x4000) and PLIC (ID n+16). */
#define RS_RTT_CLINT UINT32_C(0x0C000000)
#define RS_RTT_PLIC UINT32_C(0x08000000)
#define RS_RTT_MAILBOX UINT32_C(0x10019000)
#define RS_RTT_MAILBOX_PLIC_ID UINT32_C(18)
static struct rt_semaphore s_mailbox_sem;
static volatile uint32_t s_irq_command;
@@ -23,19 +25,16 @@ static void rs_write32(uint32_t address, uint32_t value) {
}
static uint64_t rs_time(void) {
uint32_t high;
uint32_t low;
do {
high = rs_read32(RS_RTT_CLINT + UINT32_C(0xBFFC));
low = rs_read32(RS_RTT_CLINT + UINT32_C(0xBFF8));
} while (high != rs_read32(RS_RTT_CLINT + UINT32_C(0xBFFC)));
return ((uint64_t)high << 32U) | low;
uint64_t value;
/* No memory-mapped mtime: the SoC drives mtime into the core. */
__asm__ volatile("csrr %0, time" : "=r"(value));
return value;
}
static void rs_set_timer(uint64_t value) {
rs_write32(RS_RTT_CLINT + UINT32_C(0x4008), UINT32_MAX);
rs_write32(RS_RTT_CLINT + UINT32_C(0x400C), (uint32_t)(value >> 32U));
rs_write32(RS_RTT_CLINT + UINT32_C(0x4008), (uint32_t)value);
rs_write32(RS_RTT_CLINT + UINT32_C(0x4000), UINT32_MAX);
rs_write32(RS_RTT_CLINT + UINT32_C(0x4004), (uint32_t)(value >> 32U));
rs_write32(RS_RTT_CLINT + UINT32_C(0x4000), (uint32_t)value);
__asm__ volatile("fence iorw, iorw" ::: "memory");
}
@@ -82,11 +81,11 @@ static void rs_assert(const char *expression, const char *function, rt_size_t li
}
void rt_trigger_software_interrupt(void) {
rs_write32(RS_RTT_CLINT + UINT32_C(4), 1U);
rs_write32(RS_RTT_CLINT, 1U);
}
void rt_hw_do_after_save_above(void) {
rs_write32(RS_RTT_CLINT + UINT32_C(4), 0U);
rs_write32(RS_RTT_CLINT, 0U);
}
void handle_trap(rt_ubase_t cause, rt_ubase_t epc, void *frame) {
@@ -109,7 +108,7 @@ void handle_trap(rt_ubase_t cause, rt_ubase_t epc, void *frame) {
break;
case 11U: {
uint32_t claim = rs_read32(RS_RTT_PLIC + UINT32_C(0x200004));
if (claim != 2U) {
if (claim != RS_RTT_MAILBOX_PLIC_ID) {
rs_rtt_fail(93U);
}
s_irq_command = rs_read32(RS_RTT_MAILBOX + UINT32_C(0x10));
@@ -149,11 +148,11 @@ void rt_hw_board_init(void) {
rs_write32(RS_RTT_UART + UINT32_C(4), 32U);
rs_write32(RS_RTT_UART + UINT32_C(8), 3U);
rs_write32(RS_RTT_UART + UINT32_C(0x0C), 3U);
rs_write32(RS_RTT_CLINT + UINT32_C(4), 0U);
rs_write32(RS_RTT_CLINT, 0U);
rs_write32(RS_RTT_MAILBOX + UINT32_C(0x40), 1U);
rs_write32(RS_RTT_MAILBOX + UINT32_C(0x44), 1U);
rs_write32(RS_RTT_PLIC + UINT32_C(8), 1U);
rs_write32(RS_RTT_PLIC + UINT32_C(0x2000), 4U);
rs_write32(RS_RTT_PLIC + (UINT32_C(4) * RS_RTT_MAILBOX_PLIC_ID), 1U);
rs_write32(RS_RTT_PLIC + UINT32_C(0x2000), UINT32_C(1) << RS_RTT_MAILBOX_PLIC_ID);
rs_write32(RS_RTT_PLIC + UINT32_C(0x200000), 0U);
s_next_tick = rs_time() + UINT64_C(1000);
rs_set_timer(s_next_tick);
+1 -1
View File
@@ -10,7 +10,7 @@ CC = AS = LINK = PREFIX + 'gcc'
CXX = PREFIX + 'g++'
AR = PREFIX + 'ar'
TARGET_EXT = 'elf'
DEVICE = '-march=rv64imafdc_zicbom_zicsr_zifencei -mabi=lp64d -mcmodel=medany'
DEVICE = '-march=rv64imafdc_zicsr_zifencei -mabi=lp64d -mcmodel=medany'
CFLAGS = DEVICE + ' -O2 -g -ffreestanding -fno-builtin -ffunction-sections -fdata-sections -Wall'
AFLAGS = DEVICE + ' -g -x assembler-with-cpp'
LFLAGS = DEVICE + ' -nostdlib -nostartfiles -Wl,--gc-sections,-Map=rtthread.map -T linker.ld'
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
PDK_BEHAV := YES
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
PDK_BEHAV := YES
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
PDK_BEHAV := YES
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
AUD_CLK_HZ := 18432000
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
AUD_CLK_HZ := 18432000
-1
View File
@@ -4,7 +4,6 @@ PDK := IHP130
HAVE_PLL := NO
HAVE_HP := YES
APU_ENABLE_P7 := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
PDK_BEHAV := YES
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
-1
View File
@@ -3,7 +3,6 @@ MINI_MODE := PRODUCT
PDK := IHP130
HAVE_PLL := NO
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
-1
View File
@@ -4,7 +4,6 @@ MINI_MODE := PRODUCT
PDK := IHP130
HAVE_PLL := NO
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
AUD_CLK_HZ := 18432000
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
PDK_BEHAV := YES
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
AUD_CLK_HZ := 18432000
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
AUD_CLK_HZ := 18432000
-1
View File
@@ -6,7 +6,6 @@ HAVE_SRAM_IF := YES
HAVE_SRAM_MACRO := YES
SRAM_SIZE_KIB := 32
HAVE_HP := YES
HP_CONFIG := rv64imafdc_zicbom_max
HAVE_SVA := NO
EXT_CLK_HZ := 72000000
AUD_CLK_HZ := 18432000
+14 -18
View File
@@ -49,23 +49,21 @@ static void rs_print_hp_core_spec(void) {
printf("\nHigh-Performance-Core Specification:\n");
printf(" Identity\n");
printf(" Core: VexiiRiscv(hart 1), dual-issue in-order\n");
printf(" Core: T-Head OpenC906(hart 1), dual-issue in-order\n");
printf(" Role: application, RT-Thread and Linux\n");
printf(" Source: https://github.com/SpinalHDL/VexiiRiscv\n");
printf(" Source: https://github.com/XUANTIE-RV/openc906\n");
printf(" Hardware ISA and privilege\n");
printf(" Base: RV64IMAFDC_Zicbom_Zicntr_Zihpm\n");
printf(" Mode: M/S/U; Sv39 MMU, 9-bit ASID\n");
printf(" Protection: 16 PMP regions, 4 KiB granularity\n");
printf(" IRQ: machine software/timer/external + supervisor external\n");
printf(" Microarchitecture\n");
printf(" Execution: 2 decoders/lanes, late ALU, full bypassing\n");
printf(" Prediction: BTB + GShare + RAS\n");
printf(" Base: RV64IMAFDC_Zicsr_Zifencei (RV64GC)\n");
printf(" Mode: M/S/U; Sv39 MMU\n");
printf(" IRQ: internal CLINT/PLIC (T-Head c900 layout)\n");
printf(" Interrupt and timer windows\n");
printf(" PLIC: 0x08000000; SoC external source n -> ID n+16\n");
printf(" CLINT: 0x0c000000; MSIP/MTIMECMP/SSIP/STIMECMP\n");
printf(" No MMIO mtime; software reads the time CSR\n");
printf(" LP->HP notification: mailbox doorbell (PLIC ID 18)\n");
printf(" Cache and memory\n");
printf(" L1: separate 16 KiB, 4-way instruction and data caches\n");
printf(" Maintenance: 64-byte Zicbom CBO; no hardware coherency\n");
printf(" Bus: native AXI64 I/D/MMIO; MMIO downsized to AXI32\n");
printf(" Debug\n");
printf(" Embedded RISC-V JTAG, 4 triggers\n");
printf(" L1: separate instruction and data caches; no hardware coherency\n");
printf(" Bus: AXI4 via core BIU; MMIO downsized to AXI32\n");
printf(" Runtime\n");
printf(" Released: %s; actual: %s; reset asserted: %s\n", rs_boolean_name(status.released),
rs_boolean_name(status.actual_released), rs_boolean_name(status.reset_asserted));
@@ -75,10 +73,8 @@ static void rs_print_hp_core_spec(void) {
static void rs_print_mmio_map(void) {
printf("Memory-Mapped I/O Devices:\n");
printf(" 1 x HP ACLINT @%p\n",
(void *)(uintptr_t)RS_SOC_HP_ACLINT_BASE);
printf(" 1 x HP PLIC @%p\n",
(void *)(uintptr_t)RS_SOC_HP_PLIC_BASE);
printf(" 1 x GLOBAL CLINT @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_CLINT_BASE);
printf(" 1 x GPIO(32PIN) @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_GPIO_BASE);
printf(" 1 x UART0 @%p\n",
+12 -8
View File
@@ -40,14 +40,18 @@ manifest, geometry, source revisions, generated-file hashes, and TT/SS views
before materializing it below `.cache/retrosoc/pdk/sky130/openram/`. Generated
Verilog, Liberty, LEF, GDS, and SPICE views are never committed here.
The HP profile additionally locks VexiiRiscv, OpenSBI, Linux stable, and
Buildroot source revisions and the SBT launcher used by VexiiRiscv generation.
`make setup-hp-linux` installs the software sources below
`.cache/retrosoc/sources/`; VexiiRiscv may be supplied through
`VEXIIRISCV_ROOT`, but its revision is still checked before generated RTL is
accepted. Java 17 is a host runtime supplied by Docker, Nix, or the documented
Ubuntu prerequisites. No generated CPU RTL or Linux build output belongs in
Git.
The HP profile locks the OpenC906 source (`sources.openc906`, Apache-2.0) below
`.cache/retrosoc/sources/openc906`; `make setup-openc906` installs it and
`make openc906-prepare` emits the build-variant `openc906.fl` filelist with the
reviewed hart-ID override substituted (the locked checkout is never modified).
OpenSBI, Linux stable, and Buildroot source revisions are locked for HP payload
builds. `make setup-hp-linux` installs the software sources below
`.cache/retrosoc/sources/`. VexiiRiscv remains locked as a Std-series asset: it
may be supplied through `VEXIIRISCV_ROOT`, its revision is still checked before
generated RTL is accepted, and `make std-vexii-generate` invokes the SBT
launcher for `GenerateRetroSocStd.scala`. Java 17 is a host runtime supplied
by Docker, Nix, or the documented Ubuntu prerequisites. No generated CPU RTL or
Linux build output belongs in Git.
`rtthread_hp` pins official RT-Thread v5.3.0 at
`99428a1e7f7447955aa860f7c969273a12095b8f`. `make setup-hp-rtthread` installs
+9 -1
View File
@@ -25,7 +25,15 @@
"revision": "ef7da4134ff11ec6a681d0632123b232b853b046",
"destination": ".cache/retrosoc/sources/vexiiriscv",
"recursive": true,
"license": "MIT"
"license": "MIT",
"purpose": "Std series performance-core generator source (Std asset; no longer consumed by Mini)"
},
"openc906": {
"url": "https://github.com/XUANTIE-RV/openc906.git",
"revision": "b0c06eb1f8b3bae663bd8b87eac89ff48e68a57f",
"destination": ".cache/retrosoc/sources/openc906",
"license": "Apache-2.0",
"purpose": "Mini HP core: pre-generated openC906 RTL (C906_RTL_FACTORY/gen_rtl), default configuration"
},
"rtthread_hp": {
"url": "https://github.com/RT-Thread/rt-thread.git",
+3 -2
View File
@@ -120,8 +120,9 @@ the root README and subsystem guides.
counting modes, interrupt, debug-freeze, HAL, and verification contracts.
- [ip/sysctrl.md](ip/sysctrl.md) defines the SystemCtrl compatibility,
clock/pad/fault/performance/RTC/test contracts, HAL, and verification.
- [ip/hp-platform.md](ip/hp-platform.md) defines the experimental HP PLIC and
LP/HP mailbox register, interrupt, software, and verification contracts.
- [ip/hp-platform.md](ip/hp-platform.md) defines the HP OpenC906 platform, the
C906 internal CLINT/PLIC interrupt architecture, and the LP/HP mailbox
register, software, and verification contracts.
- [hp-rv64-validation.md](hp-rv64-validation.md) records RV64 core, V2 bundle,
RT-Thread/Linux acceptance evidence and deferred gates.
- [ip/onchip-sram.md](ip/onchip-sram.md) defines the configurable native-AXI4
+13 -9
View File
@@ -30,19 +30,24 @@ master. Requests to one target use Common round-robin arbitration and retain
ownership through `B` or `RLAST`. Misaligned, unsupported, cross-page, and
cross-target transactions return `SLVERR`; unmapped addresses return `DECERR`.
Hazard3 accesses APB4 registers through LP-to-PCLK async-safe bridges. HP MMIO
is downsized and crosses HP-to-LP. Product access policy prevents the HP MMIO
master from writing SYSCTRL/RCU, watchdog, and GPIO administration windows.
Hazard3 accesses APB4 registers through LP-to-PCLK async-safe bridges. The HP
core's single 128-bit AXI4 master is serialized by `axi4_downsizer_128to64`
and split by `axi4_mmio_demux`: the `0x02000000-0x2FFFFFFF` window enters the
MMIO chain, where it is downsized and crosses HP-to-LP, while every other
address reaches HP data-plane master slot 0. Product access policy prevents
the HP MMIO master from writing SYSCTRL/RCU, watchdog, and GPIO
administration windows.
## HP data plane
The native payload fabric is AXI64 with 32-bit addresses and seven-bit global
IDs. It has nine masters:
IDs. It has nine active masters over ten fixed slots (slot 1 is retired and
tied idle; the ID-prefix map is preserved):
| Index | Master | Adaptation |
| ---: | --- | --- |
| 0 | Vexii I-cache | native AXI64, source ID preserved |
| 1 | Vexii D-cache | native AXI64, source ID preserved |
| 0 | HP core (OpenC906) | single 128-bit AXI4 master serialized by `axi4_downsizer_128to64`, source ID preserved; four read credits and two write credits (the retired data port's write credits) |
| 1 | retired HP D-cache slot | tied idle |
| 2 | central DMA | PCLK-to-HP CDC, AXI32-to-64 |
| 3 | I/O gateway A | USB2 and SDIO0, PCLK-to-HP CDC, AXI32-to-64 |
| 4 | I/O gateway B | SDIO1 and SPI-SD, PCLK-to-HP CDC, AXI32-to-64 |
@@ -73,8 +78,7 @@ the integration RTL:
| Master | Read targets | Write targets | Instruction | Attribute rule |
| --- | --- | --- | --- | --- |
| HP I-cache | all five memories | none | allowed | cache attributes preserved |
| HP D-cache | all five memories | SRAM, SDRAM, QPI, OPI | denied | cache attributes preserved |
| HP core | all five memories | SRAM, SDRAM, QPI, OPI | allowed | cache attributes preserved |
| DMA, I/O A/B, LP gateway | all five memories | SRAM, SDRAM, QPI, OPI | denied | `AxCACHE=0` required |
| GA2D | all five memories | SRAM, SDRAM, QPI, OPI | denied | `AxCACHE=0` required; direct FILL/COPY/CONVERT/BLEND 2D engine, no hardware coherency |
| JPEG | all five memories | SRAM, SDRAM, QPI, OPI | denied | `AxCACHE=0` required; one normal read and one normal write credit |
@@ -86,7 +90,7 @@ and records the immutable master identity and original decoded target.
Per-target arbitration first selects the highest effective five-bit priority
and then uses the Common round-robin arbiter among equal requesters. Normal
classes are HP I/D 12, I/O gateways 10, DMA/JPEG/EXT-H/GA2D 8, and LP gateway 2, with
classes are HP core 12, I/O gateways 10, DMA/JPEG/EXT-H/GA2D 8, and LP gateway 2, with
incoming AXI QoS able to raise a normal request up to 15. A continuously
eligible request is promoted to 16 after 256 cycles. During recovery, the LP
gateway is promoted to 31. Target backpressure is outside the service bound;
+3 -2
View File
@@ -20,8 +20,9 @@ ecosystem of the referenced devices. Official sources were rechecked on
## Technical Selection
Mini remains a small, non-coherent, performance-first SoC. Hazard3 is the
only root-management master. Vexii I/D, DMA, I/O gateways, the LP data gateway, EXT-H, and GA2D use a
nine-master native AXI64 data plane with seven-bit global IDs. GA2D is a
only root-management master. The OpenC906 HP core master, DMA, I/O gateways,
the LP data gateway, JPEG, EXT-H, and GA2D share a
nine-active-master native AXI64 data plane with seven-bit global IDs. GA2D is a
dedicated PCLK-to-HP AXI64/ID3 bridge carrying direct, single-job private-AXI64
2D FILL/COPY/CONVERT/BLEND traffic; `APB4_GA2D` remains its separate PCLK
control plane and resource-owned IRQ route. It supports RGB565, RGB888,
+3 -1
View File
@@ -13,7 +13,9 @@ a second SoC bus master. Debugger memory operations execute through the halted
hart and remain subject to the AXI4 interconnect access policy. MPW user cores,
peripherals, clocks, and pad control stay outside the debug-reset scope.
The product Vexii HP hart can own shared JTAG only while held in reset. C0-C3
The product OpenC906 HP hart can own shared JTAG only while held in reset; HP
debug uses the C906 internal Debug Module behind the external JTAG DTM
(`tdt_dmi_top`). C0-C3
are software-selected only in the mini-ver-mpw compatibility profile; they are
not management-core options and do not have a management Debug Module.
+63 -8
View File
@@ -1,10 +1,65 @@
# HP RV64 Migration Validation
The active contract is [HP platform](ip/hp-platform.md), phases 2–5. LP remains
RV32 Hazard3. All PRODUCT profiles select RV64IMAFDC with Zicbom, Sv39 and
32-bit physical addresses. No upstream CPU or RT-Thread source is modified.
The active contract is [HP platform](ip/hp-platform.md). LP remains RV32
Hazard3 (hart 0); HP is the locked, pre-generated T-Head OpenC906 (hart 1,
RV64GC with Zicsr/Zifencei, M/S/U modes, Sv39, 32-bit SoC physical
addresses). No upstream CPU or RT-Thread source is modified.
## Reproduction
## Current status after the OpenC906 core swap
All simulation evidence below was gathered with the previous generated
VexiiRiscv HP core and is historical: it must not be presented as OpenC906
qualification. Current evidence requires, at minimum:
- `make setup-openc906` (part of `make setup`) restoring the locked
[openc906](https://github.com/XUANTIE-RV/openc906) checkout, and
`make openc906-prepare` emitting
`build/<variant>/generated/openc906/openc906.fl` and its manifest under the
pinned upstream sha256 guard, with the reviewed
`rtl/mini/ip_overrides/aq_sysio_kid.v` hart-ID override applied by filelist
generation rather than by editing the vendored checkout.
- Verilator compile of the OpenC906 HP subsystem, including the serializing
`axi4_downsizer_128to64` and `axi4_mmio_demux` path.
- Fresh `hp-smoke-sim`, `hp-rtthread-sim`, and `hp-linux-sim` runs from their
committed IHP130 profiles with all contract markers and
`SIM_TEST_PASS code=0`, exercising the internal C906 CLINT/PLIC and the
`time`-CSR mtime delivery.
- The IHP130 behavioral PR regression on the swapped design.
### OpenC906 evidence gathered (2026-10-10)
- `hp-smoke-sim` on `configs/ci/ihp130-hp.mk` (Verilator): `HP_LINUX_READY`,
`HP_GA2D_PASS`, `HP_GA2D_CACHE_CLEAN`, `SIM_TEST_PASS code=0`;
3,629,906 cycles in 285 s. This exercises C906 boot at 0x38000000, the
128-to-64 downsizer and MMIO demux, the mailbox protocol, the GA2D engine
through the HP data path, and the T-Head `dcache.cva`/`dcache.iva` cache
lifecycle handshake.
- Focused `hp_c906_boot_tb` (pytest `test_hp_platform.py`): the real smoke
payload runs on `hp_core_wrapper` plus the production MMIO chain
(64-to-32 downsizer, address gate, HP-to-LP CDC bridge) and completes the
full mailbox/GA2D-phase protocol.
- The swap exposed and fixed a latent integration bug: the merged HP port
initially inherited the read-only I-cache slot's zero write credits in the
data crossbar; `axi4_data_crossbar.sv` now grants the HP slot two write
credits, locked by a new write/readback case in `ga2d_platform_tb`.
- The sysmap override is required for correctness: the upstream default marks
the Mini MMIO window cacheable/bufferable, which absorbs device writes in
the C906 store buffer; `rtl/mini/ip_overrides/sysmap.h` marks the MMIO and
core-internal CLINT/PLIC windows strong-order non-cacheable per the user
manual.
`hp-rtthread-sim`, `hp-linux-sim`, and the synthesis-dependent gates remain
unrun this round (synthesis waits for the SRAM macro swap); they stay required
evidence for qualification.
Deferred this phase: low-power support (`core0_pad_lpmd_b` unconnected), DFT
(scan/mbist tied off), the debug SBA AXI master (unconnected), ASIC
memory-macro replacement for the behavioral FPGA SRAM models, and HP Linux
re-qualification timing/performance evidence.
## Historical VexiiRiscv evidence (pre-swap)
### Reproduction (VexiiRiscv)
```sh
make setup-vexiiriscv setup-hp-rtthread setup-hp-linux
@@ -38,7 +93,7 @@ The `ihp130-apu` evidence profile likewise uses workload 1 only as the existing
four-entry transport. Its application-specific `apu_release` LP loader owns the
APU acceptance semantics; that bundle label does not claim a Linux boot result.
## Measured runs
### Measured runs (VexiiRiscv)
Initial RV64 validation uses `configs/ci/ihp130-hp.mk` and
`BUILD_TIMESTAMP=2026-09-25-11-42`, producing
@@ -86,7 +141,7 @@ The IHP130 behavioral PR regression completed successfully with
new/increased signatures as non-blocking observations; baselines were not
modified. No synthesis or STA result is implied by this regression.
## RT-Thread first-schedule failure and correction
### RT-Thread first-schedule failure and correction
The first BSP run reached `HP_RTTHREAD_BOOT` and then reported
`RTTHREAD_TRAP cause=1 epc=deadbeee`, failure 92, followed by LP failure 18.
@@ -106,7 +161,7 @@ the initial variant. This was a BSP integration error:
bound. The same integrated test then passed scheduling, RV64 context, IPC,
timer timeout, and mailbox IRQ checks. Vendor source stayed unchanged.
## Linux firmware reservation correction
### Linux firmware reservation correction
The first RV64 run reached Linux 6.12.105 and memory initialization. Its log
reported no `/reserved-memory` node and included the full SDRAM range beginning
@@ -146,7 +201,7 @@ RISC-V `pt_regs` layout. UART subsequently reported the 9-bit ASID allocator.
These observations avoid treating an IRQ-handler PC or stale raw SDRAM as
evidence of main-thread progress.
## Coverage limits
### Coverage limits
The repository's mechanical C format/policy checks are partial MISRA evidence;
no complete MISRA certification or new approved Required-rule deviation is
+2 -2
View File
@@ -39,7 +39,7 @@ This refreeze is a future implementation contract, not a synthesis/PPA result.
The APU is deliberately coreless. LP loads one validated codec-microcode bundle
at startup and HP or LP later submits jobs. The APU contains a bounded codec
sequencer and fixed processing engines; it does not contain Hazard3, VexiiRiscv,
sequencer and fixed processing engines; it does not contain Hazard3, OpenC906,
a DSP CPU, a general-purpose instruction set, or a C runtime.
The design was frozen on 2026-09-02 from these repository sources of truth:
@@ -2673,7 +2673,7 @@ measured evidence. Inferred memories may be padded/duplicated by elaboration;
the 462208 logical table bits above are not interchangeable with that tool
statistic. Removing the two reported groups would arithmetically leave 568626
bits (about 70.1 percent lower), but that is a projection, not a synthesis
speed, RSS or measured memory claim. Vexii and other IP memories are outside
speed, RSS or measured memory claim. OpenC906 and other IP memories are outside
P9 scope. Fresh like-for-like reports below are required.
Stable requirements:
+11 -6
View File
@@ -1,12 +1,17 @@
# Core-Local Interruptor
The baseline Mini SoC CLINT provides machine software and machine timer
interrupts for the management hart. The HP profile adds an independent
two-slot instance at `0x02000000` and connects slot 1 to HP hart 1. Its register
layout follows the conventional SiFive
interrupts for the management hart and owns the global `mtime` source. Its
register layout follows the conventional SiFive
CLINT and RISC-V ACLINT-compatible offsets, while its bus-facing logic uses the
retroSoC APB4 target protocol.
With the OpenC906 HP core, the former HP ACLINT instance at `0x02000000` is
removed: the C906 uses its internal CLINT/PLIC (T-Head c900 layouts, decoded
inside the core BIU below `0x08000000`), and this CLINT's `mtime` is delivered
to the C906 through `pad_cpu_sys_cnt` and read by HP software through the
`time` CSR. There is no HP memory-mapped `mtime`.
## Integration
| Property | Value |
@@ -20,9 +25,9 @@ retroSoC APB4 target protocol.
| User-core access | denied by the AXI4 interconnect access policy |
| User-core interrupt visibility | masked |
The HP instance uses the same 1 MHz reference timebase. OpenSBI programs hart
1 `MSIP` at `0x02000004`, `MTIMECMP` at `0x02004008`, and shared `MTIME` at
`0x0200BFF8`. The baseline management CLINT remains at `0x10020000`.
The CLINT drives the global 1 MHz reference timebase. Its `mtime` is exported
to the HP subsystem (`pad_cpu_sys_cnt`) so the OpenC906 `time` CSR tracks the
same counter. The baseline management CLINT remains at `0x10020000`.
The timebase divider runs from the buffered external reference clock, not the
PLL-selected system clock. A toggle crosses into the system domain through the
+1 -1
View File
@@ -25,7 +25,7 @@ response after retirement, a stale response after an epoch change, and a
missing response. Engine transactions carry both an operation epoch and a
per-bank transaction token; write retirements are never consumed as read
responses. The default product store remains fixed-latency with no fault
injection. Generated VexiiRiscv output, its manifest, and the selected
injection. The generated OpenC906 filelist, its manifest, and the selected
IHP SRAM behavioral models are included in each firmware run's source hash.
The interruption argument combines universal control properties with bounded
+3 -2
View File
@@ -257,7 +257,7 @@ are permitted and are not hardware ROM implementations.
AEAD/HMAC, new key sizes, CRT, masking/blinding, HUK/key ladders, Linux crypto
drivers, private DMA, ECC/MBIST/secure scan and side-channel certification remain
deferred. Vexii and APU storage are outside this refreeze.
deferred. OpenC906 and APU storage are outside this refreeze.
### Physical layout and implementation boundary
@@ -818,7 +818,8 @@ python3 scripts/crypto_p1.py quality --variant-root build/<block-variant>
For the CI manifest use `APP=ci_smoke HAVE_CSR=YES`, the existing
`ld2_all_sram`, `SIMU=VERILATOR` and `HAVE_SVA=YES` overrides. The firmware
runner records its complete build/simulation command, per-run manifest, input
hashes including generated VexiiRiscv and selected PDK model inputs, ELF/log/
hashes including the generated OpenC906 filelist/manifest and selected PDK
model inputs, ELF/log/
result hashes and command exit status. The report rejects
missing, changed or unsuccessful runs. These helpers do not invoke Pytest.
+2 -1
View File
@@ -65,7 +65,8 @@ Confirmed baseline facts:
4. Central DMA implements a 32-bit, one-dimensional transfer contract.
GA2D does not add channels or request selectors to that controller.
5. Mini has no hardware cache coherency. Ownership, fences, and the HP
64-byte Zicbom cache-maintenance contract remain software obligations.
64-byte cache-maintenance contract (OpenC906 custom-0
`dcache.cva`/`dcache.iva` instructions) remain software obligations.
Phase 1 approves expansion of the LP interrupt platform. Phase 2 approves
the ninth data master, wider global IDs, and resource/observability changes.
+94 -47
View File
@@ -4,16 +4,52 @@
The RV64 migration approved on 2026-09-25 extends the existing HP platform in
the phases below. These are requirements, not claims of completed validation.
LP remains the RV32 Hazard3 management hart (hart 0). HP is VexiiRiscv hart 1,
RV64IMAFDC_Zicbom_Zicntr_Zihpm, with M/S/U modes and Sv39. Physical addresses
remain 32 bits; the reset vector remains `0x38000000`. The existing 16 KiB
four-way I/D caches, 64-byte lines, 9-bit ASIDs, PMP, and clocks remain fixed.
I/D and cacheless MMIO use AXI64 at HP; MMIO is downsized to the existing
AXI32/APB32 control plane. Software accesses peripheral registers as 32-bit
words, including the two halves of CLINT timer registers. No new CDC or
LP remains the RV32 Hazard3 management hart (hart 0). HP is hart 1, a T-Head
OpenC906 core from [XUANTIE-RV/openc906](https://github.com/XUANTIE-RV/openc906)
(Apache-2.0), locked in `dependencies/dependencies.lock.json` and integrated
from its pre-generated `C906_RTL_FACTORY/gen_rtl` DEFAULT configuration:
RV64GC (RV64IMAFDC plus Zicsr and Zifencei) with M/S/U modes and Sv39,
32 KiB instruction and data caches with 64-byte lines, an eight-region PMP,
and a 16K-entry BHT. The earlier VexiiRiscv-based RV64 integration is
superseded; its validation evidence is retained only as historical in
[HP RV64 validation](../hp-rv64-validation.md). VexiiRiscv remains in the
repository solely as the frozen Std-series generator asset
(`scripts/vexiiriscv/GenerateRetroSocStd.scala`, driven by
`make std-vexii-generate`); Mini no longer consumes it and Mini profiles have
no `HP_CONFIG` selector.
The C906 drives 40-bit addresses; Mini physical addresses remain 32 bits and
the reset vector remains `0x38000000`. The core exposes a single 128-bit AXI4
master (8-bit IDs, `axim_clk_en` tied high for 1:1 clocking) that a
serializing `axi4_downsizer_128to64` and `axi4_mmio_demux` split into HP
data-fabric master slot 0 and the MMIO window `0x02000000-0x2FFFFFFF`; the
former separate I-cache/D-cache/MMIO port structure and crossbar master slot 1
are retired (slot 1 is tied idle, ID-prefix map preserved). MMIO continues
through the existing 64-to-32 downsizer/gate/CDC chain into the AXI32/APB32
control plane. Software accesses peripheral registers as 32-bit words,
including the two halves of CLINT timer registers. No new CDC or
hardware coherency is introduced. LP retains SYSCTRL and terminal-status
ownership, DMA channel 6, SDRAM initialization, and HP release control.
OpenC906 implements no Zicbom, Zicntr, or Zihpm; cache maintenance uses the
T-Head custom-0 `dcache.cva`/`dcache.iva` instructions. Debug uses the C906
internal Debug Module behind the external JTAG DTM (`tdt_dmi_top`).
OpenC906 hardwires `mhartid=0` upstream; retroSoC substitutes the reviewed
override `rtl/mini/ip_overrides/aq_sysio_kid.v` (only change:
`sysio_core_hartid = 3'd1`) during build-time filelist generation through
`scripts/generate_openc906.py`, which guards the pinned upstream sha256. A
second reviewed override, `rtl/mini/ip_overrides/sysmap.h`, replaces the
upstream default sysmap region table (which targets a 40-bit reference map
and would mark the Mini peripheral window cacheable/bufferable) with the Mini
address map: the MMIO window `0x02000000`-`0x2FFFFFFF` — including the
core-internal CLINT/PLIC window — is strong-order/non-cacheable device memory
as the OpenC906 user manual requires; SRAM/SDRAM/PSRAM/OPI and the flash/XIP
windows stay cacheable. The vendored checkout is never modified. Deferred
this phase: low-power support
(`core0_pad_lpmd_b` unconnected), DFT (scan/mbist tied off), the debug SBA AXI
master (unconnected), ASIC memory-macro replacement for the behavioral FPGA
SRAM models, and HP Linux re-qualification timing/performance evidence.
### Boot bundle V2
The little-endian header remains 128 bytes at flash offset `0x00100000`, with
@@ -35,7 +71,8 @@ with a nonzero error code. LP prints `HP_LINUX_READY` and terminates on Linux
success without entering the GA2D protocol.
RT-Thread publishes ready event 1, argument `0x52545401`, sequence 1 after
enabling PLIC source 2 in machine context 0. LP sends command `0x52545402`,
enabling the mailbox-doorbell PLIC ID (18) in the machine context. LP sends
command `0x52545402`,
argument `0x12345678`, sequence 1. Its ISR clears the HP mailbox source and
completes the PLIC claim; the test thread verifies the received message. Once
all tests pass, HP publishes event 2, argument `0x52545401`, sequence 2.
@@ -48,7 +85,8 @@ handshake documented by its existing payload.
RT-Thread uses the official v5.3.0 commit
`99428a1e7f7447955aa860f7c969273a12095b8f` without vendor source modifications.
The BSP uses the common RISC-V M-mode port, static threads and IPC objects,
1000 Hz ticks, UART1, hart-1 MSIP/MTIMECMP, and the existing PLIC/mailbox.
1000 Hz ticks, UART1, the internal CLINT MSIP/MTIMECMP pair, and the internal
PLIC plus the mailbox.
The first test image covers integer RV64 computation/context, preemption,
semaphore and message queue behavior, timeouts, and external mailbox IRQ.
RT-Smart, networking, filesystems, and floating-point task qualification are
@@ -68,10 +106,13 @@ uncompressed and does not run the full Buildroot services sequence.
#### Phase 2 - RV64 HP core and platform migration
Migrate the fixed generator, all PRODUCT profiles, manifests and core reports;
retain the locked VexiiRiscv revision. Use separate RV32 LP and RV64 HP tools.
Validate generated port widths, narrow MMIO lanes, 64-bit memory accesses,
and the migrated GA2D/cache-lifecycle smoke in IHP130 Verilator.
Originally executed against a generated VexiiRiscv core; that integration is
superseded by the OpenC906 swap and its evidence is historical. The current
phase integrates the locked OpenC906 DEFAULT configuration, all PRODUCT
profiles, manifests and core reports. Use separate RV32 LP and RV64 HP tools.
Validate the 128-to-64 serializing downsizer, the MMIO demux, narrow MMIO
lanes, 64-bit memory accesses, and the migrated GA2D/cache-lifecycle smoke in
IHP130 Verilator.
#### Phase 3 - RT-Thread dependency, BSP and acceptance
@@ -90,7 +131,8 @@ Unexpected console corruption remains a failure requiring diagnosis.
#### Phase 5 - Documentation and delivery evidence
Update architecture, guides and publication source bindings. Preserve prior
RV32 evidence as historical. Each workload writes separate run logs and
RV32 and pre-swap VexiiRiscv evidence as historical. Each workload writes
separate run logs and
structured results; an interrupted or ongoing run cannot reuse an old pass.
Run affected host/Python/C/RTL checks and IHP130 behavioral regressions.
Synthesis, netlist simulation, STA, and synthesis-dependent metrics are
@@ -98,39 +140,43 @@ explicitly deferred by user instruction, as are SRAM macro replacement,
CDC/RDC/physical signoff and commercial qualification. No PPA claim is made.
Reference boundaries: [RT-Thread v5.3.0](https://github.com/RT-Thread/rt-thread/releases/tag/v5.3.0)
supplies the OS/CPU port; the repository owns board integration. The existing
CLINT/PLIC architecture and locked OpenSBI platform supply the interrupt and
supervisor boot patterns; no third-party board register map is imported.
supplies the OS/CPU port; the repository owns board integration. The C906
internal CLINT/PLIC (the `thead,c900-clint`/`thead,c900-plic` device-tree
bindings) and the locked OpenSBI platform supply the interrupt and supervisor
boot patterns; no third-party board register map is imported.
The experimental LP/HP profile adds a 32-source, two-context PLIC at
`0x0C000000` and a bidirectional mailbox at `0x10019000`. Both are self-owned
APB4 peripherals. Their role in boot and lifecycle control is defined by
[LP/HP Architecture](../lp-hp-architecture.md).
The LP/HP profile adds a bidirectional mailbox at `0x10019000` as a
self-owned APB4 peripheral. Its role in boot and lifecycle control is defined
by [LP/HP Architecture](../lp-hp-architecture.md).
## PLIC
## Interrupt and timer architecture
Source 0 is permanently reserved. Source 1 is UART1, source 2 is the HP-side
mailbox doorbell, source 3 is EXT-H, and sources 4 through 10 are central DMA,
USB2, SDIO0, SDIO1, SPI-SD, JPEG, and APU respectively. Source 11 is GA2D and
source 12 is the NPU shell. Sources 13 through 31
are reserved and tied low. Resource-owned sources are suppressed unless HP is
the exclusive owner. Each source has a three-bit priority. Context 0 drives HP
machine external interrupt and context 1 drives HP supervisor external interrupt.
The former SoC-level HP ACLINT at `0x02000000` and HP PLIC at `0x0C000000`
are removed from the HP path; their self-owned RTL sources remain in the
repository but are no longer instantiated. Interrupt and timer delivery now
uses the CLINT and PLIC internal to the C906, which follow the T-Head c900
register layouts and are decoded inside the core BIU at the 128 MiB-aligned
window base `0x08000000`. That window never reaches the SoC fabric;
`rtl/mini/address_map/memory_map.json` reserves it as `HP_C906_SYS`:
| Address offset | Register | Access |
| --- | --- | --- |
| `0x000000 + 4 * source` | source priority | RW |
| `0x001000` | pending bits 31:0 | RO |
| `0x002000 + 0x80 * context` | enable bits 31:0 | RW |
| `0x200000 + 0x1000 * context` | threshold | RW |
| `0x200004 + 0x1000 * context` | claim/complete | RO/RW |
| Address | Function |
| --- | --- |
| `0x08000000` | internal PLIC (`thead,c900-plic`) |
| `0x0C000000` | internal CLINT (`thead,c900-clint`): MSIP at +`0x0`, MTIMECMP at +`0x4000`, SSIP at +`0xC000`, STIMECMP at +`0xD000` |
Claim returns the lowest source ID at the greatest priority strictly above the
context threshold, clears its pending bit, and marks it claimed. Writing that
nonzero ID to the same context's claim/complete register completes it. A level
source that remains asserted becomes pending again after completion. Priority
zero disables delivery. The MVP implements one 32-bit pending/enable word and
does not implement MSI, AIA, virtualization, or affinity routing.
The CLINT at `0x10020000` remains the LP/global CLINT and the mtime source.
Its mtime is delivered to the C906 through `pad_cpu_sys_cnt`; HP software
reads the `time` CSR and has no memory-mapped mtime.
SoC interrupt source numbers are unchanged at the boundary: source 1 is
UART1, source 2 is the HP-side mailbox doorbell, source 3 is EXT-H, and
sources 4 through 12 are central DMA, USB2, SDIO0, SDIO1, SPI-SD, JPEG, APU,
GA2D, and the NPU shell respectively. Sources 13 and above are reserved and
tied low. Resource-owned sources are suppressed unless HP is the exclusive
owner. The C906 maps external input *i* to PLIC ID *i*+16, so software claims
these sources as PLIC IDs 17 through 28; IDs 0-15 are reserved/internal.
LP-to-HP notification is exclusively the mailbox doorbell (PLIC ID 18); the
former LP-writes-HP-MSIP path no longer exists.
## Mailbox
@@ -160,8 +206,9 @@ Linux userspace acceptance script reports event 1, argument `0x4C4E5801`, and
sequence 1 after init; this is a bring-up verdict, not a general Linux mailbox
driver ABI.
`tests/rtl/plic_tb.sv` and `tests/rtl/hp_mailbox_tb.sv` cover register and
interrupt behavior. `tests/test_hp_boot_bundle.py` enforces the handwritten
mailbox RTL/C offset parity. Production work still requires a Linux mailbox
driver, concurrent sequence/wrap policy, malformed-message tests, lifecycle
timeouts, and fault-injection coverage.
`tests/rtl/hp_mailbox_tb.sv` covers mailbox register and interrupt behavior.
`tests/rtl/plic_tb.sv` covers the retained self-owned PLIC RTL, which is no
longer part of the HP interrupt path. `tests/test_hp_boot_bundle.py` enforces
the handwritten mailbox RTL/C offset parity. Production work still requires a
Linux mailbox driver, concurrent sequence/wrap policy, malformed-message
tests, lifecycle timeouts, and fault-injection coverage.
+6 -3
View File
@@ -154,7 +154,8 @@ simulation and the applicable bounded formal harness:
The reference is the pinned portable-C INT8 implementation running beside the
NPU path on the same complete PRODUCT Verilator model of the 72 MHz HP
VexiiRiscv configuration, with the same model, corpus, memory placement and
core configuration (OpenC906 after the 2026-10-09 core swap), with the same
model, corpus, memory placement and
declared cache policy. Both paths include the inference result through CPU
softmax; the NPU path additionally includes command submission, DMA transfers,
synchronization and wait. Preprocessing and corpus transport are measured
@@ -173,7 +174,8 @@ replacement would change the measured denominator and requires an explicit
verification-contract refreeze before implementation.
The stage-instrumented Mini IHP130 diagnostic run at root revision
`d084002bfe99`, using `configs/ci/ihp130.mk` and the locked VexiiRiscv revision,
`d084002bfe99`, using `configs/ci/ihp130.mk` and the then-current locked
VexiiRiscv revision (pre-OpenC906-swap evidence),
entered `reference-start` for both a contention KWS shard and a non-contention
KWS shard, but did not reach `reference-compute-done` within the bounded host
run. This establishes a portable-C reference runtime/evidence gap, not an NPU
@@ -347,7 +349,8 @@ The LP `ci_smoke` run used real external-interrupt entry and acknowledgement,
completed the KWS job and terminal CPU Softmax, and ended with
`SIM_TEST_PASS code=0`. Its retained counters were 5765715 active cycles,
320326 DMA read bytes, 72076 DMA write bytes and 59530 CPU Softmax cycles. The
HP run used polling plus Zicbom maintenance, completed the same KWS deployment,
HP run (pre-OpenC906-swap, VexiiRiscv evidence) used polling plus Zicbom
maintenance, completed the same KWS deployment,
passed the concurrent GA2D/resource hand-off checks and ended with
`HP_NPU_PASS` and `SIM_TEST_PASS code=0`.
+2 -2
View File
@@ -291,7 +291,7 @@ integration advertises no execution readiness, DMA, or operator capability.
| HP IRQ | PLIC source 12 |
The peripheral IRQ group expands 25 to 26 bits; the existing 64-bit LP vector
and 32-source PLIC container need no width increase. Preserve the separate
and the HP PLIC input container need no width increase. Preserve the separate
MPW compatibility path and all existing harts, resources and interrupts.
Phase 2 MUST update topology generator names/policies, hardcoded master
credit/priority functions, 9x6 assertions, resource vectors, monitor banks,
@@ -649,7 +649,7 @@ Software serializes one submitter and acquires resource ownership before use.
Before START it cleans input/constants/descriptors and cleans/invalidates
output lines as applicable, then fences. After terminal successful output
completion it invalidates output and fences before CPU access. Use the
existing 64-byte HP Zicbom boundary and avoid sharing cache lines with
existing 64-byte HP cache-line boundary and avoid sharing cache lines with
unrelated allocations. LP still executes ordering fences despite no D-cache.
Cache ownership of an active NPU job remains the application's responsibility
during HP lifecycle operations; automatic coherence is not implied.
+7 -4
View File
@@ -87,17 +87,20 @@ resource-8 idle and ACK with the live source-safe-idle signal.
## Cache Maintenance
VexiiRiscv implements `Zicbom` with a 64-byte CBO block. On HP shutdown the AON
VexiiRiscv-era note: the pre-swap HP core implemented `Zicbom` with a 64-byte
CBO block; OpenC906 instead uses 64-byte cache lines with the T-Head custom-0
`dcache.cva`/`dcache.iva` maintenance instructions. On HP shutdown the AON
lifecycle controller first asserts the Resource Controller cache request while
HP remains released and its MMIO path remains open. Software cleans and
invalidates shared ranges with CBO operations, reports completion to LP, and LP
invalidates shared ranges with those instructions, reports completion to LP,
and LP
writes `CACHE_CONTROL.CLEAN`. AON then blocks new addresses and drains the data
plane. Missing acknowledgement is bounded by the lifecycle timeout and records
a forced fault before reset proceeds.
This handshake provides an execution window and explicit evidence point; it
does not create hardware coherency. Buffer ownership, fences, CBO range policy,
and a Linux platform driver remain software responsibilities.
does not create hardware coherency. Buffer ownership, fences, maintenance
range policy, and a Linux platform driver remain software responsibilities.
## Delivery Boundary
+26 -11
View File
@@ -19,9 +19,9 @@ Every committed `MINI_MODE=PRODUCT` profile instantiates two fixed harts:
| Property | LP management | HP application |
| --- | --- | --- |
| Core | Hazard3 | generated VexiiRiscv |
| Core | Hazard3 | T-Head OpenC906 (locked pre-generated DEFAULT configuration) |
| Hart ID | 0 | 1 |
| ISA | profile RV32I/RV32IM | RV64IMAFDC + Zicbom, S/U mode, Sv39 |
| ISA | profile RV32I/RV32IM | RV64GC (RV64IMAFDC + Zicsr/Zifencei), S/U mode, Sv39 |
| Reset clock | REF24 at 24 MHz | external 72 MHz safe clock |
| Role | boot, control, diagnostics, recovery | high-throughput application/Linux |
| JTAG | reset owner | selectable while HP is held in reset |
@@ -34,6 +34,19 @@ product address, interrupt, or lifecycle ABI.
There is no hardware cache coherency. Firmware and operating systems must use
explicit ownership, fences, and cache maintenance for shared buffers.
HP interrupt and timer delivery uses the CLINT and PLIC internal to the C906
(T-Head c900 register layouts), decoded inside the core BIU below the
128 MiB-aligned base `0x08000000`; that window never reaches the SoC fabric
and is reserved as `HP_C906_SYS` in the address map. The former SoC-level HP
ACLINT (`0x02000000`) and HP PLIC (`0x0C000000`) are removed. SoC interrupt
source numbers are unchanged at the boundary (1 UART1, 2 mailbox doorbell,
3 EXT-H, 4-12 DMA/USB2/SDIO0/SDIO1/SPI-SD/JPEG/APU/GA2D/NPU); the C906 maps
external input *i* to PLIC ID *i*+16, so software sees IDs 17-28. The CLINT
at `0x10020000` remains the LP/global CLINT and mtime source; mtime reaches
the C906 through `pad_cpu_sys_cnt` and is read through the `time` CSR.
LP-to-HP notification is exclusively the mailbox doorbell (PLIC ID 18). See
[HP platform](ip/hp-platform.md).
## Clock and reset domains
`soc_clock_reset_subsystem` is the product clock/reset implementation behind
@@ -74,10 +87,11 @@ Hazard3 -> AHB-Lite adapter -> LP AXI32 control fabric
-> LP/PCLK bridge -> APB4 peripheral and system register banks
```
HP uncached MMIO is downsized to AXI32 and crosses HP to LP through
`axi4_async_bridge`. Product access control rejects HP writes to root SYSCTRL,
watchdog, and GPIO administration windows with `SLVERR`; Hazard3 retains full
management access.
HP uncached MMIO is demuxed from the HP core's single AXI4 master by
`axi4_mmio_demux` (window `0x02000000-0x2FFFFFFF`), downsized to AXI32, and
crosses HP to LP through `axi4_async_bridge`. Product access control rejects
HP writes to root SYSCTRL, watchdog, and GPIO administration windows with
`SLVERR`; Hazard3 retains full management access.
`axi4_mgmt_router` keeps APB/control addresses on this path and routes every
memory window through an LP-to-HP data gateway. Hazard3 therefore shares the
@@ -94,8 +108,8 @@ and a Common FIFO preserves write-data order where AXI4 W has no ID.
| Master | Entry path |
| --- | --- |
| HP I-cache | native AXI64, ID prefix 0 |
| HP D-cache | native AXI64, ID prefix 1 |
| HP core (OpenC906) | single 128-bit AXI4 master serialized by `axi4_downsizer_128to64`, ID prefix 0; `axi4_mmio_demux` splits off the MMIO window |
| retired HP D-cache slot | tied idle; ID-prefix map preserved |
| central DMA | PCLK-to-HP async bridge, AXI32-to-64 upsizer |
| I/O gateway A | USB2 and SDIO0, then PCLK-to-HP CDC and upsizer |
| I/O gateway B | SDIO1 and SPI-SD, then PCLK-to-HP CDC and upsizer |
@@ -203,9 +217,10 @@ files remain available only for optional PLL experiments.
Behavioral RTL, firmware, directed data-plane/lifecycle/clock tests, manifest
parity, and quality checks are the evidence for this implementation. HP stop
implements a pre-drain cache request/ACK window, drain, coordinated flush,
actual-release status, and bounded forced reset. Vexii implements 64-byte
`Zicbom`; software still owns shared-range selection, and a forced reset cannot
preserve dirty cache data when the ACK times out. It must not be
actual-release status, and bounded forced reset. OpenC906 uses 64-byte cache
lines with T-Head custom-0 `dcache.cva`/`dcache.iva` maintenance instructions
instead of Zicbom; software still owns shared-range selection, and a forced
reset cannot preserve dirty cache data when the ACK times out. It must not be
called cache coherent, power isolated, timing closed, CDC/RDC signed off, or
silicon-qualified. Synthesis, netlist simulation, STA, MMMC, clock-tree, DFT,
and analogue PLL qualification are separate gates.
+8 -4
View File
@@ -19,7 +19,7 @@
| Initiator ACL and first-fault attribution | Generated data policy, crossbar, SYSCTRL, and Fabric Monitor | target/execute/cache/range denial and injection tests | implemented: fixed policy is topology-generated and valid/ready fault reporting retains every accepted event across the HP/PCLK CDC |
| Stable memory functional clocks | Memory integration | HP DFS while refresh/protocol engines continue | implemented digitally: SRAM is native HP AXI64; SDRAM and all serial targets cross directly from HP to stable memory as AXI64 before local downsizing |
| Reset epoch and stale-response rejection | Async bridges | unilateral reset and clock-stop matrix | partial: coordinated warm flush and epoch implemented |
| HP normal and forced hot reset | AON lifecycle controller and Resource Controller | cache request/ACK, drain, timeout, flush, and recovery tests | implemented digitally: Zicbom and bounded ACK window exist; range policy and Linux service remain software work |
| HP normal and forced hot reset | AON lifecycle controller and Resource Controller | cache request/ACK, drain, timeout, flush, and recovery tests | implemented digitally: C906 custom-0 cache-maintenance instructions and bounded ACK window exist; range policy and Linux service remain software work |
| Clock monitor and programmable timeout | AON clock/reset subsystem | 8x8 DFS and clock-loss tests | implemented |
| Operational EXT-H ACL, timeout, and data path | Extension subsystem | transfer, denial, hang, and quiesce tests | implemented |
| Ownership-aware IRQ handoff | Resource Controller and HP PLIC | idle handoff, owner lock, LP/HP exclusion, and fault tests | implemented for DMA, USB2, SDIO0/1, SPI-SD, EXT-H, and JPEG; downstream per-engine reset ACK remains pending |
@@ -36,8 +36,12 @@ sources of truth.
## Historical RV32 verification evidence
The results below predate the RV64 migration and must not be used as RV64
qualification. Current generation selects `rv64imafdc_zicbom_max`; see
[HP RV64 validation](hp-rv64-validation.md) for migration-specific evidence.
qualification. The RV64 VexiiRiscv evidence recorded after that migration is
likewise historical: the HP core is now the locked, pre-generated T-Head
OpenC906 (RV64GC), and the `rv64imafdc_zicbom_max` VexiiRiscv configuration
survives only as the frozen Std-series generator asset. See
[HP RV64 validation](hp-rv64-validation.md) for the swap status and the new
evidence requirements.
- The complete Python suite passes 308 tests, including directed AXI64
multi-ID/ACL/QoS, target isolation, native AXI64 SRAM, Fabric Monitor,
@@ -64,7 +68,7 @@ qualification. Current generation selects `rv64imafdc_zicbom_max`; see
The strict IHP130 warning-baseline comparison remains an observation: the
baseline predates the fixed HP/product topology and does not contain many
generated VexiiRiscv, newly enabled peripheral, and PDK signatures. New warning
OpenC906, newly enabled peripheral, and PDK signatures. New warning
signatures introduced directly by the data-plane, lifecycle, extension, and
CDC integration were removed; the baseline was intentionally not regenerated
or hand-edited in this change.
+9 -4
View File
@@ -104,9 +104,13 @@ digraph mini_soc_block_diagram {
label="HP data domain @ EXT72 / PLL";
style="rounded";
vexii [
c906 [
fillcolor="#DBEAFE",
label="VexiiRiscv hart 1\nindependent native AXI64 I-cache / D-cache"
label="OpenC906 hart 1\nsingle 128-bit AXI4 master\ninternal CLINT/PLIC @ 0x08000000"
];
hp_demux [
fillcolor="#E0F2FE",
label="128 -> 64 serializing downsizer\n+ MMIO demux (0x02000000-0x2FFFFFFF)"
];
ext_h [
fillcolor="#DBEAFE",
@@ -158,8 +162,9 @@ digraph mini_soc_block_diagram {
lp_fabric -> lp_gateway [label="memory windows"];
hp_mmio -> lp_fabric [label="uncached MMIO"];
vexii -> data_plane [label="I$ / D$ AXI64"];
vexii -> hp_mmio [label="MMIO"];
c906 -> hp_demux [label="AXI4 128-bit"];
hp_demux -> data_plane [label="mem AXI64, slot 0"];
hp_demux -> hp_mmio [label="MMIO window"];
io_gateway -> data_plane [label="M2-M4"];
lp_gateway -> data_plane [label="M5"];
ext_h -> data_plane [label="M7"];
+185 -170
View File
@@ -4,66 +4,66 @@
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: mini_soc_block_diagram Pages: 1 -->
<svg width="3185pt" height="671pt"
viewBox="0.00 0.00 3185.11 671.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 667)">
<svg width="3183pt" height="596pt"
viewBox="0.00 0.00 3183.11 596.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 592)">
<title>mini_soc_block_diagram</title>
<text text-anchor="middle" x="145.5" y="-644.6" font-family="Arial" font-size="18.00">retroSoC Mini Product Architecture</text>
<text text-anchor="middle" x="145.5" y="-569.6" font-family="Arial" font-size="18.00">retroSoC Mini Product Architecture</text>
<g id="clust1" class="cluster">
<title>cluster_aon</title>
<path fill="transparent" stroke="#7c3aed" d="M233,-147C233,-147 415,-147 415,-147 421,-147 427,-153 427,-159 427,-159 427,-227 427,-227 427,-233 421,-239 415,-239 415,-239 233,-239 233,-239 227,-239 221,-233 221,-227 221,-227 221,-159 221,-159 221,-153 227,-147 233,-147"/>
<text text-anchor="middle" x="291" y="-220.6" font-family="Arial" font-size="18.00">AON @ REF24</text>
<path fill="transparent" stroke="#7c3aed" d="M233,-102C233,-102 415,-102 415,-102 421,-102 427,-108 427,-114 427,-114 427,-182 427,-182 427,-188 421,-194 415,-194 415,-194 233,-194 233,-194 227,-194 221,-188 221,-182 221,-182 221,-114 221,-114 221,-108 227,-102 233,-102"/>
<text text-anchor="middle" x="291" y="-175.6" font-family="Arial" font-size="18.00">AON @ REF24</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_lp</title>
<path fill="transparent" stroke="#15803d" d="M525,-215C525,-215 1370.51,-215 1370.51,-215 1376.51,-215 1382.51,-221 1382.51,-227 1382.51,-227 1382.51,-349 1382.51,-349 1382.51,-355 1376.51,-361 1370.51,-361 1370.51,-361 525,-361 525,-361 519,-361 513,-355 513,-349 513,-349 513,-227 513,-227 513,-221 519,-215 525,-215"/>
<path fill="transparent" stroke="#15803d" d="M525,-215C525,-215 1369.51,-215 1369.51,-215 1375.51,-215 1381.51,-221 1381.51,-227 1381.51,-227 1381.51,-349 1381.51,-349 1381.51,-355 1375.51,-361 1369.51,-361 1369.51,-361 525,-361 525,-361 519,-361 513,-355 513,-349 513,-349 513,-227 513,-227 513,-221 519,-215 525,-215"/>
<text text-anchor="middle" x="593" y="-342.6" font-family="Arial" font-size="18.00">LP control domain</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_pclk</title>
<path fill="transparent" stroke="#a16207" d="M1209.01,-38C1209.01,-38 1399.01,-38 1399.01,-38 1405.01,-38 1411.01,-44 1411.01,-50 1411.01,-50 1411.01,-195 1411.01,-195 1411.01,-201 1405.01,-207 1399.01,-207 1399.01,-207 1209.01,-207 1209.01,-207 1203.01,-207 1197.01,-201 1197.01,-195 1197.01,-195 1197.01,-50 1197.01,-50 1197.01,-44 1203.01,-38 1209.01,-38"/>
<text text-anchor="middle" x="1292.51" y="-188.6" font-family="Arial" font-size="18.00">PCLK register domain</text>
<path fill="transparent" stroke="#a16207" d="M1208.01,-38C1208.01,-38 1398.01,-38 1398.01,-38 1404.01,-38 1410.01,-44 1410.01,-50 1410.01,-50 1410.01,-195 1410.01,-195 1410.01,-201 1404.01,-207 1398.01,-207 1398.01,-207 1208.01,-207 1208.01,-207 1202.01,-207 1196.01,-201 1196.01,-195 1196.01,-195 1196.01,-50 1196.01,-50 1196.01,-44 1202.01,-38 1208.01,-38"/>
<text text-anchor="middle" x="1291.51" y="-188.6" font-family="Arial" font-size="18.00">PCLK register domain</text>
</g>
<g id="clust4" class="cluster">
<title>cluster_hp</title>
<path fill="transparent" stroke="#1d4ed8" d="M1201.51,-369C1201.51,-369 2506.61,-369 2506.61,-369 2512.61,-369 2518.61,-375 2518.61,-381 2518.61,-381 2518.61,-515 2518.61,-515 2518.61,-521 2512.61,-527 2506.61,-527 2506.61,-527 1201.51,-527 1201.51,-527 1195.51,-527 1189.51,-521 1189.51,-515 1189.51,-515 1189.51,-381 1189.51,-381 1189.51,-375 1195.51,-369 1201.51,-369"/>
<text text-anchor="middle" x="1327.01" y="-508.6" font-family="Arial" font-size="18.00">HP data domain @ EXT72 / PLL</text>
<path fill="transparent" stroke="#1d4ed8" d="M850.75,-369C850.75,-369 2504.61,-369 2504.61,-369 2510.61,-369 2516.61,-375 2516.61,-381 2516.61,-381 2516.61,-515 2516.61,-515 2516.61,-521 2510.61,-527 2504.61,-527 2504.61,-527 850.75,-527 850.75,-527 844.75,-527 838.75,-521 838.75,-515 838.75,-515 838.75,-381 838.75,-381 838.75,-375 844.75,-369 850.75,-369"/>
<text text-anchor="middle" x="976.25" y="-508.6" font-family="Arial" font-size="18.00">HP data domain @ EXT72 / PLL</text>
</g>
<g id="clust5" class="cluster">
<title>cluster_memory</title>
<path fill="transparent" stroke="#b45309" d="M2357.11,-535C2357.11,-535 2859.11,-535 2859.11,-535 2865.11,-535 2871.11,-541 2871.11,-547 2871.11,-547 2871.11,-615 2871.11,-615 2871.11,-621 2865.11,-627 2859.11,-627 2859.11,-627 2357.11,-627 2357.11,-627 2351.11,-627 2345.11,-621 2345.11,-615 2345.11,-615 2345.11,-547 2345.11,-547 2345.11,-541 2351.11,-535 2357.11,-535"/>
<text text-anchor="middle" x="2445.11" y="-608.6" font-family="Arial" font-size="18.00">Stable memory domain</text>
<path fill="transparent" stroke="#b45309" d="M2355.11,-174C2355.11,-174 2857.11,-174 2857.11,-174 2863.11,-174 2869.11,-180 2869.11,-186 2869.11,-186 2869.11,-254 2869.11,-254 2869.11,-260 2863.11,-266 2857.11,-266 2857.11,-266 2355.11,-266 2355.11,-266 2349.11,-266 2343.11,-260 2343.11,-254 2343.11,-254 2343.11,-186 2343.11,-186 2343.11,-180 2349.11,-174 2355.11,-174"/>
<text text-anchor="middle" x="2443.11" y="-247.6" font-family="Arial" font-size="18.00">Stable memory domain</text>
</g>
<!-- clocks -->
<g id="node1" class="node">
<title>clocks</title>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M107,-202.5C107,-202.5 12,-202.5 12,-202.5 6,-202.5 0,-196.5 0,-190.5 0,-190.5 0,-167.5 0,-167.5 0,-161.5 6,-155.5 12,-155.5 12,-155.5 107,-155.5 107,-155.5 113,-155.5 119,-161.5 119,-167.5 119,-167.5 119,-190.5 119,-190.5 119,-196.5 113,-202.5 107,-202.5"/>
<text text-anchor="middle" x="59.5" y="-187.5" font-family="Arial" font-size="10.00" fill="#111827">Clock and reset inputs</text>
<text text-anchor="middle" x="59.5" y="-176.5" font-family="Arial" font-size="10.00" fill="#111827">REF24, EXT72, audio</text>
<text text-anchor="middle" x="59.5" y="-165.5" font-family="Arial" font-size="10.00" fill="#111827">DVP, ULPI, JTAG</text>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M107,-157.5C107,-157.5 12,-157.5 12,-157.5 6,-157.5 0,-151.5 0,-145.5 0,-145.5 0,-122.5 0,-122.5 0,-116.5 6,-110.5 12,-110.5 12,-110.5 107,-110.5 107,-110.5 113,-110.5 119,-116.5 119,-122.5 119,-122.5 119,-145.5 119,-145.5 119,-151.5 113,-157.5 107,-157.5"/>
<text text-anchor="middle" x="59.5" y="-142.5" font-family="Arial" font-size="10.00" fill="#111827">Clock and reset inputs</text>
<text text-anchor="middle" x="59.5" y="-131.5" font-family="Arial" font-size="10.00" fill="#111827">REF24, EXT72, audio</text>
<text text-anchor="middle" x="59.5" y="-120.5" font-family="Arial" font-size="10.00" fill="#111827">DVP, ULPI, JTAG</text>
</g>
<!-- aon -->
<g id="node3" class="node">
<title>aon</title>
<path fill="#ede9fe" stroke="#4b5563" stroke-width="1.1" d="M407,-202.5C407,-202.5 241,-202.5 241,-202.5 235,-202.5 229,-196.5 229,-190.5 229,-190.5 229,-167.5 229,-167.5 229,-161.5 235,-155.5 241,-155.5 241,-155.5 407,-155.5 407,-155.5 413,-155.5 419,-161.5 419,-167.5 419,-167.5 419,-190.5 419,-190.5 419,-196.5 413,-202.5 407,-202.5"/>
<text text-anchor="middle" x="324" y="-187.5" font-family="Arial" font-size="10.00" fill="#111827">Clock/reset subsystem</text>
<text text-anchor="middle" x="324" y="-176.5" font-family="Arial" font-size="10.00" fill="#111827">PLL supervisor and clock monitor</text>
<text text-anchor="middle" x="324" y="-165.5" font-family="Arial" font-size="10.00" fill="#111827">HP lifecycle, pad mode, retained faults</text>
<path fill="#ede9fe" stroke="#4b5563" stroke-width="1.1" d="M407,-157.5C407,-157.5 241,-157.5 241,-157.5 235,-157.5 229,-151.5 229,-145.5 229,-145.5 229,-122.5 229,-122.5 229,-116.5 235,-110.5 241,-110.5 241,-110.5 407,-110.5 407,-110.5 413,-110.5 419,-116.5 419,-122.5 419,-122.5 419,-145.5 419,-145.5 419,-151.5 413,-157.5 407,-157.5"/>
<text text-anchor="middle" x="324" y="-142.5" font-family="Arial" font-size="10.00" fill="#111827">Clock/reset subsystem</text>
<text text-anchor="middle" x="324" y="-131.5" font-family="Arial" font-size="10.00" fill="#111827">PLL supervisor and clock monitor</text>
<text text-anchor="middle" x="324" y="-120.5" font-family="Arial" font-size="10.00" fill="#111827">HP lifecycle, pad mode, retained faults</text>
</g>
<!-- clocks&#45;&gt;aon -->
<g id="edge1" class="edge">
<title>clocks&#45;&gt;aon</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M119.08,-179C149.2,-179 186.77,-179 221.43,-179"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="221.78,-181.45 228.78,-179 221.78,-176.55 221.78,-181.45"/>
<text text-anchor="middle" x="174" y="-181.6" font-family="Arial" font-size="8.00" fill="#374151">REF24 / EXT72</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M119.08,-134C149.2,-134 186.77,-134 221.43,-134"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="221.78,-136.45 228.78,-134 221.78,-131.55 221.78,-136.45"/>
<text text-anchor="middle" x="174" y="-136.6" font-family="Arial" font-size="8.00" fill="#374151">REF24 / EXT72</text>
</g>
<!-- pads -->
<g id="node2" class="node">
<title>pads</title>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M3165.11,-147.5C3165.11,-147.5 2991.11,-147.5 2991.11,-147.5 2985.11,-147.5 2979.11,-141.5 2979.11,-135.5 2979.11,-135.5 2979.11,-112.5 2979.11,-112.5 2979.11,-106.5 2985.11,-100.5 2991.11,-100.5 2991.11,-100.5 3165.11,-100.5 3165.11,-100.5 3171.11,-100.5 3177.11,-106.5 3177.11,-112.5 3177.11,-112.5 3177.11,-135.5 3177.11,-135.5 3177.11,-141.5 3171.11,-147.5 3165.11,-147.5"/>
<text text-anchor="middle" x="3078.11" y="-132.5" font-family="Arial" font-size="10.00" fill="#111827">Pads and devices</text>
<text text-anchor="middle" x="3078.11" y="-121.5" font-family="Arial" font-size="10.00" fill="#111827">SDRAM, QPI/OPI shared pads, XPI</text>
<text text-anchor="middle" x="3078.11" y="-110.5" font-family="Arial" font-size="10.00" fill="#111827">USB2, SDIO, SPI&#45;SD, GPIO/peripherals</text>
<path fill="#f3f4f6" stroke="#4b5563" stroke-width="1.1" d="M3163.11,-147.5C3163.11,-147.5 2989.11,-147.5 2989.11,-147.5 2983.11,-147.5 2977.11,-141.5 2977.11,-135.5 2977.11,-135.5 2977.11,-112.5 2977.11,-112.5 2977.11,-106.5 2983.11,-100.5 2989.11,-100.5 2989.11,-100.5 3163.11,-100.5 3163.11,-100.5 3169.11,-100.5 3175.11,-106.5 3175.11,-112.5 3175.11,-112.5 3175.11,-135.5 3175.11,-135.5 3175.11,-141.5 3169.11,-147.5 3163.11,-147.5"/>
<text text-anchor="middle" x="3076.11" y="-132.5" font-family="Arial" font-size="10.00" fill="#111827">Pads and devices</text>
<text text-anchor="middle" x="3076.11" y="-121.5" font-family="Arial" font-size="10.00" fill="#111827">SDRAM, QPI/OPI shared pads, XPI</text>
<text text-anchor="middle" x="3076.11" y="-110.5" font-family="Arial" font-size="10.00" fill="#111827">USB2, SDIO, SPI&#45;SD, GPIO/peripherals</text>
</g>
<!-- hazard3 -->
<g id="node4" class="node">
@@ -75,98 +75,98 @@
<!-- aon&#45;&gt;hazard3 -->
<g id="edge2" class="edge">
<title>aon&#45;&gt;hazard3</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M419.38,-200.16C449.94,-207.02 483.69,-214.58 513.75,-221.32"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="513.54,-223.79 520.9,-222.93 514.61,-219.01 513.54,-223.79"/>
<text text-anchor="middle" x="470" y="-217.6" font-family="Arial" font-size="8.00" fill="#374151">LP clock/reset</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M386.02,-157.61C434.53,-176.38 501.71,-202.38 548.1,-220.34"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="547.38,-222.68 554.79,-222.92 549.15,-218.11 547.38,-222.68"/>
<text text-anchor="middle" x="470" y="-199.6" font-family="Arial" font-size="8.00" fill="#374151">LP clock/reset</text>
</g>
<!-- apb -->
<g id="node8" class="node">
<title>apb</title>
<path fill="#fef3c7" stroke="#4b5563" stroke-width="1.1" d="M1391.01,-93.5C1391.01,-93.5 1217.01,-93.5 1217.01,-93.5 1211.01,-93.5 1205.01,-87.5 1205.01,-81.5 1205.01,-81.5 1205.01,-58.5 1205.01,-58.5 1205.01,-52.5 1211.01,-46.5 1217.01,-46.5 1217.01,-46.5 1391.01,-46.5 1391.01,-46.5 1397.01,-46.5 1403.01,-52.5 1403.01,-58.5 1403.01,-58.5 1403.01,-81.5 1403.01,-81.5 1403.01,-87.5 1397.01,-93.5 1391.01,-93.5"/>
<text text-anchor="middle" x="1304.01" y="-78.5" font-family="Arial" font-size="10.00" fill="#111827">APB4 system + peripheral islands</text>
<text text-anchor="middle" x="1304.01" y="-67.5" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL, Resource Controller</text>
<text text-anchor="middle" x="1304.01" y="-56.5" font-family="Arial" font-size="10.00" fill="#111827">EXT&#45;L/EXT&#45;H, memory/peripheral control</text>
<path fill="#fef3c7" stroke="#4b5563" stroke-width="1.1" d="M1390.01,-93.5C1390.01,-93.5 1216.01,-93.5 1216.01,-93.5 1210.01,-93.5 1204.01,-87.5 1204.01,-81.5 1204.01,-81.5 1204.01,-58.5 1204.01,-58.5 1204.01,-52.5 1210.01,-46.5 1216.01,-46.5 1216.01,-46.5 1390.01,-46.5 1390.01,-46.5 1396.01,-46.5 1402.01,-52.5 1402.01,-58.5 1402.01,-58.5 1402.01,-81.5 1402.01,-81.5 1402.01,-87.5 1396.01,-93.5 1390.01,-93.5"/>
<text text-anchor="middle" x="1303.01" y="-78.5" font-family="Arial" font-size="10.00" fill="#111827">APB4 system + peripheral islands</text>
<text text-anchor="middle" x="1303.01" y="-67.5" font-family="Arial" font-size="10.00" fill="#111827">SYSCTRL, Resource Controller</text>
<text text-anchor="middle" x="1303.01" y="-56.5" font-family="Arial" font-size="10.00" fill="#111827">EXT&#45;L/EXT&#45;H, memory/peripheral control</text>
</g>
<!-- aon&#45;&gt;apb -->
<g id="edge3" class="edge">
<title>aon&#45;&gt;apb</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M419.22,-168.5C602.59,-148.06 1006.2,-103.08 1197.91,-81.71"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1198.24,-84.14 1204.92,-80.93 1197.69,-79.27 1198.24,-84.14"/>
<text text-anchor="middle" x="739.5" y="-137.6" font-family="Arial" font-size="8.00" fill="#374151">PCLK/reset</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M419.12,-127.83C602.18,-115.84 1004.98,-89.46 1196.65,-76.9"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1196.83,-79.34 1203.66,-76.44 1196.51,-74.46 1196.83,-79.34"/>
<text text-anchor="middle" x="739.5" y="-110.6" font-family="Arial" font-size="8.00" fill="#374151">PCLK/reset</text>
</g>
<!-- data_plane -->
<g id="node12" class="node">
<g id="node13" class="node">
<title>data_plane</title>
<path fill="#bfdbfe" stroke="#4b5563" stroke-width="1.1" d="M1871.04,-420.1C1871.04,-420.1 1811.22,-448.16 1811.22,-448.16 1805.79,-450.7 1794.36,-453.25 1788.36,-453.25 1788.36,-453.25 1649.26,-453.25 1649.26,-453.25 1643.26,-453.25 1631.83,-450.7 1626.39,-448.16 1626.39,-448.16 1566.57,-420.1 1566.57,-420.1 1561.14,-417.55 1561.14,-412.45 1566.57,-409.9 1566.57,-409.9 1626.39,-381.84 1626.39,-381.84 1631.83,-379.3 1643.26,-376.75 1649.26,-376.75 1649.26,-376.75 1788.36,-376.75 1788.36,-376.75 1794.36,-376.75 1805.79,-379.3 1811.22,-381.84 1811.22,-381.84 1871.04,-409.9 1871.04,-409.9 1876.47,-412.45 1876.47,-417.55 1871.04,-420.1"/>
<text text-anchor="middle" x="1718.81" y="-423.5" font-family="Arial" font-size="10.00" fill="#111827">Native AXI64 Data Plane</text>
<text text-anchor="middle" x="1718.81" y="-412.5" font-family="Arial" font-size="10.00" fill="#111827">9 masters x 6 targets, global ID7</text>
<text text-anchor="middle" x="1718.81" y="-401.5" font-family="Arial" font-size="10.00" fill="#111827">target credits, QoS aging, generated ACL</text>
<path fill="#bfdbfe" stroke="#4b5563" stroke-width="1.1" d="M1869.04,-420.1C1869.04,-420.1 1809.22,-448.16 1809.22,-448.16 1803.79,-450.7 1792.36,-453.25 1786.36,-453.25 1786.36,-453.25 1647.26,-453.25 1647.26,-453.25 1641.26,-453.25 1629.83,-450.7 1624.39,-448.16 1624.39,-448.16 1564.57,-420.1 1564.57,-420.1 1559.14,-417.55 1559.14,-412.45 1564.57,-409.9 1564.57,-409.9 1624.39,-381.84 1624.39,-381.84 1629.83,-379.3 1641.26,-376.75 1647.26,-376.75 1647.26,-376.75 1786.36,-376.75 1786.36,-376.75 1792.36,-376.75 1803.79,-379.3 1809.22,-381.84 1809.22,-381.84 1869.04,-409.9 1869.04,-409.9 1874.47,-412.45 1874.47,-417.55 1869.04,-420.1"/>
<text text-anchor="middle" x="1716.81" y="-423.5" font-family="Arial" font-size="10.00" fill="#111827">Native AXI64 Data Plane</text>
<text text-anchor="middle" x="1716.81" y="-412.5" font-family="Arial" font-size="10.00" fill="#111827">9 masters x 6 targets, global ID7</text>
<text text-anchor="middle" x="1716.81" y="-401.5" font-family="Arial" font-size="10.00" fill="#111827">target credits, QoS aging, generated ACL</text>
</g>
<!-- aon&#45;&gt;data_plane -->
<g id="edge4" class="edge">
<title>aon&#45;&gt;data_plane</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M343.36,-202.77C405.11,-282.72 601.5,-537 601.5,-537 601.5,-537 601.5,-537 1305.01,-537 1305.01,-537 1411.01,-506 1411.01,-506 1411.01,-506 1522.72,-472.87 1611.32,-446.58"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1612.18,-448.88 1618.2,-444.55 1610.79,-444.19 1612.18,-448.88"/>
<text text-anchor="middle" x="936.25" y="-548.6" font-family="Arial" font-size="8.00" fill="#374151">HP clock/reset</text>
<text text-anchor="middle" x="936.25" y="-539.6" font-family="Arial" font-size="8.00" fill="#374151">block, drain, flush</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M341.06,-157.7C400.07,-244.78 601.5,-542 601.5,-542 601.5,-542 601.5,-542 1304.01,-542 1304.01,-542 1489.1,-484.92 1611.11,-447.29"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1611.99,-449.58 1617.96,-445.18 1610.54,-444.9 1611.99,-449.58"/>
<text text-anchor="middle" x="936.25" y="-553.6" font-family="Arial" font-size="8.00" fill="#374151">HP clock/reset</text>
<text text-anchor="middle" x="936.25" y="-544.6" font-family="Arial" font-size="8.00" fill="#374151">block, drain, flush</text>
</g>
<!-- memory -->
<g id="node17" class="node">
<g id="node18" class="node">
<title>memory</title>
<path fill="#fed7aa" stroke="#4b5563" stroke-width="1.1" d="M2851.11,-590.5C2851.11,-590.5 2673.11,-590.5 2673.11,-590.5 2667.11,-590.5 2661.11,-584.5 2661.11,-578.5 2661.11,-578.5 2661.11,-555.5 2661.11,-555.5 2661.11,-549.5 2667.11,-543.5 2673.11,-543.5 2673.11,-543.5 2851.11,-543.5 2851.11,-543.5 2857.11,-543.5 2863.11,-549.5 2863.11,-555.5 2863.11,-555.5 2863.11,-578.5 2863.11,-578.5 2863.11,-584.5 2857.11,-590.5 2851.11,-590.5"/>
<text text-anchor="middle" x="2762.11" y="-575.5" font-family="Arial" font-size="10.00" fill="#111827">Fixed&#45;present frontends</text>
<text text-anchor="middle" x="2762.11" y="-564.5" font-family="Arial" font-size="10.00" fill="#111827">SDRAM | QPI | OPI/HyperBus | XPI</text>
<text text-anchor="middle" x="2762.11" y="-553.5" font-family="Arial" font-size="10.00" fill="#111827">QPI/OPI boot&#45;selected, inactive SLVERR</text>
<path fill="#fed7aa" stroke="#4b5563" stroke-width="1.1" d="M2849.11,-229.5C2849.11,-229.5 2671.11,-229.5 2671.11,-229.5 2665.11,-229.5 2659.11,-223.5 2659.11,-217.5 2659.11,-217.5 2659.11,-194.5 2659.11,-194.5 2659.11,-188.5 2665.11,-182.5 2671.11,-182.5 2671.11,-182.5 2849.11,-182.5 2849.11,-182.5 2855.11,-182.5 2861.11,-188.5 2861.11,-194.5 2861.11,-194.5 2861.11,-217.5 2861.11,-217.5 2861.11,-223.5 2855.11,-229.5 2849.11,-229.5"/>
<text text-anchor="middle" x="2760.11" y="-214.5" font-family="Arial" font-size="10.00" fill="#111827">Fixed&#45;present frontends</text>
<text text-anchor="middle" x="2760.11" y="-203.5" font-family="Arial" font-size="10.00" fill="#111827">SDRAM | QPI | OPI/HyperBus | XPI</text>
<text text-anchor="middle" x="2760.11" y="-192.5" font-family="Arial" font-size="10.00" fill="#111827">QPI/OPI boot&#45;selected, inactive SLVERR</text>
</g>
<!-- aon&#45;&gt;memory -->
<g id="edge5" class="edge">
<title>aon&#45;&gt;memory</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M361.43,-155.41C436.51,-106.81 601.5,0 601.5,0 601.5,0 601.5,0 2278.11,0 2278.11,0 2327.11,-25 2327.11,-25 2327.11,-25 2647.09,-424.61 2737.55,-537.58"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2735.89,-539.43 2742.18,-543.36 2739.72,-536.37 2735.89,-539.43"/>
<text text-anchor="middle" x="1483.01" y="-2.6" font-family="Arial" font-size="8.00" fill="#374151">stable memory clock/reset</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M373.8,-110.35C453.17,-71.88 601.5,0 601.5,0 601.5,0 601.5,0 2276.11,0 2276.11,0 2566.93,-124.04 2697.24,-179.61"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2696.3,-181.88 2703.7,-182.37 2698.22,-177.37 2696.3,-181.88"/>
<text text-anchor="middle" x="1481.01" y="-2.6" font-family="Arial" font-size="8.00" fill="#374151">stable memory clock/reset</text>
</g>
<!-- lp_fabric -->
<g id="node5" class="node">
<title>lp_fabric</title>
<path fill="#dbeafe" stroke="#4b5563" stroke-width="1.1" d="M1066.18,-296.6C1066.18,-296.6 1017.84,-316.68 1017.84,-316.68 1012.3,-318.99 1000.76,-321.29 994.76,-321.29 994.76,-321.29 877.75,-321.29 877.75,-321.29 871.75,-321.29 860.21,-318.99 854.67,-316.68 854.67,-316.68 806.33,-296.6 806.33,-296.6 800.79,-294.3 800.79,-289.7 806.33,-287.4 806.33,-287.4 854.67,-267.32 854.67,-267.32 860.21,-265.01 871.75,-262.71 877.75,-262.71 877.75,-262.71 994.76,-262.71 994.76,-262.71 1000.76,-262.71 1012.3,-265.01 1017.84,-267.32 1017.84,-267.32 1066.18,-287.4 1066.18,-287.4 1071.72,-289.7 1071.72,-294.3 1066.18,-296.6"/>
<text text-anchor="middle" x="936.25" y="-295" font-family="Arial" font-size="10.00" fill="#111827">32&#45;bit LP control fabric</text>
<text text-anchor="middle" x="936.25" y="-284" font-family="Arial" font-size="10.00" fill="#111827">root access policy and fault routing</text>
<path fill="#dbeafe" stroke="#4b5563" stroke-width="1.1" d="M1066.18,-265.6C1066.18,-265.6 1017.84,-285.68 1017.84,-285.68 1012.3,-287.99 1000.76,-290.29 994.76,-290.29 994.76,-290.29 877.75,-290.29 877.75,-290.29 871.75,-290.29 860.21,-287.99 854.67,-285.68 854.67,-285.68 806.33,-265.6 806.33,-265.6 800.79,-263.3 800.79,-258.7 806.33,-256.4 806.33,-256.4 854.67,-236.32 854.67,-236.32 860.21,-234.01 871.75,-231.71 877.75,-231.71 877.75,-231.71 994.76,-231.71 994.76,-231.71 1000.76,-231.71 1012.3,-234.01 1017.84,-236.32 1017.84,-236.32 1066.18,-256.4 1066.18,-256.4 1071.72,-258.7 1071.72,-263.3 1066.18,-265.6"/>
<text text-anchor="middle" x="936.25" y="-264" font-family="Arial" font-size="10.00" fill="#111827">32&#45;bit LP control fabric</text>
<text text-anchor="middle" x="936.25" y="-253" font-family="Arial" font-size="10.00" fill="#111827">root access policy and fault routing</text>
</g>
<!-- hazard3&#45;&gt;lp_fabric -->
<g id="edge6" class="edge">
<title>hazard3&#45;&gt;lp_fabric</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M684.23,-253.41C726.83,-259.96 779.71,-268.09 825.93,-275.19"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="825.7,-277.64 832.99,-276.28 826.44,-272.79 825.7,-277.64"/>
<text text-anchor="middle" x="739.5" y="-266.6" font-family="Arial" font-size="8.00" fill="#374151">AHB &#45;&gt; AXI32</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M684.23,-245.87C720.77,-248.07 764.86,-250.73 805.83,-253.2"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="805.77,-255.65 812.91,-253.62 806.07,-250.76 805.77,-255.65"/>
<text text-anchor="middle" x="739.5" y="-252.6" font-family="Arial" font-size="8.00" fill="#374151">AHB &#45;&gt; AXI32</text>
</g>
<!-- lp_gateway -->
<g id="node6" class="node">
<title>lp_gateway</title>
<path fill="#e0f2fe" stroke="#4b5563" stroke-width="1.1" d="M1362.51,-321.5C1362.51,-321.5 1245.51,-321.5 1245.51,-321.5 1239.51,-321.5 1233.51,-315.5 1233.51,-309.5 1233.51,-309.5 1233.51,-286.5 1233.51,-286.5 1233.51,-280.5 1239.51,-274.5 1245.51,-274.5 1245.51,-274.5 1362.51,-274.5 1362.51,-274.5 1368.51,-274.5 1374.51,-280.5 1374.51,-286.5 1374.51,-286.5 1374.51,-309.5 1374.51,-309.5 1374.51,-315.5 1368.51,-321.5 1362.51,-321.5"/>
<text text-anchor="middle" x="1304.01" y="-306.5" font-family="Arial" font-size="10.00" fill="#111827">LP &#45;&gt; HP data gateway</text>
<text text-anchor="middle" x="1304.01" y="-295.5" font-family="Arial" font-size="10.00" fill="#111827">AXI32 &#45;&gt; 64 + async bridge</text>
<text text-anchor="middle" x="1304.01" y="-284.5" font-family="Arial" font-size="10.00" fill="#111827">background / recovery QoS</text>
<path fill="#e0f2fe" stroke="#4b5563" stroke-width="1.1" d="M1361.51,-300.5C1361.51,-300.5 1244.51,-300.5 1244.51,-300.5 1238.51,-300.5 1232.51,-294.5 1232.51,-288.5 1232.51,-288.5 1232.51,-265.5 1232.51,-265.5 1232.51,-259.5 1238.51,-253.5 1244.51,-253.5 1244.51,-253.5 1361.51,-253.5 1361.51,-253.5 1367.51,-253.5 1373.51,-259.5 1373.51,-265.5 1373.51,-265.5 1373.51,-288.5 1373.51,-288.5 1373.51,-294.5 1367.51,-300.5 1361.51,-300.5"/>
<text text-anchor="middle" x="1303.01" y="-285.5" font-family="Arial" font-size="10.00" fill="#111827">LP &#45;&gt; HP data gateway</text>
<text text-anchor="middle" x="1303.01" y="-274.5" font-family="Arial" font-size="10.00" fill="#111827">AXI32 &#45;&gt; 64 + async bridge</text>
<text text-anchor="middle" x="1303.01" y="-263.5" font-family="Arial" font-size="10.00" fill="#111827">background / recovery QoS</text>
</g>
<!-- lp_fabric&#45;&gt;lp_gateway -->
<g id="edge8" class="edge">
<title>lp_fabric&#45;&gt;lp_gateway</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1072.15,-294.21C1124.13,-295.07 1181.69,-296.01 1226.32,-296.74"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1226.33,-299.19 1233.37,-296.86 1226.41,-294.29 1226.33,-299.19"/>
<text text-anchor="middle" x="1137.51" y="-297.6" font-family="Arial" font-size="8.00" fill="#374151">memory windows</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1064.06,-266.56C1117.76,-268.92 1178.57,-271.59 1225.28,-273.63"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1225.25,-276.09 1232.35,-273.94 1225.47,-271.19 1225.25,-276.09"/>
<text text-anchor="middle" x="1137.51" y="-272.6" font-family="Arial" font-size="8.00" fill="#374151">memory windows</text>
</g>
<!-- lp_fabric&#45;&gt;apb -->
<g id="edge7" class="edge">
<title>lp_fabric&#45;&gt;apb</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M984.66,-262.66C1053.11,-220.29 1171.51,-147 1171.51,-147 1171.51,-147 1189.51,-109 1189.51,-109 1189.51,-109 1206.72,-103.09 1227.74,-95.86"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1228.54,-98.18 1234.37,-93.59 1226.95,-93.54 1228.54,-98.18"/>
<text text-anchor="middle" x="1137.51" y="-187.6" font-family="Arial" font-size="8.00" fill="#374151">LP &#45;&gt; PCLK APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M987.14,-231.69C1062.34,-187.52 1196.01,-109 1196.01,-109 1196.01,-109 1211.81,-103.19 1231.2,-96.05"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1232.18,-98.3 1237.9,-93.59 1230.49,-93.7 1232.18,-98.3"/>
<text text-anchor="middle" x="1137.51" y="-164.6" font-family="Arial" font-size="8.00" fill="#374151">LP &#45;&gt; PCLK APB</text>
</g>
<!-- lp_gateway&#45;&gt;data_plane -->
<g id="edge13" class="edge">
<g id="edge14" class="edge">
<title>lp_gateway&#45;&gt;data_plane</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1374.57,-317.72C1438.79,-335.92 1535.17,-363.24 1609.47,-384.29"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1609.19,-386.76 1616.59,-386.31 1610.52,-382.05 1609.19,-386.76"/>
<text text-anchor="middle" x="1483.01" y="-362.6" font-family="Arial" font-size="8.00" fill="#374151">M5</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1373.86,-300.41C1439.91,-322.54 1539.75,-356 1614.53,-381.06"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1613.81,-383.4 1621.23,-383.31 1615.37,-378.76 1613.81,-383.4"/>
<text text-anchor="middle" x="1481.01" y="-352.6" font-family="Arial" font-size="8.00" fill="#374151">M5</text>
</g>
<!-- hp_mmio -->
<g id="node7" class="node">
@@ -178,162 +178,177 @@
<!-- hp_mmio&#45;&gt;lp_fabric -->
<g id="edge9" class="edge">
<title>hp_mmio&#45;&gt;lp_fabric</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M673.05,-303.86C710.38,-302.17 757.68,-300.03 801.79,-298.03"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="801.96,-300.48 808.84,-297.72 801.74,-295.58 801.96,-300.48"/>
<text text-anchor="middle" x="739.5" y="-304.6" font-family="Arial" font-size="8.00" fill="#374151">uncached MMIO</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M673.05,-297.36C716.51,-291.33 773.47,-283.43 823.2,-276.54"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="823.57,-278.96 830.16,-275.57 822.89,-274.11 823.57,-278.96"/>
<text text-anchor="middle" x="739.5" y="-294.6" font-family="Arial" font-size="8.00" fill="#374151">uncached MMIO</text>
</g>
<!-- apb&#45;&gt;pads -->
<g id="edge22" class="edge">
<g id="edge23" class="edge">
<title>apb&#45;&gt;pads</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1410.33,-67.96C1532.63,-65.59 1717.81,-62 1717.81,-62 1717.81,-62 1717.81,-62 2763.11,-62 2763.11,-62 2880.71,-85.22 2971.97,-103.24"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1410.05,-65.51 1403.1,-68.1 1410.14,-70.41 1410.05,-65.51"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2971.7,-105.69 2979.05,-104.64 2972.65,-100.88 2971.7,-105.69"/>
<text text-anchor="middle" x="2277.11" y="-64.6" font-family="Arial" font-size="8.00" fill="#374151">control and peripheral I/O</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1409.34,-67.95C1531.34,-65.58 1715.81,-62 1715.81,-62 1715.81,-62 1715.81,-62 2761.11,-62 2761.11,-62 2878.71,-85.22 2969.97,-103.24"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1409.07,-65.51 1402.12,-68.09 1409.17,-70.41 1409.07,-65.51"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2969.7,-105.69 2977.05,-104.64 2970.65,-100.88 2969.7,-105.69"/>
<text text-anchor="middle" x="2275.11" y="-64.6" font-family="Arial" font-size="8.00" fill="#374151">control and peripheral I/O</text>
</g>
<!-- ext_h -->
<g id="node11" class="node">
<g id="node12" class="node">
<title>ext_h</title>
<path fill="#dbeafe" stroke="#4b5563" stroke-width="1.1" d="M1343.01,-490.5C1343.01,-490.5 1265.01,-490.5 1265.01,-490.5 1259.01,-490.5 1253.01,-484.5 1253.01,-478.5 1253.01,-478.5 1253.01,-455.5 1253.01,-455.5 1253.01,-449.5 1259.01,-443.5 1265.01,-443.5 1265.01,-443.5 1343.01,-443.5 1343.01,-443.5 1349.01,-443.5 1355.01,-449.5 1355.01,-455.5 1355.01,-455.5 1355.01,-478.5 1355.01,-478.5 1355.01,-484.5 1349.01,-490.5 1343.01,-490.5"/>
<text text-anchor="middle" x="1304.01" y="-475.5" font-family="Arial" font-size="10.00" fill="#111827">EXT&#45;H</text>
<text text-anchor="middle" x="1304.01" y="-464.5" font-family="Arial" font-size="10.00" fill="#111827">AXI64 data master</text>
<text text-anchor="middle" x="1304.01" y="-453.5" font-family="Arial" font-size="10.00" fill="#111827">fixed range ACL</text>
<path fill="#dbeafe" stroke="#4b5563" stroke-width="1.1" d="M1342.01,-490.5C1342.01,-490.5 1264.01,-490.5 1264.01,-490.5 1258.01,-490.5 1252.01,-484.5 1252.01,-478.5 1252.01,-478.5 1252.01,-455.5 1252.01,-455.5 1252.01,-449.5 1258.01,-443.5 1264.01,-443.5 1264.01,-443.5 1342.01,-443.5 1342.01,-443.5 1348.01,-443.5 1354.01,-449.5 1354.01,-455.5 1354.01,-455.5 1354.01,-478.5 1354.01,-478.5 1354.01,-484.5 1348.01,-490.5 1342.01,-490.5"/>
<text text-anchor="middle" x="1303.01" y="-475.5" font-family="Arial" font-size="10.00" fill="#111827">EXT&#45;H</text>
<text text-anchor="middle" x="1303.01" y="-464.5" font-family="Arial" font-size="10.00" fill="#111827">AXI64 data master</text>
<text text-anchor="middle" x="1303.01" y="-453.5" font-family="Arial" font-size="10.00" fill="#111827">fixed range ACL</text>
</g>
<!-- apb&#45;&gt;ext_h -->
<g id="edge15" class="edge">
<g id="edge16" class="edge">
<title>apb&#45;&gt;ext_h</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1234.76,-93.59C1210.65,-101.8 1189.51,-109 1189.51,-109 1189.51,-109 1132.51,-369.5 1132.51,-369.5 1132.51,-369.5 1132.51,-378.5 1132.51,-378.5 1132.51,-378.5 1189.51,-428 1189.51,-428 1189.51,-428 1217.61,-437.57 1245.97,-447.23"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1245.37,-449.62 1252.79,-449.55 1246.95,-444.98 1245.37,-449.62"/>
<path fill="none" stroke="#4b5563" stroke-width="1.2" stroke-dasharray="5,2" d="M1238.3,-93.59C1215.76,-101.8 1196.01,-109 1196.01,-109 1196.01,-109 1130.51,-369.5 1130.51,-369.5 1130.51,-369.5 1130.51,-378.5 1130.51,-378.5 1130.51,-378.5 1196.01,-428 1196.01,-428 1196.01,-428 1219.8,-436.67 1244.94,-445.84"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1244.29,-448.2 1251.7,-448.3 1245.96,-443.6 1244.29,-448.2"/>
<text text-anchor="middle" x="1137.51" y="-372.1" font-family="Arial" font-size="8.00" fill="#374151">control / ownership</text>
</g>
<!-- monitor -->
<g id="node15" class="node">
<g id="node16" class="node">
<title>monitor</title>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M2177.61,-424.5C2177.61,-424.5 2028.61,-424.5 2028.61,-424.5 2022.61,-424.5 2016.61,-418.5 2016.61,-412.5 2016.61,-412.5 2016.61,-389.5 2016.61,-389.5 2016.61,-383.5 2022.61,-377.5 2028.61,-377.5 2028.61,-377.5 2177.61,-377.5 2177.61,-377.5 2183.61,-377.5 2189.61,-383.5 2189.61,-389.5 2189.61,-389.5 2189.61,-412.5 2189.61,-412.5 2189.61,-418.5 2183.61,-424.5 2177.61,-424.5"/>
<text text-anchor="middle" x="2103.11" y="-409.5" font-family="Arial" font-size="10.00" fill="#111827">Fabric Monitor @ 0x2000_B000</text>
<text text-anchor="middle" x="2103.11" y="-398.5" font-family="Arial" font-size="10.00" fill="#111827">snapshot counters, wait/high&#45;water</text>
<text text-anchor="middle" x="2103.11" y="-387.5" font-family="Arial" font-size="10.00" fill="#111827">timeout/isolation, sticky first fault</text>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M2175.61,-424.5C2175.61,-424.5 2026.61,-424.5 2026.61,-424.5 2020.61,-424.5 2014.61,-418.5 2014.61,-412.5 2014.61,-412.5 2014.61,-389.5 2014.61,-389.5 2014.61,-383.5 2020.61,-377.5 2026.61,-377.5 2026.61,-377.5 2175.61,-377.5 2175.61,-377.5 2181.61,-377.5 2187.61,-383.5 2187.61,-389.5 2187.61,-389.5 2187.61,-412.5 2187.61,-412.5 2187.61,-418.5 2181.61,-424.5 2175.61,-424.5"/>
<text text-anchor="middle" x="2101.11" y="-409.5" font-family="Arial" font-size="10.00" fill="#111827">Fabric Monitor @ 0x2000_B000</text>
<text text-anchor="middle" x="2101.11" y="-398.5" font-family="Arial" font-size="10.00" fill="#111827">snapshot counters, wait/high&#45;water</text>
<text text-anchor="middle" x="2101.11" y="-387.5" font-family="Arial" font-size="10.00" fill="#111827">timeout/isolation, sticky first fault</text>
</g>
<!-- apb&#45;&gt;monitor -->
<g id="edge21" class="edge">
<g id="edge22" class="edge">
<title>apb&#45;&gt;monitor</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1369.11,-93.59C1391.44,-101.8 1411.01,-109 1411.01,-109 1411.01,-109 1869.83,-302.86 2039.77,-374.66"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2039.03,-377.01 2046.43,-377.48 2040.93,-372.49 2039.03,-377.01"/>
<text text-anchor="middle" x="1718.81" y="-309.6" font-family="Arial" font-size="8.00" fill="#374151">PCLK &#45;&gt; HP APB</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1368.11,-93.59C1390.44,-101.8 1410.01,-109 1410.01,-109 1410.01,-109 1868.16,-302.86 2037.86,-374.66"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2037.11,-377 2044.51,-377.48 2039.02,-372.49 2037.11,-377"/>
<text text-anchor="middle" x="1716.81" y="-309.6" font-family="Arial" font-size="8.00" fill="#374151">PCLK &#45;&gt; HP APB</text>
</g>
<!-- io_gateway -->
<g id="node9" class="node">
<title>io_gateway</title>
<path fill="#fef3c7" stroke="#4b5563" stroke-width="1.1" d="M1388.01,-170.5C1388.01,-170.5 1220.01,-170.5 1220.01,-170.5 1214.01,-170.5 1208.01,-164.5 1208.01,-158.5 1208.01,-158.5 1208.01,-135.5 1208.01,-135.5 1208.01,-129.5 1214.01,-123.5 1220.01,-123.5 1220.01,-123.5 1388.01,-123.5 1388.01,-123.5 1394.01,-123.5 1400.01,-129.5 1400.01,-135.5 1400.01,-135.5 1400.01,-158.5 1400.01,-158.5 1400.01,-164.5 1394.01,-170.5 1388.01,-170.5"/>
<text text-anchor="middle" x="1304.01" y="-155.5" font-family="Arial" font-size="10.00" fill="#111827">DMA and I/O sub&#45;fabrics</text>
<text text-anchor="middle" x="1304.01" y="-144.5" font-family="Arial" font-size="10.00" fill="#111827">central DMA, USB2, SDIO0/1, SPI&#45;SD</text>
<text text-anchor="middle" x="1304.01" y="-133.5" font-family="Arial" font-size="10.00" fill="#111827">AXI32 &#45;&gt; 64 + async bridges</text>
<path fill="#fef3c7" stroke="#4b5563" stroke-width="1.1" d="M1387.01,-170.5C1387.01,-170.5 1219.01,-170.5 1219.01,-170.5 1213.01,-170.5 1207.01,-164.5 1207.01,-158.5 1207.01,-158.5 1207.01,-135.5 1207.01,-135.5 1207.01,-129.5 1213.01,-123.5 1219.01,-123.5 1219.01,-123.5 1387.01,-123.5 1387.01,-123.5 1393.01,-123.5 1399.01,-129.5 1399.01,-135.5 1399.01,-135.5 1399.01,-158.5 1399.01,-158.5 1399.01,-164.5 1393.01,-170.5 1387.01,-170.5"/>
<text text-anchor="middle" x="1303.01" y="-155.5" font-family="Arial" font-size="10.00" fill="#111827">DMA and I/O sub&#45;fabrics</text>
<text text-anchor="middle" x="1303.01" y="-144.5" font-family="Arial" font-size="10.00" fill="#111827">central DMA, USB2, SDIO0/1, SPI&#45;SD</text>
<text text-anchor="middle" x="1303.01" y="-133.5" font-family="Arial" font-size="10.00" fill="#111827">AXI32 &#45;&gt; 64 + async bridges</text>
</g>
<!-- io_gateway&#45;&gt;pads -->
<g id="edge23" class="edge">
<g id="edge24" class="edge">
<title>io_gateway&#45;&gt;pads</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1407.17,-157.6C1476.46,-164.8 1555.51,-173 1555.51,-173 1555.51,-173 1882.11,-173 1882.11,-173 1882.11,-173 2102.11,-124 2102.11,-124 2102.11,-124 2102.11,-124 2763.11,-124 2763.11,-124 2880.71,-124 2971.97,-124"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1407.28,-155.15 1400.07,-156.87 1406.78,-160.03 1407.28,-155.15"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2972.05,-126.45 2979.05,-124 2972.05,-121.55 2972.05,-126.45"/>
<text text-anchor="middle" x="2277.11" y="-126.6" font-family="Arial" font-size="8.00" fill="#374151">payload</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1406.11,-157.64C1475.04,-164.82 1553.51,-173 1553.51,-173 1553.51,-173 1880.11,-173 1880.11,-173 1880.11,-173 2100.11,-124 2100.11,-124 2100.11,-124 2100.11,-124 2761.11,-124 2761.11,-124 2878.71,-124 2969.97,-124"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1406.26,-155.19 1399.04,-156.9 1405.75,-160.07 1406.26,-155.19"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2970.05,-126.45 2977.05,-124 2970.05,-121.55 2970.05,-126.45"/>
<text text-anchor="middle" x="2275.11" y="-126.6" font-family="Arial" font-size="8.00" fill="#374151">payload</text>
</g>
<!-- io_gateway&#45;&gt;data_plane -->
<g id="edge12" class="edge">
<g id="edge13" class="edge">
<title>io_gateway&#45;&gt;data_plane</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1345.99,-170.58C1375.82,-187.75 1411.01,-208 1411.01,-208 1411.01,-208 1565.25,-312.07 1655,-372.63"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1653.65,-374.67 1660.82,-376.55 1656.39,-370.6 1653.65,-374.67"/>
<text text-anchor="middle" x="1483.01" y="-288.6" font-family="Arial" font-size="8.00" fill="#374151">M2&#45;M4</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1344.99,-170.58C1374.82,-187.75 1410.01,-208 1410.01,-208 1410.01,-208 1563.75,-312.07 1653.21,-372.63"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1651.84,-374.65 1659.01,-376.55 1654.58,-370.6 1651.84,-374.65"/>
<text text-anchor="middle" x="1481.01" y="-288.6" font-family="Arial" font-size="8.00" fill="#374151">M2&#45;M4</text>
</g>
<!-- vexii -->
<!-- c906 -->
<g id="node10" class="node">
<title>vexii</title>
<path fill="#dbeafe" stroke="#4b5563" stroke-width="1.1" d="M1398.51,-413C1398.51,-413 1209.51,-413 1209.51,-413 1203.51,-413 1197.51,-407 1197.51,-401 1197.51,-401 1197.51,-389 1197.51,-389 1197.51,-383 1203.51,-377 1209.51,-377 1209.51,-377 1398.51,-377 1398.51,-377 1404.51,-377 1410.51,-383 1410.51,-389 1410.51,-389 1410.51,-401 1410.51,-401 1410.51,-407 1404.51,-413 1398.51,-413"/>
<text text-anchor="middle" x="1304.01" y="-398" font-family="Arial" font-size="10.00" fill="#111827">VexiiRiscv hart 1</text>
<text text-anchor="middle" x="1304.01" y="-387" font-family="Arial" font-size="10.00" fill="#111827">independent native AXI64 I&#45;cache / D&#45;cache</text>
<title>c906</title>
<path fill="#dbeafe" stroke="#4b5563" stroke-width="1.1" d="M1013.75,-481.5C1013.75,-481.5 858.75,-481.5 858.75,-481.5 852.75,-481.5 846.75,-475.5 846.75,-469.5 846.75,-469.5 846.75,-446.5 846.75,-446.5 846.75,-440.5 852.75,-434.5 858.75,-434.5 858.75,-434.5 1013.75,-434.5 1013.75,-434.5 1019.75,-434.5 1025.75,-440.5 1025.75,-446.5 1025.75,-446.5 1025.75,-469.5 1025.75,-469.5 1025.75,-475.5 1019.75,-481.5 1013.75,-481.5"/>
<text text-anchor="middle" x="936.25" y="-466.5" font-family="Arial" font-size="10.00" fill="#111827">OpenC906 hart 1</text>
<text text-anchor="middle" x="936.25" y="-455.5" font-family="Arial" font-size="10.00" fill="#111827">single 128&#45;bit AXI4 master</text>
<text text-anchor="middle" x="936.25" y="-444.5" font-family="Arial" font-size="10.00" fill="#111827">internal CLINT/PLIC @ 0x08000000</text>
</g>
<!-- vexii&#45;&gt;hp_mmio -->
<g id="edge11" class="edge">
<title>vexii&#45;&gt;hp_mmio</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1197.42,-387.06C1149.56,-383.46 1103.51,-380 1103.51,-380 1103.51,-380 795,-336 795,-336 795,-336 733.57,-326.7 680.3,-318.63"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="680.47,-316.18 673.18,-317.55 679.73,-321.02 680.47,-316.18"/>
<text text-anchor="middle" x="936.25" y="-377.6" font-family="Arial" font-size="8.00" fill="#374151">MMIO</text>
<!-- hp_demux -->
<g id="node11" class="node">
<title>hp_demux</title>
<path fill="#e0f2fe" stroke="#4b5563" stroke-width="1.1" d="M1396.51,-413C1396.51,-413 1209.51,-413 1209.51,-413 1203.51,-413 1197.51,-407 1197.51,-401 1197.51,-401 1197.51,-389 1197.51,-389 1197.51,-383 1203.51,-377 1209.51,-377 1209.51,-377 1396.51,-377 1396.51,-377 1402.51,-377 1408.51,-383 1408.51,-389 1408.51,-389 1408.51,-401 1408.51,-401 1408.51,-407 1402.51,-413 1396.51,-413"/>
<text text-anchor="middle" x="1303.01" y="-398" font-family="Arial" font-size="10.00" fill="#111827">128 &#45;&gt; 64 serializing downsizer</text>
<text text-anchor="middle" x="1303.01" y="-387" font-family="Arial" font-size="10.00" fill="#111827">+ MMIO demux (0x02000000&#45;0x2FFFFFFF)</text>
</g>
<!-- vexii&#45;&gt;data_plane -->
<!-- c906&#45;&gt;hp_demux -->
<g id="edge10" class="edge">
<title>vexii&#45;&gt;data_plane</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1410.51,-400.11C1456.94,-402.36 1512.4,-405.05 1563.34,-407.52"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1563.39,-409.97 1570.5,-407.86 1563.63,-405.08 1563.39,-409.97"/>
<text text-anchor="middle" x="1483.01" y="-407.6" font-family="Arial" font-size="8.00" fill="#374151">I$ / D$ AXI64</text>
<title>c906&#45;&gt;hp_demux</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1025.82,-444.01C1092.15,-433.53 1171.51,-421 1171.51,-421 1171.51,-421 1185.46,-418.22 1204.25,-414.48"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1204.98,-416.83 1211.37,-413.06 1204.03,-412.02 1204.98,-416.83"/>
<text text-anchor="middle" x="1137.51" y="-432.6" font-family="Arial" font-size="8.00" fill="#374151">AXI4 128&#45;bit</text>
</g>
<!-- hp_demux&#45;&gt;hp_mmio -->
<g id="edge12" class="edge">
<title>hp_demux&#45;&gt;hp_mmio</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1197.24,-387.08C1149.52,-383.48 1103.51,-380 1103.51,-380 1103.51,-380 820.06,-338.62 679.99,-318.17"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="680.3,-315.74 673.02,-317.15 679.6,-320.59 680.3,-315.74"/>
<text text-anchor="middle" x="936.25" y="-377.6" font-family="Arial" font-size="8.00" fill="#374151">MMIO window</text>
</g>
<!-- hp_demux&#45;&gt;data_plane -->
<g id="edge11" class="edge">
<title>hp_demux&#45;&gt;data_plane</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1408.72,-400.09C1455.15,-402.34 1510.71,-405.04 1561.73,-407.52"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1561.79,-409.97 1568.9,-407.87 1562.03,-405.08 1561.79,-409.97"/>
<text text-anchor="middle" x="1481.01" y="-407.6" font-family="Arial" font-size="8.00" fill="#374151">mem AXI64, slot 0</text>
</g>
<!-- ext_h&#45;&gt;data_plane -->
<g id="edge14" class="edge">
<g id="edge15" class="edge">
<title>ext_h&#45;&gt;data_plane</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1355.21,-460.68C1411.42,-453.6 1504.85,-441.83 1582.79,-432.01"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1583.17,-434.43 1589.81,-431.12 1582.56,-429.57 1583.17,-434.43"/>
<text text-anchor="middle" x="1483.01" y="-452.6" font-family="Arial" font-size="8.00" fill="#374151">M7</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1354.09,-460.68C1410.06,-453.61 1503.02,-441.87 1580.69,-432.06"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1581.04,-434.49 1587.68,-431.18 1580.43,-429.63 1581.04,-434.49"/>
<text text-anchor="middle" x="1481.01" y="-452.6" font-family="Arial" font-size="8.00" fill="#374151">M7</text>
</g>
<!-- guards -->
<g id="node13" class="node">
<g id="node14" class="node">
<title>guards</title>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M2189.11,-491C2189.11,-491 2017.11,-491 2017.11,-491 2011.11,-491 2005.11,-485 2005.11,-479 2005.11,-479 2005.11,-467 2005.11,-467 2005.11,-461 2011.11,-455 2017.11,-455 2017.11,-455 2189.11,-455 2189.11,-455 2195.11,-455 2201.11,-461 2201.11,-467 2201.11,-467 2201.11,-479 2201.11,-479 2201.11,-485 2195.11,-491 2189.11,-491"/>
<text text-anchor="middle" x="2103.11" y="-476" font-family="Arial" font-size="10.00" fill="#111827">Queued target guards</text>
<text text-anchor="middle" x="2103.11" y="-465" font-family="Arial" font-size="10.00" fill="#111827">bounded SLVERR, timeout and isolation</text>
<path fill="#fce7f3" stroke="#4b5563" stroke-width="1.1" d="M2187.11,-491C2187.11,-491 2015.11,-491 2015.11,-491 2009.11,-491 2003.11,-485 2003.11,-479 2003.11,-479 2003.11,-467 2003.11,-467 2003.11,-461 2009.11,-455 2015.11,-455 2015.11,-455 2187.11,-455 2187.11,-455 2193.11,-455 2199.11,-461 2199.11,-467 2199.11,-467 2199.11,-479 2199.11,-479 2199.11,-485 2193.11,-491 2187.11,-491"/>
<text text-anchor="middle" x="2101.11" y="-476" font-family="Arial" font-size="10.00" fill="#111827">Queued target guards</text>
<text text-anchor="middle" x="2101.11" y="-465" font-family="Arial" font-size="10.00" fill="#111827">bounded SLVERR, timeout and isolation</text>
</g>
<!-- data_plane&#45;&gt;guards -->
<g id="edge16" class="edge">
<g id="edge17" class="edge">
<title>data_plane&#45;&gt;guards</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1842.35,-433.59C1892.51,-441.2 1949.95,-449.92 1998.04,-457.21"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1997.77,-459.65 2005.06,-458.28 1998.51,-454.8 1997.77,-459.65"/>
<text text-anchor="middle" x="1943.61" y="-456.6" font-family="Arial" font-size="8.00" fill="#374151">five memory targets</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1840.35,-433.59C1890.51,-441.2 1947.95,-449.92 1996.04,-457.21"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="1995.77,-459.65 2003.06,-458.28 1996.51,-454.8 1995.77,-459.65"/>
<text text-anchor="middle" x="1941.61" y="-456.6" font-family="Arial" font-size="8.00" fill="#374151">five memory targets</text>
</g>
<!-- data_plane&#45;&gt;monitor -->
<g id="edge20" class="edge">
<g id="edge21" class="edge">
<title>data_plane&#45;&gt;monitor</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1870.35,-409.49C1917.26,-407.77 1967.6,-405.93 2009.33,-404.4"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2009.58,-406.84 2016.48,-404.14 2009.4,-401.94 2009.58,-406.84"/>
<text text-anchor="middle" x="1943.61" y="-410.6" font-family="Arial" font-size="8.00" fill="#374151">events / fault</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M1868.35,-409.49C1915.26,-407.77 1965.6,-405.93 2007.33,-404.4"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2007.58,-406.84 2014.48,-404.14 2007.4,-401.94 2007.58,-406.84"/>
<text text-anchor="middle" x="1941.61" y="-410.6" font-family="Arial" font-size="8.00" fill="#374151">events / fault</text>
</g>
<!-- sram -->
<g id="node14" class="node">
<g id="node15" class="node">
<title>sram</title>
<path fill="#fde68a" stroke="#4b5563" stroke-width="1.1" d="M2498.61,-491C2498.61,-491 2405.61,-491 2405.61,-491 2399.61,-491 2393.61,-485 2393.61,-479 2393.61,-479 2393.61,-467 2393.61,-467 2393.61,-461 2399.61,-455 2405.61,-455 2405.61,-455 2498.61,-455 2498.61,-455 2504.61,-455 2510.61,-461 2510.61,-467 2510.61,-467 2510.61,-479 2510.61,-479 2510.61,-485 2504.61,-491 2498.61,-491"/>
<text text-anchor="middle" x="2452.11" y="-476" font-family="Arial" font-size="10.00" fill="#111827">32 KiB on&#45;chip SRAM</text>
<text text-anchor="middle" x="2452.11" y="-465" font-family="Arial" font-size="10.00" fill="#111827">native AXI64 / ID7</text>
<path fill="#fde68a" stroke="#4b5563" stroke-width="1.1" d="M2496.61,-491C2496.61,-491 2403.61,-491 2403.61,-491 2397.61,-491 2391.61,-485 2391.61,-479 2391.61,-479 2391.61,-467 2391.61,-467 2391.61,-461 2397.61,-455 2403.61,-455 2403.61,-455 2496.61,-455 2496.61,-455 2502.61,-455 2508.61,-461 2508.61,-467 2508.61,-467 2508.61,-479 2508.61,-479 2508.61,-485 2502.61,-491 2496.61,-491"/>
<text text-anchor="middle" x="2450.11" y="-476" font-family="Arial" font-size="10.00" fill="#111827">32 KiB on&#45;chip SRAM</text>
<text text-anchor="middle" x="2450.11" y="-465" font-family="Arial" font-size="10.00" fill="#111827">native AXI64 / ID7</text>
</g>
<!-- guards&#45;&gt;sram -->
<g id="edge17" class="edge">
<g id="edge18" class="edge">
<title>guards&#45;&gt;sram</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2201.23,-473C2260.3,-473 2334.14,-473 2386.18,-473"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2386.38,-475.45 2393.38,-473 2386.38,-470.55 2386.38,-475.45"/>
<text text-anchor="middle" x="2277.11" y="-475.6" font-family="Arial" font-size="8.00" fill="#374151">native AXI64</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2199.23,-473C2258.3,-473 2332.14,-473 2384.18,-473"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2384.38,-475.45 2391.38,-473 2384.38,-470.55 2384.38,-475.45"/>
<text text-anchor="middle" x="2275.11" y="-475.6" font-family="Arial" font-size="8.00" fill="#374151">native AXI64</text>
</g>
<!-- memory_cdc -->
<g id="node16" class="node">
<g id="node17" class="node">
<title>memory_cdc</title>
<path fill="#ffedd5" stroke="#4b5563" stroke-width="1.1" d="M2539.11,-585C2539.11,-585 2365.11,-585 2365.11,-585 2359.11,-585 2353.11,-579 2353.11,-573 2353.11,-573 2353.11,-561 2353.11,-561 2353.11,-555 2359.11,-549 2365.11,-549 2365.11,-549 2539.11,-549 2539.11,-549 2545.11,-549 2551.11,-555 2551.11,-561 2551.11,-561 2551.11,-573 2551.11,-573 2551.11,-579 2545.11,-585 2539.11,-585"/>
<text text-anchor="middle" x="2452.11" y="-570" font-family="Arial" font-size="10.00" fill="#111827">Four direct HP &#45;&gt; memory AXI64 bridges</text>
<text text-anchor="middle" x="2452.11" y="-559" font-family="Arial" font-size="10.00" fill="#111827">local AXI64 &#45;&gt; 32 adaptation</text>
<path fill="#ffedd5" stroke="#4b5563" stroke-width="1.1" d="M2537.11,-230C2537.11,-230 2363.11,-230 2363.11,-230 2357.11,-230 2351.11,-224 2351.11,-218 2351.11,-218 2351.11,-206 2351.11,-206 2351.11,-200 2357.11,-194 2363.11,-194 2363.11,-194 2537.11,-194 2537.11,-194 2543.11,-194 2549.11,-200 2549.11,-206 2549.11,-206 2549.11,-218 2549.11,-218 2549.11,-224 2543.11,-230 2537.11,-230"/>
<text text-anchor="middle" x="2450.11" y="-215" font-family="Arial" font-size="10.00" fill="#111827">Four direct HP &#45;&gt; memory AXI64 bridges</text>
<text text-anchor="middle" x="2450.11" y="-204" font-family="Arial" font-size="10.00" fill="#111827">local AXI64 &#45;&gt; 32 adaptation</text>
</g>
<!-- guards&#45;&gt;memory_cdc -->
<g id="edge18" class="edge">
<g id="edge19" class="edge">
<title>guards&#45;&gt;memory_cdc</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2170.6,-491.01C2229.82,-507.05 2316.31,-530.49 2377.57,-547.08"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2377.14,-549.5 2384.54,-548.97 2378.43,-544.77 2377.14,-549.5"/>
<text text-anchor="middle" x="2277.11" y="-533.6" font-family="Arial" font-size="8.00" fill="#374151">SDRAM/QPI/OPI/XPI AXI64</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2155.15,-454.96C2177.79,-447.25 2199.11,-440 2199.11,-440 2199.11,-440 2359.89,-293.36 2423.58,-235.28"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2425.55,-236.8 2429.07,-230.27 2422.25,-233.18 2425.55,-236.8"/>
<text text-anchor="middle" x="2275.11" y="-418.6" font-family="Arial" font-size="8.00" fill="#374151">SDRAM/QPI/OPI/XPI AXI64</text>
</g>
<!-- memory_cdc&#45;&gt;memory -->
<g id="edge19" class="edge">
<g id="edge20" class="edge">
<title>memory_cdc&#45;&gt;memory</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2551.41,-567C2584.11,-567 2620.7,-567 2654.03,-567"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2654.1,-569.45 2661.1,-567 2654.1,-564.55 2654.1,-569.45"/>
<text text-anchor="middle" x="2606.11" y="-569.6" font-family="Arial" font-size="8.00" fill="#374151">AXI32 frontends</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2549.41,-210.09C2582.11,-209.45 2618.7,-208.74 2652.03,-208.09"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2652.15,-210.53 2659.1,-207.95 2652.05,-205.64 2652.15,-210.53"/>
<text text-anchor="middle" x="2604.11" y="-211.6" font-family="Arial" font-size="8.00" fill="#374151">AXI32 frontends</text>
</g>
<!-- memory&#45;&gt;pads -->
<g id="edge24" class="edge">
<g id="edge25" class="edge">
<title>memory&#45;&gt;pads</title>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2784.13,-537.34C2841.25,-456.75 2998.86,-234.4 3056.03,-153.73"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2781.82,-536.37 2779.77,-543.5 2785.81,-539.2 2781.82,-536.37"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="3058.25,-154.84 3060.3,-147.72 3054.25,-152.01 3058.25,-154.84"/>
<text text-anchor="middle" x="2921.11" y="-387.6" font-family="Arial" font-size="8.00" fill="#374151">memory protocols</text>
<path fill="none" stroke="#4b5563" stroke-width="1.2" d="M2858.46,-180.58C2896.5,-170.64 2940.03,-159.28 2978.04,-149.35"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2857.66,-178.25 2851.51,-182.39 2858.9,-182.99 2857.66,-178.25"/>
<polygon fill="#4b5563" stroke="#4b5563" stroke-width="1.2" points="2978.92,-151.65 2985.07,-147.51 2977.68,-146.91 2978.92,-151.65"/>
<text text-anchor="middle" x="2919.11" y="-174.6" font-family="Arial" font-size="8.00" fill="#374151">memory protocols</text>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 31 KiB

+32 -19
View File
@@ -27,14 +27,21 @@ advertised for a device or PDK.
| Tier | Product role | Compute topology | Primary software | Defining boundary |
| --- | --- | --- | --- | --- |
| Tiny | Low-power MCU and edge-connectivity endpoint | One Hazard3 MCU core | Bare metal or RTOS | No MMU or external DRAM dependency |
| Mini | Low-cost heterogeneous Linux control SoC | RV32 Hazard3 management plus one RV64 VexiiRiscv application core | Embedded Linux or RT-Thread plus management firmware | Lightweight Linux and basic HMI, without a desktop-class accelerator requirement |
| Mini | Low-cost heterogeneous Linux control SoC | RV32 Hazard3 management plus one RV64 T-Head OpenC906 application core | Embedded Linux or RT-Thread plus management firmware | Lightweight Linux and basic HMI, without a desktop-class accelerator requirement |
| Std | Heterogeneous RV32 graphical Linux edge SoC | Hazard3 management core plus VexiiRiscv performance and efficiency cores | Graphical Linux plus RTOS firmware | Full AXI4 memory fabric, GPU, audio, and AI acceleration |
| Pro | Highest-performance coherent RV64 family tier | Hazard3 management core plus four coherent RV64 VexiiRiscv Linux cores | RV64 graphical Linux | Coherent SMP, high-bandwidth memory, GPU, NPU, and video codecs |
The VexiiRiscv targets rely on the upstream core's documented RV32/RV64,
single/dual-issue, cache, Sv32/Sv39, AXI4, and Linux capabilities. The exact
[VexiiRiscv](https://github.com/SpinalHDL/VexiiRiscv) revision and generated
configuration must be locked and verified before integration.
configuration must be locked and verified before integration. The former Mini
HP VexiiRiscv configuration (RV64IMAFDC + Zicbom, reset vector `0x38000000`,
hart ID 1) is now preserved as a frozen Std-series generator asset:
`scripts/vexiiriscv/GenerateRetroSocStd.scala` (module
`vexiiriscv_std_generated`), driven by `make std-vexii-generate`, with the
locked VexiiRiscv revision retained in the dependency lock. Mini no longer
consumes it; the Mini HP core is the locked, pre-generated T-Head
[OpenC906](https://github.com/XUANTIE-RV/openc906).
The names describe capability tiers, not die-size derivatives. In particular,
Tiny is not a Mini with features disabled, and Std is not a Mini that merely
@@ -170,7 +177,7 @@ feature reference when Wi-Fi is included.
### Status and Position
retroSoC Mini is an open-source asymmetric RISC-V SoC with a fixed Hazard3 LP
management core and a fixed 32-bit VexiiRiscv HP application core. C0-C3 are
management core and a fixed RV64 T-Head OpenC906 HP application core. C0-C3 are
available only in the separate MPW compatibility profile. RTL integration, a direct-Linux image
flow, and LP boot firmware are implemented; repeatable Linux boot,
performance, synthesis, timing, and hardware evidence are still qualification
@@ -180,8 +187,7 @@ Mini is the price, complexity, and Linux-capability anchor for the family. It
targets industrial control, protocol gateways, compact human-machine
interfaces, and retro multimedia systems that need Linux but do not need a
desktop-class graphics pipeline. Hazard3 remains the trusted management core,
and one RV32 VexiiRiscv application core runs Linux in the planned
configuration.
and one RV64 OpenC906 application core runs Linux.
The product target starts at 64 MiB of external SDRAM, with 128 MiB preferred.
A simple display controller or framebuffer is compatible with the Mini
@@ -213,8 +219,11 @@ capabilities:
window, and an 8 MiB PSRAM window. Address-window capacity does not guarantee
that every implementation includes the corresponding physical memory.
- AXI4 uses a 32-bit LP control plane and a 10x6 native AXI64 HP data plane
with seven-bit global IDs. Vexii I/D ports remain independent; DMA and I/O
masters cross into HP and current memory frontends are reached through
with seven-bit global IDs. The OpenC906 HP core presents a single 128-bit
AXI4 master, serialized through a 128-to-64 downsizer and demuxed into
data-plane master slot 0 and the MMIO window; the former separate
I-cache/D-cache ports are retired and master slot 1 is tied idle. DMA and
I/O masters cross into HP and current memory frontends are reached through
64-to-32 target adapters. Master 8 is the dedicated PCLK-to-HP AXI64/ID3
GA2D bridge for a direct single-job private-AXI64 2D engine; master 9 is
the HP-native NPU path, tied safely idle until the Phase 3 DMA lands.
@@ -232,7 +241,8 @@ capabilities:
PSRAM, flash, or SPI-SD physical transaction.
The experimental HP profile adds the fixed hart 1 core, a compatibility AXI
plane, HP ACLINT/PLIC, UART1, mailbox, reset release, and shared-JTAG selection.
plane, the C906 internal CLINT/PLIC, UART1, mailbox, reset release, and
shared-JTAG selection.
Its detailed executable contract is [LP/HP Architecture](lp-hp-architecture.md).
The generated address map, user-extension map,
@@ -243,8 +253,8 @@ for the implemented baseline.
### Experimental Linux Configuration
The Linux configuration keeps Hazard3 as the always-available trusted
management core and adds VexiiRiscv as the application processor. Hazard3 is
responsible for clock and memory initialization, image selection, VexiiRiscv
management core and adds OpenC906 as the application processor. Hazard3 is
responsible for clock and memory initialization, image selection, OpenC906
boot release, fault recovery, and final power-state control. Linux must not be
able to reconfigure the management-core lifecycle controls.
@@ -252,19 +262,22 @@ The frozen Mini RV64 configuration provides the following architectural target;
validation status is recorded separately in [HP RV64 validation](hp-rv64-validation.md).
The Std/Pro roadmap below remains independent of this implemented Mini profile.
- RV64IMAFDC with machine, supervisor, and user modes.
- RV64GC (RV64IMAFDC plus Zicsr and Zifencei) with machine, supervisor, and
user modes.
- Sv39 virtual memory, hardware page-table walking, and the privileged CSRs
required by the supported Linux kernel.
- LR/SC atomics, separate 16 KiB instruction and data caches, and uncached MMIO
regions.
- A PLIC-compatible external interrupt controller, CLINT-compatible timer and
software interrupts, and a deterministic reset vector.
- A documented DMA cache-maintenance contract unless the memory system supplies
- LR/SC atomics, separate 32 KiB instruction and data caches with 64-byte
lines, and uncached MMIO regions.
- The C906 internal PLIC (T-Head c900 layout) for external interrupts, the
C906 internal CLINT for timer and software interrupts, `time`-CSR mtime
delivery from the LP/global CLINT, and a deterministic reset vector.
- A documented DMA cache-maintenance contract (T-Head custom-0
`dcache.cva`/`dcache.iva` instructions) unless the memory system supplies
hardware coherency.
The implemented management firmware waits for external memory, validates and
places the OpenSBI firmware, device tree, kernel, and initial filesystem at
fixed addresses, and then releases the fixed VexiiRiscv reset vector. The
fixed addresses, and then releases the fixed HP reset vector. The
bundle uses CRC32 for accidental-corruption detection, not secure boot. A
future normal stop must first request Linux shutdown through the mailbox. After
Linux acknowledges and flushes persistent data, the management core must
@@ -279,9 +292,9 @@ implemented or cross-PDK guarantee:
| Area | Minimum target | Preferred target |
| --- | --- | --- |
| VexiiRiscv frequency | 150 MHz | PDK-qualified maximum above 150 MHz |
| HP core frequency | 150 MHz | PDK-qualified maximum above 150 MHz |
| Main memory | 64 MiB SDRAM | 128 MiB SDRAM |
| L1 caches | 16 KiB I-cache and 16 KiB D-cache | Same, with measured refill and DMA behavior |
| L1 caches | 32 KiB I-cache and 32 KiB D-cache | Same, with measured refill and DMA behavior |
| Memory transport | Native cache-line burst | Native burst with two to four outstanding transactions per master |
| Boot storage | SPI NAND or qualified SDIO path | SDIO/eMMC plus recovery image |
| Linux platform devices | UART, timer, interrupt controller, storage | Ethernet or USB selected by the product profile |
+7 -2
View File
@@ -8,6 +8,10 @@ The canonical RTL/configuration inputs remain authoritative.
The current working source includes the Mini RV64/Sv39 migration, V2 workload
bundle checks, and minimal Linux `/init` handoff. RT-Thread's M-mode BSP and
acceptance evidence are documented in [HP RV64 validation](../docs/hp-rv64-validation.md).
The HP core is being switched from VexiiRiscv to the locked T-Head OpenC906
(default RV64GC configuration, core-internal c900 CLINT/PLIC, mhartid 1 via a
reviewed override); the Mini publication now describes that integration, and the
Overview drops the former HP ACLINT/HP PLIC SoC-peripheral labels (43 labels).
These edits do not advance `mini.json.source_revision` or relabel an existing
PDF. Review and commit the implementation snapshot before producing a matching
new PDF; the source-drift check remains mandatory.
@@ -246,9 +250,10 @@ initial-state/dependency summary, interface selection/subset matrices, multimedi
format interoperability and an image-maintenance chapter. Its publication-only
records live under `system-reference.json.product_details`; the
`implementation_reference.py` collector validates source/reset bindings and
extracts explicit LP/HP parameters, PMA envelopes and build flags. The LP firmware
extracts explicit LP instance parameters, the fixed HP OpenC906 integration
constants and build flags. The LP firmware
ISA/CSR choices are kept separate from hardware parameters. Unreviewed upstream
defaults and cache capacity are not inferred from the HP generator's sets/ways.
defaults and cache capacity are not inferred from the vendored HP core configuration.
The Multimedia overview is outside the actual I2S IP page markers; its label
ends the preceding IP header scope. All actual IP sections retain independent
+1 -3
View File
@@ -475,8 +475,6 @@ def check_document_sources(config: dict, data: dict) -> None:
"opipsram": "OPI PSRAM",
"dma": "Central DMA",
"clint": "LP CLINT",
"hp_aclint": "HP ACLINT",
"hp_plic": "HP PLIC",
"hp_mailbox": "LP/HP Mailbox",
"ps2": "PS/2",
"resource_ctrl": "Resource Controller",
@@ -494,7 +492,7 @@ def check_document_sources(config: dict, data: dict) -> None:
]
expected = {aliases.get(name, name.upper()) for name in names} | {
"Hazard3",
"VexiiRiscv",
"OpenC906",
"JTAG",
"RCU",
}
+114 -368
View File
@@ -4441,7 +4441,7 @@
"zigzag-dir": "horizontal"
}
],
"note": "UART1 is the HP console instance with dedicated TX/RX pads and an HP PLIC route. DMA pacing and RTS/CTS are not connected for this instance. FIFO geometry and serial formatting are shared with UART0."
"note": "UART1 is the HP console instance with dedicated TX/RX pads and an HP external interrupt route (PLIC ID 17). DMA pacing and RTS/CTS are not connected for this instance. FIFO geometry and serial formatting are shared with UART0."
},
"pwm": {
"nodes": [
@@ -7273,72 +7273,27 @@
"hp-aclint": {
"nodes": [
{
"id": "apb",
"title": "APB4 control\n32-bit register access",
"x": 0.0,
"y": 7.0,
"w": 4.0,
"h": 1.8,
"ports": [
{
"id": "p0",
"direction": "out",
"width": 32,
"side": "south"
}
],
"sources": [
"rtl/ip/peripheral/apb4_clint.sv"
]
},
{
"id": "reg",
"title": "Register bank\nconfiguration / status",
"id": "tick",
"title": "LP CLINT timebase\n64-bit MTIME",
"x": 0.0,
"y": 3.5,
"w": 4.0,
"h": 1.8,
"ports": [
{
"id": "p0",
"direction": "in",
"width": 32,
"side": "north"
},
{
"id": "p1",
"direction": "out",
"width": 64,
"side": "east"
},
{
"id": "p2",
"direction": "in",
"width": 64,
"side": "east"
},
{
"id": "p5",
"direction": "out",
"width": null,
"side": "south",
"bundle": true
}
],
"sources": [
"rtl/ip/peripheral/apb4_clint.sv",
"rtl/ip/peripheral/clint_reg.sv"
],
"instance_source": {
"file": "rtl/ip/peripheral/apb4_clint.sv",
"name": "u_clint_reg",
"module": "clint_reg",
"declaration_file": "rtl/ip/peripheral/clint_reg.sv"
}
"rtl/mini/top/apb4_periph.sv"
]
},
{
"id": "core",
"title": "Time counter / comparator\nsoftware interrupt state",
"title": "OpenC906 internal CLINT\nc900 layout, core-BIU decode",
"x": 6.3,
"y": 3.5,
"w": 4.0,
@@ -7350,18 +7305,6 @@
"width": 64,
"side": "west"
},
{
"id": "p2",
"direction": "out",
"width": 64,
"side": "west"
},
{
"id": "p3",
"direction": "in",
"width": 1,
"side": "north"
},
{
"id": "p4",
"direction": "out",
@@ -7371,38 +7314,20 @@
}
],
"sources": [
"rtl/ip/peripheral/apb4_clint.sv",
"rtl/ip/peripheral/clint_core.sv"
"rtl/mini/top/hp_subsystem.sv",
"rtl/mini/top/hp_core_wrapper.sv",
"rtl/mini/ip_overrides/aq_sysio_kid.v"
],
"instance_source": {
"file": "rtl/ip/peripheral/apb4_clint.sv",
"name": "u_clint_core",
"module": "clint_core",
"declaration_file": "rtl/ip/peripheral/clint_core.sv"
"file": "rtl/mini/top/hp_subsystem.sv",
"name": "u_hp_core_wrapper",
"module": "hp_core_wrapper",
"declaration_file": "rtl/mini/top/hp_core_wrapper.sv"
}
},
{
"id": "tick",
"title": "Shared timebase tick",
"x": 6.3,
"y": 7.0,
"w": 4.0,
"h": 1.8,
"ports": [
{
"id": "p3",
"direction": "out",
"width": 1,
"side": "south"
}
],
"sources": [
"rtl/ip/peripheral/apb4_clint.sv"
]
},
{
"id": "irq",
"title": "HP timer/software routes",
"id": "hart",
"title": "HP hart 1\nM/S timer + software IRQ",
"x": 12.6,
"y": 3.5,
"w": 4.0,
@@ -7414,211 +7339,73 @@
"width": null,
"side": "west",
"bundle": true
},
{
"id": "p5",
"direction": "in",
"width": null,
"side": "south",
"bundle": true
}
],
"sources": [
"rtl/ip/peripheral/apb4_clint.sv"
"rtl/mini/ip_overrides/aq_sysio_kid.v"
]
}
],
"edges": [
{
"from": "apb.p0",
"to": "reg.p0",
"kind": "data",
"label": "APB4 / 32",
"style": "direct",
"bindings": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".apb4(apb4)"
}
],
"instance_ports": [
{
"node": "reg",
"port": "apb4",
"expression": "apb4"
}
],
"zigzag-dir": "horizontal"
},
{
"from": "reg.p1",
"from": "tick.p1",
"to": "core.p1",
"kind": "data",
"label": "LOAD / 64",
"label": "MTIME / 64",
"style": "direct",
"bindings": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".mtime_load_value_o(s_mtime_load_value)"
"file": "rtl/mini/top/apb4_periph.sv",
"text": "assign hp_time_o = u_clint_if.mtime_o;"
},
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".mtime_load_value_i(s_mtime_load_value)"
"file": "rtl/mini/top/hp_subsystem.sv",
"text": ".time_i(time_i)"
}
],
"signals": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"scope": "apb4_clint",
"symbol": "s_mtime_load_value",
"bits": 64
},
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"scope": "apb4_clint",
"symbol": "s_mtime_load_value",
"bits": 64
}
],
"instance_ports": [
{
"node": "reg",
"port": "mtime_load_value_o",
"expression": "s_mtime_load_value"
},
{
"node": "core",
"port": "mtime_load_value_i",
"expression": "s_mtime_load_value"
}
]
},
{
"from": "core.p2",
"to": "reg.p2",
"kind": "data",
"label": "TIME / 64",
"style": "direct",
"bindings": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".mtime_o(s_mtime)"
},
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".mtime_i(s_mtime)"
}
],
"signals": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"scope": "apb4_clint",
"symbol": "s_mtime",
"bits": 64
},
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"scope": "apb4_clint",
"symbol": "s_mtime",
"file": "rtl/mini/top/retrosoc.sv",
"scope": "retrosoc",
"symbol": "s_hp_time",
"bits": 64
}
],
"instance_ports": [
{
"node": "core",
"port": "mtime_o",
"expression": "s_mtime"
},
{
"node": "reg",
"port": "mtime_i",
"expression": "s_mtime"
}
]
},
{
"from": "tick.p3",
"to": "core.p3",
"kind": "control",
"label": "TICK",
"style": "direct",
"bindings": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".tick_i(timebase_tick_i)"
}
],
"signals": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"scope": "apb4_clint",
"symbol": "timebase_tick_i",
"bits": 1
}
],
"instance_ports": [
{
"node": "core",
"port": "tick_i",
"expression": "timebase_tick_i"
"port": "time_i",
"expression": "time_i"
}
],
"zigzag-dir": "horizontal"
},
{
"from": "core.p4",
"to": "irq.p4",
"to": "hart.p4",
"kind": "control",
"label": "Timer IRQ",
"label": "M/S IRQ",
"style": "direct",
"bindings": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".timer_irq_o(s_timer_irq)"
"file": "rtl/mini/top/hp_core_wrapper.sv",
"text": ".pad_cpu_sys_cnt(time_i)"
},
{
"file": "rtl/mini/ip_overrides/aq_sysio_kid.v",
"text": "input clint_core_mt_int;"
}
],
"instance_ports": [
{
"node": "core",
"port": "timer_irq_o",
"expression": "s_timer_irq"
}
]
},
{
"from": "reg.p5",
"to": "irq.p5",
"kind": "control",
"label": "Software IRQ",
"style": "dodge",
"bindings": [
{
"file": "rtl/ip/peripheral/apb4_clint.sv",
"text": ".msip_o(s_msip)"
}
],
"instance_ports": [
{
"node": "reg",
"port": "msip_o",
"expression": "s_msip"
}
],
"zigzag-dir": "horizontal",
"dodge-y": 1.7,
"dodge-margins": [
0,
0
]
"zigzag-dir": "horizontal"
}
],
"note": "The LP CLINT and HP ACLINT share this RTL family but own separate register windows and interrupt routing. HP logical contexts are not additional physical harts."
"note": "The OpenC906 CLINT is decoded inside the core BIU within the 0x08000000 system window and never appears on the SoC fabric. There is no memory-mapped mtime: the SoC drives the 64-bit time value into the core and software reads the time CSR."
},
"hp-plic": {
"nodes": [
{
"id": "sources",
"title": "Peripheral IRQ sources\n32 source slots",
"title": "SoC peripheral IRQs\n16 external sources",
"x": 0.0,
"y": 3.5,
"w": 4.0,
@@ -7627,17 +7414,24 @@
{
"id": "p0",
"direction": "out",
"width": 32,
"width": 16,
"side": "east"
}
],
"sources": [
"rtl/mini/top/apb4_periph.sv"
]
"rtl/mini/top/apb4_periph.sv",
"rtl/mini/top/retrosoc.sv"
],
"instance_source": {
"file": "rtl/mini/top/retrosoc.sv",
"name": "u_apb4_periph",
"module": "apb4_periph",
"declaration_file": "rtl/mini/top/apb4_periph.sv"
}
},
{
"id": "plic",
"title": "Pending / priority / claim\n2 context arbiters",
"id": "core",
"title": "OpenC906 internal PLIC\nc900 layout, ID = source + 16",
"x": 6.3,
"y": 3.5,
"w": 4.0,
@@ -7646,36 +7440,31 @@
{
"id": "p0",
"direction": "in",
"width": 32,
"width": 16,
"side": "west"
},
{
"id": "p1",
"direction": "out",
"width": 2,
"side": "east"
},
{
"id": "p2",
"direction": "in",
"width": 32,
"side": "north"
"width": null,
"side": "east",
"bundle": true
}
],
"sources": [
"rtl/mini/top/apb4_periph.sv",
"rtl/ip/peripheral/apb4_plic.sv"
"rtl/mini/top/hp_subsystem.sv",
"rtl/mini/top/hp_core_wrapper.sv"
],
"instance_source": {
"file": "rtl/mini/top/apb4_periph.sv",
"name": "u_apb4_hp_plic",
"module": "apb4_plic",
"declaration_file": "rtl/ip/peripheral/apb4_plic.sv"
"file": "rtl/mini/top/hp_subsystem.sv",
"name": "u_hp_core_wrapper",
"module": "hp_core_wrapper",
"declaration_file": "rtl/mini/top/hp_core_wrapper.sv"
}
},
{
"id": "hp",
"title": "HP machine / supervisor\nexternal interrupt inputs",
"id": "hart",
"title": "HP hart 1\nM/S external interrupts",
"x": 12.6,
"y": 3.5,
"w": 4.0,
@@ -7684,114 +7473,71 @@
{
"id": "p1",
"direction": "in",
"width": 2,
"side": "west"
"width": null,
"side": "west",
"bundle": true
}
],
"sources": [
"rtl/mini/top/apb4_periph.sv"
]
},
{
"id": "apb",
"title": "APB4 configuration\npriority / enable / threshold",
"x": 6.3,
"y": 7.0,
"w": 4.0,
"h": 1.8,
"ports": [
{
"id": "p2",
"direction": "out",
"width": 32,
"side": "south"
}
],
"sources": [
"rtl/mini/top/apb4_periph.sv"
"rtl/mini/top/hp_core_wrapper.sv"
]
}
],
"edges": [
{
"from": "sources.p0",
"to": "plic.p0",
"kind": "control",
"label": "IRQ / 32",
"style": "direct",
"bindings": [
{
"file": "rtl/mini/top/apb4_periph.sv",
"text": ".source_i(s_hp_plic_source)"
}
],
"signals": [
{
"file": "rtl/mini/top/apb4_periph.sv",
"scope": "apb4_periph",
"symbol": "s_hp_plic_source",
"bits": 32
}
],
"instance_ports": [
{
"node": "plic",
"port": "source_i",
"expression": "s_hp_plic_source"
}
]
},
{
"from": "plic.p1",
"to": "hp.p1",
"kind": "control",
"label": "CTX / 2",
"style": "direct",
"bindings": [
{
"file": "rtl/mini/top/apb4_periph.sv",
"text": ".context_irq_o(s_hp_plic_context_irq)"
}
],
"signals": [
{
"file": "rtl/mini/top/apb4_periph.sv",
"scope": "apb4_periph",
"symbol": "s_hp_plic_context_irq",
"bits": 2
}
],
"instance_ports": [
{
"node": "plic",
"port": "context_irq_o",
"expression": "s_hp_plic_context_irq"
}
]
},
{
"from": "apb.p2",
"to": "plic.p2",
"to": "core.p0",
"kind": "data",
"label": "APB4 / 32",
"label": "SOURCES / 16",
"style": "direct",
"bindings": [
{
"file": "rtl/mini/top/apb4_periph.sv",
"text": ".apb4(u_hp_plic_apb4_if)"
"file": "rtl/mini/top/retrosoc.sv",
"text": ".hp_plic_src_o(s_hp_plic_src)"
},
{
"file": "rtl/mini/top/hp_subsystem.sv",
"text": ".plic_src_i(plic_src_i)"
}
],
"signals": [
{
"file": "rtl/mini/top/retrosoc.sv",
"scope": "retrosoc",
"symbol": "s_hp_plic_src",
"bits": 16
}
],
"instance_ports": [
{
"node": "plic",
"port": "apb4",
"expression": "u_hp_plic_apb4_if"
"node": "sources",
"port": "hp_plic_src_o",
"expression": "s_hp_plic_src"
},
{
"node": "core",
"port": "plic_src_i",
"expression": "plic_src_i"
}
],
"zigzag-dir": "horizontal"
},
{
"from": "core.p1",
"to": "hart.p1",
"kind": "control",
"label": "MEIP / SEIP",
"style": "direct",
"bindings": [
{
"file": "rtl/mini/top/hp_core_wrapper.sv",
"text": ".pad_plic_int_vld({224'd0, plic_src_i})"
}
],
"zigzag-dir": "horizontal"
}
],
"note": "32 source slots feed two logical HP interrupt contexts. Pending/claimed state, priority and thresholds are inside apb4_plic. This is the HP external-interrupt controller, not the LP IRQ route."
"note": "The OpenC906 PLIC is decoded inside the core BIU at the base of the 0x08000000 system window and never appears on the SoC fabric. SoC external source n is delivered to the core as PLIC ID n+16; IDs 0-15 are reserved or internal."
},
"hp-mailbox": {
"nodes": [
@@ -8165,7 +7911,7 @@
"zigzag-dir": "horizontal"
}
],
"note": "Ten resources retain independent owner/lock/quiesce/reset state. Resource 8 owns GA2D; resource 9 owns NPU and routes LP vector 33 / HP PLIC source 12. IRQ steering and cache handoff are control relationships, not a payload DMA path."
"note": "Ten resources retain independent owner/lock/quiesce/reset state. Resource 8 owns GA2D; resource 9 owns NPU and routes LP vector 33 / HP external source 12 (PLIC ID 28). IRQ steering and cache handoff are control relationships, not a payload DMA path."
},
"monitor": {
"nodes": [
@@ -10714,7 +10460,7 @@
},
{
"id": "hp",
"title": "VexiiRiscv HP\nI-cache / D-cache",
"title": "OpenC906 HP\nAXI4 128-bit master, downsized to 64",
"x": 6.3,
"y": 7.0,
"w": 4.0,
@@ -11001,28 +10747,28 @@
"from": "hp.p1",
"to": "fabric.p1",
"kind": "data",
"label": "I-cache / 64",
"label": "Memory / 64",
"style": "direct",
"bindings": [
{
"file": "rtl/mini/top/retrosoc.sv",
"text": ".icache_axi4(u_hp_icache_axi4_if)"
"text": ".mem_axi4(u_hp_mem_axi4_if)"
},
{
"file": "rtl/mini/top/retrosoc.sv",
"text": ".hp_icache_axi4(u_hp_icache_axi4_if)"
"text": ".hp_mem_axi4(u_hp_mem_axi4_if)"
}
],
"instance_ports": [
{
"node": "hp",
"port": "icache_axi4",
"expression": "u_hp_icache_axi4_if"
"port": "mem_axi4",
"expression": "u_hp_mem_axi4_if"
},
{
"node": "fabric",
"port": "hp_icache_axi4",
"expression": "u_hp_icache_axi4_if"
"port": "hp_mem_axi4",
"expression": "u_hp_mem_axi4_if"
}
],
"zigzag-dir": "horizontal"
+4 -4
View File
@@ -114,9 +114,9 @@
#diagram-text[Relative byte boundaries: 0 · #c.granule · #c.covered_bytes]
#v(4pt)
#bc.region(width:100%,fill:white,stroke:0.6pt+ink,radius:0pt)[
#bc.cell(width:77mm,height:12mm,fill:gray,stroke:0.6pt+ink)[#align(center+horizon)[CBO block 0: bytes 0–63]]
#bc.cell(width:77mm,height:12mm,fill:gray,stroke:0.6pt+ink)[#align(center+horizon)[Cache line 0: bytes 0–63]]
#h(2mm)
#bc.cell(width:77mm,height:12mm,fill:gray,stroke:0.6pt+ink)[#align(center+horizon)[CBO block 1: bytes 64–127]]
#bc.cell(width:77mm,height:12mm,fill:gray,stroke:0.6pt+ink)[#align(center+horizon)[Cache line 1: bytes 64–127]]
#linebreak()
#v(4pt)
#bc.cell(width:19mm,height:15mm,fill:gray,stroke:0.6pt+ink)[16 B \ before]
@@ -125,8 +125,8 @@
#bc.cell(width:19mm,height:15mm,fill:pale-gold,stroke:0.6pt+ink)[16 B \ payload]
#bc.cell(width:57mm,height:15mm,fill:gray,stroke:0.6pt+ink)[48 B after \ bytes 80–127]
]
#diagram-note[The software-declared 64-byte maintenance granule covers a 64-byte payload at offset 16
using two blocks. Keep boundary bytes under compatible ownership. Relative offsets are illustrative;
#diagram-note[A 64-byte payload at offset 16 touches two 64-byte HP D-cache lines, so
maintenance spans both. Keep boundary bytes under compatible ownership. Relative offsets are illustrative;
this is not a verified HP cache tag/set/way layout or an allocated buffer address.]
#diagram-end("blockcell","cache-boundaries")
]
+6 -6
View File
@@ -35,9 +35,9 @@
"One management hart slot in the reference integration."
],
"aclint": [
"Two addressable hart slots; **HP consumes slot 1**.",
"Machine software and timer interrupts for the HP subsystem.",
"Separate address window from management CLINT."
"**Core-internal CLINT** of the OpenC906 HP hart (c900 layout).",
"Machine/supervisor timer and software interrupts; **no memory-mapped mtime**.",
"Decoded inside the core BIU; **no SoC register window**."
],
"dma": [
"**Eight channel contexts** share a 32-bit AXI master.",
@@ -181,9 +181,9 @@
"Clock division and memory-pad mode through SYSCTRL."
],
"plic": [
"32 source IDs, with **source 0 reserved**.",
"Two delivery contexts: machine and supervisor.",
"Priorities, masks, threshold and claim/complete semantics."
"**Core-internal PLIC** of the OpenC906 HP hart (c900 layout).",
"**16 SoC external sources**, delivered as PLIC ID = source + 16.",
"Machine/supervisor contexts; priorities, thresholds and claim/complete."
],
"mpw-timer": [
"**MPW-selectable** timer and divider.",
+1 -1
View File
@@ -106,7 +106,7 @@
panel(0,0.4,-1.7,w,4.0,(2,1),weights:(2,1))
panel(1,0.4 + w + 0.3,-1.7,w,4.0,(2,2,1))
panel(2,0.4 + 2*(w + 0.3),-1.7,w,4.0,(2,2,1))
panel(3,0.4,-6.0,w,4.0,(2,2))
panel(3,0.4,-6.0,w,4.0,(2,))
panel(4,0.4 + w + 0.3,-6.0,w,4.0,(1,1,1))
panel(5,0.4 + 2*(w + 0.3),-6.0,w,4.0,(2,2,1))
panel(6,0.4,-10.3,2*w + 0.3,5.5,(3,3,3,2))
+2 -3
View File
@@ -309,8 +309,7 @@
{
"id": "hp-platform",
"regions": [
"HP_ACLINT",
"HP_PLIC",
"HP_C906_SYS",
"APB4_HP_MAILBOX"
],
"irqs": [
@@ -320,7 +319,7 @@
"docs/ip/hp-platform.md",
"docs/lp-hp-architecture.md"
],
"summary": "HP local timer/software interrupts, two-context PLIC and bidirectional mailbox."
"summary": "HP core-internal CLINT/PLIC window (decoded inside the OpenC906 core) and bidirectional mailbox."
},
{
"id": "resource",
+27 -27
View File
@@ -1283,47 +1283,47 @@
"aclint": {
"title": "HP ACLINT",
"blocks": [
"APB decoder",
"Two hart slots",
"64-bit timer",
"Compare registers",
"Hart 1 IRQ outputs"
"Core-internal CLINT",
"c900 layout",
"64-bit time input",
"M/S timer + software IRQ"
],
"function_sections": [],
"software_sections": [],
"notes": [
"The HP ACLINT is mapped at 0x02000000. The shared implementation provides two addressable hart slots, and hart slot 1 drives the HP software and timer interrupt inputs. MSIP1 is at offset 0x0004, MTIMECMP1 at 0x4008/0x400C, and the common MTIME at 0xBFF8/0xBFFC. This is separate from the management CLINT at 0x02010000.",
"Each 64-bit timer value is accessed as two 32-bit words. Use the retry and safe compare-update sequences below. The HP boot configuration uses a 1 MHz reference timebase; changing a CPU PLL setting does not redefine this reference."
"There is **no memory-mapped mtime**: the SoC drives the shared 64-bit time value from the management CLINT into the core, and HP software reads the time CSR. The compare value is programmed through the core-internal window; the supplied OpenSBI platform writes MTIMECMP at window offsets 0x4000/0x4004 with the 1 MHz reference timebase. Changing a CPU PLL setting does not redefine this reference.",
"Machine and supervisor timer/software interrupts follow the c900 per-hart order (M-SW, M-timer, S-SW, S-timer), as declared by the supplied device tree. The management CLINT at 0x10020000 is a separate LP-owned peripheral with its own chapter."
],
"software_steps": [
"HP consumes **hart slot 1** of the two-slot window. Do not use a management-CLINT base-address helper.",
"Read **high/low/high and retry** if the high words differ when a coherent RV32 time value is required.",
"Update compare using the **safe high/low sequence**. OpenSBI may provide this service for HP software."
"Use the OpenSBI platform services for HP timer and software interrupts; the supplied platform binds the ACLINT MSWI driver at the internal base with **first hart ID 1 and hart count 1**.",
"Program timer events through the platform's custom timer device, which reads the **time CSR** and writes MTIMECMP with the safe high/low sequence; do not assume a memory-mapped MTIME register.",
"Do not use a management-CLINT base-address helper for HP-local interrupts."
],
"flow": [
"Reference ticks / MSIP",
"Hart 1 compare / pending",
"HP MTIP / MSIP"
"SoC 64-bit time value",
"Core-internal compare / pending",
"HP M/S timer + software IRQ"
]
},
"plic": {
"title": "HP PLIC",
"blocks": [
"APB decoder",
"Source priorities",
"Pending/claimed bits",
"Context enables",
"Priority arbitration",
"Claim/complete"
],
"function_sections": [
"PLIC"
"Core-internal PLIC",
"c900 layout",
"16 SoC sources",
"PLIC ID = source + 16",
"M/S external contexts"
],
"function_sections": [],
"software_sections": [],
"notes": [],
"notes": [
"Sixteen SoC external interrupt sources drive the core's PLIC vector. **SoC source n is delivered to software as PLIC ID n+16**; IDs 0-15 are reserved or internal. Source 1 is UART1, source 2 is the HP-side mailbox doorbell, source 3 is EXT-H, and sources 4 through 12 are the resource-owned DMA, USB2, SDIO0, SDIO1, SPI-SD, JPEG, APU, GA2D and NPU lines. Sources 13 through 15 are reserved and tied low.",
"The c900 PLIC provides machine and supervisor external-interrupt contexts for the HP hart, with per-source priorities, enables, thresholds and claim/complete arbitration. Register-bit detail follows the T-Head C906 manuals; the supplied device tree declares the thead,c900-plic node with riscv,ndev = 31.",
"Resource-owned sources are suppressed unless HP is the exclusive owner; see the Resource Controller chapter for the ownership and routing contract."
],
"software_steps": [
"Program source priority, the machine/supervisor **context enable and threshold**.",
"Read CLAIM_COMPLETE **once per claim**. Zero means no eligible source; a nonzero ID claims that source.",
"Program source priority and the machine/supervisor **context enable and threshold** in the core-internal PLIC window, using **PLIC ID = SoC source + 16**.",
"Read the claim register **once per claim**. Zero means no eligible source; a nonzero ID claims that source.",
"Service the device cause, then write the claimed ID to the **same context** to complete it. A still-active level can pend again."
],
"flow": [
@@ -1784,7 +1784,7 @@
"The deployed implementation advertises CAPABILITY=0x0000007F and OP_CAPABILITY=0x000001FE. It includes the complete eight-operator execution path; reusable module defaults and older phase comments do not describe the deployed configuration.",
"The HP-native AXI64 master is index 9 and resource 9. It uses source ID zero, one outstanding read and one outstanding write, and an integrated maximum of eight beats per burst. It does not allocate a central-DMA channel.",
"The PCLK register shell exchanges launch, result and snapshot mailboxes with HP computation. Resource quiesce waits for cancellation/drain; a coordinated clock pause retains the active job.",
"LP vector 33 (external ordinal 31) and HP PLIC source 12 are selected through resource ownership. No dedicated NPU pad, GPIO alternate function or camera/audio stream port is added.",
"LP vector 33 (external ordinal 31) and HP external source 12 (PLIC ID 28) are selected through resource ownership. No dedicated NPU pad, GPIO alternate function or camera/audio stream port is added.",
"All APB writes require full word strobes. Unknown offsets, reserved-bit violations, busy configuration changes and disallowed START commands complete with PSLVERR without the prohibited side effect."
],
"software_steps": [
@@ -2295,7 +2295,7 @@
"Read capability/format words, select an implemented operation, and obtain resource ownership. Confirm DATA_READY and that **no recovery is pending**.",
"Allocate **disjoint bounded surfaces**, except the explicitly supported equal background/destination BLEND case. Validate pitch, format, dimensions, alignment and addresses with rs_ga2d_job_validate.",
"Clean CPU-produced inputs as required, prepare destination ownership, and issue the required memory fence before configuring the job. Keep surfaces and configuration **stable while active**.",
"Call rs_ga2d_configure, then rs_ga2d_start. Use rs_ga2d_wait or the **owner-routed IRQ**; LP vector 32, external ordinal 30 and HP PLIC source 11 name different routing layers.",
"Call rs_ga2d_configure, then rs_ga2d_start. Use rs_ga2d_wait or the **owner-routed IRQ**; LP vector 32, external ordinal 30 and HP external source 11 (PLIC ID 27) name different routing layers.",
"Capture terminal status, first-error details and counter snapshots **before acknowledging** W1C IRQ causes. Invalidate a DMA-written destination before CPU consumption where its mapping is cached.",
"A polling timeout **does not prove hardware idle**. Use rs_ga2d_abort_wait to stop/drain accepted traffic, inspect recovery_required, and perform the documented resource/bridge rearm when required. A soft reset must not be used to discard in-flight bus obligations."
],
+26 -8
View File
@@ -1,6 +1,7 @@
#import "../style.typ": *
#import "../ip-reference.typ": ip-reference
#import "../ip-reference.typ": inline, subhead
#import "../diagram-packages.typ": circuit-diagram
#pagebreak(weak:true)
@@ -10,15 +11,32 @@
===== HP Local Interrupt Controller (ACLINT) <hp-aclint>
#let r=data.regions.find(r=>r.symbol=="HP_ACLINT")
Base address: #code(r.base_hex). Window size: #r.size_label. HP software and timer interrupts; *hart slot 1 is connected*.
#let chapter=data.chapters.at("aclint")
#let r=data.regions.find(r=>r.symbol=="HP_C906_SYS")
The HP local timer and software interrupt function is *internal to the OpenC906 core*: the core
BIU decodes the T-Head c900 CLINT layout inside the reserved system window at #code(r.base_hex)
(size #r.size_label), which never appears as a SoC fabric target. This chapter therefore has
*no SoC register table*; register-bit detail follows the T-Head C906 manuals, which remain
outside this publication's scope together with the CPU ISA/CSR manuals.
#ip-reference("hp-aclint","aclint",5,legacy:[
#subhead("hp-aclint","Features and Block Diagram",5)
#list(..chapter.at("features",default:()).map(inline))
#block(breakable:false)[
#figure(circuit-diagram("hp-aclint"),kind:image,supplement:[Figure],caption:[#chapter.title integration boundary.])
#label("circuit-hp-aclint")
]
The HP ACLINT supplies local software and timer interrupts to VexiiRiscv. The PLIC
handles external interrupt sources, including the separate mailbox doorbell. These
controllers have *distinct address windows and interrupt semantics*.
])
#subhead("hp-aclint","Functional Description",5)
#for paragraph in chapter.notes { par(inline(paragraph)) }
#subhead("hp-aclint","Software",5)
#enum(..chapter.software_steps.map(inline))
#block(breakable:false)[
#set text(size:9pt)
#source("rtl/mini/top/hp_core_wrapper.sv",title:"Internal window and time/counter wiring") ·
#source("app/ports/linux/opensbi/retrosoc_hp/platform.c",title:"OpenSBI MSWI and timer device") ·
#source("app/ports/linux/linux/retrosoc_hp.dts",title:"thead,c900-clint declaration")
]
#context metadata((kind:"ip-end",id:"hp-aclint",page:here().page()))
+1 -1
View File
@@ -9,7 +9,7 @@
===== LP/HP Mailbox <hp-mailbox>
#let r=data.regions.find(r=>r.symbol=="APB4_HP_MAILBOX")
Base address: #code(r.base_hex). Window size: #r.size_label. LP IRQ25 and HP PLIC source 2.
Base address: #code(r.base_hex). Window size: #r.size_label. LP IRQ25 and HP external source 2 (PLIC ID 18).
#ip-reference("hp-mailbox","mailbox",5,legacy:[
+26 -5
View File
@@ -1,6 +1,7 @@
#import "../style.typ": *
#import "../ip-reference.typ": ip-reference
#import "../ip-reference.typ": inline, subhead
#import "../diagram-packages.typ": circuit-diagram
#pagebreak(weak:true)
@@ -8,12 +9,32 @@
===== HP Platform-Level Interrupt Controller (PLIC) <hp-plic>
#let r=data.regions.find(r=>r.symbol=="HP_PLIC")
Base address: #code(r.base_hex). Window size: #r.size_label. HP machine and supervisor external interrupts.
#let chapter=data.chapters.at("plic")
#let r=data.regions.find(r=>r.symbol=="HP_C906_SYS")
The HP external interrupt controller is *internal to the OpenC906 core*: the core BIU decodes
the T-Head c900 PLIC layout at the base of the reserved system window at #code(r.base_hex)
(size #r.size_label), which never appears as a SoC fabric target. This chapter therefore has
*no SoC register table*; register-bit detail follows the T-Head C906 manuals, which remain
outside this publication's scope together with the CPU ISA/CSR manuals.
#ip-reference("hp-plic","plic",5,legacy:[
#subhead("hp-plic","Features and Block Diagram",5)
#list(..chapter.at("features",default:()).map(inline))
#block(breakable:false)[
#figure(circuit-diagram("hp-plic"),kind:image,supplement:[Figure],caption:[#chapter.title integration boundary.])
#label("circuit-hp-plic")
]
])
#subhead("hp-plic","Functional Description",5)
#for paragraph in chapter.notes { par(inline(paragraph)) }
#subhead("hp-plic","Software",5)
#enum(..chapter.software_steps.map(inline))
#block(breakable:false)[
#set text(size:9pt)
#source("rtl/mini/top/hp_core_wrapper.sv",title:"Source wiring into the core") ·
#source("rtl/mini/top/apb4_periph.sv",title:"SoC external source assignments") ·
#source("app/ports/linux/linux/retrosoc_hp.dts",title:"thead,c900-plic declaration")
]
#context metadata((kind:"ip-end",id:"hp-plic",page:here().page()))
+1 -1
View File
@@ -13,7 +13,7 @@
#ip-reference("resource","resource",4,legacy:[
*Ten resources* are managed: central DMA, USB2, SDIO0, SDIO1, SPI-SD, EXT-H, JPEG,
APU, GA2D and NPU. Resource ABI 1.2 reports ten slots. Resource 9 owns the native-HP
NPU, including LP vector 33 / HP PLIC 12 steering. Resource 8 routes the GA2D
NPU, including LP vector 33 / HP external source 12 (PLIC ID 28) steering. Resource 8 routes the GA2D
its IRQ according to its current owner and controls its private AXI64 lifecycle.
GA2D supports FILL, COPY, bit-exact CONVERT, opaque alpha BLEND, A8 fixed-color
foreground masks, and exact equal background/destination in-place composition.
+1 -1
View File
@@ -12,7 +12,7 @@
#ip-reference("uart1","uart",5,shared:"uart0",legacy:[
UART1 uses the *same 64-byte FIFO UART v3 ABI*, not a separate non-FIFO implementation. Its
dedicated TX/RX pads serve the HP console. HP PLIC source 1 is distinct from the LP vector
dedicated TX/RX pads serve the HP console. HP external source 1 (PLIC ID 17) is distinct from the LP vector
number above. The initial Linux console uses OpenSBI/hvc0; a *native Linux UART driver remains
a separate delivery item*.
])
+1 -3
View File
@@ -3,7 +3,7 @@
"title": "Processors and Debug",
"items": [
"Hazard3",
"VexiiRiscv",
"OpenC906",
"JTAG"
]
},
@@ -31,8 +31,6 @@
"title": "Interrupts and IPC",
"items": [
"LP CLINT",
"HP ACLINT",
"HP PLIC",
"LP/HP Mailbox"
]
},
@@ -7069,76 +7069,6 @@
"description": "Machine time bits 63:32."
}
},
"aclint": {
"msip.MSIP": {
"fields": [
{
"name": "PENDING",
"lsb": 0,
"msb": 0,
"description": "Machine software-interrupt request for this hart.",
"reset": "0x0",
"expression": "reviewed field"
},
{
"name": "Reserved",
"lsb": 1,
"msb": 31,
"description": "Reserved; write zero.",
"reset": "0x0",
"expression": "reserved"
}
],
"access": "RW",
"reset": "0",
"description": "Per-hart software interrupt pending bit."
},
"compare.MTIMECMP": {
"fields": [
{
"name": "VALUE",
"lsb": 0,
"msb": 31,
"description": "Comparator bits 31:0.",
"reset": "0xffffffff",
"expression": "reviewed field"
}
],
"access": "RW",
"reset": "0xFFFFFFFF",
"description": "Comparator bits 31:0."
},
"main.MTIME": {
"fields": [
{
"name": "VALUE",
"lsb": 0,
"msb": 31,
"description": "Machine time bits 31:0.",
"reset": "0x0",
"expression": "reviewed field"
}
],
"access": "RW",
"reset": "0",
"description": "Machine time bits 31:0."
},
"main.MTIMEH": {
"fields": [
{
"name": "VALUE",
"lsb": 0,
"msb": 31,
"description": "Machine time bits 63:32.",
"reset": "0x0",
"expression": "reviewed field"
}
],
"access": "RW",
"reset": "0",
"description": "Machine time bits 63:32."
}
},
"mpw-timer": {
"main.USER_IP_APB_ID": {
"fields": [
@@ -2233,251 +2233,6 @@
],
"support": []
},
"plic": {
"document": "docs/ip/hp-platform.md",
"defines": [],
"rtl": [
"rtl/ip/peripheral/apb4_plic.sv"
],
"parameters": {
"NumMasters": 8,
"NumTargets": 6,
"ResourceCount": 8
},
"groups": [
{
"id": "priority",
"title": "Source priorities",
"pattern": "(?!)",
"strip": "^",
"base": 0,
"stride": 4,
"count": 32
},
{
"id": "pending",
"title": "Pending sources",
"pattern": "(?!)",
"strip": "^",
"base": 4096,
"stride": 0,
"count": 1
},
{
"id": "enable",
"title": "Context enables",
"pattern": "(?!)",
"strip": "^",
"base": 8192,
"stride": 128,
"count": 2
},
{
"id": "context",
"title": "Context threshold and claim",
"pattern": "(?!)",
"strip": "^",
"base": 2097152,
"stride": 4096,
"count": 2
}
],
"extra": [
{
"group": "priority",
"name": "PRIORITY",
"offset": 0,
"access": "RW",
"reset": "0",
"description": "Per-source three-bit priority.",
"fields": [
{
"name": "PRIORITY",
"lsb": 0,
"msb": 2,
"description": "Priority 0 disables delivery; source 0 is reserved and hardwired zero.",
"reset": "Register reset applies",
"expression": "reviewed semantic field"
},
{
"name": "Reserved",
"lsb": 3,
"msb": 31,
"description": "Reserved; preserve zero when writing.",
"reset": "0",
"expression": "reserved"
}
]
},
{
"group": "pending",
"name": "PENDING",
"offset": 0,
"access": "RO",
"reset": "0",
"description": "Pending sources; claim changes pending/claimed state.",
"fields": [
{
"name": "Reserved",
"lsb": 0,
"msb": 0,
"description": "Reserved; preserve zero when writing.",
"reset": "0",
"expression": "reserved"
},
{
"name": "PENDING",
"lsb": 1,
"msb": 31,
"description": "Bit n indicates pending source n. Source 0 remains zero.",
"reset": "Register reset applies",
"expression": "reviewed semantic field"
}
]
},
{
"group": "enable",
"name": "ENABLE",
"offset": 0,
"access": "RW",
"reset": "0",
"description": "Context source mask; context 0 is machine and context 1 supervisor.",
"fields": [
{
"name": "Reserved",
"lsb": 0,
"msb": 0,
"description": "Reserved; preserve zero when writing.",
"reset": "0",
"expression": "reserved"
},
{
"name": "ENABLE",
"lsb": 1,
"msb": 31,
"description": "Enable source n for this context. Source 0 cannot be enabled.",
"reset": "Register reset applies",
"expression": "reviewed semantic field"
}
]
},
{
"group": "context",
"name": "THRESHOLD",
"offset": 0,
"access": "RW",
"reset": "0",
"description": "Interrupt delivery threshold.",
"fields": [
{
"name": "THRESHOLD",
"lsb": 0,
"msb": 2,
"description": "Only a source with priority strictly greater than this value is eligible.",
"reset": "Register reset applies",
"expression": "reviewed semantic field"
},
{
"name": "Reserved",
"lsb": 3,
"msb": 31,
"description": "Reserved; preserve zero when writing.",
"reset": "0",
"expression": "reserved"
}
]
},
{
"group": "context",
"name": "CLAIM_COMPLETE",
"offset": 4,
"access": "RO claim / WO complete",
"reset": "0",
"description": "Claim and complete register; reads and writes have different side effects.",
"fields": [
{
"name": "SOURCE_ID",
"lsb": 0,
"msb": 4,
"description": "Read claims the winning source, or zero if none. Write the nonzero claimed ID to complete it.",
"reset": "Register reset applies",
"expression": "reviewed semantic field"
},
{
"name": "Reserved",
"lsb": 5,
"msb": 31,
"description": "Reserved; preserve zero when writing.",
"reset": "0",
"expression": "reserved"
}
]
}
],
"support": []
},
"aclint": {
"document": "docs/ip/clint.md",
"defines": [
"rtl/ip/peripheral/clint_define.svh"
],
"rtl": [
"rtl/ip/peripheral/clint_reg.sv"
],
"parameters": {
"HartNum": 2
},
"groups": [
{
"id": "msip",
"title": "Per-hart software interrupt",
"pattern": "APB4_CLINT_MSIP",
"strip": "^APB4_CLINT_",
"base": 0,
"stride": 4,
"count": 2
},
{
"id": "compare",
"title": "Per-hart timer comparator",
"pattern": "APB4_CLINT_MTIMECMP",
"strip": "^APB4_CLINT_",
"base": 0,
"stride": 8,
"count": 2
},
{
"id": "main",
"title": "Shared 64-bit time",
"pattern": "APB4_CLINT_MTIMEH?",
"strip": "^APB4_CLINT_",
"base": 0,
"stride": 0,
"count": 1
}
],
"extra": [
{
"group": "compare",
"name": "MTIMECMP_HI",
"offset": 16388,
"access": "RW",
"reset": "0xFFFFFFFF",
"description": "High word of the per-hart 64-bit machine timer comparator.",
"fields": [
{
"name": "VALUE",
"lsb": 0,
"msb": 31,
"description": "Comparator bits 63:32.",
"reset": "Register reset applies",
"expression": "reviewed field"
}
]
}
],
"support": []
},
"mpw-timer": {
"document": "docs/ip/user-ip.md",
"defines": [],
@@ -24,11 +24,13 @@ halt, resume, register and system-bus access. LP retains control while HP is hel
#source-note("docs/hazard3-debug.md", title:"Management debug transport and acceptance flow")
=== Application Processor
==== VexiiRiscv
The generated HP hart is a dual-issue RV64IMAFDC + Zicbom configuration, with supervisor/user
modes, Sv39 virtual memory and *64-byte cache-maintenance blocks*. Hart 1 uses native AXI64
instruction and data paths. Its uncached MMIO path is downsized and crosses into the LP
control plane. OpenSBI/Linux inputs and generated-core configuration are dependency-locked.
==== OpenC906
The HP hart is the locked T-Head OpenC906 pre-generated RTL in its default RV64GC
configuration, with supervisor/user modes and Sv39 virtual memory. Hart 1 issues a single
*128-bit AXI4 master*, downsized to the 64-bit HP data fabric and split into memory and MMIO
ports by address window. The uncached MMIO path is downsized further and crosses into the LP
control plane. Its CLINT/PLIC are *core-internal* (c900 layouts) and never appear as SoC
fabric targets. OpenSBI/Linux inputs and the vendored core revision are dependency-locked.
#source-note("docs/lp-hp-architecture.md", title:"LP/HP architecture and boot contract")
#include "processor-details.typ"
@@ -70,7 +72,7 @@ An allowed entry does not guarantee throughput.]
#pagebreak()
#figure(matrix-diagram(), caption:[AXI64 memory access matrix: R = read, W = write, - = denied.])<bus-matrix>
The I-cache is the only instruction-permitted initiator. HP cache attributes are preserved;
The HP memory master is the only instruction-permitted initiator. HP cache attributes are preserved;
DMA, I/O gateways, LP gateway, JPEG, EXT-H, GA2D and NPU require non-cacheable transactions. XPI is read-only
on this data plane; indirect writes use its APB-controlled command engine.
@@ -94,7 +96,8 @@ advertise an implemented IP.
data.regions.filter(r=>r.route in ("axi4","ram","reserved") and r.size > 4096).map(r=>(
code(r.symbol),code(r.base_hex),code(r.end_hex),r.size_label)),
widths:(1fr,1.1fr,1.1fr,0.65fr),
notes:[FLASH is the reset/boot alias. SPISD's former card-data aperture is reserved. The physical
notes:[FLASH is the reset/boot alias. SPISD's former card-data aperture is reserved. HP_C906_SYS
is reserved for the HP core's internal CLINT/PLIC decode; it is not a SoC fabric target. The physical
capacity of fitted XPI/OPI devices remains board-dependent.],
)
#ds-table("registers", [Register and interrupt-controller windows],
@@ -150,7 +153,7 @@ qualification. No crystal-oscillator range or maximum core frequency is specifie
== Interrupt System
The management interrupt vector is 64 bits wide; two local causes and 62 external positions
are distinct from the currently allocated source list. The following numbers are
LP vector bits, not HP PLIC source IDs. Peripheral-level status registers identify causes
LP vector bits, not HP PLIC IDs. Peripheral-level status registers identify causes
within an aggregate source. Resource-controlled interrupts are routed according to ownership.
#ds-table("lp-irqs", [LP interrupt vector],
([LP bit], [Source], [Description]),
@@ -158,13 +161,16 @@ within an aggregate source. Resource-controlled interrupts are routed according
widths:(0.45fr,1.25fr,2fr),
)
HP has local software/timer interrupts and a 32-source, two-context PLIC. Source 0 is
reserved; sources 1-12 are UART1, mailbox, EXT-H, DMA, USB2, SDIO0, SDIO1, SPI-SD, JPEG, APU,
GA2D and NPU. Sources 13-31 are reserved. GA2D uses LP vector bit 32 (external ordinal 30),
which is distinct from HP PLIC source 11; NPU uses LP vector bit 33 (external ordinal 31)
or HP PLIC source 12 according to Resource Controller ownership. The contexts drive machine
and supervisor external interrupts.
Claim/complete and priority rules are defined in the HP platform contract.
HP local software/timer interrupts come from the core-internal CLINT, and external sources
from the core-internal PLIC (T-Head c900 layouts, decoded inside the OpenC906 core). Sixteen
SoC external sources are wired; *SoC source n reaches software as PLIC ID n+16*. Source 1 is
UART1, source 2 is the mailbox doorbell, source 3 is EXT-H, and sources 4-12 are the
resource-owned DMA, USB2, SDIO0, SDIO1, SPI-SD, JPEG, APU, GA2D and NPU lines; sources 13-15
are reserved. GA2D uses LP vector bit 32 (external ordinal 30),
which is distinct from HP external source 11; NPU uses LP vector bit 33 (external ordinal 31)
or HP external source 12 according to Resource Controller ownership. The PLIC drives the
hart's machine and supervisor external interrupts.
Claim/complete and priority rules follow the T-Head C906 manuals.
#block(above:rhythm.metadata-before,below:rhythm.metadata-after,breakable:false)[
#set text(size:9pt)
#source("docs/ip/hp-platform.md",title:"HP PLIC, local interrupts and mailbox") · LP software: @irq-runtime
@@ -12,7 +12,7 @@ the domains; the table below records which clock must be supplied to the relevan
(([UART / I2C / general timer],[Actual clock driving the selected engine; check PCLK/root routing.],[Recalculate divisors/timing or counter period after that clock changes.]),
([I2S],[External audio-domain frequency, not the HP CPU clock.],[Select a compatible preset or exact programmable divisors while disabled.]),
([SDRAM / QPI / OPI / XPI],[Stable memory domain plus the controller's local divider/sampling convention.],[Convert device timing to controller cycles and reinitialize where required.]),
([LP CLINT / HP ACLINT],[Configured CLINT timebase. The reference configuration selects 1 MHz.],[Use the timebase for deadlines rather than a core instruction frequency.]),
([LP CLINT / HP time base],[Configured CLINT timebase; the HP core receives the 64-bit time value and software reads the time CSR. The reference configuration selects 1 MHz.],[Use the timebase for deadlines rather than a core instruction frequency.]),
([RTC / watchdog],[Their actual independent timing source and divider contract.],[Do not infer their tick from a CPU frequency change.]),
([DVP / ULPI / JTAG],[Externally supplied functional clock under the interface contract.],[Validate external clock availability and board timing separately.])),
widths:(0.95fr,1.55fr,1.7fr))
@@ -5,18 +5,20 @@
=== OpenSBI platform and console path <linux-runtime>
The supplied OpenSBI platform exposes *one application hart*, with hart ID #platform.hart_id.
LP remains the separate management firmware processor. The platform's ACLINT descriptor covers
two hart-indexed register positions beginning at zero so it can address hart 1; that storage
LP remains the separate management firmware processor. The platform's software-interrupt
descriptor targets the core-internal CLINT with first hart ID 1 and hart count 1; that storage
range is not a declaration that Linux runs on both harts. The *kernel configuration disables SMP*.
The early platform setup programs UART1, registers its polled console and initializes machine
software-interrupt support. Timer initialization uses the ACLINT machine timer. Console writes
software-interrupt support. Timer initialization registers a custom timer device that reads
the time CSR and programs the core-internal MTIMECMP; there is *no memory-mapped mtime*.
Console writes
wait while TX is full; this loop has *no local timeout*. These implemented callbacks do not
establish that all optional SBI services or all peripherals have native Linux drivers.
#figure(sequence-diagram((
[*LP handoff* \ Existing bundle validation \ Release HP at OpenSBI],
[*OpenSBI on hart 1* \ UART1 SBI console \ ACLINT platform setup],
[*OpenSBI on hart 1* \ UART1 SBI console \ CLINT timer/MSWI setup],
[*FW_JUMP* \ Enter Linux Image \ Pass the prepared DTB],
[*Kernel / initramfs* \ SBI early console and hvc0 \ Run /init],
[*Rootfs ready service* \ Print ready text \ Publish mailbox fields],
@@ -27,11 +29,11 @@ The kernel uses #code(platform.bootargs). Console text therefore reaches UART1 t
path in this configuration. The UART1 device-tree node's presence does not substitute for a
native driver. The configured machine timer and software-interrupt path are distinct from
external interrupt-controller and custom peripheral driver integration.
#source-note("app/ports/linux/opensbi/retrosoc_hp/platform.c",title:"Hart mapping, console callbacks and ACLINT setup")
#source-note("app/ports/linux/opensbi/retrosoc_hp/platform.c",title:"Hart mapping, console callbacks and timer/MSWI setup")
#source-note("app/ports/linux/linux/retrosoc_hp.config",title:"RV64, SBI console and single-hart kernel configuration")
=== Device-tree and image consistency
The device-tree template, OpenSBI build arguments, boot-bundle bounds and actual generated HP
The device-tree template, OpenSBI build arguments, boot-bundle bounds and actual integrated HP
core must agree. The existing image addresses in @boot-configuration remain authoritative;
the following values explain the platform relationship rather than defining a second layout.
@@ -39,11 +41,11 @@ the following values explain the platform relationship rather than defining a se
([Property],[Source value],[Consistency boundary]),
(([CPU identity],[Hart #platform.hart_id],[Match OpenSBI's hart-index map and the generated core.]),
([Main memory],[#code(platform.memory_base), #(platform.memory_bytes / 1024 / 1024) MiB],[Device-tree envelope; actual external memory and boot-loader bounds must agree.]),
([Timer base rate],[#platform.timebase_hz Hz],[Match ACLINT timebase-frequency and the OpenSBI mtimer declaration.]),
([Timer base rate],[#platform.timebase_hz Hz],[Match the device-tree timebase-frequency and the OpenSBI timer-frequency declaration.]),
([CPU / UART clock declarations],[#platform.clock_hz Hz],[Nominal template values, not measured or dynamically synchronized frequencies.]),
([MMU / cache maintenance],[Sv39; #(platform.cbom_bytes)-byte CBO blocks],[Software metadata must be checked against the generated HP artifact.]),
([MMU / cache maintenance],[Sv39; 64-byte D-cache lines via T-Head extended operations],[Software must enable the extended instruction set before using the maintenance encodings.]),
([Initial ramdisk],[Start #code("0x"+str(platform.initrd_start,base:16))],[The source template's equal start/end is patched using the built uncompressed CPIO size.]),
([Interrupt controllers],[ACLINT CPU causes; PLIC machine/supervisor contexts],[A DT node and binding alone do not demonstrate a complete driver or interrupt acceptance test.])),
([Interrupt controllers],[Core-internal CLINT CPU causes; core-internal PLIC machine/supervisor contexts],[A DT node and binding alone do not demonstrate a complete driver or interrupt acceptance test.])),
widths:(1fr,1.3fr,2.15fr))
The image builder replaces linux,initrd-end with the start plus the actual rootfs.cpio size.
@@ -29,16 +29,17 @@ programming uses the command engine. Reserved ranges and inactive QPI/OPI window
used as scratch space. Physical device capacity must match the controller and board setup.
=== Buffer ownership and alignment
The supplied HP platform metadata declares Zicbom with a 64-byte cache-maintenance block. Round shared
maintenance ranges to full blocks and *prevent unrelated owners from sharing a boundary block*.
The OpenC906 HP hart maintains its 64-byte D-cache lines with T-Head extended cache
operations (XTheadCmo). Round shared
maintenance ranges to full lines and *prevent unrelated owners from sharing a boundary line*.
*Check address-plus-length overflow* before rounding. Device descriptors can impose additional
alignment, byte-count, stride and memory-placement constraints; the DMA TCD is a separate
64-byte descriptor contract, not a universal transfer-alignment rule for every IP.
#figure(cache-boundary-diagram(),kind:image,supplement:[Figure],caption:[Software-declared maintenance blocks around a shared-buffer range.])<cache-maintenance-layout>
Match the platform declaration to the generated HP artifact before deployment; this schematic
#figure(cache-boundary-diagram(),kind:image,supplement:[Figure],caption:[HP D-cache maintenance lines around a shared-buffer range.])<cache-maintenance-layout>
Match the maintenance operations to the vendored HP core before deployment; this schematic
does not independently establish physical cache-line geometry or total cache capacity.
#source-note("app/ports/linux/linux/retrosoc_hp.dts",title:"Software-declared cache-maintenance block size")
#source-note("app/ports/linux/smoke/start.S",title:"C906 cache-maintenance instruction encodings")
#ds-table("buffer-ownership",[Shared-buffer responsibilities],
([Actor],[Responsibility before handoff],[Responsibility after completion]),
@@ -70,8 +71,8 @@ does not independently establish physical cache-line geometry or total cache cap
operation, then transfer the buffer to the application.
These are integration sequences, not a new cache HAL. Linux drivers must use the DMA mapping
and synchronization interfaces appropriate to their platform. The existence of Zicbom and a
device-tree block-size property does not establish complete Linux DMA coherency integration.
and synchronization interfaces appropriate to their platform. The existence of core cache
maintenance operations does not establish complete Linux DMA coherency integration.
=== LP-to-HP and HP-to-LP handoff
#figure(sequence-diagram((
@@ -93,6 +94,6 @@ transaction at the protocol level; retries require a new ownership decision.
#source-note("docs/lp-hp-architecture.md",title:"Memory paths and non-coherent ownership contract")
#source-note("docs/ip/resource-controller.md",title:"Cache request and clean acknowledgement")
#source-note("docs/ip/dma.md",title:"DMA descriptors, transfer restrictions and completion")
#source-note("app/ports/linux/linux/retrosoc_hp.dts",title:"Linux RAM and cache-maintenance properties")
#source-note("app/ports/linux/linux/retrosoc_hp.dts",title:"Linux RAM and platform properties")
#change-end("v05-emphasis-memory-use")
@@ -36,7 +36,7 @@
#set list(tight:false,spacing:rhythm.cover-list-spacing,body-indent:rhythm.cover-list-indent)
*Compute and control*
- Hazard3 LP: boot, clocks, resource ownership and fault recovery.
- Dual-issue VexiiRiscv HP: RV64IMAFDC + Zicbom, Sv39.
- OpenC906 HP: RV64GC, Sv39, single 128-bit AXI4 master.
- NPU: *64 dense MACs*, eight INT8 operator classes and 64 KiB private SRAM.
- JTAG debug; fixed EXT-L control and EXT-H AXI64 slots.
@@ -90,7 +90,7 @@ retained document title; no separate derivative specifications are inferred.]
#change-start("v05-overview","NPU-inclusive functional inventory and configuration reference")
retroSoC Mini combines a small management processor with an application processor and shared
memory and I/O. Hazard3 retains authority over startup, clock transitions, resource ownership
and fault recovery. VexiiRiscv supplies the application-side compute and Linux integration.
and fault recovery. OpenC906 supplies the application-side compute and Linux integration.
The design is intended for embedded control, basic human-machine interfaces, retro multimedia
experimentation, education and ASIC prototyping.
@@ -3,64 +3,59 @@
#let cpu = data.system_reference.product_details.cpu
=== Processor Configuration and Software-visible Capabilities <processor-details>
The table separates the actual LP instance arguments, the explicit HP generator settings and
The table separates the actual LP instance arguments, the fixed HP OpenC906 integration and
the selected firmware build. It is a *configuration summary*, not a replacement for the CPU
ISA/CSR manuals. A software compiler option does not remove a hardware extension or CSR block.
#ds-table("processor-config",[Processor settings and the reference software configuration],
([Property],[LP: instantiated Hazard3],[HP: explicit VexiiRiscv generator configuration]),
(([Hart / role],[Hart 0; root management.],[Hart 1; application/Linux platform.]),
([Execution width],[RV32 integration.],[XLEN #cpu.hp.xlen / physical address width #cpu.hp.physicalWidth.]),
([Configured extensions],cpu.lp_extensions.join(", "),cpu.hp_isa.filter(x=>not(x in ("s","u"))).join(", ")),
([Privilege],[Machine-mode configuration, U_MODE = #cpu.lp.U_MODE.],[S and U selected by the generator, in addition to machine-mode operation.]),
([MMU / software platform],[No LP MMU is advertised by this integration.],[Supplied software platform declares Sv39; verify agreement with the generated core before deployment.]),
([Protection],[PMP_REGIONS = #cpu.lp.PMP_REGIONS.],[PMP entries = #cpu.hp.at("pmpParam.pmpSize") / granularity = #cpu.hp.at("pmpParam.granularity") bytes.]),
([Reset entry],code(data.reset_address),code(cpu.hp.resetVector.trim("L",at:end))),
([Trap / counter configuration],[MTVEC_INIT: #code(cpu.lp.MTVEC_INIT) \ Machine CSR: #cpu.lp.CSR_M_MANDATORY / counters: #cpu.lp.CSR_COUNTER.],[ASID width #cpu.hp.asidWidth and #cpu.hp.additionalPerformanceCounters additional performance counters. \ Time-read option: #cpu.hp.at("privParam.withRdTime").]),
([Debug],[DEBUG_SUPPORT = #cpu.lp.DEBUG_SUPPORT \ Breakpoint triggers: #cpu.lp.BREAKPOINT_TRIGGERS.],[Embedded JTAG/debug configured; triggers #cpu.hp.at("privParam.debugTriggers").]),
([Issue configuration],[Use the selected Hazard3 instance and upstream core contract.],[#cpu.hp.decoders decoders and #cpu.hp.lanes lanes configured.])),
([Property],[LP: instantiated Hazard3],[HP: locked OpenC906 default configuration]),
(([Hart / role],[Hart 0; root management.],[Hart #cpu.hp.hartId; application/Linux platform.]),
([Execution width],[RV32 integration.],[RV64 (#code(cpu.hp_isa_base) base); the core drives 40-bit addresses over a 32-bit physical fabric.]),
([Configured extensions],cpu.lp_extensions.join(", "),[#cpu.hp_isa.join(", ") (the RV64GC set).]),
([Privilege],[Machine-mode configuration, U_MODE = #cpu.lp.U_MODE.],[M/S/U per the C906 default configuration; the supplied software platform declares #cpu.hp_mmu.]),
([Protection],[PMP_REGIONS = #cpu.lp.PMP_REGIONS.],[PMP per the T-Head C906 manuals; entry geometry is not separately extracted in this publication.]),
([Reset entry],code(data.reset_address),code(cpu.hp.resetVector)),
([Trap / counter configuration],[MTVEC_INIT: #code(cpu.lp.MTVEC_INIT) \ Machine CSR: #cpu.lp.CSR_M_MANDATORY / counters: #cpu.lp.CSR_COUNTER.],[No memory-mapped mtime; HP software reads the time CSR.]),
([Debug],[DEBUG_SUPPORT = #cpu.lp.DEBUG_SUPPORT \ Breakpoint triggers: #cpu.lp.BREAKPOINT_TRIGGERS.],[JTAG debug through the core-internal Debug Module and the external DTM; the debug system-bus master is unconnected.]),
([Bus interfaces],[Use the selected Hazard3 instance and upstream core contract.],[One #(cpu.hp.coreAxiDataWidth)-bit AXI4 master, downsized to the #(cpu.hp.fabricAxiDataWidth)-bit HP fabric; internal CLINT/PLIC window at #code(cpu.hp.sysWindowBase).])),
widths:(0.8fr,1.6fr,1.75fr))
The reference LP build uses #code(cpu.build.ISA) with #code("HAVE_CSR="+cpu.build.HAVE_CSR).
Those build choices are separate from the instantiated LP extension and mandatory CSR settings.
The HP profile selects #code(cpu.build.HP_CONFIG). OpenSBI, the device tree and the kernel
configuration *must remain consistent with the core that is actually generated and used*.
The HP core is the dependency-locked OpenC906 pre-generated RTL in its default configuration;
there is no Mini-side generator selection. OpenSBI, the device tree and the kernel
configuration *must remain consistent with the core that is actually integrated and used*.
==== Cache geometry and evidence basis
#ds-table("processor-cache-evidence",[Cache and generated-core evidence boundaries],
#ds-table("processor-cache-evidence",[Cache and vendored-core evidence boundaries],
([Item],[Recorded configuration],[Qualification]),
(([HP instruction cache],[Enable setting #cpu.hp.fetchL1Enable with #cpu.hp.fetchL1Sets sets and #cpu.hp.fetchL1Ways ways; minimum memory data width #cpu.hp.fetchMemDataWidthMin bits.],[Explicit generator settings.]),
([HP data cache],[Enable setting #cpu.hp.lsuL1Enable with #cpu.hp.lsuL1Sets sets and #cpu.hp.lsuL1Ways ways; minimum memory data width #cpu.hp.lsuMemDataWidthMin bits.],[Explicit generator settings.]),
([Cache total capacity],cpu.hp_cache_capacity,[Sets multiplied by ways is *not a byte capacity* without the reviewed block size.]),
([Cache maintenance],[Zicbom selected; supplied platform metadata declares a 64-byte CBO block.],[Keep platform metadata and the eventual generated implementation consistent.]),
(([HP instruction cache],[32 KiB in the default OpenC906 configuration.],[Vendored default configuration; see the qualification note below.]),
([HP data cache],[32 KiB in the default OpenC906 configuration; 64-byte lines.],[Vendored default configuration; see the qualification note below.]),
([Cache total capacity],cpu.hp_cache_capacity,[Do not relabel a configured feature as a tested or silicon capability.]),
([Cache maintenance],[T-Head extended operations (XTheadCmo custom-0 dcache clean/invalidate by address) on 64-byte lines; no Zicbom CBO block.],[Used by the supplied HP smoke image; the extended instruction set must be enabled in the machine status CSR first.]),
([Locked HP source],[#code(cpu.hp_revision.slice(0,12))],[The full dependency revision is recorded in the lock and publication manifest.]),
([Generated HP artifact],cpu.generated_artifact_basis,[No new HP RTL generation or independent generated-manifest validation was performed for this publication.])),
([Vendored HP RTL],cpu.generated_artifact_basis,[The Mini mhartid = #cpu.hp.hartId assignment comes from the reviewed override file, not from editing the vendored checkout.])),
widths:(0.8fr,1.7fr,1.65fr))
The current publication workspace does not supply the locked VexiiRiscv checkout and a matching
generated-core manifest for independent inspection. Only explicit repository generator settings
are listed as such. Upstream defaults, plugin expansion and derived byte capacities remain
unconfirmed until that artifact/source evidence is attached. Do not relabel a configured feature
as a tested generated-core or silicon capability.
The vendored OpenC906 checkout is a locked, managed input; the C906 user and integration
manuals ship with it and remain the register/CSR reference. This publication lists only
integration-visible settings and does not re-derive upstream implementation parameters.
==== PMA coverage versus implemented memory
#ds-table("hp-pma-coverage",[Explicit PMA envelopes in the HP generator],
([Base],[Inclusive end],[Bytes],[Main memory],[Executable]),
cpu.pma.map(r=>(code(r.base),code(r.end),str(r.bytes),r.main,r.executable)),
widths:(1.1fr,1.1fr,0.8fr,0.65fr,0.65fr))
A PMA envelope describes core-side attributes. It does not instantiate RAM or override the
SoC decoder, per-master ACL, resource owner or physical device. In particular, the generator's
SRAM attribute envelope is larger than the reference profile's 32 KiB physical SRAM region.
Use the generated address map and selected profile for capacity and valid access bounds.
==== System window and address decode
The HP core decodes its internal CLINT/PLIC window at #code(cpu.hp.sysWindowBase) inside the
core BIU; the matching 128 MiB SoC range is reserved and never reaches the external fabric.
The reset vector #code(cpu.hp.resetVector) and the 32-bit physical fabric are unchanged by the
core swap. Per-hart identity is fixed at integration time: the LP Hazard3 reports mhartid 0
and the HP OpenC906 reports mhartid 1 through the reviewed override.
Before deploying a new HP image, retain the lock revision, generator source, generated RTL/hash
manifest and software build identity together. Check the core/device-tree feature agreement and
Before deploying a new HP image, retain the lock revision, vendored source identity, override
file and software build identity together. Check the core/device-tree feature agreement and
the existing non-coherent buffer protocol. LP and HP configuration differences do not turn the
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/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("rtl/mini/top/hp_core_wrapper.sv",title:"HP OpenC906 integration") ·
#source("scripts/generate_openc906.py",title:"Vendored filelist and hart-ID override") ·
#source("app/ports/linux/linux/retrosoc_hp.dts",title:"HP platform properties")
]
@@ -19,7 +19,7 @@ selector zero has no dedicated peripheral request wire. WS2812 uses that softwar
The endpoint IRQ column identifies the peripheral's own event line where one exists; it is
*not the DMA transfer-completion interrupt*. Central DMA channel events aggregate at the DMA
resource's LP IRQ or HP PLIC source according to the central resource owner. Crypto has no
resource's LP IRQ or HP external source according to the central resource owner. Crypto has no
separate LP vector entry in this integration; inspect its register status and DMA completion path.
=== Software channel allocation
@@ -39,10 +39,11 @@ descriptors or 2D operation merely from fields in the descriptor structure.
=== Private DMA masters and owner-directed completion
#ds-table("private-dma-routes",[Central and private-master routes with owner-directed interrupts],
([Engine],[Native master / gateway],[LP vector bit],[HP PLIC source]),
([Engine],[Native master / gateway],[LP vector bit],[HP external source]),
programming.engines.map(r=>(link(label(r.id),r.name),r.master,str(r.lp_irq),str(r.hp_irq))),
widths:(1.2fr,1.5fr,0.65fr,0.7fr))
These HP source numbers are read from the actual PLIC assignments. The Resource Controller
These HP source numbers are read from the actual SoC interrupt wiring. On the OpenC906
core-internal PLIC, software addresses each one as *PLIC ID = source + 16*. The Resource Controller
selects one owner's route and masks routes according to its lifecycle contract; it does not
deliver a completion to both owners. Private DMA engines do not consume a central DMA channel
simply because both move memory. They can still share a gateway or destination bandwidth.
@@ -96,13 +96,13 @@ the C runtime dispatches LP external interrupts through Hazard3 Xh3irq; it is no
(code("rs_irq_disable_external"),[Mask the selected external source.],[The no-CSR implementations return RS_ENOTSUP; they do not silently emulate interrupts.]),
([Global enable],[The caller controls the global interrupt-enable bit separately.],[Complete handler and source setup before enabling delivery.]),
([Default exception],[Print diagnostic mcause and stack pointer, then loop.],[No automatic TEST_STATUS failure or instruction recovery is generated.]),
([External interrupt dispatch],[Claim the highest-priority Xh3irq source, call its installed handler, then restore context; mask a source with no handler.],[The peripheral cause still needs acknowledgement in the handler. HP PLIC claim/complete belongs to the HP platform.])),
([External interrupt dispatch],[Claim the highest-priority Xh3irq source, call its installed handler, then restore context; mask a source with no handler.],[The peripheral cause still needs acknowledgement in the handler. HP claim/complete belongs to the core-internal PLIC on the HP platform.])),
widths:(1.05fr,1.7fr,1.7fr))
The supplied IRQ example registers machine timer/software handlers, enables global delivery,
updates the compare value in the timer handler and clears the software-pending source in its
handler. Its bounded foreground waits are example-specific. LP vector bits, CPU cause numbers,
handler-table indexes and HP PLIC source IDs are distinct namespaces. See @dma-routing for
handler-table indexes and HP PLIC IDs (SoC source + 16) are distinct namespaces. See @dma-routing for
hardware routes and @fault-code-reference for interpreting captured results.
#source-note("crt/arch/riscv/system_irq.S",title:"Saved context and direct trap entry")
#source-note("crt/src/core/system_irq_handler.c",title:"Registration, supported enables and default dispatch behavior")
@@ -190,12 +190,12 @@ the source paths used for each row and allows later reports to be bound to a pro
multimedia throughput, physical pin timing or whole-system Linux stability.
The supplied Linux console uses #code("console=hvc0 earlycon=sbi"). OpenSBI contains the UART1
console implementation and ACLINT timer/software-interrupt setup. UART1 and mailbox DT nodes
console implementation and the core-internal CLINT timer/software-interrupt setup. UART1 and mailbox DT nodes
reserve their platform ABI; the presence of #code("status = okay") is not evidence that a
native custom driver is available or correct. No generic HAL-to-Linux bridge is supplied here.
=== Validated-configuration record
A reusable run record must name the source commit, committed profile, generated HP core,
A reusable run record must name the source commit, committed profile, vendored HP core revision,
toolchain/kernel/OpenSBI versions, device/model or board, command, log/result digest and
tested feature set. Record skips and missing tools explicitly. Keep simulation, FPGA and
silicon stages separate and retain failed runs as diagnostics rather than overwriting them
@@ -5,7 +5,7 @@
#include "routing-reference.typ"
== Multicore Operation and Resource Ownership <multicore-operation>
Hazard3 is the *root-management hart*; VexiiRiscv is the application hart. Linux does not take
Hazard3 is the *root-management hart*; OpenC906 is the application hart. Linux does not take
over the SoC's root clock, reset, admission and recovery controls merely by booting. Decide
which software owns each resource and buffer *before enabling interrupts or bus mastering*.
@@ -105,7 +105,7 @@ the stated inclusive end address. Numeric suffixes in signal names denote signal
not package pin numbers. `_i`, `_o` and `_n` retain their declared direction/polarity meaning.
An RTL `inout` pad wrapper may contain a functionally input-only route.
LP interrupt vector bits, HP PLIC source IDs, DMA request values, software channel contexts
LP interrupt vector bits, HP external sources and their PLIC IDs, DMA request values, software channel contexts
and native master slots are separate namespaces. A matching integer does not connect them.
Clock configuration, nominal calculated rate, model timing and characterized pin timing are
also distinct. Interpret every Min/Typ/Max entry with its stated evidence and conditions.
+8 -71
View File
@@ -273,14 +273,17 @@
},
{
"id": "hp_core",
"label": "VexiiRiscv\nI$ / D$ / FPU / MMU",
"label": "OpenC906\nI$ / D$ / FPU / MMU",
"x": 107,
"y": 4.793103448275862,
"w": 43,
"h": 11.896551724137932,
"domain": "hp",
"role": "module",
"ips": [],
"ips": [
"hp-aclint",
"hp-plic"
],
"rotate": false,
"clock": {
"file": "rtl/mini/top/retrosoc.sv",
@@ -844,48 +847,6 @@
"signal": "clk_pclk_i"
}
},
{
"id": "hp-aclint",
"label": "HP ACLINT",
"x": 108,
"y": 118,
"w": 42,
"h": 5.5,
"domain": "pclk",
"role": "module",
"ips": [
"hp-aclint"
],
"rotate": false,
"clock": {
"file": "rtl/mini/top/retrosoc.sv",
"name": "u_apb4_periph",
"module": "apb4_periph",
"port": "clk_i",
"signal": "clk_pclk_i"
}
},
{
"id": "hp-plic",
"label": "HP PLIC",
"x": 108,
"y": 125,
"w": 42,
"h": 5.5,
"domain": "pclk",
"role": "module",
"ips": [
"hp-plic"
],
"rotate": false,
"clock": {
"file": "rtl/mini/top/retrosoc.sv",
"name": "u_apb4_periph",
"module": "apb4_periph",
"port": "clk_i",
"signal": "clk_pclk_i"
}
},
{
"id": "hp-mailbox",
"label": "LP / HP Mailbox",
@@ -2599,30 +2560,6 @@
"kind": "control",
"arrow": true
},
{
"id": "e55",
"from": "cfg_right",
"to": "hp-aclint",
"source_side": "east",
"target_side": "west",
"source_position": 0.38392857142857145,
"target_position": 0.5,
"via": [],
"kind": "control",
"arrow": true
},
{
"id": "e56",
"from": "cfg_right",
"to": "hp-plic",
"source_side": "east",
"target_side": "west",
"source_position": 0.6339285714285714,
"target_position": 0.5,
"via": [],
"kind": "control",
"arrow": true
},
{
"id": "e57",
"from": "cfg_right",
@@ -3405,7 +3342,7 @@
},
"output_bits": {
"file": "rtl/mini/top/retrosoc.sv",
"name": "u_hp_icache_axi4_if"
"name": "u_hp_mem_axi4_if"
}
}
},
@@ -3812,11 +3749,11 @@
"masters": [
{
"index": 0,
"name": "hp_icache"
"name": "hp_mem"
},
{
"index": 1,
"name": "hp_dcache"
"name": "hp_retired"
},
{
"index": 2,
+2 -1
View File
@@ -135,7 +135,8 @@ collector checks RTL/SDK request-number parity (including explicit QSPI/XPI
aliases), coverage, actual connection snippets and referenced instances. Channel
conventions are supported by driver call sites, not inferred from selector IDs.
Private masters and central DMA contexts are different resources. Preserve
endpoint IRQ, aggregate DMA IRQ, LP vector bit and HP PLIC source as separate
endpoint IRQ, aggregate DMA IRQ, LP vector bit and HP external source (PLIC ID = source + 16
on the OpenC906 internal PLIC) as separate
fields/namespaces. Derive PLIC assignments and normal master credits from the
current implementation; mark any connected zero-credit route explicitly.
+27 -65
View File
@@ -582,16 +582,15 @@
"id": "hp-aclint",
"title": "HP ACLINT",
"implementation": "Integrated",
"scope": "Two addressable hart slots; HP consumes slot 1.",
"scope": "Core-internal CLINT of the OpenC906 HP hart (thead,c900-clint layout), decoded inside the core at 0x0C000000 within the 0x08000000 system window; no memory-mapped mtime.",
"dependencies": "No additional off-chip component implied; use the selected clock/reset and access policy.",
"hal": "Register/platform interface; no standalone HAL example indexed.",
"linux": "OpenSBI timer/IPI and standard DT bindings present; target boot report not supplied.",
"hal": "Core-internal unit; no SoC register bank or standalone HAL example indexed.",
"linux": "OpenSBI uses the ACLINT software-interrupt driver at the core-internal base and a custom timer device reading the time CSR; target boot report not supplied.",
"verification": "Tests available",
"sources": [
"app/ports/linux/linux/retrosoc_hp.dts",
"app/ports/linux/opensbi/retrosoc_hp/platform.c",
"docs/ip/clint.md",
"rtl/ip/peripheral/clint_reg.sv"
"rtl/mini/top/hp_core_wrapper.sv"
],
"tests": [
"tests/test_hp_platform.py"
@@ -602,16 +601,15 @@
"id": "hp-plic",
"title": "HP PLIC",
"implementation": "Integrated",
"scope": "32 source IDs, with source 0 reserved.",
"scope": "Core-internal PLIC of the OpenC906 HP hart (thead,c900-plic layout), decoded inside the core at 0x08000000; SoC external interrupt source n is delivered as PLIC ID n+16.",
"dependencies": "No additional off-chip component implied; use the selected clock/reset and access policy.",
"hal": "Register/platform interface; no standalone HAL example indexed.",
"linux": "Standard PLIC DT binding present; target IRQ validation report not supplied.",
"hal": "Core-internal unit; no SoC register bank or standalone HAL example indexed.",
"linux": "thead,c900-plic DT binding present; target IRQ validation report not supplied.",
"verification": "Tests available",
"sources": [
"app/ports/linux/linux/retrosoc_hp.dts",
"app/ports/linux/opensbi/retrosoc_hp/platform.c",
"docs/ip/hp-platform.md",
"rtl/ip/peripheral/apb4_plic.sv"
"rtl/mini/top/hp_core_wrapper.sv"
],
"tests": [
"tests/test_hp_platform.py"
@@ -2130,7 +2128,7 @@
{
"id": "hp",
"term": "HP",
"meaning": "VexiiRiscv application hart; asymmetric Linux platform.",
"meaning": "OpenC906 application hart; asymmetric Linux platform.",
"sources": [
"docs/lp-hp-architecture.md",
"docs/ip/dma.md",
@@ -2179,12 +2177,12 @@
},
{
"id": "cbo",
"term": "CBO / Zicbom",
"meaning": "Cache-block maintenance operation / RISC-V extension; not hardware coherency.",
"term": "XTheadCmo",
"meaning": "T-Head extended cache-maintenance operations used by OpenC906 HP software (64-byte line); not hardware coherency.",
"sources": [
"app/ports/linux/smoke/start.S",
"docs/lp-hp-architecture.md",
"docs/ip/dma.md",
"crt/linker/ld2_all_sram.lds"
"docs/ip/dma.md"
]
},
{
@@ -2305,26 +2303,12 @@
"U_MODE"
],
"hp_fields": [
"additionalPerformanceCounters",
"asidWidth",
"decoders",
"fetchL1Enable",
"fetchL1Sets",
"fetchL1Ways",
"fetchMemDataWidthMin",
"lanes",
"lsuL1Enable",
"lsuL1Sets",
"lsuL1Ways",
"lsuMemDataWidthMin",
"physicalWidth",
"pmpParam.granularity",
"pmpParam.pmpSize",
"privParam.debugTriggers",
"privParam.withDebug",
"privParam.withRdTime",
"coreAxiDataWidth",
"externalInterruptSources",
"fabricAxiDataWidth",
"hartId",
"resetVector",
"xlen"
"sysWindowBase"
]
},
"reset": [
@@ -3388,9 +3372,10 @@
"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",
"scripts/generate_openc906.py",
"scripts/program_xpi_flash.py",
"scripts/vexiiriscv/GenerateRetroSocHp.scala",
"rtl/mini/ip_overrides/aq_sysio_kid.v",
"rtl/mini/top/hp_core_wrapper.sv",
"tests/test_xpi_flash_tool.py"
]
},
@@ -3727,32 +3712,6 @@
"docs/ip/clint.md"
]
},
{
"id": "hp_aclint",
"chapter": "hp-aclint",
"family": "aclint",
"mode": "PRODUCT",
"region": "HP_ACLINT",
"catalog": "hp-platform",
"qualification": "Use the named instance, ownership and reset conditions in the linked IP reference.",
"sources": [
"docs/ip/hp-platform.md",
"docs/lp-hp-architecture.md"
]
},
{
"id": "hp_plic",
"chapter": "hp-plic",
"family": "plic",
"mode": "PRODUCT",
"region": "HP_PLIC",
"catalog": "hp-platform",
"qualification": "PRIORITY index 0 is reserved and hardwired zero; its generic array access does not make source 0 programmable. Context indices retain the HP-platform contract.",
"sources": [
"docs/ip/hp-platform.md",
"docs/lp-hp-architecture.md"
]
},
{
"id": "apb4_hp_mailbox",
"chapter": "hp-mailbox",
@@ -3867,7 +3826,7 @@
"mode": "PRODUCT",
"region": "APB4_NPU",
"catalog": "npu",
"qualification": "Integrated native-HP NPU execution with eight operator classes, descriptor DMA and private SRAM; CAPABILITY=0x7F and OP_CAPABILITY=0x1FE. Resource 9 routes LP vector 33 / HP PLIC source 12. Use configured lifecycle, cache and descriptor admission rules; no native Linux driver, arbitrary model or current corpus/physical qualification is implied.",
"qualification": "Integrated native-HP NPU execution with eight operator classes, descriptor DMA and private SRAM; CAPABILITY=0x7F and OP_CAPABILITY=0x1FE. Resource 9 routes LP vector 33 / HP external source 12 (PLIC ID 28 on the OpenC906 internal PLIC). Use configured lifecycle, cache and descriptor admission rules; no native Linux driver, arbitrary model or current corpus/physical qualification is implied.",
"sources": [
"docs/ip/npu.md",
"rtl/ip/multimedia/npu_reg.sv",
@@ -5355,7 +5314,7 @@
{
"id": "aclint-index-range",
"file": "app/ports/linux/opensbi/retrosoc_hp/platform.c",
"text": ".first_hartid = 0U,\n.hart_count = 2U,"
"text": ".first_hartid = 1U,\n.hart_count = 1U,"
},
{
"id": "sbi-console",
@@ -5372,7 +5331,7 @@
{
"id": "sbi-timer",
"file": "app/ports/linux/opensbi/retrosoc_hp/platform.c",
"text": "return aclint_mtimer_cold_init(&s_mtimer, NULL);",
"text": "sbi_timer_set_device(&s_timer);",
"function": "retrosoc_hp_timer_init"
},
{
@@ -5956,6 +5915,7 @@
"app/apps/hp_boot/main.c",
"app/apps/xpi_flash_loader/startup.S",
"app/ports/linux/linux/retrosoc_hp.dts",
"app/ports/linux/smoke/start.S",
"configs/ci/ihp130-debug.mk",
"configs/ci/ihp130-hp.mk",
"configs/ci/ihp130-xpi-flash-loader.mk",
@@ -6146,8 +6106,10 @@
"rtl/mini/top/extension_slot.sv",
"rtl/mini/top/extension_subsystem.sv",
"rtl/mini/top/fabric_monitor.sv",
"rtl/mini/top/hp_core_wrapper.sv",
"rtl/mini/top/hp_subsystem.sv",
"rtl/mini/top/memory_pad_mux.sv",
"rtl/mini/ip_overrides/aq_sysio_kid.v",
"rtl/ip/core/mgmt_debug_wrapper.sv",
"rtl/ip/memory/onchip_ram.sv",
"rtl/mini/top/rcu.sv",
-144
View File
@@ -1768,150 +1768,6 @@
},
"parameter_note": "Each LP or HP local interrupt block in this example has one hart."
},
"aclint": {
"source": {
"signal": [
{
"name": "tick_i",
"wave": "0101010."
},
{
"name": "mtime_o",
"wave": "=.=.=.==",
"data": [
"N-1",
"N",
"N+1",
"N+2",
"N+2"
]
},
{
"name": "mtimecmp_i[0]",
"wave": "=.....=.",
"data": [
"N",
"N+8"
]
},
{
"name": "timer_irq_o[0]",
"wave": "0..1...0"
}
],
"config": {
"hscale": 1,
"skin": "lowkey"
}
},
"note": "Scope: clint_core. Clock: clk_i; mtime tick and comparator update. Hart 0: the timer IRQ is a registered comparison of mtime_o against mtimecmp_i[0]. Updating compare above the current time deasserts the IRQ on a subsequent core edge; timebase tick spacing is illustrative.",
"clock_domain": "clk_i; mtime tick and comparator update",
"signals": {
"tick_i": {
"file": "rtl/ip/peripheral/clint_core.sv",
"scope": "clint_core",
"symbol": "tick_i",
"meaning": "Qualified timebase increments.",
"polarity": "active-high"
},
"mtime_o": {
"file": "rtl/ip/peripheral/clint_core.sv",
"scope": "clint_core",
"symbol": "mtime_o",
"meaning": "MTIME advances through the programmed compare value.",
"polarity": "data"
},
"mtimecmp_i[0]": {
"file": "rtl/ip/peripheral/clint_core.sv",
"scope": "clint_core",
"symbol": "mtimecmp_i",
"meaning": "Hart 0 compare is moved beyond the current time.",
"polarity": "data"
},
"timer_irq_o[0]": {
"file": "rtl/ip/peripheral/clint_core.sv",
"scope": "clint_core",
"symbol": "timer_irq_o",
"meaning": "Registered timer interrupt follows comparison.",
"polarity": "active-high"
}
},
"review_sources": [
"rtl/ip/peripheral/clint_core.sv"
],
"review_note": "Mapped mtime/mtimecmp aliases to ports and retained the registered comparator delay.",
"parameters": {
"HartNum": 1
},
"parameter_note": "Each LP or HP local interrupt block in this example has one hart."
},
"plic": {
"source": {
"signal": [
{
"name": "source_i[1]",
"wave": "010......"
},
{
"name": "s_pending_q[1]",
"wave": "0.1.0...."
},
{
"name": "s_claimed_q[1]",
"wave": "0...1..0."
},
{
"name": "context_irq_o[0]",
"wave": "0.1.0...."
}
],
"config": {
"hscale": 1,
"skin": "lowkey"
}
},
"note": "Scope: apb4_plic. Clock: clk_i; APB access and service intervals omitted. Source 1 enabled for context 0 with priority above threshold. Claim clears pending and marks the source claimed; completion releases it. APB read/write handshakes and software service time are omitted.",
"clock_domain": "clk_i; APB access and service intervals omitted",
"signals": {
"source_i[1]": {
"file": "rtl/ip/peripheral/apb4_plic.sv",
"scope": "apb4_plic",
"symbol": "source_i",
"meaning": "Source 1 pulse.",
"polarity": "active-high"
},
"s_pending_q[1]": {
"file": "rtl/ip/peripheral/apb4_plic.sv",
"scope": "apb4_plic",
"symbol": "s_pending_q",
"meaning": "Pending latch is set then cleared by a claim.",
"polarity": "active-high"
},
"s_claimed_q[1]": {
"file": "rtl/ip/peripheral/apb4_plic.sv",
"scope": "apb4_plic",
"symbol": "s_claimed_q",
"meaning": "Claimed state persists until completion.",
"polarity": "active-high"
},
"context_irq_o[0]": {
"file": "rtl/ip/peripheral/apb4_plic.sv",
"scope": "apb4_plic",
"symbol": "context_irq_o",
"meaning": "Context 0 interrupt while enabled pending priority wins.",
"polarity": "active-high"
}
},
"review_sources": [
"rtl/ip/peripheral/apb4_plic.sv"
],
"review_note": "Reviewed priority arbitration, pending and claimed arrays. Removed claim-read/complete-write pseudo-signals and kept their software actions in the note.",
"parameters": {
"NumSources": 32,
"NumContexts": 2
},
"parameter_note": "Reference HP PLIC exposes 32 source slots and two contexts."
},
"mailbox": {
"source": {
"signal": [
+6 -2
View File
@@ -206,9 +206,13 @@ def collect_diagrams(root: Path, spec: dict, regions: list[dict], system: dict)
("argument", 8, 32), ("crc7", 1, 7), ("end", 0, 1)]:
raise ValueError("SDIO field order differs from the bound transmitter assembly")
dts = (root / "app/ports/linux/linux/retrosoc_hp.dts").read_text(encoding="utf-8")
cbo = re.findall(r"riscv,cbom-block-size\s*=\s*<(\d+)>", dts)
if cbo != ["64"]:
if "riscv,cbom-block-size" in dts:
raise ValueError("review cache-maintenance diagram after platform granule change")
smoke = (root / "app/ports/linux/smoke/start.S").read_text(encoding="utf-8")
if (".insn r 0x0b, 0x0, 0x01, x0, a0, x5" not in smoke
or ".insn r 0x0b, 0x0, 0x01, x0, a0, x6" not in smoke
or "csrs 0x7c0, t0" not in smoke):
raise ValueError("review cache-maintenance diagram after platform maintenance-operation change")
windows = [{k: r[k] for k in ("symbol", "base", "size", "base_hex", "end_hex", "size_label")}
for r in regions if r["size"] > 4096 and r["route"] in {"axi4", "ram"} and r["kind"] == "active"]
if not windows or any(r["base"] + r["size"] > 1 << 32 for r in windows):
+54 -22
View File
@@ -42,13 +42,49 @@ def lp_parameters(text: str) -> dict[str, str]:
for name, value in parameters.items()}
def hp_parameters(text: str) -> tuple[dict[str, str], list[str]]:
text = without_comments(text)
values = unique_pairs(re.findall(r"^\s*param\.([A-Za-z][\w.]*)\s*=\s*([^\n]+)", text, re.M), "HP")
isa = re.findall(r"param\.addISA\(([^)]*)\)", text)
if len(isa) != 1:
raise ValueError("HP ISA configuration missing or ambiguous")
return values, re.findall(r'"([a-z0-9]+)"', isa[0])
def hp_parameters(wrapper: str, override: str) -> dict[str, str]:
"""Read the fixed OpenC906 integration constants from the Mini HP wrapper."""
text = without_comments(wrapper)
constants = unique_pairs(
[(name, f"0x{int(value.replace('_', ''), 16):08X}")
for name, value in re.findall(
r"localparam\s+logic\s+\[39:0\]\s+(HpResetVector|HpApbBase)\s*=\s*40'h([0-9A-Fa-f_]+)\s*;", text)],
"HP")
interfaces = {}
for body, name in re.findall(
r"axi4_if\s*#\s*\(([^;]+?)\)\s*(u_c906_axi4_if|u_hp_64_axi4_if)\s*\(", text, re.S):
width = re.findall(r"\.\s*DATA_WIDTH\s*\(\s*(\d+)\s*\)", body)
if len(width) != 1 or name in interfaces:
raise ValueError("HP interface width missing or ambiguous")
interfaces[name] = width[0]
sources = re.findall(r"input\s+logic\s+\[15:0\]\s+plic_src_i\b", text)
hart = re.findall(r"assign\s+sysio_core_hartid\[2:0\]\s*=\s*3'd(\d)\s*;", without_comments(override))
if len(constants) != 2 or len(interfaces) != 2 or len(sources) != 1 or len(hart) != 1:
raise ValueError("HP OpenC906 integration constants missing or ambiguous")
return {
"resetVector": constants["HpResetVector"],
"sysWindowBase": constants["HpApbBase"],
"coreAxiDataWidth": interfaces["u_c906_axi4_if"],
"fabricAxiDataWidth": interfaces["u_hp_64_axi4_if"],
"externalInterruptSources": "16",
"hartId": hart[0],
}
def hp_isa(dts: str) -> dict[str, object]:
"""Read the software-visible HP ISA/MMU identity from the reviewed device tree."""
cpu = re.findall(r"cpu@1\s*\{(.*?)hp_cpu_intc:", dts, re.S)
if len(cpu) != 1:
raise ValueError("HP device-tree CPU node missing or ambiguous")
node = cpu[0]
compatible = re.findall(r'compatible\s*=\s*"thead,c906"', node)
base = re.findall(r'riscv,isa-base\s*=\s*"(\w+)"', node)
extensions = re.findall(r'riscv,isa-extensions\s*=\s*((?:\s*"[a-z0-9]+",?)+)\s*;', node)
mmu = re.findall(r'mmu-type\s*=\s*"riscv,(\w+)"', node)
if not compatible or len(base) != 1 or len(extensions) != 1 or len(mmu) != 1:
raise ValueError("HP device-tree ISA/MMU identity missing or ambiguous")
return {"compatible": "thead,c906", "isa_base": base[0],
"extensions": re.findall(r'"([a-z0-9]+)"', extensions[0]), "mmu": mmu[0]}
def reset_assignments(text: str, signal: str, module: str | None = None) -> dict[str, str]:
@@ -115,32 +151,28 @@ 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/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)
hp = hp_parameters((root / "rtl/mini/top/hp_core_wrapper.sv").read_text(encoding="utf-8"),
(root / "rtl/mini/ip_overrides/aq_sysio_kid.v").read_text(encoding="utf-8"))
identity = hp_isa((root / "app/ports/linux/linux/retrosoc_hp.dts").read_text(encoding="utf-8"))
for required, actual, name in ((spec["cpu"]["lp_fields"], lp, "LP"), (spec["cpu"]["hp_fields"], hp, "HP")):
if len(set(required)) != len(required) or not set(required) <= set(actual):
raise ValueError(f"missing or duplicate requested {name} parameters")
config = json.loads((root / "publications/datasheets/mini.json").read_text(encoding="utf-8"))
profile = (root / config["profile"]).read_text(encoding="utf-8")
build = unique_pairs(re.findall(r"^\s*(ISA|HAVE_CSR|HAVE_HP|HP_CONFIG)\s*:?=\s*([^\n#]+)", profile, re.M), "firmware")
if set(build) != {"ISA", "HAVE_CSR", "HAVE_HP", "HP_CONFIG"}:
build = unique_pairs(re.findall(r"^\s*(ISA|HAVE_CSR|HAVE_HP)\s*:?=\s*([^\n#]+)", profile, re.M), "firmware")
if set(build) != {"ISA", "HAVE_CSR", "HAVE_HP"} or build["HAVE_HP"] != "YES":
raise ValueError("incomplete firmware/core profile identity")
lock = json.loads((root / "dependencies/dependencies.lock.json").read_text(encoding="utf-8"))
result = copy.deepcopy(spec)
result["cpu"] = {
"lp": lp, "hp": hp, "hp_isa": hp_isa, "build": build,
"lp": lp, "hp": hp, "hp_isa": identity["extensions"], "build": build,
"hp_isa_base": identity["isa_base"], "hp_mmu": identity["mmu"],
"hp_compatible": identity["compatible"],
"lp_extensions": [name.removeprefix("EXTENSION_") for name, value in lp.items() if name.startswith("EXTENSION_") and value == "1"],
"hp_revision": lock["sources"]["vexiiriscv"]["revision"],
"generated_artifact_basis": "Not supplied in the publication evidence set",
"hp_cache_capacity": "Unconfirmed; upstream default block size not independently reviewed",
"hp_revision": lock["sources"]["openc906"]["revision"],
"generated_artifact_basis": "Pre-generated vendored OpenC906 RTL at the locked revision, with the reviewed retroSoC hart-ID override; no new core generation",
"hp_cache_capacity": "Default OpenC906 configuration (32 KiB instruction + 32 KiB data L1 per the T-Head C906 manuals); not independently re-measured",
}
pma = re.findall(r"SizeMapping\((0x[0-9A-Fa-f]+)L,\s*(0x[0-9A-Fa-f]+)L\),\s*isMain\s*=\s*(true|false),\s*isExecutable\s*=\s*(true|false)", without_comments(hp_source))
if not pma:
raise ValueError("explicit HP PMA mappings missing")
result["cpu"]["pma"] = [{"base": f"0x{int(base, 16):08X}",
"end": f"0x{int(base, 16)+int(size, 16)-1:08X}",
"bytes": int(size, 16), "main": main, "executable": execute}
for base, size, main, execute in pma]
result["service_results"] = [{"executed": str(e).lower(), "passed": str(p).lower(),
"meaning": programming_result({"executed": e, "passed": p})}
for e, p in ((False, True), (False, False), (True, False), (True, True))]
-1
View File
@@ -927,7 +927,6 @@ def extract_profile(ip: str, spec: dict, annotations: dict) -> dict:
"mailbox": "hp_mailbox",
"monitor": "fabric_monitor",
"extensions": "extension",
"aclint": "clint",
"wdg": "watchdog",
}.get(ip, ip)
candidates = [f"crt/include/retrosoc/hal/{alias}_regs.h", f"crt/src/hal/{alias}.c"]
+5 -2
View File
@@ -164,7 +164,7 @@ def linux_platform(root: Path) -> dict:
if harts != ["1"] or hart_ids != ["1"] or len(cpu) != 1 or not re.search(r"\breg\s*=\s*<1>\s*;", cpu[0]):
raise ValueError("Linux/OpenSBI hart identity changed")
timebase = dt_value("timebase-frequency")
mtimer = re.findall(r"\.mtime_freq\s*=\s*(\d+)UL", platform)
mtimer = re.findall(r"\.timer_freq\s*=\s*(\d+)UL", platform)
if mtimer != [str(timebase)]:
raise ValueError("Linux/OpenSBI timebase mismatch")
profile = (root / "configs/ci/ihp130-hp.mk").read_text(encoding="utf-8")
@@ -181,8 +181,11 @@ def linux_platform(root: Path) -> dict:
raise ValueError("CPU and UART device-tree clock declarations disagree")
if dt_value("linux,initrd-start") != dt_value("linux,initrd-end"):
raise ValueError("reviewed initrd template placeholder changed")
controllers = re.findall(r'"(thead,c900-clint|thead,c900-plic)"', dts)
if controllers != ["thead,c900-clint", "thead,c900-plic"] or dt_value("riscv,ndev") != 31:
raise ValueError("Linux internal CLINT/PLIC declaration changed")
return {"hart_id": 1, "timebase_hz": timebase, "clock_hz": int(clocks[0]),
"cbom_bytes": dt_value("riscv,cbom-block-size"), "memory_base": memory[0][0],
"memory_base": memory[0][0],
"memory_bytes": int(memory[0][1], 0), "initrd_start": dt_value("linux,initrd-start"),
"initrd_template_end": dt_value("linux,initrd-end"), "bootargs": bootargs[0],
"ready_writes": ready_mailbox(root)}
File diff suppressed because it is too large. Load diff
+11 -4
View File
@@ -12,10 +12,17 @@ notices. `filelist/` selects PDK-specific RTL sources; `tech/` contains
technology wrappers. Respect managed upstream boundaries and use setup helpers
rather than editing generated MPW output.
The optional IHP130 LP/HP profile integrates VexiiRiscv through self-owned
wrappers, a 64-to-32 compatibility plane, HP ACLINT/PLIC, mailbox, UART1, and
SYSCTRL lifecycle signals. The generated CPU Verilog lives only below
`build/<variant>/generated/vexiiriscv/` and is an external lint boundary. See
The optional IHP130 LP/HP profile integrates the locked, pre-generated T-Head
OpenC906 HP core through self-owned wrappers, a serializing 128-to-64
downsizer with an MMIO demux, the C906 internal CLINT/PLIC, mailbox, UART1, and
SYSCTRL lifecycle signals. `make setup-openc906` (part of `make setup`)
restores the locked checkout and `make openc906-prepare` emits the generated
filelist and manifest below `build/<variant>/generated/openc906/`; the OpenC906
sources are an external lint boundary. The reviewed hart-ID and sysmap
address-attribute overrides live in `rtl/mini/ip_overrides/` and are applied
by filelist generation, never by editing the vendored checkout. The former
VexiiRiscv HP generator is preserved
only as the frozen Std-series asset (`make std-vexii-generate`). See
[LP/HP Architecture](../docs/lp-hp-architecture.md).
RTL changes require an affected firmware build and simulation. Use
+1 -1
View File
@@ -182,7 +182,7 @@ RTL_FILELISTS := $(MEMORY_MAP_FILELIST) $(SOC_TOPOLOGY_FILELIST) $(USER_EXTENSIO
$(GENERATED_FL_DIR)/core_hazard3.fl \
$(if $(filter MPW,$(MINI_MODE)),$(MPW_OUTPUT_DIR)/core/core.fl,$(USER_EXTENSIONS_DIR)/legacy_core.fl) \
$(if $(filter MPW,$(MINI_MODE)),$(MPW_OUTPUT_DIR)/ip/ip.fl,$(USER_EXTENSIONS_DIR)/legacy_ip.fl) \
$(if $(filter YES,$(HAVE_HP)),$(HP_GENERATED_DIR)/vexiiriscv.fl) \
$(if $(filter YES,$(HAVE_HP)),$(HP_GENERATED_FL)) \
$(GENERATED_FL_DIR)/top.fl
RTL_FLIST := $(foreach filelist,$(RTL_FILELISTS),-f $(filelist))
#====================== end ======================
+6 -15
View File
@@ -220,22 +220,13 @@
"burst": "incr16"
},
{
"symbol": "HP_ACLINT",
"base": "0x02000000",
"size": "0x00010000",
"route": "apb4_periph",
"kind": "active",
"symbol": "HP_C906_SYS",
"base": "0x08000000",
"size": "0x08000000",
"route": "reserved",
"kind": "reserved",
"public": true,
"user_access": "rw"
},
{
"symbol": "HP_PLIC",
"base": "0x0C000000",
"size": "0x04000000",
"route": "apb4_periph",
"kind": "active",
"public": true,
"user_access": "rw"
"user_access": "none"
},
{
"symbol": "APB4_GPIO",
+2
View File
@@ -25,6 +25,8 @@
/top/axi42apb4_periph.sv
/top/axi4_word_bridge.sv
/top/axi4_downsizer_64to32.sv
/top/axi4_downsizer_128to64.sv
/top/axi4_mmio_demux.sv
/top/hp_axi4_mux3.sv
/top/axi42ram.sv
/top/rib_error_slave.sv
@@ -21,8 +21,8 @@ FABRIC_PROTOCOLS = {name: "axi4" for name in FABRIC_LINK_NAMES}
IRQ_GROUP_NAMES = ("apb4_periph", "apb4_system")
IRQ_VECTOR_WIDTH = 64
DATA_MASTER_NAMES = (
"hp_icache",
"hp_dcache",
"hp_mem",
"hp_retired",
"dma",
"io_gateway_a",
"io_gateway_b",
+8 -22
View File
@@ -366,17 +366,17 @@
"data_master_policies": [
{
"index": 0,
"name": "hp_icache",
"name": "hp_mem",
"read_targets": ["sram", "sdram", "qpi", "opi", "xpi"],
"write_targets": [],
"write_targets": ["sram", "sdram", "qpi", "opi"],
"allow_instruction": true,
"require_noncacheable": false
},
{
"index": 1,
"name": "hp_dcache",
"read_targets": ["sram", "sdram", "qpi", "opi", "xpi"],
"write_targets": ["sram", "sdram", "qpi", "opi"],
"name": "hp_retired",
"read_targets": [],
"write_targets": [],
"allow_instruction": false,
"require_noncacheable": false
},
@@ -625,41 +625,27 @@
},
{
"slot": 24,
"name": "hp_aclint",
"timed_interface": "u_hp_aclint_apb4_if",
"pure_interface": "u_hp_aclint_apb4_pure_if",
"region": "HP_ACLINT"
},
{
"slot": 25,
"name": "hp_plic",
"timed_interface": "u_hp_plic_apb4_if",
"pure_interface": "u_hp_plic_apb4_pure_if",
"region": "HP_PLIC"
},
{
"slot": 26,
"name": "jpeg",
"timed_interface": "u_jpeg_apb4_if",
"pure_interface": "u_jpeg_apb4_pure_if",
"region": "APB4_JPEG"
},
{
"slot": 27,
"slot": 25,
"name": "apu",
"timed_interface": "u_apu_apb4_if",
"pure_interface": "u_apu_apb4_pure_if",
"region": "APB4_APU"
},
{
"slot": 28,
"slot": 26,
"name": "ga2d",
"timed_interface": "u_ga2d_apb4_if",
"pure_interface": "u_ga2d_apb4_pure_if",
"region": "APB4_GA2D"
},
{
"slot": 29,
"slot": 27,
"name": "npu",
"timed_interface": "u_npu_apb4_if",
"pure_interface": "u_npu_apb4_pure_if",
+203
View File
@@ -0,0 +1,203 @@
// retroSoC controlled override of the vendored OpenC906 aq_sysio_kid.v.
//
// Source: openc906 dependency (dependencies.lock.json "openc906"),
// C906_RTL_FACTORY/gen_rtl/cpu/rtl/aq_sysio_kid.v
// revision b0c06eb1f8b3bae663bd8b87eac89ff48e68a57f
// License: Apache-2.0 (T-Head Semiconductor)
//
// retroSoC change (Mini LP/HP contract): the HP core must report mhartid=1
// (the LP Hazard3 core is hart 0). Upstream hardwires sysio_core_hartid to
// 3'b0 and exposes no top-level hart-id port, so this file substitutes the
// vendored module with sysio_core_hartid = 3'd1. Everything else is
// byte-identical to upstream. Keep in sync when the lock revision changes.
/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
module aq_sysio_kid(
apb_clk_en,
axim_clk_en,
clint_core_ms_int,
clint_core_mt_int,
clint_core_ss_int,
clint_core_st_int,
core_pad_lpmd_b,
core_sysio_lpmd_b,
cpurst_b,
forever_cpuclk,
pad_yy_icg_scan_en,
plic_core_me_int,
plic_core_se_int,
sysio_core_hartid,
sysio_core_me_int,
sysio_core_ms_int,
sysio_core_mt_int,
sysio_core_se_int,
sysio_core_ss_int,
sysio_core_st_int
);
// &Ports; @23
input apb_clk_en;
input axim_clk_en;
input clint_core_ms_int;
input clint_core_mt_int;
input clint_core_ss_int;
input clint_core_st_int;
input [1:0] core_sysio_lpmd_b;
input cpurst_b;
input forever_cpuclk;
input pad_yy_icg_scan_en;
input plic_core_me_int;
input plic_core_se_int;
output [1:0] core_pad_lpmd_b;
output [2:0] sysio_core_hartid;
output sysio_core_me_int;
output sysio_core_ms_int;
output sysio_core_mt_int;
output sysio_core_se_int;
output sysio_core_ss_int;
output sysio_core_st_int;
// &Regs; @24
reg clint_core_ms_int_cpu;
reg clint_core_mt_int_cpu;
reg clint_core_ss_int_cpu;
reg clint_core_st_int_cpu;
reg [1:0] core_pad_lpmd_b;
reg plic_core_me_int_cpu;
reg plic_core_se_int_cpu;
// &Wires; @25
wire apb_clk_en;
wire axim_clk_en;
wire clint_core_ms_int;
wire clint_core_mt_int;
wire clint_core_ss_int;
wire clint_core_st_int;
wire [1:0] core_sysio_lpmd_b;
wire cpurst_b;
wire forever_cpuclk;
wire kid_int_clk;
wire kid_int_clk_en;
wire pad_yy_icg_scan_en;
wire plic_core_me_int;
wire plic_core_se_int;
wire sysio_clk_en;
wire [2:0] sysio_core_hartid;
wire sysio_core_me_int;
wire sysio_core_ms_int;
wire sysio_core_mt_int;
wire sysio_core_se_int;
wire sysio_core_ss_int;
wire sysio_core_st_int;
wire sysio_kid_clk;
//input
assign sysio_clk_en = axim_clk_en;
// &Instance("gated_clk_cell", "x_sysio_kid_gated_clk"); @29
gated_clk_cell x_sysio_kid_gated_clk (
.clk_in (forever_cpuclk ),
.clk_out (sysio_kid_clk ),
.external_en (1'b0 ),
.global_en (1'b1 ),
.local_en (sysio_clk_en ),
.module_en (1'b0 ),
.pad_yy_icg_scan_en (pad_yy_icg_scan_en)
);
// &Connect(.clk_in (forever_cpuclk), @30
// .external_en (1'b0 ), @31
// .global_en (1'b1 ), @32
// .module_en (1'b0 ). @33
// .local_en (sysio_clk_en ), @34
// .clk_out (sysio_kid_clk ) @35
// ); @36
//output
always @(posedge sysio_kid_clk or negedge cpurst_b)
begin
if (!cpurst_b)
begin
core_pad_lpmd_b[1:0] <= 2'b11;
end
else if (axim_clk_en)
begin
core_pad_lpmd_b[1:0] <= core_sysio_lpmd_b[1:0];
end
end
// &Force("output", "sysio_core_me_int"); @51
// &Force("output", "sysio_core_mt_int"); @52
// &Force("output", "sysio_core_ms_int"); @53
// &Force("output", "sysio_core_se_int"); @54
// &Force("output", "sysio_core_st_int"); @55
// &Force("output", "sysio_core_ss_int"); @56
assign kid_int_clk_en = apb_clk_en;
// &Instance("gated_clk_cell", "x_sysio_kid_int_gated_clk"); @59
gated_clk_cell x_sysio_kid_int_gated_clk (
.clk_in (forever_cpuclk ),
.clk_out (kid_int_clk ),
.external_en (1'b0 ),
.global_en (1'b1 ),
.local_en (kid_int_clk_en ),
.module_en (1'b0 ),
.pad_yy_icg_scan_en (pad_yy_icg_scan_en)
);
// &Connect(.clk_in (forever_cpuclk), @60
// .external_en (1'b0 ), @61
// .global_en (1'b1 ), @62
// .module_en (1'b0 ). @63
// .local_en (kid_int_clk_en), @64
// .clk_out (kid_int_clk ) @65
// ); @66
always @(posedge kid_int_clk or negedge cpurst_b)
begin
if (!cpurst_b)
begin
plic_core_me_int_cpu <= 1'b0;
plic_core_se_int_cpu <= 1'b0;
clint_core_ms_int_cpu <= 1'b0;
clint_core_ss_int_cpu <= 1'b0;
clint_core_mt_int_cpu <= 1'b0;
clint_core_st_int_cpu <= 1'b0;
end
else if (apb_clk_en)
begin
plic_core_me_int_cpu <= plic_core_me_int;
plic_core_se_int_cpu <= plic_core_se_int;
clint_core_ms_int_cpu <= clint_core_ms_int;
clint_core_ss_int_cpu <= clint_core_ss_int;
clint_core_mt_int_cpu <= clint_core_mt_int;
clint_core_st_int_cpu <= clint_core_st_int;
end
end
assign sysio_core_me_int = plic_core_me_int_cpu;
assign sysio_core_se_int = plic_core_se_int_cpu;
assign sysio_core_ms_int = clint_core_ms_int_cpu;
assign sysio_core_ss_int = clint_core_ss_int_cpu;
assign sysio_core_mt_int = clint_core_mt_int_cpu;
assign sysio_core_st_int = clint_core_st_int_cpu;
// retroSoC: HP hart id is 1 (LP Hazard3 is hart 0); upstream ties this to 3'b0.
assign sysio_core_hartid[2:0] = 3'd1;
// &Force("output","core_pad_lpmd_b"); @100
// &ModuleEnd; @103
endmodule
+72
View File
@@ -0,0 +1,72 @@
// retroSoC controlled override of the vendored OpenC906 sysmap.h.
//
// Source: openc906 dependency (dependencies.lock.json "openc906"),
// C906_RTL_FACTORY/gen_rtl/mmu/rtl/sysmap.h
// revision b0c06eb1f8b3bae663bd8b87eac89ff48e68a57f
// License: Apache-2.0 (T-Head Semiconductor)
//
// retroSoC change: the upstream default region table targets a 40-bit
// reference map and marks the entire low 2.4 GiB (including the Mini
// peripheral window) as cacheable/bufferable memory. The OpenC906 user
// manual (section 3, sysmap.h) requires the integrator to configure address
// attributes per SoC and explicitly requires CLINT/PLIC regions to be
// non-cacheable devices. This override maps the Mini address map:
//
// region 0: 0x0000_0000-0x01FF_FFFF flash XIP -> normal cacheable
// region 1: 0x0200_0000-0x2FFF_FFFF MMIO window (incl. the core-internal
// CLINT/PLIC window 0x0800_0000-0x0FFF_FFFF) -> device SO/NC/NB
// region 2: 0x3000_0000-0x4FFF_FFFF SRAM/SDRAM/PSRAM/OPI -> cacheable
// region 3: 0x5000_0000-0x5FFF_FFFF XPI window -> normal cacheable
// region 4: 0x6000_0000-0x7FFF_FFFF reserved -> device SO/NC/NB
// region 5-7: everything above -> device SO/NC/NB (also the
// out-of-table default per the user manual)
//
// Flag bit layout (aq_mmu_utlb.v: utlb_so=flg[9]=pma[4], utlb_ca=pma[3]):
// flag[4]=SO (strong order) flag[3]=C (cacheable) flag[2]=B (bufferable)
// flag[1]=shareable flag[0]=security (unused without TEE)
//
// Keep in sync when the lock revision changes.
/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// ADDR is 28-bit, 4K address
// Flag includes: Strong Order, Cacheable, Bufferable, Shareable, Security
`define SYSMAP_BASE_ADDR0 28'h02000
`define SYSMAP_FLG0 5'b01111
`define SYSMAP_BASE_ADDR1 28'h30000
`define SYSMAP_FLG1 5'b10011
`define SYSMAP_BASE_ADDR2 28'h50000
`define SYSMAP_FLG2 5'b01111
`define SYSMAP_BASE_ADDR3 28'h60000
`define SYSMAP_FLG3 5'b01111
`define SYSMAP_BASE_ADDR4 28'h80000
`define SYSMAP_FLG4 5'b10011
`define SYSMAP_BASE_ADDR5 28'hC0000
`define SYSMAP_FLG5 5'b10011
`define SYSMAP_BASE_ADDR6 28'hFF00000
`define SYSMAP_FLG6 5'b10011
`define SYSMAP_BASE_ADDR7 28'hFFFFFFF
`define SYSMAP_FLG7 5'b10011
//End ct_mmu_sysmap
+4 -30
View File
@@ -90,10 +90,7 @@ module apb4_periph #(
input logic [3:0] fault_wstrb_i,
input logic fault_reserved_i,
output logic [63:0] hp_time_o,
output logic hp_timer_irq_o,
output logic hp_software_irq_o,
output logic hp_machine_external_irq_o,
output logic hp_supervisor_external_irq_o,
output logic [15:0] hp_plic_src_o,
output logic apu_idle_o,
output logic jpeg_idle_o,
output logic ga2d_idle_o,
@@ -177,7 +174,6 @@ axi4_stream_if #(
);
clint_if u_clint_if ();
clint_if #(.HartNum(2)) u_hp_clint_if ();
dma_req_if u_dma_req_if ();
apb4_if u_psram_mem_apb4_if (
.pclk (clk_mem_i),
@@ -221,8 +217,7 @@ axi4_stream_if #(
logic s_dma_xpi_tx_stall_mem;
logic s_dma_xpi_rx_stall_mem;
logic s_mailbox_lp_irq, s_mailbox_hp_irq;
logic [31:0] s_hp_plic_source;
logic [ 1:0] s_hp_plic_context_irq;
logic [15:0] s_hp_plic_source;
logic [ 3:0] s_unused_optional_status;
axi42apb4_periph u_axi42apb4_periph (
@@ -244,11 +239,8 @@ axi4_stream_if #(
assign u_dma_req_if.i2c1_rx_proc = ~s_dma_i2c1_rx_stall;
assign u_dma_req_if.crypto_in_proc = s_dma_crypto_in_proc;
assign u_dma_req_if.crypto_out_proc = s_dma_crypto_out_proc;
assign hp_time_o = u_hp_clint_if.mtime_o;
assign hp_timer_irq_o = u_hp_clint_if.timer_irq_o[1];
assign hp_software_irq_o = u_hp_clint_if.software_irq_o[1];
assign hp_machine_external_irq_o = s_hp_plic_context_irq[0];
assign hp_supervisor_external_irq_o = s_hp_plic_context_irq[1];
assign hp_time_o = u_clint_if.mtime_o;
assign hp_plic_src_o = s_hp_plic_source;
assign resource_irq_raw_o = {
s_npu_irq_raw,
s_ga2d_irq_raw,
@@ -389,24 +381,6 @@ axi4_stream_if #(
.hp_irq_o(s_mailbox_hp_irq)
);
apb4_clint #(
.HartNum(2)
) u_apb4_hp_aclint (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.timebase_tick_i(timebase_tick_i),
.apb4 (u_hp_aclint_apb4_if),
.clint (u_hp_clint_if)
);
apb4_plic u_apb4_hp_plic (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.source_i (s_hp_plic_source),
.apb4 (u_hp_plic_apb4_if),
.context_irq_o(s_hp_plic_context_irq)
);
apb4_timer u_apb4_timer0 (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
+3 -1
View File
@@ -304,7 +304,9 @@ module axi4_data_crossbar #(
endfunction
function automatic logic [CountWidth-1:0] master_write_limit(input int unsigned master);
if ((master == 1) || (master == 2) || (master == 7)) return CountWidth'(2);
// Master 0 is the merged HP core port (instruction and data); it inherits
// the retired HP data port's write credits. Master 1 is the retired slot.
if ((master == 0) || (master == 2) || (master == 7)) return CountWidth'(2);
if (((master >= 3) && (master <= 6)) || (master == 8) || (master == 9)) return CountWidth'(1);
return '0;
endfunction
+327
View File
@@ -0,0 +1,327 @@
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// SPDX-License-Identifier: MulanPSL-2.0
`include "axi4_define.svh"
// Serializing 128-bit to 64-bit AXI4 downsizer for the OpenC906 BIU master.
// Accepts one outstanding wide transaction per direction and emits legal
// narrow bursts. The C906 only issues size-4 INCR (len 1/4) and WRAP4 reads
// and size<=4 INCR writes, so no burst splitting is required: a size-4 wide
// burst maps to a doubled-length narrow burst (WRAP4x16B becomes WRAP8x8B).
module axi4_downsizer_128to64 #(
parameter int unsigned WideIdWidth = 8
) (
input logic clk_i,
input logic rst_n_i,
input logic clear_i,
axi4_if.slave wide,
axi4_if.master narrow
);
typedef enum logic {
Idle,
Active
} channel_state_e;
channel_state_e s_read_state_d, s_read_state_q;
channel_state_e s_write_state_d, s_write_state_q;
logic s_read_state_bits_q;
logic s_write_state_bits_q;
logic [WideIdWidth-1:0] s_read_id_d, s_read_id_q;
logic [WideIdWidth-1:0] s_write_id_d, s_write_id_q;
logic [2:0] s_read_size_d, s_read_size_q;
logic [2:0] s_write_size_d, s_write_size_q;
logic [31:0] s_read_addr_d, s_read_addr_q;
logic [31:0] s_write_addr_d, s_write_addr_q;
logic s_read_upper_d, s_read_upper_q;
logic s_write_upper_d, s_write_upper_q;
logic [63:0] s_read_lower_d, s_read_lower_q;
logic [1:0] s_read_resp_d, s_read_resp_q;
logic s_read_accept;
logic s_write_addr_accept;
logic s_narrow_read_accept;
logic s_narrow_write_accept;
logic s_wide_read_accept;
logic s_wide_write_accept;
logic s_b_pending_d, s_b_pending_q;
logic [1:0] s_b_resp_d, s_b_resp_q;
assign s_read_state_q = channel_state_e'(s_read_state_bits_q);
assign s_write_state_q = channel_state_e'(s_write_state_bits_q);
// Address channels are forwarded combinationally while idle; a size-4 wide
// burst doubles its beat count on the narrow side, all other transfers
// pass through unchanged.
assign wide.arready = (s_read_state_q == Idle) && narrow.arready;
assign narrow.arvalid = (s_read_state_q == Idle) && wide.arvalid;
assign narrow.arid = '0;
assign narrow.araddr = wide.araddr;
assign narrow.arlen = (wide.arsize == 3'd4) ? 8'((wide.arlen << 1) | 8'd1) : wide.arlen;
assign narrow.arsize = (wide.arsize == 3'd4) ? 3'd3 : wide.arsize;
assign narrow.arburst = wide.arburst;
assign narrow.arlock = wide.arlock;
assign narrow.arcache = wide.arcache;
assign narrow.arprot = wide.arprot;
assign narrow.arqos = wide.arqos;
assign narrow.arregion = wide.arregion;
assign narrow.aruser = '0;
assign s_read_accept = wide.arvalid && wide.arready;
assign wide.rid = s_read_id_q;
assign wide.rdata = (s_read_size_q == 3'd4) ? {narrow.rdata, s_read_lower_q} :
s_read_addr_q[3] ? {narrow.rdata, 64'd0} : {64'd0, narrow.rdata};
assign wide.rresp = (s_read_size_q == 3'd4) && (s_read_resp_q != `AXI4_RESP_OKAY) ?
s_read_resp_q : narrow.rresp;
assign wide.rlast = narrow.rlast;
assign wide.ruser = '0;
assign wide.rvalid = (s_read_state_q == Active) && narrow.rvalid &&
((s_read_size_q != 3'd4) || s_read_upper_q);
assign narrow.rready = (s_read_state_q == Active) &&
(((s_read_size_q == 3'd4) && !s_read_upper_q) || wide.rready);
assign s_narrow_read_accept = narrow.rvalid && narrow.rready;
assign s_wide_read_accept = wide.rvalid && wide.rready;
always_comb begin
s_read_state_d = s_read_state_q;
s_read_id_d = s_read_id_q;
s_read_size_d = s_read_size_q;
s_read_addr_d = s_read_addr_q;
s_read_upper_d = s_read_upper_q;
s_read_lower_d = s_read_lower_q;
s_read_resp_d = s_read_resp_q;
if (s_read_accept) begin
s_read_state_d = Active;
s_read_id_d = wide.arid;
s_read_size_d = wide.arsize;
s_read_addr_d = wide.araddr;
s_read_upper_d = 1'b0;
s_read_resp_d = `AXI4_RESP_OKAY;
end
if (s_narrow_read_accept && (s_read_size_q == 3'd4)) begin
if (!s_read_upper_q) begin
s_read_lower_d = narrow.rdata;
s_read_resp_d = narrow.rresp;
s_read_upper_d = 1'b1;
end else begin
s_read_upper_d = 1'b0;
s_read_resp_d = `AXI4_RESP_OKAY;
end
end
if (s_wide_read_accept && narrow.rlast) s_read_state_d = Idle;
if (clear_i) begin
s_read_state_d = Idle;
s_read_upper_d = 1'b0;
s_read_resp_d = `AXI4_RESP_OKAY;
end
end
assign wide.awready = (s_write_state_q == Idle) && narrow.awready;
assign narrow.awvalid = (s_write_state_q == Idle) && wide.awvalid;
assign narrow.awid = '0;
assign narrow.awaddr = wide.awaddr;
assign narrow.awlen = (wide.awsize == 3'd4) ? 8'((wide.awlen << 1) | 8'd1) : wide.awlen;
assign narrow.awsize = (wide.awsize == 3'd4) ? 3'd3 : wide.awsize;
assign narrow.awburst = wide.awburst;
assign narrow.awlock = wide.awlock;
assign narrow.awcache = wide.awcache;
assign narrow.awprot = wide.awprot;
assign narrow.awqos = wide.awqos;
assign narrow.awregion = wide.awregion;
assign narrow.awuser = '0;
assign s_write_addr_accept = wide.awvalid && wide.awready;
assign narrow.wdata = (s_write_size_q == 3'd4) ?
(s_write_upper_q ? wide.wdata[127:64] : wide.wdata[63:0]) :
(s_write_addr_q[3] ? wide.wdata[127:64] : wide.wdata[63:0]);
assign narrow.wstrb = (s_write_size_q == 3'd4) ?
(s_write_upper_q ? wide.wstrb[15:8] : wide.wstrb[7:0]) :
(s_write_addr_q[3] ? wide.wstrb[15:8] : wide.wstrb[7:0]);
assign narrow.wlast = (s_write_size_q != 3'd4) ? wide.wlast : s_write_upper_q && wide.wlast;
assign narrow.wuser = '0;
assign narrow.wvalid = (s_write_state_q == Active) && wide.wvalid;
assign wide.wready = (s_write_state_q == Active) && narrow.wready &&
((s_write_size_q != 3'd4) || s_write_upper_q);
assign s_narrow_write_accept = narrow.wvalid && narrow.wready;
assign s_wide_write_accept = wide.wvalid && wide.wready;
assign wide.bid = s_write_id_q;
assign wide.bresp = s_b_resp_q;
assign wide.buser = '0;
assign wide.bvalid = s_b_pending_q;
assign narrow.bready = (s_write_state_q == Active) && !s_b_pending_q;
always_comb begin
s_write_state_d = s_write_state_q;
s_write_id_d = s_write_id_q;
s_write_size_d = s_write_size_q;
s_write_addr_d = s_write_addr_q;
s_write_upper_d = s_write_upper_q;
s_b_pending_d = s_b_pending_q;
s_b_resp_d = s_b_resp_q;
if (s_write_addr_accept) begin
s_write_state_d = Active;
s_write_id_d = wide.awid;
s_write_size_d = wide.awsize;
s_write_addr_d = wide.awaddr;
s_write_upper_d = 1'b0;
s_b_pending_d = 1'b0;
end
if (s_narrow_write_accept && (s_write_size_q == 3'd4)) s_write_upper_d = !s_write_upper_q;
if (narrow.bvalid && narrow.bready) begin
s_b_pending_d = 1'b1;
s_b_resp_d = narrow.bresp;
end
if (wide.bvalid && wide.bready) begin
s_b_pending_d = 1'b0;
s_write_state_d = Idle;
end
if (clear_i) begin
s_write_state_d = Idle;
s_write_upper_d = 1'b0;
s_b_pending_d = 1'b0;
s_b_resp_d = `AXI4_RESP_OKAY;
end
end
dffr #(
.DATA_WIDTH(1)
) u_read_state_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_state_d),
.dat_o (s_read_state_bits_q)
);
dffr #(
.DATA_WIDTH(1)
) u_write_state_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_write_state_d),
.dat_o (s_write_state_bits_q)
);
dffr #(
.DATA_WIDTH(WideIdWidth)
) u_read_id_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_id_d),
.dat_o (s_read_id_q)
);
dffr #(
.DATA_WIDTH(WideIdWidth)
) u_write_id_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_write_id_d),
.dat_o (s_write_id_q)
);
dffr #(
.DATA_WIDTH(3)
) u_read_size_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_size_d),
.dat_o (s_read_size_q)
);
dffr #(
.DATA_WIDTH(3)
) u_write_size_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_write_size_d),
.dat_o (s_write_size_q)
);
dffr #(
.DATA_WIDTH(32)
) u_read_addr_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_addr_d),
.dat_o (s_read_addr_q)
);
dffr #(
.DATA_WIDTH(32)
) u_write_addr_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_write_addr_d),
.dat_o (s_write_addr_q)
);
dffr #(
.DATA_WIDTH(1)
) u_read_upper_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_upper_d),
.dat_o (s_read_upper_q)
);
dffr #(
.DATA_WIDTH(1)
) u_write_upper_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_write_upper_d),
.dat_o (s_write_upper_q)
);
dffr #(
.DATA_WIDTH(64)
) u_read_lower_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_lower_d),
.dat_o (s_read_lower_q)
);
dffr #(
.DATA_WIDTH(2)
) u_read_resp_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_resp_d),
.dat_o (s_read_resp_q)
);
dffr #(
.DATA_WIDTH(1)
) u_b_pending_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_b_pending_d),
.dat_o (s_b_pending_q)
);
dffr #(
.DATA_WIDTH(2)
) u_b_resp_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_b_resp_d),
.dat_o (s_b_resp_q)
);
`ifndef SYNTHESIS
property p_wide_read_geometry;
@(posedge clk_i) disable iff (!rst_n_i) wide.arvalid |->
((wide.arsize <= 3'd4) &&
((wide.arsize != 3'd4) ||
((wide.arlen <= 8'd15) && (wide.araddr[3:0] == 4'd0) &&
((wide.arburst != `AXI4_BURST_TYPE_WRAP) || (wide.arlen == 8'd3)))));
endproperty
assert property (p_wide_read_geometry);
property p_wide_write_geometry;
@(posedge clk_i) disable iff (!rst_n_i) wide.awvalid |->
((wide.awsize <= 3'd4) &&
((wide.awsize != 3'd4) ||
((wide.awlen <= 8'd15) && (wide.awaddr[3:0] == 4'd0) &&
(wide.awburst == `AXI4_BURST_TYPE_INCR))));
endproperty
assert property (p_wide_write_geometry);
`endif
endmodule
+203
View File
@@ -0,0 +1,203 @@
// Copyright (c) 2026 Yuchi Miao <miaoyuchi@ict.ac.cn>
// SPDX-License-Identifier: MulanPSL-2.0
`include "axi4_define.svh"
// Routes the single OpenC906 64-bit data stream between the HP data fabric
// and the MMIO chain by address window. The upstream master is the
// serializing axi4_downsizer_128to64, so at most one read and one write are
// outstanding at any time; the routing decision is registered at the address
// handshake and held until the response completes.
module axi4_mmio_demux #(
parameter logic [31:0] MmioBase = 32'h0200_0000,
parameter logic [31:0] MmioLimit = 32'h3000_0000
) (
input logic clk_i,
input logic rst_n_i,
input logic clear_i,
axi4_if.slave source,
axi4_if.master mem,
axi4_if.master mmio
);
typedef enum logic {
Idle,
Active
} channel_state_e;
channel_state_e s_read_state_d, s_read_state_q;
channel_state_e s_write_state_d, s_write_state_q;
logic s_read_state_bits_q;
logic s_write_state_bits_q;
logic s_read_sel_d, s_read_sel_q;
logic s_write_sel_d, s_write_sel_q;
logic s_read_route_mmio;
logic s_write_route_mmio;
logic s_read_accept;
logic s_write_accept;
logic s_read_done;
logic s_write_done;
assign s_read_state_q = channel_state_e'(s_read_state_bits_q);
assign s_write_state_q = channel_state_e'(s_write_state_bits_q);
assign s_read_route_mmio = (source.araddr >= MmioBase) && (source.araddr < MmioLimit);
assign s_write_route_mmio = (source.awaddr >= MmioBase) && (source.awaddr < MmioLimit);
assign source.arready = (s_read_state_q == Idle) &&
(s_read_route_mmio ? mmio.arready : mem.arready);
assign mem.arvalid = (s_read_state_q == Idle) && !s_read_route_mmio && source.arvalid;
assign mmio.arvalid = (s_read_state_q == Idle) && s_read_route_mmio && source.arvalid;
assign mem.arid = source.arid;
assign mmio.arid = source.arid;
assign mem.araddr = source.araddr;
assign mmio.araddr = source.araddr;
assign mem.arlen = source.arlen;
assign mmio.arlen = source.arlen;
assign mem.arsize = source.arsize;
assign mmio.arsize = source.arsize;
assign mem.arburst = source.arburst;
assign mmio.arburst = source.arburst;
assign mem.arlock = source.arlock;
assign mmio.arlock = source.arlock;
assign mem.arcache = source.arcache;
assign mmio.arcache = source.arcache;
assign mem.arprot = source.arprot;
assign mmio.arprot = source.arprot;
assign mem.arqos = source.arqos;
assign mmio.arqos = source.arqos;
assign mem.arregion = source.arregion;
assign mmio.arregion = source.arregion;
assign mem.aruser = source.aruser;
assign mmio.aruser = source.aruser;
assign s_read_accept = source.arvalid && source.arready;
assign source.rid = s_read_sel_q ? mmio.rid : mem.rid;
assign source.rdata = s_read_sel_q ? mmio.rdata : mem.rdata;
assign source.rresp = s_read_sel_q ? mmio.rresp : mem.rresp;
assign source.rlast = s_read_sel_q ? mmio.rlast : mem.rlast;
assign source.ruser = s_read_sel_q ? mmio.ruser : mem.ruser;
assign source.rvalid = (s_read_state_q == Active) && (s_read_sel_q ? mmio.rvalid : mem.rvalid);
assign mem.rready = (s_read_state_q == Active) && !s_read_sel_q && source.rready;
assign mmio.rready = (s_read_state_q == Active) && s_read_sel_q && source.rready;
assign s_read_done = source.rvalid && source.rready && source.rlast;
assign source.awready = (s_write_state_q == Idle) &&
(s_write_route_mmio ? mmio.awready : mem.awready);
assign mem.awvalid = (s_write_state_q == Idle) && !s_write_route_mmio && source.awvalid;
assign mmio.awvalid = (s_write_state_q == Idle) && s_write_route_mmio && source.awvalid;
assign mem.awid = source.awid;
assign mmio.awid = source.awid;
assign mem.awaddr = source.awaddr;
assign mmio.awaddr = source.awaddr;
assign mem.awlen = source.awlen;
assign mmio.awlen = source.awlen;
assign mem.awsize = source.awsize;
assign mmio.awsize = source.awsize;
assign mem.awburst = source.awburst;
assign mmio.awburst = source.awburst;
assign mem.awlock = source.awlock;
assign mmio.awlock = source.awlock;
assign mem.awcache = source.awcache;
assign mmio.awcache = source.awcache;
assign mem.awprot = source.awprot;
assign mmio.awprot = source.awprot;
assign mem.awqos = source.awqos;
assign mmio.awqos = source.awqos;
assign mem.awregion = source.awregion;
assign mmio.awregion = source.awregion;
assign mem.awuser = source.awuser;
assign mmio.awuser = source.awuser;
assign s_write_accept = source.awvalid && source.awready;
// AXI4 has no WID; with a single outstanding write the W channel follows
// the registered address routing until WLAST.
assign mem.wdata = source.wdata;
assign mmio.wdata = source.wdata;
assign mem.wstrb = source.wstrb;
assign mmio.wstrb = source.wstrb;
assign mem.wlast = source.wlast;
assign mmio.wlast = source.wlast;
assign mem.wuser = source.wuser;
assign mmio.wuser = source.wuser;
assign mem.wvalid = (s_write_state_q == Active) && !s_write_sel_q && source.wvalid;
assign mmio.wvalid = (s_write_state_q == Active) && s_write_sel_q && source.wvalid;
assign source.wready = (s_write_state_q == Active) && (s_write_sel_q ? mmio.wready : mem.wready);
assign source.bid = s_write_sel_q ? mmio.bid : mem.bid;
assign source.bresp = s_write_sel_q ? mmio.bresp : mem.bresp;
assign source.buser = s_write_sel_q ? mmio.buser : mem.buser;
assign source.bvalid = (s_write_state_q == Active) && (s_write_sel_q ? mmio.bvalid : mem.bvalid);
assign mem.bready = (s_write_state_q == Active) && !s_write_sel_q && source.bready;
assign mmio.bready = (s_write_state_q == Active) && s_write_sel_q && source.bready;
assign s_write_done = source.bvalid && source.bready;
always_comb begin
s_read_state_d = s_read_state_q;
s_read_sel_d = s_read_sel_q;
if (s_read_accept) begin
s_read_state_d = Active;
s_read_sel_d = s_read_route_mmio;
end
if (s_read_done) s_read_state_d = Idle;
if (clear_i) s_read_state_d = Idle;
end
always_comb begin
s_write_state_d = s_write_state_q;
s_write_sel_d = s_write_sel_q;
if (s_write_accept) begin
s_write_state_d = Active;
s_write_sel_d = s_write_route_mmio;
end
if (s_write_done) s_write_state_d = Idle;
if (clear_i) s_write_state_d = Idle;
end
dffr #(
.DATA_WIDTH(1)
) u_read_state_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_state_d),
.dat_o (s_read_state_bits_q)
);
dffr #(
.DATA_WIDTH(1)
) u_write_state_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_write_state_d),
.dat_o (s_write_state_bits_q)
);
dffr #(
.DATA_WIDTH(1)
) u_read_sel_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_read_sel_d),
.dat_o (s_read_sel_q)
);
dffr #(
.DATA_WIDTH(1)
) u_write_sel_dffr (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.dat_i (s_write_sel_d),
.dat_o (s_write_sel_q)
);
`ifndef SYNTHESIS
property p_single_outstanding_read;
@(posedge clk_i) disable iff (!rst_n_i) source.arvalid |-> (s_read_state_q == Idle);
endproperty
assert property (p_single_outstanding_read);
property p_single_outstanding_write;
@(posedge clk_i) disable iff (!rst_n_i) source.awvalid |-> (s_write_state_q == Idle);
endproperty
assert property (p_single_outstanding_write);
`endif
endmodule
+234 -144
View File
@@ -3,167 +3,257 @@
`include "axi4_define.svh"
// OpenC906 HP core integration.
//
// Contract (docs/ip/hp-platform.md):
// - Reset vector 0x38000000 (pad_cpu_rvba), internal CLINT/PLIC window at
// 0x08000000 (pad_cpu_apb_base; 128 MiB aligned, decoded inside the BIU,
// never reaches the external bus).
// - Single 128-bit AXI4 master, downsized to the 64-bit HP fabric and split
// into the data-fabric port and the MMIO port by address window.
// - mhartid reports 1 via the controlled aq_sysio_kid.v override (LP is
// hart 0). SoC interrupt source n drives pad_plic_int_vld[n] and appears
// to software as PLIC ID n+16.
// - The JTAG DTM (tdt_dmi_top) runs on a divide-by-2 sys_apb clock; its
// hartreset request participates in the core reset so debugger resets
// preserve the existing lifecycle semantics.
// - No low-power or DFT support: scan/mbist inputs are tied off and the
// debug SBA AXI master is left unconnected.
module hp_core_wrapper (
// verilog_format: off -- preserve generated-core boundary alignment
// verilog_format: off -- preserve the HP integration boundary alignment
input logic clk_i,
input logic rst_n_i,
input logic core_reset_i,
input logic [63:0] time_i,
input logic timer_irq_i,
input logic software_irq_i,
input logic machine_external_irq_i,
input logic supervisor_external_irq_i,
input logic [15:0] plic_src_i,
input logic jtag_tck_i,
input logic jtag_tms_i,
input logic jtag_tdi_i,
input logic jtag_trst_n_i,
output logic jtag_tdo_o,
output logic debug_reset_req_o,
axi4_if.master icache_axi4,
axi4_if.master dcache_axi4,
axi4_if.master mem_axi4,
axi4_if.master mmio_axi4
// verilog_format: on
);
logic s_unused_debug_stoptime;
localparam logic [39:0] HpResetVector = 40'h00_3800_0000;
localparam logic [39:0] HpApbBase = 40'h00_0800_0000;
assign icache_axi4.awid = '0;
assign icache_axi4.awaddr = '0;
assign icache_axi4.awlen = '0;
assign icache_axi4.awsize = '0;
assign icache_axi4.awburst = '0;
assign icache_axi4.awlock = '0;
assign icache_axi4.awcache = '0;
assign icache_axi4.awprot = '0;
assign icache_axi4.awqos = '0;
assign icache_axi4.awregion = '0;
assign icache_axi4.awuser = '0;
assign icache_axi4.awvalid = 1'b0;
assign icache_axi4.wdata = '0;
assign icache_axi4.wstrb = '0;
assign icache_axi4.wlast = 1'b0;
assign icache_axi4.wuser = '0;
assign icache_axi4.wvalid = 1'b0;
assign icache_axi4.bready = 1'b1;
logic s_sys_apb_clk;
logic s_sys_apb_rst_b;
logic s_core_rst_b;
logic s_hartreset_n;
logic s_ndmreset_n;
logic s_dtm_tdo;
logic s_dtm_tdo_en;
logic [11:0] s_dmi_paddr;
logic s_dmi_psel;
logic s_dmi_penable;
logic s_dmi_pwrite;
logic [31:0] s_dmi_pwdata;
logic [31:0] s_dmi_prdata;
logic s_dmi_pready;
logic s_dmi_pslverr;
// The C906 drives 40-bit addresses; the Mini HP fabric is 32-bit physical.
logic [39:0] s_c906_araddr;
logic [39:0] s_c906_awaddr;
// verilog_format: off -- generated VexiiRiscv ports are upstream ABI
vexii_riscv_hp_generated u_vexii_riscv_hp_generated (
.EmbeddedRiscvJtag_logic_jtag_tms (jtag_tms_i),
.EmbeddedRiscvJtag_logic_jtag_tdi (jtag_tdi_i),
.EmbeddedRiscvJtag_logic_jtag_tdo (jtag_tdo_o),
.EmbeddedRiscvJtag_logic_jtag_tck (jtag_tck_i),
.EmbeddedRiscvJtag_logic_ndmreset (debug_reset_req_o),
.LsuL1Axi4Plugin_logic_axi_aw_valid (dcache_axi4.awvalid),
.LsuL1Axi4Plugin_logic_axi_aw_ready (dcache_axi4.awready),
.LsuL1Axi4Plugin_logic_axi_aw_payload_addr (dcache_axi4.awaddr),
.LsuL1Axi4Plugin_logic_axi_aw_payload_id (dcache_axi4.awid),
.LsuL1Axi4Plugin_logic_axi_aw_payload_len (dcache_axi4.awlen),
.LsuL1Axi4Plugin_logic_axi_aw_payload_size (dcache_axi4.awsize),
.LsuL1Axi4Plugin_logic_axi_aw_payload_burst (dcache_axi4.awburst),
.LsuL1Axi4Plugin_logic_axi_aw_payload_cache (dcache_axi4.awcache),
.LsuL1Axi4Plugin_logic_axi_aw_payload_prot (dcache_axi4.awprot),
.LsuL1Axi4Plugin_logic_axi_w_valid (dcache_axi4.wvalid),
.LsuL1Axi4Plugin_logic_axi_w_ready (dcache_axi4.wready),
.LsuL1Axi4Plugin_logic_axi_w_payload_data (dcache_axi4.wdata),
.LsuL1Axi4Plugin_logic_axi_w_payload_strb (dcache_axi4.wstrb),
.LsuL1Axi4Plugin_logic_axi_w_payload_last (dcache_axi4.wlast),
.LsuL1Axi4Plugin_logic_axi_b_valid (dcache_axi4.bvalid),
.LsuL1Axi4Plugin_logic_axi_b_ready (dcache_axi4.bready),
.LsuL1Axi4Plugin_logic_axi_b_payload_id (dcache_axi4.bid),
.LsuL1Axi4Plugin_logic_axi_b_payload_resp (dcache_axi4.bresp),
.LsuL1Axi4Plugin_logic_axi_ar_valid (dcache_axi4.arvalid),
.LsuL1Axi4Plugin_logic_axi_ar_ready (dcache_axi4.arready),
.LsuL1Axi4Plugin_logic_axi_ar_payload_addr (dcache_axi4.araddr),
.LsuL1Axi4Plugin_logic_axi_ar_payload_id (dcache_axi4.arid),
.LsuL1Axi4Plugin_logic_axi_ar_payload_len (dcache_axi4.arlen),
.LsuL1Axi4Plugin_logic_axi_ar_payload_size (dcache_axi4.arsize),
.LsuL1Axi4Plugin_logic_axi_ar_payload_burst (dcache_axi4.arburst),
.LsuL1Axi4Plugin_logic_axi_ar_payload_cache (dcache_axi4.arcache),
.LsuL1Axi4Plugin_logic_axi_ar_payload_prot (dcache_axi4.arprot),
.LsuL1Axi4Plugin_logic_axi_r_valid (dcache_axi4.rvalid),
.LsuL1Axi4Plugin_logic_axi_r_ready (dcache_axi4.rready),
.LsuL1Axi4Plugin_logic_axi_r_payload_data (dcache_axi4.rdata),
.LsuL1Axi4Plugin_logic_axi_r_payload_id (dcache_axi4.rid),
.LsuL1Axi4Plugin_logic_axi_r_payload_resp (dcache_axi4.rresp),
.LsuL1Axi4Plugin_logic_axi_r_payload_last (dcache_axi4.rlast),
.PrivilegedPlugin_logic_rdtime (time_i),
.PrivilegedPlugin_logic_harts_0_int_m_timer (timer_irq_i),
.PrivilegedPlugin_logic_harts_0_int_m_software (software_irq_i),
.PrivilegedPlugin_logic_harts_0_int_m_external (machine_external_irq_i),
.PrivilegedPlugin_logic_harts_0_int_s_external (supervisor_external_irq_i),
.FetchL1Axi4Plugin_logic_axi_ar_valid (icache_axi4.arvalid),
.FetchL1Axi4Plugin_logic_axi_ar_ready (icache_axi4.arready),
.FetchL1Axi4Plugin_logic_axi_ar_payload_addr (icache_axi4.araddr),
.FetchL1Axi4Plugin_logic_axi_ar_payload_id (icache_axi4.arid[0]),
.FetchL1Axi4Plugin_logic_axi_ar_payload_len (icache_axi4.arlen),
.FetchL1Axi4Plugin_logic_axi_ar_payload_size (icache_axi4.arsize),
.FetchL1Axi4Plugin_logic_axi_ar_payload_burst (icache_axi4.arburst),
.FetchL1Axi4Plugin_logic_axi_ar_payload_cache (icache_axi4.arcache),
.FetchL1Axi4Plugin_logic_axi_ar_payload_prot (icache_axi4.arprot),
.FetchL1Axi4Plugin_logic_axi_r_valid (icache_axi4.rvalid),
.FetchL1Axi4Plugin_logic_axi_r_ready (icache_axi4.rready),
.FetchL1Axi4Plugin_logic_axi_r_payload_data (icache_axi4.rdata),
.FetchL1Axi4Plugin_logic_axi_r_payload_id (icache_axi4.rid[0]),
.FetchL1Axi4Plugin_logic_axi_r_payload_resp (icache_axi4.rresp),
.FetchL1Axi4Plugin_logic_axi_r_payload_last (icache_axi4.rlast),
.PrivilegedPlugin_logic_harts_0_debug_stoptime (s_unused_debug_stoptime),
.LsuCachelessAxi4Plugin_logic_axi_aw_valid (mmio_axi4.awvalid),
.LsuCachelessAxi4Plugin_logic_axi_aw_ready (mmio_axi4.awready),
.LsuCachelessAxi4Plugin_logic_axi_aw_payload_addr (mmio_axi4.awaddr),
.LsuCachelessAxi4Plugin_logic_axi_aw_payload_size (mmio_axi4.awsize),
.LsuCachelessAxi4Plugin_logic_axi_aw_payload_cache (mmio_axi4.awcache),
.LsuCachelessAxi4Plugin_logic_axi_aw_payload_prot (mmio_axi4.awprot),
.LsuCachelessAxi4Plugin_logic_axi_w_valid (mmio_axi4.wvalid),
.LsuCachelessAxi4Plugin_logic_axi_w_ready (mmio_axi4.wready),
.LsuCachelessAxi4Plugin_logic_axi_w_payload_data (mmio_axi4.wdata),
.LsuCachelessAxi4Plugin_logic_axi_w_payload_strb (mmio_axi4.wstrb),
.LsuCachelessAxi4Plugin_logic_axi_w_payload_last (mmio_axi4.wlast),
.LsuCachelessAxi4Plugin_logic_axi_b_valid (mmio_axi4.bvalid),
.LsuCachelessAxi4Plugin_logic_axi_b_ready (mmio_axi4.bready),
.LsuCachelessAxi4Plugin_logic_axi_b_payload_resp (mmio_axi4.bresp),
.LsuCachelessAxi4Plugin_logic_axi_ar_valid (mmio_axi4.arvalid),
.LsuCachelessAxi4Plugin_logic_axi_ar_ready (mmio_axi4.arready),
.LsuCachelessAxi4Plugin_logic_axi_ar_payload_addr (mmio_axi4.araddr),
.LsuCachelessAxi4Plugin_logic_axi_ar_payload_size (mmio_axi4.arsize),
.LsuCachelessAxi4Plugin_logic_axi_ar_payload_cache (mmio_axi4.arcache),
.LsuCachelessAxi4Plugin_logic_axi_ar_payload_prot (mmio_axi4.arprot),
.LsuCachelessAxi4Plugin_logic_axi_r_valid (mmio_axi4.rvalid),
.LsuCachelessAxi4Plugin_logic_axi_r_ready (mmio_axi4.rready),
.LsuCachelessAxi4Plugin_logic_axi_r_payload_data (mmio_axi4.rdata),
.LsuCachelessAxi4Plugin_logic_axi_r_payload_resp (mmio_axi4.rresp),
.LsuCachelessAxi4Plugin_logic_axi_r_payload_last (mmio_axi4.rlast),
.clk (clk_i),
.reset (!rst_n_i || core_reset_i),
.EmbeddedRiscvJtag_logic_debug_reset (!jtag_trst_n_i)
axi4_if #(
.ADDR_WIDTH(32),
.DATA_WIDTH(128),
.ID_WIDTH (8),
.USER_WIDTH(1)
) u_c906_axi4_if (
.aclk (clk_i),
.aresetn(rst_n_i)
);
axi4_if #(
.ADDR_WIDTH(32),
.DATA_WIDTH(64),
.ID_WIDTH (3),
.USER_WIDTH(1)
) u_hp_64_axi4_if (
.aclk (clk_i),
.aresetn(rst_n_i)
);
// The debug module clock must be slower than the core clock; divide the
// core clock by two (JTAG tck is always slower still).
clk_int_even_div_static #(
.DIV_VALUE_WIDTH(1)
) u_sys_apb_clk_div (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.clk_o (s_sys_apb_clk)
);
// The debug module lives in the JTAG reset domain so that a lifecycle
// reset of the core does not detach the debugger; the DM hartreset
// request joins the core reset exactly like the previous ndmreset path.
assign s_sys_apb_rst_b = rst_n_i && jtag_trst_n_i;
assign s_core_rst_b = rst_n_i && !core_reset_i && s_hartreset_n;
assign debug_reset_req_o = !s_ndmreset_n;
assign jtag_tdo_o = s_dtm_tdo && s_dtm_tdo_en;
// verilog_format: off -- vendored OpenC906 ports are upstream ABI
openC906 u_openc906 (
.pll_core_cpuclk (clk_i),
.axim_clk_en (1'b1),
.sys_apb_clk (s_sys_apb_clk),
.sys_apb_rst_b (s_sys_apb_rst_b),
.pad_cpu_rst_b (s_core_rst_b),
.pad_cpu_rvba (HpResetVector),
.pad_cpu_apb_base (HpApbBase),
.pad_cpu_sys_cnt (time_i),
.pad_plic_int_vld ({224'd0, plic_src_i}),
.pad_plic_int_cfg (240'd0),
.biu_pad_araddr (s_c906_araddr),
.biu_pad_arburst (u_c906_axi4_if.arburst),
.biu_pad_arcache (u_c906_axi4_if.arcache),
.biu_pad_arid (u_c906_axi4_if.arid),
.biu_pad_arlen (u_c906_axi4_if.arlen),
.biu_pad_arlock (u_c906_axi4_if.arlock),
.biu_pad_arprot (u_c906_axi4_if.arprot),
.biu_pad_arsize (u_c906_axi4_if.arsize),
.biu_pad_arvalid (u_c906_axi4_if.arvalid),
.biu_pad_awaddr (s_c906_awaddr),
.biu_pad_awburst (u_c906_axi4_if.awburst),
.biu_pad_awcache (u_c906_axi4_if.awcache),
.biu_pad_awid (u_c906_axi4_if.awid),
.biu_pad_awlen (u_c906_axi4_if.awlen),
.biu_pad_awlock (u_c906_axi4_if.awlock),
.biu_pad_awprot (u_c906_axi4_if.awprot),
.biu_pad_awsize (u_c906_axi4_if.awsize),
.biu_pad_awvalid (u_c906_axi4_if.awvalid),
.biu_pad_bready (u_c906_axi4_if.bready),
.biu_pad_rready (u_c906_axi4_if.rready),
.biu_pad_wdata (u_c906_axi4_if.wdata),
.biu_pad_wlast (u_c906_axi4_if.wlast),
.biu_pad_wstrb (u_c906_axi4_if.wstrb),
.biu_pad_wvalid (u_c906_axi4_if.wvalid),
.pad_biu_arready (u_c906_axi4_if.arready),
.pad_biu_awready (u_c906_axi4_if.awready),
.pad_biu_bid (u_c906_axi4_if.bid),
.pad_biu_bresp (u_c906_axi4_if.bresp),
.pad_biu_bvalid (u_c906_axi4_if.bvalid),
.pad_biu_rdata (u_c906_axi4_if.rdata),
.pad_biu_rid (u_c906_axi4_if.rid),
.pad_biu_rlast (u_c906_axi4_if.rlast),
.pad_biu_rresp (u_c906_axi4_if.rresp),
.pad_biu_rvalid (u_c906_axi4_if.rvalid),
.pad_biu_wready (u_c906_axi4_if.wready),
.pad_tdt_dm_arready (1'b0),
.pad_tdt_dm_awready (1'b0),
.pad_tdt_dm_bid (4'd0),
.pad_tdt_dm_bresp (2'd0),
.pad_tdt_dm_bvalid (1'b0),
.pad_tdt_dm_core_unavail(1'b0),
.pad_tdt_dm_rdata (128'd0),
.pad_tdt_dm_rid (4'd0),
.pad_tdt_dm_rlast (1'b0),
.pad_tdt_dm_rresp (2'd0),
.pad_tdt_dm_rvalid (1'b0),
.pad_tdt_dm_wready (1'b0),
.pad_yy_dft_clk_rst_b (rst_n_i),
.pad_yy_icg_scan_en (1'b0),
.pad_yy_mbist_mode (1'b0),
.pad_yy_scan_enable (1'b0),
.pad_yy_scan_mode (1'b0),
.pad_yy_scan_rst_b (1'b1),
.core0_pad_halted (),
.core0_pad_lpmd_b (),
.core0_pad_retire (),
.core0_pad_retire_pc (),
.cpu_debug_port (),
.tdt_dm_pad_araddr (),
.tdt_dm_pad_arburst (),
.tdt_dm_pad_arcache (),
.tdt_dm_pad_arid (),
.tdt_dm_pad_arlen (),
.tdt_dm_pad_arlock (),
.tdt_dm_pad_arprot (),
.tdt_dm_pad_arsize (),
.tdt_dm_pad_arvalid (),
.tdt_dm_pad_awaddr (),
.tdt_dm_pad_awburst (),
.tdt_dm_pad_awcache (),
.tdt_dm_pad_awid (),
.tdt_dm_pad_awlen (),
.tdt_dm_pad_awlock (),
.tdt_dm_pad_awprot (),
.tdt_dm_pad_awsize (),
.tdt_dm_pad_awvalid (),
.tdt_dm_pad_bready (),
.tdt_dm_pad_hartreset_n(s_hartreset_n),
.tdt_dm_pad_ndmreset_n (s_ndmreset_n),
.tdt_dm_pad_rready (),
.tdt_dm_pad_wdata (),
.tdt_dm_pad_wlast (),
.tdt_dm_pad_wstrb (),
.tdt_dm_pad_wvalid (),
.tdt_dmi_paddr (s_dmi_paddr),
.tdt_dmi_penable (s_dmi_penable),
.tdt_dmi_prdata (s_dmi_prdata),
.tdt_dmi_pready (s_dmi_pready),
.tdt_dmi_psel (s_dmi_psel),
.tdt_dmi_pslverr (s_dmi_pslverr),
.tdt_dmi_pwdata (s_dmi_pwdata),
.tdt_dmi_pwrite (s_dmi_pwrite)
);
tdt_dmi_top u_tdt_dmi_top (
.pad_tdt_dtm_jtag2_sel(1'b0),
.pad_tdt_dtm_tap_en (1'b1),
.pad_tdt_dtm_tclk (jtag_tck_i),
.pad_tdt_dtm_tdi (jtag_tdi_i),
.pad_tdt_dtm_tms_i (jtag_tms_i),
.pad_tdt_dtm_trst_b (jtag_trst_n_i),
.pad_tdt_icg_scan_en (1'b0),
.pad_yy_scan_mode (1'b0),
.pad_yy_scan_rst_b (1'b1),
.sys_apb_clk (s_sys_apb_clk),
.sys_apb_rst_b (s_sys_apb_rst_b),
.tdt_dmi_paddr (s_dmi_paddr),
.tdt_dmi_penable (s_dmi_penable),
.tdt_dmi_prdata (s_dmi_prdata),
.tdt_dmi_pready (s_dmi_pready),
.tdt_dmi_psel (s_dmi_psel),
.tdt_dmi_pslverr (s_dmi_pslverr),
.tdt_dmi_pwdata (s_dmi_pwdata),
.tdt_dmi_pwrite (s_dmi_pwrite),
.tdt_dtm_pad_tdo (s_dtm_tdo),
.tdt_dtm_pad_tdo_en (s_dtm_tdo_en),
.tdt_dtm_pad_tms_o (),
.tdt_dtm_pad_tms_oe ()
);
// verilog_format: on
assign icache_axi4.arid[2:1] = '0;
assign icache_axi4.arlock = 1'b0;
assign icache_axi4.arqos = '0;
assign icache_axi4.arregion = '0;
assign icache_axi4.aruser = '0;
assign dcache_axi4.awlock = 1'b0;
assign dcache_axi4.awqos = '0;
assign dcache_axi4.awregion = '0;
assign dcache_axi4.awuser = '0;
assign dcache_axi4.wuser = '0;
assign dcache_axi4.arlock = 1'b0;
assign dcache_axi4.arqos = '0;
assign dcache_axi4.arregion = '0;
assign dcache_axi4.aruser = '0;
assign mmio_axi4.awid = '0;
assign mmio_axi4.awlen = '0;
assign mmio_axi4.awburst = `AXI4_BURST_TYPE_INCR;
assign mmio_axi4.awlock = 1'b0;
assign mmio_axi4.awqos = '0;
assign mmio_axi4.awregion = '0;
assign mmio_axi4.awuser = '0;
assign mmio_axi4.wuser = '0;
assign mmio_axi4.arid = '0;
assign mmio_axi4.arlen = '0;
assign mmio_axi4.arburst = `AXI4_BURST_TYPE_INCR;
assign mmio_axi4.arlock = 1'b0;
assign mmio_axi4.arqos = '0;
assign mmio_axi4.arregion = '0;
assign mmio_axi4.aruser = '0;
assign u_c906_axi4_if.araddr = s_c906_araddr[31:0];
assign u_c906_axi4_if.awaddr = s_c906_awaddr[31:0];
// The C906 BIU has no qos/region/user sidebands; tie the interface fields.
assign u_c906_axi4_if.arqos = '0;
assign u_c906_axi4_if.arregion = '0;
assign u_c906_axi4_if.aruser = '0;
assign u_c906_axi4_if.awqos = '0;
assign u_c906_axi4_if.awregion = '0;
assign u_c906_axi4_if.awuser = '0;
assign u_c906_axi4_if.wuser = '0;
axi4_downsizer_128to64 u_hp_downsizer (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.clear_i(core_reset_i),
.wide (u_c906_axi4_if),
.narrow (u_hp_64_axi4_if)
);
axi4_mmio_demux u_hp_mmio_demux (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.clear_i(core_reset_i),
.source (u_hp_64_axi4_if),
.mem (mem_axi4),
.mmio (mmio_axi4)
);
endmodule
+15 -23
View File
@@ -7,38 +7,30 @@ module hp_subsystem (
input logic rst_n_i,
input logic core_reset_i,
input logic [63:0] time_i,
input logic timer_irq_i,
input logic software_irq_i,
input logic machine_external_irq_i,
input logic supervisor_external_irq_i,
input logic [15:0] plic_src_i,
input logic jtag_tck_i,
input logic jtag_tms_i,
input logic jtag_tdi_i,
input logic jtag_trst_n_i,
output logic jtag_tdo_o,
output logic debug_reset_req_o,
axi4_if.master icache_axi4,
axi4_if.master dcache_axi4,
axi4_if.master mem_axi4,
axi4_if.master mmio_axi4
// verilog_format: on
);
hp_core_wrapper u_hp_core_wrapper (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.core_reset_i (core_reset_i),
.time_i (time_i),
.timer_irq_i (timer_irq_i),
.software_irq_i (software_irq_i),
.machine_external_irq_i (machine_external_irq_i),
.supervisor_external_irq_i(supervisor_external_irq_i),
.jtag_tck_i (jtag_tck_i),
.jtag_tms_i (jtag_tms_i),
.jtag_tdi_i (jtag_tdi_i),
.jtag_trst_n_i (jtag_trst_n_i),
.jtag_tdo_o (jtag_tdo_o),
.debug_reset_req_o (debug_reset_req_o),
.icache_axi4 (icache_axi4),
.dcache_axi4 (dcache_axi4),
.mmio_axi4 (mmio_axi4)
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.core_reset_i (core_reset_i),
.time_i (time_i),
.plic_src_i (plic_src_i),
.jtag_tck_i (jtag_tck_i),
.jtag_tms_i (jtag_tms_i),
.jtag_tdi_i (jtag_tdi_i),
.jtag_trst_n_i (jtag_trst_n_i),
.jtag_tdo_o (jtag_tdo_o),
.debug_reset_req_o(debug_reset_req_o),
.mem_axi4 (mem_axi4),
.mmio_axi4 (mmio_axi4)
);
endmodule
Loaded 100 of 133 files, more files were not shown because too many files have changed in this diff. Show more