mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
feat: enhance test coverage and update system control interfaces
- Added interface to and implemented error handling for register writes. - Introduced a new test for AXI4 address gate functionality in . - Updated clock and reset domain assertions in to reflect new domain names. - Modified expected outputs in to include new clock domains. - Adjusted chip configuration assertions in to account for additional power pads. - Enhanced memory map tests in with new definitions and includes. - Updated pin mapping tests in to include new reference clock pads. - Improved script tools tests in to ensure correct validation of extension bindings. - Refined system control tests in to include new clock control interface. - Updated USB2 packet RAM tests in to include new SRAM definitions. - Enhanced user extensions tests in to validate new product extension configurations. - Adjusted user IP register parity tests to use legacy extensions. - Updated Yosys synthesis recipe tests to reflect changes in STA period calculations.
This commit is contained in:
131 files changed
+5983
-1790
No files matched your search
@@ -10,16 +10,17 @@ from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
EXTENSIONS = ROOT / "rtl/mini/integration/user_extensions.json"
|
||||
LEGACY_EXTENSIONS = ROOT / "rtl/mini/integration/user_extensions_legacy.json"
|
||||
GENERATOR = ROOT / "rtl/mini/integration/generate_user_extensions.py"
|
||||
|
||||
|
||||
def generate(output_dir: Path) -> None:
|
||||
def generate(output_dir: Path, manifest: Path = EXTENSIONS) -> None:
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(GENERATOR),
|
||||
"--map",
|
||||
str(EXTENSIONS),
|
||||
str(manifest),
|
||||
"--output-dir",
|
||||
str(output_dir),
|
||||
],
|
||||
@@ -41,13 +42,38 @@ def write_invalid_extensions(tmp_path: Path, document: dict[str, object]) -> Pat
|
||||
return path
|
||||
|
||||
|
||||
def test_extensions_generate_isolated_scalar_bindings(tmp_path: Path) -> None:
|
||||
def test_product_extensions_generate_fixed_slot_contract(tmp_path: Path) -> None:
|
||||
generate(tmp_path)
|
||||
|
||||
core = (tmp_path / "rtl/user_core_bindings.svh").read_text(encoding="utf-8")
|
||||
ip = (tmp_path / "rtl/user_ip_bindings.svh").read_text(encoding="utf-8")
|
||||
filelist = (tmp_path / "user_extensions.fl").read_text(encoding="utf-8")
|
||||
config = (tmp_path / "rtl/user_extensions_config.svh").read_text(encoding="utf-8")
|
||||
product = (tmp_path / "rtl/product_extensions_config.svh").read_text(encoding="utf-8")
|
||||
c_config = (tmp_path / "include/retrosoc/generated/user_extensions.h").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
assert "rib_if u_user_" not in core
|
||||
assert "mpw_i" not in ip
|
||||
assert "`define USER_CORE_COUNT 0" in config
|
||||
assert "`define USER_IP_COUNT 0" in config
|
||||
assert "`define RETROSOC_EXTENSION__COUNT 2" in config
|
||||
assert "`define RETROSOC_EXTENSION__EXT_L_COUNT 1" in config
|
||||
assert "`define RETROSOC_EXTENSION__EXT_H_COUNT 1" in config
|
||||
assert "RETROSOC_EXTENSION__SLOT0_KIND_EXT_H" in product
|
||||
assert "RETROSOC_EXTENSION__SLOT1_KIND_EXT_H" in product
|
||||
assert "RS_SOC_USER_CORE_COUNT UINT32_C(0)" in c_config
|
||||
assert "RS_SOC_EXTENSION_COUNT UINT32_C(2)" in c_config
|
||||
assert filelist.startswith("+incdir+")
|
||||
|
||||
|
||||
def test_legacy_extensions_generate_isolated_scalar_bindings(tmp_path: Path) -> None:
|
||||
generate(tmp_path, LEGACY_EXTENSIONS)
|
||||
|
||||
core = (tmp_path / "rtl/user_core_bindings.svh").read_text(encoding="utf-8")
|
||||
ip = (tmp_path / "rtl/user_ip_bindings.svh").read_text(encoding="utf-8")
|
||||
config = (tmp_path / "rtl/user_extensions_config.svh").read_text(encoding="utf-8")
|
||||
|
||||
assert core.count("rib_if u_user_") == 4
|
||||
assert core.count("ribp_if u_user_") == 4
|
||||
@@ -71,35 +97,48 @@ def test_extensions_generate_isolated_scalar_bindings(tmp_path: Path) -> None:
|
||||
assert "gpio.do_o = '0;" in ip
|
||||
assert "8'd2: begin" in ip
|
||||
assert "u_user_2_apb4_if.psel = apb.psel;" in ip
|
||||
assert filelist.startswith("+incdir+")
|
||||
assert "`define USER_CORE_COUNT 4" in config
|
||||
|
||||
|
||||
def test_extensions_reject_noncontiguous_slots_and_invalid_modules(tmp_path: Path) -> None:
|
||||
document = json.loads(EXTENSIONS.read_text(encoding="utf-8"))
|
||||
document["core_targets"][2]["slot"] = 7
|
||||
document["extensions"][1]["slot"] = 7
|
||||
result = validate(write_invalid_extensions(tmp_path, document))
|
||||
assert result.returncode != 0
|
||||
assert "slots must be contiguous from 0" in result.stderr
|
||||
assert "product extension slots must be contiguous from 0" in result.stderr
|
||||
|
||||
document = json.loads(EXTENSIONS.read_text(encoding="utf-8"))
|
||||
document["ip_targets"][0]["module"] = "user-ip"
|
||||
document["extensions"][0]["control_region"] = "user-ip"
|
||||
result = validate(write_invalid_extensions(tmp_path, document))
|
||||
assert result.returncode != 0
|
||||
assert "must be a SystemVerilog identifier" in result.stderr
|
||||
|
||||
|
||||
def test_extensions_reject_invalid_core_reset_style(tmp_path: Path) -> None:
|
||||
def test_extensions_reject_invalid_kind_and_ext_l_data_path(tmp_path: Path) -> None:
|
||||
document = json.loads(EXTENSIONS.read_text(encoding="utf-8"))
|
||||
document["core_targets"][0]["reset"] = "mixed"
|
||||
document["extensions"][0]["kind"] = "mixed"
|
||||
result = validate(write_invalid_extensions(tmp_path, document))
|
||||
assert result.returncode != 0
|
||||
assert ".reset must be sync or async" in result.stderr
|
||||
assert ".kind must be ext_l or ext_h" in result.stderr
|
||||
|
||||
|
||||
def test_extensions_reject_duplicate_design_selection(tmp_path: Path) -> None:
|
||||
document = json.loads(EXTENSIONS.read_text(encoding="utf-8"))
|
||||
document["core_targets"][1]["design_id"] = document["core_targets"][0]["design_id"]
|
||||
document["extensions"][0]["data_master"] = True
|
||||
result = validate(write_invalid_extensions(tmp_path, document))
|
||||
assert result.returncode != 0
|
||||
assert "design_id kianv_rv32i is duplicated" in result.stderr
|
||||
assert "EXT-L cannot expose a data master or stream" in result.stderr
|
||||
|
||||
|
||||
def test_extensions_reject_duplicate_regions_and_irqs(tmp_path: Path) -> None:
|
||||
document = json.loads(EXTENSIONS.read_text(encoding="utf-8"))
|
||||
document["extensions"][1]["control_region"] = document["extensions"][0][
|
||||
"control_region"
|
||||
]
|
||||
result = validate(write_invalid_extensions(tmp_path, document))
|
||||
assert result.returncode != 0
|
||||
assert "duplicates a slot or control region" in result.stderr
|
||||
|
||||
document = json.loads(EXTENSIONS.read_text(encoding="utf-8"))
|
||||
document["extensions"][1]["irq_base"] = document["extensions"][0]["irq_base"]
|
||||
result = validate(write_invalid_extensions(tmp_path, document))
|
||||
assert result.returncode != 0
|
||||
assert "overlapping or out-of-range IRQs" in result.stderr
|
||||
Reference in new issue
Block a user