Files
retroSoC/tests/test_publication_tiny.py
T
maksyuki 31daf3e84c feat(spi): implement SPI-P3 Tiny GPIO RCU and SDK integration
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.
2026-10-22 11:57:29 +08:00

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"])