mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-04 22:32:36 +00:00
feat: add smoke regression suite for IHP130 and enhance regression workflows
This commit is contained in:
10 files changed
+167
-37
No files matched your search
+3
-3
@@ -4,9 +4,9 @@ This directory owns repository automation metadata: pull-request templates,
|
||||
CODEOWNERS, Dependabot configuration, reusable actions, and CI/release
|
||||
workflows.
|
||||
|
||||
`workflows/quality.yml` runs the fast quality gate. `workflows/regression.yml`,
|
||||
`workflows/regression-gf180.yml`, `workflows/regression-sky130.yml`, and
|
||||
`workflows/nightly.yml` call the reusable regression workflow;
|
||||
`workflows/quality.yml` runs the fast quality gate. `workflows/regression-smoke.yml`,
|
||||
`workflows/regression-ihp130.yml`, `workflows/regression-gf180.yml`,
|
||||
`workflows/regression-sky130.yml`, and `workflows/nightly.yml` call the reusable regression workflow;
|
||||
`workflows/release.yml` packages tagged releases. `actions/locked-tools/`
|
||||
installs the locked open-source tools used by CI.
|
||||
|
||||
|
||||
@@ -20,6 +20,21 @@ on:
|
||||
required: false
|
||||
default: 30
|
||||
type: number
|
||||
timeout_minutes:
|
||||
description: Maximum job duration
|
||||
required: false
|
||||
default: 240
|
||||
type: number
|
||||
toolset:
|
||||
description: Space-separated locked tools required by this suite
|
||||
required: false
|
||||
default: verilator sv2v iverilog yosys opensta riscv_gnu
|
||||
type: string
|
||||
full_flow_checks:
|
||||
description: Check Yosys and OpenSTA environments before running the suite
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -27,7 +42,7 @@ permissions:
|
||||
jobs:
|
||||
regression:
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 240
|
||||
timeout-minutes: ${{ inputs.timeout_minutes }}
|
||||
env:
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
steps:
|
||||
@@ -87,19 +102,25 @@ jobs:
|
||||
- name: Set up locked EDA and compiler tools
|
||||
uses: ./.github/actions/locked-tools
|
||||
with:
|
||||
tools: verilator sv2v iverilog yosys opensta riscv_gnu
|
||||
tools: ${{ inputs.toolset }}
|
||||
|
||||
- name: Set up locked source dependencies
|
||||
run: make CONFIG=${{ inputs.profile }} setup
|
||||
|
||||
- name: Check environment
|
||||
- name: Check behavioral environments
|
||||
run: |
|
||||
make CONFIG=${{ inputs.profile }} \
|
||||
SIMU=IVERILOG SYNTH=NONE STA=NONE doctor
|
||||
make CONFIG=${{ inputs.profile }} \
|
||||
SIMU=VERILATOR SYNTH=NONE STA=NONE doctor
|
||||
|
||||
- name: Check synthesis and timing environments
|
||||
if: inputs.full_flow_checks
|
||||
run: |
|
||||
make CONFIG=${{ inputs.profile }} \
|
||||
SIMU=IVERILOG SYNTH=YOSYS STA=NONE doctor
|
||||
make CONFIG=${{ inputs.profile }} SIMU=VERILATOR doctor
|
||||
|
||||
- name: Check timing environment
|
||||
run: make CONFIG=${{ inputs.profile }} SIMU=IVERILOG STA=OPENSTA doctor
|
||||
make CONFIG=${{ inputs.profile }} \
|
||||
SIMU=IVERILOG SYNTH=NONE STA=OPENSTA doctor
|
||||
|
||||
- name: Run ${{ inputs.suite }} regression
|
||||
run: python3 scripts/regress.py --root . --suite "${{ inputs.suite }}" --pdk "${{ inputs.pdk }}"
|
||||
|
||||
@@ -81,3 +81,4 @@ jobs:
|
||||
python3 scripts/regress.py --root . --suite pr --pdk GF180 --dry-run
|
||||
python3 scripts/regress.py --root . --suite pr --pdk SKY130 --dry-run
|
||||
python3 scripts/regress.py --root . --suite nightly --pdk IHP130 --dry-run
|
||||
python3 scripts/regress.py --root . --suite smoke --pdk IHP130 --dry-run
|
||||
File renamed without changes.
@@ -0,0 +1,27 @@
|
||||
name: regression-smoke
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev]
|
||||
pull_request:
|
||||
branches: [main, dev]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: regression-smoke-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
ihp130-smoke:
|
||||
uses: ./.github/workflows/_regression.yml
|
||||
with:
|
||||
suite: smoke
|
||||
pdk: IHP130
|
||||
profile: configs/ci/hazard3-rv32im-ihp130.mk
|
||||
retention_days: 14
|
||||
timeout_minutes: 60
|
||||
toolset: verilator sv2v iverilog riscv_gnu
|
||||
full_flow_checks: false
|
||||
@@ -168,7 +168,7 @@ endif
|
||||
|
||||
.PHONY: help config doctor setup setup-mpw setup-core setup-clusterip setup-ip setup-pdk setup-app \
|
||||
clean-all purge-cache manifest check-warnings metrics check-metrics package \
|
||||
regress-pr regress-nightly sim-asm format format-check sw-format sw-format-check mk-format \
|
||||
regress-smoke regress-pr regress-nightly sim-asm format format-check sw-format sw-format-check mk-format \
|
||||
mk-format-check rtl-format rtl-format-check sw-policy-check sw-host-test \
|
||||
pin-map check-pin-map soc-topology check-soc-topology user-extensions check-user-extensions \
|
||||
check-clock-reset-domains tech-cell-test
|
||||
@@ -206,7 +206,8 @@ help:
|
||||
' rtl-format | rtl-format-check apply/check self-owned RTL formatting' \
|
||||
' sw-policy-check check embedded C API and naming policy' \
|
||||
' sw-host-test run host tests for deterministic SDK utilities' \
|
||||
' regress-pr | regress-nightly run supported regression suites' \
|
||||
' regress-smoke run the IHP130 fast regression suite' \
|
||||
' regress-pr | regress-nightly run supported full regression suites' \
|
||||
' package create checksummed source deliverables' \
|
||||
' clean | clean-all clean current flow or all build output' \
|
||||
' purge-cache remove dependency and compiler caches' \
|
||||
@@ -317,6 +318,9 @@ package: $(MPW_VARIANT_STAMP) $(FILELIST_STAMP) manifest
|
||||
python3 $(ROOT_PATH)/scripts/package.py --root $(ROOT_PATH) --lock $(LOCK_FILE) \
|
||||
--variant-root $(VARIANT_ROOT) --output-dir $(ROOT_PATH)/dist/$(VARIANT_ID)
|
||||
|
||||
regress-smoke:
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite smoke --pdk IHP130
|
||||
|
||||
regress-pr:
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite pr --pdk IHP130
|
||||
python3 $(ROOT_PATH)/scripts/regress.py --root $(ROOT_PATH) --suite pr --pdk GF180
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# retroSoC
|
||||
|
||||
[](https://github.com/retroSoC/retroSoC/actions/workflows/quality.yml)
|
||||
[](https://github.com/retroSoC/retroSoC/actions/workflows/regression.yml)
|
||||
[](https://github.com/retroSoC/retroSoC/actions/workflows/regression-ihp130.yml)
|
||||
[](https://github.com/retroSoC/retroSoC/actions/workflows/regression-gf180.yml)
|
||||
[](https://github.com/retroSoC/retroSoC/actions/workflows/regression-sky130.yml)
|
||||
[](https://github.com/retroSoC/retroSoC/actions/workflows/nightly.yml)
|
||||
@@ -123,14 +123,19 @@ make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk SIMU=IVERILOG \
|
||||
| Yosys synthesis | `make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk SYNTH=YOSYS synth` |
|
||||
| Icarus netlist simulation after synthesis | `make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk SIMU=IVERILOG netsim` |
|
||||
| OpenSTA core timing analysis after synthesis | `make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk STA=OPENSTA sta` |
|
||||
`make regress-pr` runs the supported IHP130, GF180, and SKY130 PR matrices in
|
||||
sequence, including slow-corner OpenSTA core timing analysis for each PDK.
|
||||
| IHP130 fast smoke suite | `make regress-smoke` |
|
||||
| Pull-request regression suite | `make regress-pr` |
|
||||
| Nightly regression suite | `make regress-nightly` |
|
||||
| Format C, Makefile, and RTL sources | `make format` |
|
||||
| Check C, Makefile, and RTL formatting | `make format-check` |
|
||||
| Script and policy checks | `make sw-policy-check sw-host-test` |
|
||||
|
||||
`make regress-smoke` builds the IHP130 firmware, compiles the Verilator SVA
|
||||
configuration, and runs the Icarus assembly self-test. It omits synthesis,
|
||||
timing, and netlist simulation for fast feedback. `make regress-pr` runs the
|
||||
supported IHP130, GF180, and SKY130 PR matrices in sequence, including
|
||||
slow-corner OpenSTA core timing analysis for each PDK.
|
||||
|
||||
Build outputs are isolated below `build/<profile>-<YYYY-MM-DD-HH-MM>-<config-hash>/`. Each variant keeps its
|
||||
firmware, generated sources, simulator output, synthesis and timing reports, manifest, warning
|
||||
analysis, and metrics separate from other configurations. Use `make clean` to remove the
|
||||
|
||||
+5
-3
@@ -4,6 +4,7 @@
|
||||
|
||||
| Tier | Profile | Automated coverage |
|
||||
| --- | --- | --- |
|
||||
| Smoke | `configs/ci/hazard3-rv32im-ihp130.mk` | firmware, Verilator SVA compilation, Icarus assembly self-test |
|
||||
| Pull request | `configs/ci/hazard3-rv32im-ihp130.mk` | firmware, Verilator, Icarus, Yosys, netlist Icarus, OpenSTA |
|
||||
| Pull request | `configs/ci/hazard3-rv32im-gf180.mk` | firmware, Verilator, Icarus, Yosys, netlist Icarus, OpenSTA |
|
||||
| Pull request | `configs/ci/hazard3-rv32im-sky130.mk` | firmware, Verilator, Icarus, Yosys, netlist Icarus, OpenSTA |
|
||||
@@ -136,9 +137,10 @@ for diagnosis but is initially non-blocking.
|
||||
## CI And Releases
|
||||
|
||||
`quality.yml` validates C, Makefile, and self-owned RTL formatting as well as Python, YAML, GitHub
|
||||
Actions, the dependency lock, and script tests. `regression.yml` runs verified configurations on pull
|
||||
requests and main branches without repeating the format checks. `nightly.yml` adds PICORV32. Source
|
||||
dependencies, locked tool archives, and Verilator `ccache` use separate cache keys.
|
||||
Actions, the dependency lock, and script tests. `regression-smoke.yml` provides fast IHP130 feedback;
|
||||
the three full PDK regression workflows remain required PR coverage and do not repeat the format checks.
|
||||
`nightly.yml` adds PICORV32. Source dependencies, locked tool archives, and Verilator `ccache` use
|
||||
separate cache keys.
|
||||
|
||||
Tags matching `v*` run `release.yml`. The release contains a flattened SystemVerilog export, a source
|
||||
tarball, build manifest, dependency lock, CycloneDX SBOM, and `SHA256SUMS`. `make package` creates the
|
||||
|
||||
+39
-18
@@ -48,6 +48,17 @@ PR_COMMANDS = (
|
||||
),
|
||||
("configs/ci/hazard3-rv32im-ihp130.mk", ("STA=OPENSTA", "sta")),
|
||||
)
|
||||
SMOKE_COMMANDS = (
|
||||
("configs/ci/hazard3-rv32im-ihp130.mk", ("firmware",)),
|
||||
(
|
||||
"configs/ci/hazard3-rv32im-ihp130.mk",
|
||||
("SIMU=VERILATOR", "HAVE_SVA=YES", "comp"),
|
||||
),
|
||||
(
|
||||
"configs/ci/hazard3-rv32im-ihp130.mk",
|
||||
("SIMU=IVERILOG", "RTL_SIM_TIMEOUT=5200000", "sim-asm"),
|
||||
),
|
||||
)
|
||||
NIGHTLY_COMMANDS = PR_COMMANDS + (
|
||||
(
|
||||
"configs/nightly/picorv32-rv32im-ihp130.mk",
|
||||
@@ -63,6 +74,7 @@ PR_PROFILES = (
|
||||
"configs/ci/hazard3-rv32im-ihp130-ip-mdd.mk",
|
||||
"configs/ci/mdd-rv32im-ihp130.mk",
|
||||
)
|
||||
SMOKE_PROFILES: tuple[str, ...] = ()
|
||||
NIGHTLY_PROFILES = PR_PROFILES + ("configs/nightly/picorv32-rv32im-ihp130.mk",)
|
||||
|
||||
PDK_PR_PROFILES = {
|
||||
@@ -92,6 +104,27 @@ def pdk_pr_commands(profile: str) -> tuple[tuple[str, tuple[str, ...]], ...]:
|
||||
)
|
||||
|
||||
|
||||
def select_regression(
|
||||
suite: str, pdk: str | None
|
||||
) -> tuple[tuple[tuple[str, tuple[str, ...]], ...], tuple[str, ...]]:
|
||||
if suite == "smoke":
|
||||
if pdk is not None and pdk != "IHP130":
|
||||
raise ValueError("smoke regression supports only --pdk IHP130")
|
||||
return SMOKE_COMMANDS, SMOKE_PROFILES
|
||||
if pdk:
|
||||
if suite == "nightly":
|
||||
if pdk != "IHP130":
|
||||
raise ValueError("nightly regression supports only --pdk IHP130")
|
||||
return NIGHTLY_COMMANDS, NIGHTLY_PROFILES
|
||||
if pdk == "IHP130":
|
||||
return PR_COMMANDS, PR_PROFILES
|
||||
profile = PDK_PR_PROFILES[pdk]
|
||||
return pdk_pr_commands(profile), (profile,)
|
||||
if suite == "pr":
|
||||
return PR_COMMANDS, PR_PROFILES
|
||||
return NIGHTLY_COMMANDS, NIGHTLY_PROFILES
|
||||
|
||||
|
||||
def regression_environment() -> dict[str, str]:
|
||||
environment = os.environ.copy()
|
||||
environment.setdefault(
|
||||
@@ -124,26 +157,14 @@ def run_command(
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Run a supported retroSoC regression suite")
|
||||
parser.add_argument("--root", type=Path, required=True)
|
||||
parser.add_argument("--suite", choices=("pr", "nightly"), required=True)
|
||||
parser.add_argument("--pdk", choices=tuple(PDK_PR_PROFILES), help="run one PR PDK matrix")
|
||||
parser.add_argument("--suite", choices=("smoke", "pr", "nightly"), required=True)
|
||||
parser.add_argument("--pdk", choices=tuple(PDK_PR_PROFILES), help="run one PDK matrix")
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
args = parser.parse_args()
|
||||
if args.pdk:
|
||||
if args.suite == "nightly":
|
||||
if args.pdk != "IHP130":
|
||||
parser.error("nightly regression supports only --pdk IHP130")
|
||||
commands = NIGHTLY_COMMANDS
|
||||
profiles = NIGHTLY_PROFILES
|
||||
elif args.pdk == "IHP130":
|
||||
commands = PR_COMMANDS
|
||||
profiles = PR_PROFILES
|
||||
else:
|
||||
profile = PDK_PR_PROFILES[args.pdk]
|
||||
commands = pdk_pr_commands(profile)
|
||||
profiles = (profile,)
|
||||
else:
|
||||
commands = PR_COMMANDS if args.suite == "pr" else NIGHTLY_COMMANDS
|
||||
profiles = PR_PROFILES if args.suite == "pr" else NIGHTLY_PROFILES
|
||||
try:
|
||||
commands, profiles = select_regression(args.suite, args.pdk)
|
||||
except ValueError as error:
|
||||
parser.error(str(error))
|
||||
environment = regression_environment()
|
||||
for profile, values in commands:
|
||||
command = ["make", f"CONFIG={profile}", *values]
|
||||
|
||||
@@ -31,8 +31,10 @@ from scripts.regress import ( # noqa: E402
|
||||
NIGHTLY_COMMANDS,
|
||||
PDK_PR_PROFILES,
|
||||
PR_COMMANDS,
|
||||
SMOKE_COMMANDS,
|
||||
pdk_pr_commands,
|
||||
regression_environment,
|
||||
select_regression,
|
||||
)
|
||||
from scripts import setup_helpers # noqa: E402
|
||||
from scripts.setup_helpers import download_file, ensure_git_repo # noqa: E402
|
||||
@@ -360,13 +362,60 @@ def test_verilator_simulations_use_uniform_timeout() -> None:
|
||||
verilator_makefile = ROOT / "rtl/mini/mk/verilator.mk"
|
||||
assert "SOC_SIM_TIME ?= 180" in verilator_makefile.read_text(encoding="utf-8")
|
||||
|
||||
regression_commands = (*PR_COMMANDS, *NIGHTLY_COMMANDS)
|
||||
regression_commands = (*SMOKE_COMMANDS, *PR_COMMANDS, *NIGHTLY_COMMANDS)
|
||||
for _, values in regression_commands:
|
||||
if "SIMU=VERILATOR" in values:
|
||||
assert not any(value.startswith("SOC_SIM_TIME=") for value in values)
|
||||
assert "HAVE_SVA=YES" in values
|
||||
|
||||
|
||||
def test_smoke_regression_uses_ihp130_behavioral_coverage_only() -> None:
|
||||
commands, profiles = select_regression("smoke", "IHP130")
|
||||
|
||||
assert commands == SMOKE_COMMANDS
|
||||
assert profiles == ()
|
||||
command_values = [values for _, values in commands]
|
||||
assert ("firmware",) in command_values
|
||||
assert ("SIMU=VERILATOR", "HAVE_SVA=YES", "comp") in command_values
|
||||
assert ("SIMU=IVERILOG", "RTL_SIM_TIMEOUT=5200000", "sim-asm") in command_values
|
||||
assert not any(
|
||||
"synth" in values or "sta" in values or "netsim" in values
|
||||
for values in command_values
|
||||
)
|
||||
|
||||
dry_run = run(
|
||||
sys.executable,
|
||||
str(ROOT / "scripts/regress.py"),
|
||||
"--root",
|
||||
str(ROOT),
|
||||
"--suite",
|
||||
"smoke",
|
||||
"--pdk",
|
||||
"IHP130",
|
||||
"--dry-run",
|
||||
)
|
||||
assert "+ make CONFIG=configs/ci/hazard3-rv32im-ihp130.mk firmware" in dry_run.stdout
|
||||
assert "netsim" not in dry_run.stdout
|
||||
|
||||
invalid = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(ROOT / "scripts/regress.py"),
|
||||
"--root",
|
||||
str(ROOT),
|
||||
"--suite",
|
||||
"smoke",
|
||||
"--pdk",
|
||||
"GF180",
|
||||
"--dry-run",
|
||||
],
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
assert invalid.returncode != 0
|
||||
assert "smoke regression supports only --pdk IHP130" in invalid.stderr
|
||||
|
||||
|
||||
def test_pdk_pr_regressions_cover_firmware_rtl_and_netlist() -> None:
|
||||
assert set(PDK_PR_PROFILES) == {"GF180", "IHP130", "SKY130"}
|
||||
for profile in PDK_PR_PROFILES.values():
|
||||
|
||||
Reference in new issue
Block a user