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.
54 lines
2.2 KiB
Python
54 lines
2.2 KiB
Python
"""Historical Tiny publication contracts remain separate from P6 source support."""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
|
|
import pytest
|
|
|
|
from publications import tiny_reference as tiny
|
|
from publication_history import ORIGINAL_BOOK, P5_CONTRACT, snapshot
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
@pytest.mark.parametrize("revision", [ORIGINAL_BOOK, P5_CONTRACT])
|
|
def test_historical_publication_contracts(tmp_path, revision):
|
|
historical = snapshot(tmp_path / "source", revision)
|
|
result = subprocess.run(
|
|
[sys.executable, "-m", "pytest", "-q", "tests/test_publication_tiny.py",
|
|
"--basetemp=" + str(tmp_path / "tests"), "--tb=short"],
|
|
cwd=historical, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
|
env={**os.environ, "PYTHONDONTWRITEBYTECODE": "1"}, timeout=180,
|
|
)
|
|
(tmp_path / "historical-tests.log").write_text(result.stdout)
|
|
assert result.returncode == 0, result.stdout
|
|
assert " passed" in result.stdout and " skipped" not in result.stdout
|
|
|
|
|
|
def test_current_source_cannot_relabel_historical_publication():
|
|
config = tiny.read(ROOT / tiny.BOOK / "tiny.json")
|
|
assert config["source_revision"] == "9c706ba0ff1da1028c299cfff573010a86dfd7ce"
|
|
with pytest.raises(ValueError, match="DMA parameters changed"):
|
|
tiny.collect(config)
|
|
|
|
|
|
@pytest.mark.parametrize("before,after", [
|
|
("s_req_q.write_done && !s_req_q.b_captured", "1'b1"),
|
|
("s_r_valid && s_rready[s_req_q.owner] && s_r_data[4]", "s_r_valid"),
|
|
(".flush_i(1'b0)", ".flush_i(!enable_i)"),
|
|
])
|
|
def test_current_reset_binding_still_rejects_unsafe_completion(tmp_path, before, after):
|
|
contract = tiny.read(ROOT / tiny.BOOK / "source-contract.json")
|
|
binding = next(item for item in contract["bindings"]
|
|
if item["file"] == "rtl/tiny/top/tiny_axi4_target.sv")
|
|
path = tmp_path / binding["file"]
|
|
path.parent.mkdir(parents=True)
|
|
original = (ROOT / binding["file"]).read_text()
|
|
assert before in original
|
|
path.write_text(original.replace(before, after))
|
|
with pytest.raises(ValueError, match="Tiny behavior binding changed"):
|
|
tiny.require_snippets(tmp_path, binding["file"], binding["text"])
|