mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
Integrate the SPI-P2 shared-DMA ABI into the Tiny product: SPI0 at 0x1001D000 with IRQ25 and RCU target16, the four frozen Gen1 ALT routes, latched four-bit source qualification through the fabric and APB CDC, GPIO readiness/ownership guard, and the bounded rs_spi_* HAL with the TINY_SPI_P3_ACCEPTANCE ci_smoke image. Tiny DMA enables V2.2 requests 16/17 with exact fixed FIFO MMIO checks; Mini remains default-disabled and unchanged. Review closure: the DMA AXI4 master stages the origin channel with each burst so final and contended SPI alias bursts stay qualified, the RCU spare feedback bit is tied off for four-state simulators, and the clock-switch quiescence now includes the SPI session. Validation: full Pytest 2097 passed, 0 failed, 1 skipped (optional pypdf); both Tiny profiles pass the SPI-P3 Verilator acceptance (SIM_TEST_PASS cycles=1030088); R2-P7 Verilator acceptance, Mini DMA formal prove and cover, Mini/Tiny lint, Tiny Yosys synthesis, netsim-boot and OpenSTA pass; C format/policy/host tests and RTL format/style checks clean. Evidence and remaining obligations are recorded in docs/ip/spi-verification.md. Tiny Icarus behavioral remains blocked by the pre-existing observer/sv2v defect (routed to the R2 DV owners); Mini smoke synthesis host timeout is skipped per maintainer decision. Human phase acceptance and SPI-P4/P5 remain outstanding; phase_accepted stays false.
51 lines
2.1 KiB
Python
51 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Source-bound focused SPI-P3 Tiny integration checks."""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT))
|
|
from scripts.setup_helpers import atomic_write # noqa: E402
|
|
|
|
|
|
def configuration_digest(manifest: dict) -> str:
|
|
payload = json.dumps(manifest["configuration"], sort_keys=True).encode("utf-8")
|
|
return hashlib.sha256(payload).hexdigest()
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("stage", choices=("lint", "rtl", "report"))
|
|
parser.add_argument("--variant-root", type=Path, required=True)
|
|
parser.add_argument("--pdk", choices=("ICS55", "IHP130"), required=True)
|
|
args = parser.parse_args()
|
|
variant = args.variant_root.resolve()
|
|
variant.relative_to(ROOT / "build")
|
|
manifest = json.loads((variant / "meta/manifest.json").read_text())
|
|
if manifest["configuration"]["SOC"] != "TINY" or manifest["configuration"]["PDK"] != args.pdk:
|
|
raise ValueError("profile/PDK mismatch")
|
|
output = variant / "meta/spi-p3" / args.stage
|
|
output.mkdir(parents=True, exist_ok=False)
|
|
command = [sys.executable, "-m", "pytest", "-q", "tests/test_spi_p3.py",
|
|
"tests/test_spi_p2.py", "tests/test_spi_register_parity.py"]
|
|
result = subprocess.run(command, cwd=ROOT, capture_output=True, text=True, check=False)
|
|
atomic_write(output / "pytest.log", result.stdout + result.stderr)
|
|
record = {"phase": "SPI-P3", "stage": args.stage,
|
|
"status": "passed" if result.returncode == 0 else "failed",
|
|
"command": command, "configuration_digest": configuration_digest(manifest),
|
|
"phase_accepted": False}
|
|
atomic_write(output / "record.json", json.dumps(record, indent=2, sort_keys=True) + "\n")
|
|
if result.returncode != 0:
|
|
print(result.stdout + result.stderr, file=sys.stderr)
|
|
return result.returncode
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|