mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-05 06:32:37 +00:00
- 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.
323 lines
9.6 KiB
Python
323 lines
9.6 KiB
Python
"""Focused standalone SDIO RTL regressions."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
CONVERTER = ROOT / "rtl/mini/script/convt_sv2v.py"
|
|
BUILD = ROOT / "build/test-sdio"
|
|
|
|
SDIO_FULL_SOURCES = [
|
|
"rtl/managed/clusterip/common/rtl/interface/apb4_if.sv",
|
|
"rtl/managed/clusterip/common/rtl/interface/axi4_if.sv",
|
|
"rtl/ip/storage/sdio_if.sv",
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_define.svh",
|
|
"rtl/ip/storage/sdio_crc7.sv",
|
|
"rtl/ip/storage/sdio_crc16.sv",
|
|
"rtl/ip/storage/sdio_clock.sv",
|
|
"rtl/ip/storage/sdio_command.sv",
|
|
"rtl/ip/storage/sdio_data.sv",
|
|
"rtl/ip/storage/sdio_dma_descriptor.sv",
|
|
"rtl/ip/peripheral/dma_axi4_master.sv",
|
|
"rtl/ip/storage/sdio_dma.sv",
|
|
"rtl/ip/storage/sdio_reg.sv",
|
|
"rtl/ip/storage/sdio_core.sv",
|
|
"rtl/ip/storage/apb4_sdio.sv",
|
|
"tests/rtl/sdio_native_model.sv",
|
|
"tests/rtl/sdio_axi_memory_responder.sv",
|
|
]
|
|
|
|
SDIO_FULL_INCDIRS = [
|
|
"rtl/managed/clusterip/common/rtl/interface",
|
|
"rtl/ip/peripheral",
|
|
"rtl/ip/storage",
|
|
]
|
|
|
|
|
|
def _run_tb(name: str, top: str, sources: list[str], incdirs: list[str], marker: str) -> None:
|
|
iverilog = shutil.which("iverilog")
|
|
vvp = shutil.which("vvp")
|
|
if iverilog is None or vvp is None:
|
|
return
|
|
BUILD.mkdir(parents=True, exist_ok=True)
|
|
filelist = BUILD / f"{name}.fl"
|
|
filelist.write_text(
|
|
"\n".join([*(f"+incdir+{ROOT / path}" for path in incdirs), *(str(ROOT / path) for path in sources)])
|
|
+ "\n",
|
|
encoding="utf-8",
|
|
)
|
|
converted = BUILD / f"{name}.v"
|
|
simulation = BUILD / f"{name}.vvp"
|
|
subprocess.run(
|
|
["python3", str(CONVERTER), "-f", str(filelist), "--output", str(converted)],
|
|
check=True,
|
|
)
|
|
subprocess.run([iverilog, "-g2012", "-s", top, "-o", str(simulation), str(converted)], check=True)
|
|
result = subprocess.run([vvp, str(simulation)], check=True, text=True, capture_output=True)
|
|
assert marker in result.stdout
|
|
|
|
|
|
def _run_verilator_tb(
|
|
name: str, top: str, sources: list[str], incdirs: list[str], marker: str
|
|
) -> None:
|
|
verilator = shutil.which("verilator")
|
|
if verilator is None:
|
|
return
|
|
build_dir = BUILD / f"{name}-verilator"
|
|
obj_dir = build_dir / "obj"
|
|
obj_dir.mkdir(parents=True, exist_ok=True)
|
|
source_paths = [str(ROOT / path) for path in sources]
|
|
include_args = [f"-I{ROOT / path}" for path in incdirs]
|
|
subprocess.run(
|
|
[
|
|
verilator,
|
|
"--binary",
|
|
"--timing",
|
|
"--top-module",
|
|
top,
|
|
"-Mdir",
|
|
str(obj_dir),
|
|
"-o",
|
|
"simv",
|
|
*include_args,
|
|
*source_paths,
|
|
],
|
|
check=True,
|
|
)
|
|
result = subprocess.run(
|
|
[str(obj_dir / "simv")], check=True, text=True, capture_output=True
|
|
)
|
|
assert marker in result.stdout
|
|
|
|
|
|
def test_sdio_crc_vectors() -> None:
|
|
_run_tb(
|
|
"crc",
|
|
"sdio_crc_tb",
|
|
[
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_crc7.sv",
|
|
"rtl/ip/storage/sdio_crc16.sv",
|
|
"tests/rtl/sdio_crc_tb.sv",
|
|
],
|
|
["rtl/ip/storage"],
|
|
"SDIO CRC vectors passed",
|
|
)
|
|
|
|
|
|
def test_sdio_phase_clock() -> None:
|
|
_run_tb(
|
|
"clock",
|
|
"sdio_clock_tb",
|
|
["rtl/ip/storage/sdio_clock.sv", "tests/rtl/sdio_clock_tb.sv"],
|
|
[],
|
|
"SDIO phase clock test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_command_engine() -> None:
|
|
_run_tb(
|
|
"command",
|
|
"sdio_command_tb",
|
|
[
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_clock.sv",
|
|
"rtl/ip/storage/sdio_command.sv",
|
|
"tests/rtl/sdio_command_tb.sv",
|
|
],
|
|
["rtl/ip/storage"],
|
|
"SDIO command engine test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_registers() -> None:
|
|
_run_tb(
|
|
"register",
|
|
"sdio_register_tb",
|
|
[
|
|
"rtl/managed/clusterip/common/rtl/interface/apb4_if.sv",
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_define.svh",
|
|
"rtl/ip/storage/sdio_reg.sv",
|
|
"tests/rtl/sdio_register_tb.sv",
|
|
],
|
|
["rtl/managed/clusterip/common/rtl/interface", "rtl/ip/storage"],
|
|
"SDIO APB register test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_descriptors() -> None:
|
|
_run_tb(
|
|
"descriptor",
|
|
"sdio_descriptor_tb",
|
|
[
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_dma_descriptor.sv",
|
|
"tests/rtl/sdio_descriptor_tb.sv",
|
|
],
|
|
["rtl/ip/storage"],
|
|
"SDIO descriptor validation test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_dma() -> None:
|
|
_run_tb(
|
|
"dma",
|
|
"sdio_dma_tb",
|
|
[
|
|
"rtl/managed/clusterip/common/rtl/interface/axi4_if.sv",
|
|
"rtl/ip/peripheral/dma_axi4_master.sv",
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_dma.sv",
|
|
"tests/rtl/sdio_dma_tb.sv",
|
|
],
|
|
[
|
|
"rtl/managed/clusterip/common/rtl/interface",
|
|
"rtl/ip/peripheral",
|
|
"rtl/ip/storage",
|
|
],
|
|
"SDIO DMA descriptor, tail, and 4 KiB split test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_wrapper() -> None:
|
|
_run_tb(
|
|
"wrapper",
|
|
"sdio_wrapper_tb",
|
|
[
|
|
"rtl/managed/clusterip/common/rtl/interface/apb4_if.sv",
|
|
"rtl/managed/clusterip/common/rtl/interface/axi4_if.sv",
|
|
"rtl/ip/storage/sdio_if.sv",
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_define.svh",
|
|
"rtl/ip/storage/sdio_crc7.sv",
|
|
"rtl/ip/storage/sdio_crc16.sv",
|
|
"rtl/ip/storage/sdio_clock.sv",
|
|
"rtl/ip/storage/sdio_command.sv",
|
|
"rtl/ip/storage/sdio_data.sv",
|
|
"rtl/ip/storage/sdio_dma_descriptor.sv",
|
|
"rtl/ip/peripheral/dma_axi4_master.sv",
|
|
"rtl/ip/storage/sdio_dma.sv",
|
|
"rtl/ip/storage/sdio_reg.sv",
|
|
"rtl/ip/storage/sdio_core.sv",
|
|
"rtl/ip/storage/apb4_sdio.sv",
|
|
"tests/rtl/sdio_wrapper_tb.sv",
|
|
],
|
|
[
|
|
"rtl/managed/clusterip/common/rtl/interface",
|
|
"rtl/ip/peripheral",
|
|
"rtl/ip/storage",
|
|
],
|
|
"SDIO wrapper elaboration and APB smoke test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_standalone_sdhc() -> None:
|
|
_run_tb(
|
|
"standalone-sdhc",
|
|
"sdio_standalone_tb",
|
|
[*SDIO_FULL_SOURCES, "tests/rtl/sdio_standalone_tb.sv"],
|
|
SDIO_FULL_INCDIRS,
|
|
"SDIO standalone native SD model test passed (SDHC)",
|
|
)
|
|
|
|
|
|
def test_sdio_standalone_sdsc() -> None:
|
|
_run_tb(
|
|
"standalone-sdsc",
|
|
"sdio_sdsc_tb",
|
|
[*SDIO_FULL_SOURCES, "tests/rtl/sdio_standalone_tb.sv"],
|
|
SDIO_FULL_INCDIRS,
|
|
"SDIO standalone native SD model test passed (SDSC)",
|
|
)
|
|
|
|
|
|
def test_sdio_standalone_onebit() -> None:
|
|
_run_tb(
|
|
"standalone-onebit",
|
|
"sdio_onebit_tb",
|
|
[*SDIO_FULL_SOURCES, "tests/rtl/sdio_standalone_tb.sv"],
|
|
SDIO_FULL_INCDIRS,
|
|
"SDIO standalone native SD model test passed (SDHC)",
|
|
)
|
|
|
|
|
|
def test_sdio_only_device() -> None:
|
|
_run_tb(
|
|
"sdio-only",
|
|
"sdio_sdio_tb",
|
|
[*SDIO_FULL_SOURCES, "tests/rtl/sdio_sdio_tb.sv"],
|
|
SDIO_FULL_INCDIRS,
|
|
"SDIO-only CMD5/CMD52/CMD53/DAT1 test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_dual_instance() -> None:
|
|
_run_tb(
|
|
"dual",
|
|
"sdio_dual_tb",
|
|
[*SDIO_FULL_SOURCES, "tests/rtl/sdio_dual_tb.sv"],
|
|
SDIO_FULL_INCDIRS,
|
|
"SDIO dual-instance isolation and concurrent traffic test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_dma_stress_contract() -> None:
|
|
_run_tb(
|
|
"dma-stress",
|
|
"sdio_dma_stress_tb",
|
|
[
|
|
"rtl/managed/clusterip/common/rtl/interface/axi4_if.sv",
|
|
"rtl/ip/peripheral/dma_axi4_master.sv",
|
|
"rtl/ip/storage/sdio_pkg.sv",
|
|
"rtl/ip/storage/sdio_dma.sv",
|
|
"tests/rtl/sdio_axi_memory_responder.sv",
|
|
"tests/rtl/sdio_dma_stress_tb.sv",
|
|
],
|
|
["rtl/managed/clusterip/common/rtl/interface", "rtl/ip/peripheral", "rtl/ip/storage"],
|
|
"SDIO AXI 16-beat, 4 KiB split, error, and abort test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_50mhz_clock() -> None:
|
|
_run_tb(
|
|
"50mhz",
|
|
"sdio_50mhz_tb",
|
|
["rtl/ip/storage/sdio_clock.sv", "tests/rtl/sdio_50mhz_tb.sv"],
|
|
[],
|
|
"SDIO 100 MHz to 50 MHz SDCLK test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_50mhz_clock_verilator() -> None:
|
|
_run_verilator_tb(
|
|
"50mhz",
|
|
"sdio_50mhz_tb",
|
|
["rtl/ip/storage/sdio_clock.sv", "tests/rtl/sdio_50mhz_tb.sv"],
|
|
[],
|
|
"SDIO 100 MHz to 50 MHz SDCLK test passed",
|
|
)
|
|
|
|
|
|
def test_sdio_sdk_high_speed_enable_sequence() -> None:
|
|
"""Keep the SDK high-speed capability/enable/verify/clock order explicit."""
|
|
|
|
source = (ROOT / "crt/src/hal/sdio.c").read_text(encoding="utf-8")
|
|
start = source.index("rs_sdio_function_initialize")
|
|
end = source.index("rs_sdio_function_enable", start)
|
|
initialize = source[start:end]
|
|
capability_read = initialize.index('rs_sdio_function_cmd52_read(instance, 0U, 0x13U')
|
|
enable_write = initialize.index("rs_sdio_function_cmd52_write", capability_read)
|
|
verify_read = initialize.index('rs_sdio_function_cmd52_read(instance, 0U, 0x13U', enable_write)
|
|
clock_change = initialize.index("rs_sdio_clock_set", verify_read)
|
|
assert capability_read < enable_write < verify_read < clock_change
|
|
assert "value | UINT8_C(0x02)" in initialize
|
|
assert "value & UINT8_C(0x02)" in initialize
|
|
high_speed_info = initialize.index("info->high_speed = high_speed_enabled")
|
|
assert clock_change < high_speed_info
|