diff --git a/crt/src/service/booter.c b/crt/src/service/booter.c index 790415f4..03feb9eb 100644 --- a/crt/src/service/booter.c +++ b/crt/src/service/booter.c @@ -56,7 +56,34 @@ void rs_app_info(void) { printf(" specs: Gen2 Plus\n"); 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]); printf(" %-15s %-12s %-12s %s\n", "[name]", "[isa]", "[maintainer]", "[repo]"); 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); printf(" XPI MMIO: @[0x%08x-0x%08x] %3d MiB\n", XPI_MEM_START, XPI_MEM_START + XPI_MEM_OFFST - 1, XPI_MEM_OFFST / 1024 / 1024); - printf(" Reserved (old SPISD):@[0x%08x-0x%08x]\n\n", TF_CARD_START, - TF_CARD_START + TF_CARD_OFFST - 1); + printf(" Reserved: @[0x%08x-0xffffffff] %3u MiB\n\n", TF_CARD_START, + (unsigned int)(((UINT32_MAX - TF_CARD_START) / UINT32_C(1048576)) + UINT32_C(1))); printf("Memory Map IO Device:\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", (void *)(uintptr_t)RS_SOC_APB4_UART0_BASE); 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); printf(" 1 x WS2812 @%p\n", (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); printf(" 1 x DMA(6CH) @%p\n", (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); printf(" 1 x CRYPTO @%p\n", (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", (void *)(uintptr_t)RS_SOC_APB4_SDRAM_BASE); printf(" 1 x DVP @%p\n", (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", (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", (void *)(uintptr_t)RS_SOC_APB4_ARCHINFO_BASE); printf(" 1 x RNG @%p\n", (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); printf(" 1 x PS2 @%p\n", (void *)(uintptr_t)RS_SOC_APB4_PS2_BASE); printf(" 1 x RTC @%p\n", (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); printf(" 1 x CRC @%p\n", (void *)(uintptr_t)RS_SOC_APB4_CRC_BASE); diff --git a/dependencies/dependencies.lock.json b/dependencies/dependencies.lock.json index 5a98f60b..89302e47 100644 --- a/dependencies/dependencies.lock.json +++ b/dependencies/dependencies.lock.json @@ -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_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_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": { "fatfs": { diff --git a/rtl/mini/dv/tb/retrosoc_tb.sv b/rtl/mini/dv/tb/retrosoc_tb.sv index 37a9b404..7533568b 100644 --- a/rtl/mini/dv/tb/retrosoc_tb.sv +++ b/rtl/mini/dv/tb/retrosoc_tb.sv @@ -16,6 +16,7 @@ module retrosoc_tb; localparam real XTAL_CPU_FREQ = 24.0; localparam real EXT_CPU_FREQ = 72.0; localparam real AUD_CPU_FREQ = 18.432; + localparam time ResetHoldTime = 170744ns; integer sim_runtime; @@ -83,10 +84,21 @@ module retrosoc_tb; wire [ 7:0] s_dvp_data; `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 - always #(1000 / EXT_CPU_FREQ / 2) r_ext_clk = (r_ext_clk === 1'b0); - always #(1000 / AUD_CPU_FREQ / 2) r_aud_clk = (r_aud_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; + + 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 assign s_ext_clk = r_ext_clk; @@ -208,15 +220,6 @@ module retrosoc_tb; .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 integer i; #1000; diff --git a/rtl/mini/top/apb4_system.sv b/rtl/mini/top/apb4_system.sv index 091f1e85..d29f912c 100644 --- a/rtl/mini/top/apb4_system.sv +++ b/rtl/mini/top/apb4_system.sv @@ -92,10 +92,10 @@ module apb4_system ( .rtc_rst_n_i(rst_aud_n_i) ); wdg_if u_wdg_if ( - .wdg_clk_i (clk_aud_i), - .wdg_rst_n_i (rst_aud_n_i), - .debug_halted_i(debug_halted_i) + .wdg_clk_i (clk_aud_i), + .wdg_rst_n_i(rst_aud_n_i) ); + assign u_wdg_if.debug_halted_i = debug_halted_i; `include "apb4_system_bridges.svh" // verilog_format: off -- preserve reviewed column alignment diff --git a/scripts/prepare_mpw.py b/scripts/prepare_mpw.py index bb0dd1ff..e768c9ef 100644 --- a/scripts/prepare_mpw.py +++ b/scripts/prepare_mpw.py @@ -18,7 +18,7 @@ except ModuleNotFoundError: # Python 3.10 ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) 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" @@ -58,6 +58,30 @@ def extract_serv() -> Path: 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: manifest = MPW_DIR / "mpw.toml" document = tomllib.loads(manifest.read_text(encoding="utf-8")) @@ -80,6 +104,7 @@ def prepare(update: bool) -> None: serv_archive["sha256"], update=update, ) serv = extract_serv() + patch_serv(serv / "rtl") sync_tree(serv / "rtl", manifest_design_dir("serv") / "serv") print("pinned MPW core sources are ready") diff --git a/tests/test_script_tools.py b/tests/test_script_tools.py index 54d206f0..a4cc0aa5 100644 --- a/tests/test_script_tools.py +++ b/tests/test_script_tools.py @@ -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.install_toolchain import safe_extract # 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 run_flow # 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 +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: manifest = tmp_path / "mpw.toml" manifest.write_text( @@ -830,6 +859,18 @@ def test_verilator_has_no_external_core_selection() -> None: 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: wrapper = (ROOT / "rtl/mini/top/mgmt_core_wrapper.sv").read_text(encoding="utf-8") makefile = (ROOT / "Makefile").read_text(encoding="utf-8")