feat: add test status handling to sysctrl and integrate with simulation framework

- Introduced test status signals (test_done_o, test_pass_o, test_code_o) in sysctrl interface and module.
- Updated memory map to include TEST_STATUS offset.
- Enhanced retrosoc_tb to monitor test completion and report results.
- Modified Emulator to handle test status and return appropriate exit codes.
- Updated formal verification to include assertions for test status.
- Added CoreMark log parsing script and integrated it into the regression tests.
- Implemented tests for test status handling in sysctrl_fault_tb.
- Adjusted simulation success and failure markers in various scripts and tests.
- Ensured compatibility with existing performance logging and regression testing frameworks.
This commit is contained in:
maksyuki committed 2026-08-06 13:23:16 +08:00
1 parent be2f351927
commit 99d4618cc2
45 files changed
+1209 -81

No files matched your search

+4 -2
View File
@@ -20,8 +20,10 @@ URL.
`parse_performance_log.py` converts the `APP=benchmark` UART `PERF` records
into `meta/performance.json`. The parser requires the terminal
`PERF_BENCHMARK_PASS` marker and deliberately does not alter the common
simulation success-marker policy.
`PERF_BENCHMARK_PASS` marker. `parse_coremark_log.py` converts the fixed
SRAM CoreMark quick report into `meta/coremark.json`; it requires one valid
`COREMARK_RESULT` record and `COREMARK_PASS`. Both reports complement, rather
than replace, the common `SIM_TEST_PASS` simulation verdict.
`run_debug_session.py` is the local Hazard3 debug acceptance driver. It starts
the Verilator remote-bitbang endpoint, the lock-pinned OpenOCD binary, and
+3 -2
View File
@@ -14,9 +14,10 @@ sys.path.insert(0, str(ROOT))
from scripts.setup_helpers import atomic_write # noqa: E402
DEFAULT_SUCCESS = "retroSoC: A Customized ASIC for Retro Stuff"
DEFAULT_SUCCESS = "SIM_TEST_PASS"
DEFAULT_FAILURE = re.compile(
r"(?:\bFAILED?\b|\bFATAL\b|assertion failed|%Error)", re.IGNORECASE
r"(?:\bFAILED?\b|\bFATAL\b|assertion failed|%Error|SIM_TEST_FAIL|SIM_TEST_TIMEOUT)",
re.IGNORECASE,
)
+104
View File
@@ -0,0 +1,104 @@
#!/usr/bin/env python3
"""Convert the quick Hazard3 CoreMark UART report into structured JSON."""
from __future__ import annotations
import argparse
import json
import re
import sys
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
from pathlib import Path
RESULT_PREFIX = "COREMARK_RESULT "
PASS_MARKER = "COREMARK_PASS"
FAIL_PREFIX = "COREMARK_FAIL"
REQUIRED_FIELDS = {"mode", "qualified", "memory", "iterations", "cycles", "cpu_hz"}
TOKEN = re.compile(r"([a-z_]+)=([^\s]+)")
def parse_number(value: str) -> int:
return int(value, 0)
def parse_log(content: str) -> dict[str, object]:
results: list[dict[str, object]] = []
for line in content.splitlines():
if not line.startswith(RESULT_PREFIX):
continue
fields = {name: value for name, value in TOKEN.findall(line)}
missing = REQUIRED_FIELDS.difference(fields)
if missing:
raise ValueError(f"CoreMark result is missing fields: {sorted(missing)}")
mode = fields["mode"]
if mode not in {"quick", "standard"}:
raise ValueError(f"unsupported CoreMark mode: {mode}")
memory = fields["memory"]
if memory != "sram":
raise ValueError(f"CoreMark result must execute from SRAM, got: {memory}")
qualified = parse_number(fields["qualified"])
if qualified not in {0, 1}:
raise ValueError("CoreMark qualified flag must be zero or one")
iterations = parse_number(fields["iterations"])
cycles = parse_number(fields["cycles"])
cpu_hz = parse_number(fields["cpu_hz"])
if iterations <= 0 or cycles <= 0 or cpu_hz <= 0:
raise ValueError("CoreMark iterations, cycles, and cpu_hz must be positive")
try:
score = (Decimal(iterations) * Decimal(1_000_000) / Decimal(cycles)).quantize(
Decimal("0.001"), rounding=ROUND_HALF_UP
)
except (InvalidOperation, ZeroDivisionError) as error:
raise ValueError("invalid CoreMark score inputs") from error
results.append(
{
"mode": mode,
"qualified": bool(qualified),
"memory": memory,
"iterations": iterations,
"cycles": cycles,
"cpu_hz": cpu_hz,
"coremark_per_mhz": str(score),
}
)
pass_marker = PASS_MARKER in content
failure_marker = any(line.startswith(FAIL_PREFIX) for line in content.splitlines())
quick_results = [result for result in results if result["mode"] == "quick"]
passed = pass_marker and not failure_marker and len(quick_results) == 1
return {
"schema_version": 1,
"status": "passed" if passed else "failed",
"failure_marker": failure_marker,
"pass_marker": pass_marker,
"results": results,
}
def atomic_write(path: Path, content: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
temporary = path.with_suffix(path.suffix + ".tmp")
temporary.write_text(content, encoding="utf-8")
temporary.replace(path)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--log", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
return parser.parse_args()
def main() -> int:
args = parse_args()
report = parse_log(args.log.read_text(encoding="utf-8", errors="replace"))
atomic_write(args.output, json.dumps(report, indent=2, sort_keys=True) + "\n")
if report["status"] != "passed":
print("CoreMark did not emit one complete quick passing report", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())
+7 -3
View File
@@ -37,7 +37,6 @@ PR_COMMANDS = (
(
"SIMU=IVERILOG",
"SIM_FIRMWARE_NAME=retrosoc_asm",
"SIM_SUCCESS_MARKER=Mem wr/rd test success",
"RTL_SIM_TIMEOUT=5200000",
"netsim",
),
@@ -56,7 +55,13 @@ SMOKE_COMMANDS = (
("SIMU=IVERILOG", "RTL_SIM_TIMEOUT=5200000", "sim-asm"),
),
)
NIGHTLY_COMMANDS = PR_COMMANDS
NIGHTLY_COMMANDS = (
*PR_COMMANDS,
(
"configs/benchmark/ihp130-hazard3-coremark.mk",
("SIMU=VERILATOR", "HAVE_SVA=YES", "coremark-report"),
),
)
PR_PROFILES = ("configs/ci/ihp130.mk",)
SMOKE_PROFILES: tuple[str, ...] = ()
NIGHTLY_PROFILES = PR_PROFILES
@@ -82,7 +87,6 @@ def pdk_pr_commands(profile: str) -> tuple[tuple[str, tuple[str, ...]], ...]:
(
"SIMU=IVERILOG",
"SIM_FIRMWARE_NAME=retrosoc_asm",
"SIM_SUCCESS_MARKER=Mem wr/rd test success",
"RTL_SIM_TIMEOUT=5200000",
"netsim",
),