feat: add SDIO support and related tests

- Introduced a new testbench for the SDIO wrapper () to validate APB interactions.
- Updated  to include IRQ handling for SDIO0 and SDIO1.
- Enhanced  to account for performance management of SDIO0 and SDIO1.
- Modified memory map tests to include SDIO base addresses and performance wait offsets.
- Updated pin mapping tests to include SDIO1 signals.
- Created a comprehensive suite of SDIO tests () covering various functionalities including CRC, command engine, DMA, and standalone operations.
- Added a new test for verifying SDIO register parity against the RTL definition.
- Adjusted SOC topology tests to reflect the addition of SDIO in the IRQ and APB fabric.
This commit is contained in:
maksyuki committed 2026-08-20 10:03:51 +08:00
1 parent faad445e42
commit a8325ab6b7
83 files changed
+11777 -153

No files matched your search

+19 -7
View File
@@ -74,14 +74,15 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
irq_sva = (tmp_path / "rtl/soc_irq_sva.svh").read_text(encoding="utf-8")
filelist = (tmp_path / "soc_topology.fl").read_text(encoding="utf-8")
assert interfaces.count("apb4_if u_") == 17
assert interfaces.count("apb4_if u_") == 18
assert "nmi_if" not in interfaces
assert "soc_nmi" not in interfaces
assert "assign s_psel_comb[17] = `SOC_ADDR_IS_APB4_I2C1(s_decode_addr);" in routes
assert "assign s_psel_comb[1] = `SOC_ADDR_IS_APB4_GPIO(s_decode_addr) || `SOC_ADDR_IS_APB4_GPIO_ADMIN(s_decode_addr);" in routes
assert "SOC_ADDR_FLASH" not in routes
assert "assign s_psel_comb[15] = 1'b0;" in routes
assert "assign s_psel_comb[15] = `SOC_ADDR_IS_APB4_SDIO0(s_decode_addr);" in routes
assert "assign s_psel_comb[16] = `SOC_ADDR_IS_APB4_OPIPSRAM(s_decode_addr);" in routes
assert "assign s_psel_comb[18] = `SOC_ADDR_IS_APB4_SDIO1(s_decode_addr);" in routes
assert gpio.count("// GPIO") == 64
assert "u_uart1_if" not in gpio
assert "assign u_uart0_if.cts_n_i = u_gpio_if.di_i[0];" in gpio
@@ -89,6 +90,8 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
assert "assign u_gpio_if.alt0_oe_i[0] = 1'b0;" in gpio
assert "assign u_gpio_if.alt0_do_i[1] = u_uart0_if.rts_n_o;" in gpio
assert "assign u_gpio_if.alt0_oe_i[1] = 1'b1;" in gpio
assert "assign u_gpio_if.alt0_do_i[15] = u_sdio0_if.sck_o;" in gpio
assert "assign u_sdio0_if.cmd_di_i = u_gpio_if.di_i[16];" in gpio
assert "assign u_gpio_if.alt1_do_i[0] = u_ps2_if.ps2_clk_o;" in gpio
assert "assign u_gpio_if.alt1_oe_i[0] = u_ps2_if.ps2_clk_oe_o;" in gpio
assert "assign u_gpio_if.alt1_do_i[1] = u_ps2_if.ps2_dat_o;" in gpio
@@ -113,16 +116,18 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
assert "assign user_ip.paddr = s_addr_q;" in apb_routes
assert "({32{s_psel_q[7]}} & user_ip.prdata)" in apb_response
assert "localparam int NSLV = 8;" in apb_declarations
assert fabric.count("axi4_if #(") == 5
assert fabric.count("axi4_if #(") == 7
assert ".mgmt_axi4(u_mgmt_axi4_if)" in bus_fabric
assert ".user_axi4(u_user_axi4_if)" in bus_fabric
assert ".dma_axi4(u_dma_axi4_if)" in bus_fabric
assert ".sdio0_axi4(u_sdio0_axi4_if)" in bus_fabric
assert ".sdio1_axi4(u_sdio1_axi4_if)" in bus_fabric
assert ".cfg_axi4(u_cfg_axi4_if)" in bus_fabric
assert ".system_axi4(u_system_axi4_if)" in bus_fabric
assert ".axi4(u_system_axi4_if)" in apb_system_fabric
assert "`define SOC_IRQ_VECTOR_WIDTH 32" in irq_config
assert "`define SOC_USER_IRQ_MASK 32'h004EFBFC" in irq_config
assert "`define SOC_IRQ_APB4_PERIPH_WIDTH 16" in irq_config
assert "`define SOC_IRQ_APB4_PERIPH_WIDTH 18" in irq_config
assert "`define SOC_IRQ_APB4_SYSTEM_WIDTH 5" in irq_config
assert "assign irq_o[0] = u_clint_if.software_irq_o[0];" in rib_irq
assert "assign irq_o[10] = ws2812.irq_o;" in rib_irq
@@ -131,17 +136,21 @@ def test_topology_generates_complete_rib_apb_and_gpio_bindings(tmp_path: Path) -
assert "assign irq_o[13] = s_dvp_irq;" in rib_irq
assert "assign irq_o[14] = s_dma_irq;" in rib_irq
assert "assign irq_o[15] = opipsram.irq_o;" in rib_irq
assert "assign irq_o[16] = sdio0.irq_o;" in rib_irq
assert "assign irq_o[17] = sdio1.irq_o;" in rib_irq
assert "assign irq_o[0] = pwm.irq_o;" in apb_irq
assert "assign irq_o[4] = s_rng_irq;" in apb_irq
assert "s_irq[10]" not in irq_wiring
assert "s_irq[10] = s_apb4_periph_irq[16];" in irq_wiring
assert "s_irq[15] = s_apb4_periph_irq[13];" in irq_wiring
assert "s_irq[16] = s_apb4_system_irq[4];" in irq_wiring
assert "s_irq[20] = s_apb4_periph_irq[14];" in irq_wiring
assert "s_irq[22] = s_apb4_periph_irq[15];" in irq_wiring
assert "irq_i[10] == 1'b0" in irq_sva
assert "s_irq[21] = s_apb4_periph_irq[17];" in irq_wiring
assert "irq_i[10] == apb4_periph_irq_i[16]" in irq_sva
assert "irq_i[15] == apb4_periph_irq_i[13]" in irq_sva
assert "irq_i[20] == apb4_periph_irq_i[14]" in irq_sva
assert "irq_i[22] == apb4_periph_irq_i[15]" in irq_sva
assert "irq_i[21] == apb4_periph_irq_i[17]" in irq_sva
assert "irq_i[31] == 1'b0" in irq_sva
assert "bind retrosoc soc_irq_topology_sva" in irq_sva
assert filelist.startswith("+incdir+")
@@ -171,6 +180,7 @@ def test_topology_preserves_default_irq_compatibility_mapping() -> None:
("i2c0", "apb4_periph", 7, 7, "i2c0.irq_o"),
("i2s", "apb4_periph", 8, 8, "i2s.irq_o"),
("xpi", "apb4_periph", 9, 9, "xpi.irq_o"),
("sdio0", "apb4_periph", 16, 10, "sdio0.irq_o"),
("pwm", "apb4_system", 0, 11, "pwm.irq_o"),
("ps2", "apb4_system", 1, 12, "ps2.irq_o"),
("rtc", "apb4_system", 2, 13, "u_rtc_if.irq_o"),
@@ -182,6 +192,7 @@ def test_topology_preserves_default_irq_compatibility_mapping() -> None:
("dvp", "apb4_periph", 13, 15, "s_dvp_irq"),
("dma", "apb4_periph", 14, 20, "s_dma_irq"),
("opipsram", "apb4_periph", 15, 22, "opipsram.irq_o"),
("sdio1", "apb4_periph", 17, 21, "sdio1.irq_o"),
]
@@ -227,7 +238,8 @@ def test_topology_rejects_duplicate_region_and_disabled_owner(tmp_path: Path) ->
assert "multiple targets" in result.stderr
document = json.loads(TOPOLOGY.read_text(encoding="utf-8"))
document["apb4_periph_targets"][15]["regions"] = ["APB4_SDIO"]
document["apb4_periph_targets"][15]["disabled"] = True
document["apb4_periph_targets"][15]["regions"] = ["APB4_SDIO0"]
result = validate(write_invalid_topology(tmp_path, document))
assert result.returncode != 0
assert "disabled but declares regions" in result.stderr