feat: enhance booter output, add reset hold time, and implement patching for serv state

This commit is contained in:
maksyuki committed 2026-08-22 12:52:20 +08:00
1 parent 8276903600
commit d9f7145592
6 files changed
+132 -26

No files matched your search

+46 -9
View File
@@ -56,7 +56,34 @@ void rs_app_info(void) {
printf(" specs: Gen2 Plus\n"); printf(" specs: Gen2 Plus\n");
printf(" version: %s(commit: %s)\n\n", RETROSOC_BRANCH, RETROSOC_COMMIT); printf(" version: %s(commit: %s)\n\n", RETROSOC_BRANCH, RETROSOC_COMMIT);
printf("User Processors:\n"); printf("SoC Architecture:\n");
printf(" +--------------+ +--------------+ +--------------+\n");
printf(" | Hazard3 Mgmt | | Selected User| | DMA |\n");
printf(" | JTAG + AHB | | AXI4 Master | | AXI4/Stream |\n");
printf(" +------+-------+ +------+-------+ +------+-------+\n");
printf(" v | |\n");
printf(" +------+-------+ | |\n");
printf(" | AHB-Lite2AXI4| | |\n");
printf(" +------+-------+ | |\n");
printf(" +-----------------+-----------------+\n");
printf(" v\n");
printf(" +-------+-------+\n");
printf(" | AXI4 Fabric |\n");
printf(" +-------+-------+\n");
printf(" |\n");
printf(" +-----------------+-----------------+\n");
printf(" | | |\n");
printf(" +------v-----+ +------v-----+ +------v-----+\n");
printf(" | Memories | | APB4 Config| | APB4 System|\n");
printf(" | SRAM / Ext | | Peripherals| | User IP |\n");
printf(" +------------+ +------------+ +------------+\n");
printf("\nManagement Processor:\n");
printf(" %-15s %-12s %-12s %s\n", "[name]", "[isa]", "[maintainer]", "[repo]");
printf("=>[0]: %-15s %-12s %-12s %s\n", "Hazard3", "rv32imac", "Wren6991",
"https://github.com/Wren6991/Hazard3");
printf("\nUser Processors:\n");
uint32_t core_size = sizeof(user_core_info) / sizeof(user_core_info[0]); uint32_t core_size = sizeof(user_core_info) / sizeof(user_core_info[0]);
printf(" %-15s %-12s %-12s %s\n", "[name]", "[isa]", "[maintainer]", "[repo]"); printf(" %-15s %-12s %-12s %s\n", "[name]", "[isa]", "[maintainer]", "[repo]");
for (uint32_t i = 0; i < core_size; ++i) { for (uint32_t i = 0; i < core_size; ++i) {
@@ -99,12 +126,12 @@ void rs_app_info(void) {
PSRAM_MEM_START + PSRAM_MEM_OFFST - 1, PSRAM_MEM_OFFST / 1024 / 1024); PSRAM_MEM_START + PSRAM_MEM_OFFST - 1, PSRAM_MEM_OFFST / 1024 / 1024);
printf(" XPI MMIO: @[0x%08x-0x%08x] %3d MiB\n", XPI_MEM_START, printf(" XPI MMIO: @[0x%08x-0x%08x] %3d MiB\n", XPI_MEM_START,
XPI_MEM_START + XPI_MEM_OFFST - 1, XPI_MEM_OFFST / 1024 / 1024); XPI_MEM_START + XPI_MEM_OFFST - 1, XPI_MEM_OFFST / 1024 / 1024);
printf(" Reserved (old SPISD):@[0x%08x-0x%08x]\n\n", TF_CARD_START, printf(" Reserved: @[0x%08x-0xffffffff] %3u MiB\n\n", TF_CARD_START,
TF_CARD_START + TF_CARD_OFFST - 1); (unsigned int)(((UINT32_MAX - TF_CARD_START) / UINT32_C(1048576)) + UINT32_C(1)));
printf("Memory Map IO Device:\n"); printf("Memory Map IO Device:\n");
printf(" 1 x GPIO(32PIN) @%p\n", printf(" 1 x GPIO(32PIN) @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_GPIO_ADMIN_BASE); (void *)(uintptr_t)RS_SOC_APB4_GPIO_BASE);
printf(" 1 x UART0 @%p\n", printf(" 1 x UART0 @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_UART0_BASE); (void *)(uintptr_t)RS_SOC_APB4_UART0_BASE);
printf(" 2 x TIMER(0,1) @%p,%p\n", printf(" 2 x TIMER(0,1) @%p,%p\n",
@@ -119,7 +146,7 @@ void rs_app_info(void) {
(void *)(uintptr_t)RS_SOC_APB4_I2S_BASE); (void *)(uintptr_t)RS_SOC_APB4_I2S_BASE);
printf(" 1 x WS2812 @%p\n", printf(" 1 x WS2812 @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_WS2812_BASE); (void *)(uintptr_t)RS_SOC_APB4_WS2812_BASE);
printf(" 1 x XPI V2 @%p\n", printf(" 1 x XPI @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_XPI_BASE); (void *)(uintptr_t)RS_SOC_APB4_XPI_BASE);
printf(" 1 x DMA(6CH) @%p\n", printf(" 1 x DMA(6CH) @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_DMA_BASE); (void *)(uintptr_t)RS_SOC_APB4_DMA_BASE);
@@ -127,25 +154,35 @@ void rs_app_info(void) {
(void *)(uintptr_t)RS_SOC_APB4_SYSCTRL_BASE); (void *)(uintptr_t)RS_SOC_APB4_SYSCTRL_BASE);
printf(" 1 x CRYPTO @%p\n", printf(" 1 x CRYPTO @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_CRYPTO_BASE); (void *)(uintptr_t)RS_SOC_APB4_CRYPTO_BASE);
printf(" 1 x CLINT @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_CLINT_BASE);
printf(" 1 x SDRAM @%p\n", printf(" 1 x SDRAM @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_SDRAM_BASE); (void *)(uintptr_t)RS_SOC_APB4_SDRAM_BASE);
printf(" 1 x DVP @%p\n", printf(" 1 x DVP @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_DVP_BASE); (void *)(uintptr_t)RS_SOC_APB4_DVP_BASE);
printf(" 1 x SDIO0 @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_SDIO0_BASE);
printf(" 1 x OPIPSRAM @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_OPIPSRAM_BASE);
printf(" 1 x I2C1 @%p\n", printf(" 1 x I2C1 @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_I2C1_BASE); (void *)(uintptr_t)RS_SOC_APB4_I2C1_BASE);
printf(" 1 x GPIO ADMIN @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_GPIO_ADMIN_BASE);
printf(" 1 x SDIO1 @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_SDIO1_BASE);
printf(" 1 x USB2 @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_USB2_BASE);
printf(" 1 x CLINT @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_CLINT_BASE);
printf(" 1 x ARCHINFO @%p\n", printf(" 1 x ARCHINFO @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_ARCHINFO_BASE); (void *)(uintptr_t)RS_SOC_APB4_ARCHINFO_BASE);
printf(" 1 x RNG @%p\n", printf(" 1 x RNG @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_RNG_BASE); (void *)(uintptr_t)RS_SOC_APB4_RNG_BASE);
printf(" 1 x PWM V2(4CH) @%p\n", printf(" 1 x PWM(4CH) @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_PWM_BASE); (void *)(uintptr_t)RS_SOC_APB4_PWM_BASE);
printf(" 1 x PS2 @%p\n", printf(" 1 x PS2 @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_PS2_BASE); (void *)(uintptr_t)RS_SOC_APB4_PS2_BASE);
printf(" 1 x RTC @%p\n", printf(" 1 x RTC @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_RTC_BASE); (void *)(uintptr_t)RS_SOC_APB4_RTC_BASE);
printf(" 1 x WDG V2 @%p\n", printf(" 1 x WDG @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_WDG_BASE); (void *)(uintptr_t)RS_SOC_APB4_WDG_BASE);
printf(" 1 x CRC @%p\n", printf(" 1 x CRC @%p\n",
(void *)(uintptr_t)RS_SOC_APB4_CRC_BASE); (void *)(uintptr_t)RS_SOC_APB4_CRC_BASE);
+1 -1
View File
@@ -72,7 +72,7 @@
"cluster_rng": {"url": "https://github.com/retroSoC/rng.git", "revision": "36f3e0774d8f3c4b597d3db8a96ca3992532b61e", "destination": "rtl/managed/clusterip/rng", "license": "MulanPSL-2.0"}, "cluster_rng": {"url": "https://github.com/retroSoC/rng.git", "revision": "36f3e0774d8f3c4b597d3db8a96ca3992532b61e", "destination": "rtl/managed/clusterip/rng", "license": "MulanPSL-2.0"},
"cluster_rtc": {"url": "https://github.com/retroSoC/rtc.git", "revision": "32548c5cbcdf39e09d0880fb611f9dd47940ea88", "destination": "rtl/managed/clusterip/rtc", "license": "NOASSERTION"}, "cluster_rtc": {"url": "https://github.com/retroSoC/rtc.git", "revision": "32548c5cbcdf39e09d0880fb611f9dd47940ea88", "destination": "rtl/managed/clusterip/rtc", "license": "NOASSERTION"},
"cluster_spi": {"url": "https://github.com/retroSoC/spi.git", "revision": "515cb408806584525605b4747db5e890dbdf1928", "destination": "rtl/managed/clusterip/spi", "license": "NOASSERTION"}, "cluster_spi": {"url": "https://github.com/retroSoC/spi.git", "revision": "515cb408806584525605b4747db5e890dbdf1928", "destination": "rtl/managed/clusterip/spi", "license": "NOASSERTION"},
"cluster_wdg": {"url": "https://github.com/retroSoC/wdg.git", "revision": "134be4b884efa8683b1617ceb41f17399b4bb83f", "destination": "rtl/managed/clusterip/wdg", "license": "MulanPSL-2.0"} "cluster_wdg": {"url": "https://github.com/retroSoC/wdg.git", "revision": "f5d39fa246054d678d34195824d943367dfcce44", "destination": "rtl/managed/clusterip/wdg", "license": "MulanPSL-2.0"}
}, },
"archives": { "archives": {
"fatfs": { "fatfs": {
+15 -12
View File
@@ -16,6 +16,7 @@ module retrosoc_tb;
localparam real XTAL_CPU_FREQ = 24.0; localparam real XTAL_CPU_FREQ = 24.0;
localparam real EXT_CPU_FREQ = 72.0; localparam real EXT_CPU_FREQ = 72.0;
localparam real AUD_CPU_FREQ = 18.432; localparam real AUD_CPU_FREQ = 18.432;
localparam time ResetHoldTime = 170744ns;
integer sim_runtime; integer sim_runtime;
@@ -83,10 +84,21 @@ module retrosoc_tb;
wire [ 7:0] s_dvp_data; wire [ 7:0] s_dvp_data;
`ifdef HAVE_PLL `ifdef HAVE_PLL
always #(1000 / XTAL_CPU_FREQ / 2) r_xtal_clk = (r_xtal_clk === 1'b0); always #(1000 / XTAL_CPU_FREQ / 2) r_xtal_clk = ~r_xtal_clk;
`endif `endif
always #(1000 / EXT_CPU_FREQ / 2) r_ext_clk = (r_ext_clk === 1'b0); always #(1000 / EXT_CPU_FREQ / 2) r_ext_clk = ~r_ext_clk;
always #(1000 / AUD_CPU_FREQ / 2) r_aud_clk = (r_aud_clk === 1'b0); always #(1000 / AUD_CPU_FREQ / 2) r_aud_clk = ~r_aud_clk;
initial begin
r_ext_clk = 1'b0;
r_aud_clk = 1'b0;
`ifdef HAVE_PLL
r_xtal_clk = 1'b0;
`endif
r_rst_n = 1'b0;
#ResetHoldTime;
r_rst_n = 1'b1;
end
// connect inout pad // connect inout pad
assign s_ext_clk = r_ext_clk; assign s_ext_clk = r_ext_clk;
@@ -208,15 +220,6 @@ module retrosoc_tb;
.dat_o (s_dvp_data) .dat_o (s_dvp_data)
); );
initial begin
r_rst_n = 1;
#43;
r_rst_n = 0;
#170701;
r_rst_n = 1;
end
initial begin : PS2_DEVICE_MODEL_BLOCK initial begin : PS2_DEVICE_MODEL_BLOCK
integer i; integer i;
#1000; #1000;
+3 -3
View File
@@ -92,10 +92,10 @@ module apb4_system (
.rtc_rst_n_i(rst_aud_n_i) .rtc_rst_n_i(rst_aud_n_i)
); );
wdg_if u_wdg_if ( wdg_if u_wdg_if (
.wdg_clk_i (clk_aud_i), .wdg_clk_i (clk_aud_i),
.wdg_rst_n_i (rst_aud_n_i), .wdg_rst_n_i(rst_aud_n_i)
.debug_halted_i(debug_halted_i)
); );
assign u_wdg_if.debug_halted_i = debug_halted_i;
`include "apb4_system_bridges.svh" `include "apb4_system_bridges.svh"
// verilog_format: off -- preserve reviewed column alignment // verilog_format: off -- preserve reviewed column alignment
+26 -1
View File
@@ -18,7 +18,7 @@ except ModuleNotFoundError: # Python 3.10
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT))
from scripts.dependency_lock import archive # noqa: E402 from scripts.dependency_lock import archive # noqa: E402
from scripts.setup_helpers import download_file # noqa: E402 from scripts.setup_helpers import atomic_write, download_file # noqa: E402
MPW_DIR = ROOT / "rtl/managed/mpw" MPW_DIR = ROOT / "rtl/managed/mpw"
@@ -58,6 +58,30 @@ def extract_serv() -> Path:
return extracted return extracted
def patch_serv(source: Path) -> None:
state = source / "serv_state.v"
content = state.read_text(encoding="utf-8")
declaration_marker = " wire misalign_trap_sync;\n"
declaration = " wire trap_pending;\n"
legacy_definition = "wire trap_pending = WITH_CSR"
patched_definition = "assign trap_pending = WITH_CSR"
if declaration in content and patched_definition in content:
return
if declaration in content or patched_definition in content:
raise RuntimeError(f"SERV trap_pending patch is incomplete in {state}")
if content.count(declaration_marker) != 1 or content.count(legacy_definition) != 1:
raise RuntimeError(f"SERV trap_pending patch markers missing in {state}")
content = content.replace(
declaration_marker,
declaration_marker + declaration,
1,
)
content = content.replace(legacy_definition, patched_definition, 1)
atomic_write(state, content)
def manifest_design_dir(identifier: str) -> Path: def manifest_design_dir(identifier: str) -> Path:
manifest = MPW_DIR / "mpw.toml" manifest = MPW_DIR / "mpw.toml"
document = tomllib.loads(manifest.read_text(encoding="utf-8")) document = tomllib.loads(manifest.read_text(encoding="utf-8"))
@@ -80,6 +104,7 @@ def prepare(update: bool) -> None:
serv_archive["sha256"], update=update, serv_archive["sha256"], update=update,
) )
serv = extract_serv() serv = extract_serv()
patch_serv(serv / "rtl")
sync_tree(serv / "rtl", manifest_design_dir("serv") / "serv") sync_tree(serv / "rtl", manifest_design_dir("serv") / "serv")
print("pinned MPW core sources are ready") print("pinned MPW core sources are ready")
+41
View File
@@ -41,6 +41,7 @@ from scripts.development_environment import ( # noqa: E402
from scripts.generate_mpw import render_active_manifest, validate_extension_bindings # noqa: E402 from scripts.generate_mpw import render_active_manifest, validate_extension_bindings # noqa: E402
from scripts.install_toolchain import safe_extract # noqa: E402 from scripts.install_toolchain import safe_extract # noqa: E402
from scripts.package import make_sbom # noqa: E402 from scripts.package import make_sbom # noqa: E402
from scripts.prepare_mpw import patch_serv # noqa: E402
from scripts import regress # noqa: E402 from scripts import regress # noqa: E402
from scripts import run_flow # noqa: E402 from scripts import run_flow # noqa: E402
from scripts.regress import ( # noqa: E402 from scripts.regress import ( # noqa: E402
@@ -399,6 +400,34 @@ def test_mpw_generator_uses_only_the_native_v2_contract() -> None:
assert '"generate"' in source assert '"generate"' in source
def test_serv_setup_patch_is_idempotent(tmp_path: Path) -> None:
state = tmp_path / "serv_state.v"
state.write_text(
"module serv_state;\n"
" wire misalign_trap_sync;\n"
" assign use_trap = !trap_pending;\n"
" wire trap_pending = WITH_CSR & trap_condition;\n"
"endmodule\n",
encoding="utf-8",
)
patch_serv(tmp_path)
first = state.read_text(encoding="utf-8")
patch_serv(tmp_path)
assert state.read_text(encoding="utf-8") == first
assert first.index("wire trap_pending;") < first.index("!trap_pending")
assert "assign trap_pending = WITH_CSR & trap_condition;" in first
def test_serv_setup_patch_rejects_unknown_source(tmp_path: Path) -> None:
state = tmp_path / "serv_state.v"
state.write_text("module serv_state; endmodule\n", encoding="utf-8")
with pytest.raises(RuntimeError, match="patch markers missing"):
patch_serv(tmp_path)
def test_mpw_active_manifest_uses_self_owned_design_selection(tmp_path: Path) -> None: def test_mpw_active_manifest_uses_self_owned_design_selection(tmp_path: Path) -> None:
manifest = tmp_path / "mpw.toml" manifest = tmp_path / "mpw.toml"
manifest.write_text( manifest.write_text(
@@ -830,6 +859,18 @@ def test_verilator_has_no_external_core_selection() -> None:
assert "core_sel_i" not in testbench assert "core_sel_i" not in testbench
def test_systemverilog_testbench_starts_in_reset_with_known_clocks() -> None:
testbench = (ROOT / "rtl/mini/dv/tb/retrosoc_tb.sv").read_text(encoding="utf-8")
assert "localparam time ResetHoldTime = 170744ns;" in testbench
for clock in ("r_ext_clk", "r_aud_clk", "r_xtal_clk"):
assert f"{clock} = 1'b0;" in testbench
assert f"{clock} = ~{clock};" in testbench
assert testbench.index("r_rst_n = 1'b0;") < testbench.index("#ResetHoldTime;")
assert testbench.index("#ResetHoldTime;") < testbench.index("r_rst_n = 1'b1;")
assert "#43;" not in testbench
def test_management_core_is_fixed_to_hazard3_with_debug() -> None: def test_management_core_is_fixed_to_hazard3_with_debug() -> None:
wrapper = (ROOT / "rtl/mini/top/mgmt_core_wrapper.sv").read_text(encoding="utf-8") wrapper = (ROOT / "rtl/mini/top/mgmt_core_wrapper.sv").read_text(encoding="utf-8")
makefile = (ROOT / "Makefile").read_text(encoding="utf-8") makefile = (ROOT / "Makefile").read_text(encoding="utf-8")