Files
retroSoC/rtl/mini/script/gen_iverilog_filelist.py
T
maksyuki f5b373fd65 feat: enhance build variant ID generation and regression environment setup
- Added timestamp normalization to  function in , allowing for optional timestamp input.
- Updated command-line interface to accept a timestamp argument for generating deterministic build variant IDs.
- Modified  in  to include a build timestamp in the environment variables.
- Introduced a new test suite in  to validate the pin-map generator, including tests for duplicate pads and invalid entries.
- Added a test for ensuring the regression runner uses a consistent build timestamp.
- Created a new SystemVerilog testbench for the APB4 interface bridge to verify correct signal crossing.
2026-07-21 10:59:31 +08:00

90 lines
3.2 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import argparse
import gzip
from pathlib import Path
from filelist import atomic_write, parse_filelists, write_filelist
SCRIPT_DIR = Path(__file__).resolve().parent
MINI_DIR = SCRIPT_DIR.parent
DEFAULT_GENERATED_DIR = MINI_DIR / ".generated_fl"
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Generate an Icarus Verilog filelist")
parser.add_argument("--mode", required=True, choices=("behv", "netl", "post"))
parser.add_argument("--pdk", required=True)
parser.add_argument("--generated-dir", type=Path, default=DEFAULT_GENERATED_DIR)
parser.add_argument("--pin-map-rtl-dir", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--converted", type=Path)
parser.add_argument("--netlist", type=Path)
parser.add_argument("--sdf", type=Path)
parser.add_argument("--sdf-scope", default="retrosoc_tb.u_retrosoc_asic")
return parser.parse_args()
def _require(path: Path | None, description: str) -> Path:
if path is None or not path.is_file():
raise FileNotFoundError(f"{description} not found: {path}")
return path.resolve()
def _prepare_sdf(source: Path, output_dir: Path, scope: str) -> Path:
sdf_output = output_dir / "timing.sdf"
if source.suffix == ".gz":
content = gzip.open(source, "rt", encoding="utf-8", errors="replace").read()
else:
content = source.read_text(encoding="utf-8", errors="replace")
atomic_write(sdf_output, content)
annotator = output_dir / "sdf_annotator.sv"
escaped_sdf = str(sdf_output.resolve()).replace("\\", "\\\\").replace('"', '\\"')
atomic_write(
annotator,
"module retrosoc_sdf_annotator;\n"
" initial begin\n"
f' $sdf_annotate("{escaped_sdf}", {scope}, , "sdf.log", "MINIMUM");\n'
" end\n"
"endmodule\n",
)
return annotator
def main() -> int:
args = parse_args()
generated_dir = args.generated_dir.resolve()
base_names = ["def.fl", "sys_def.fl", "inc.fl", "tb.fl"]
base = parse_filelists(generated_dir / name for name in base_names)
base.options.insert(0, "+timescale+1ns/1ps")
pin_map_rtl_dir = args.pin_map_rtl_dir.resolve()
if not pin_map_rtl_dir.is_dir():
raise FileNotFoundError(f"pin-map RTL directory not found: {pin_map_rtl_dir}")
base.incdirs.append(pin_map_rtl_dir)
if args.mode == "behv":
base.files.append(_require(args.converted, "converted behavioral RTL"))
else:
common = parse_filelists([generated_dir / "commonip.fl"])
base.extend(common)
base.files.append(_require(args.netlist, f"{args.mode} netlist"))
if args.mode == "post":
sdf = _require(args.sdf, "post-layout SDF")
base.files.append(_prepare_sdf(sdf, args.output.resolve().parent, args.sdf_scope))
pdk_filelist = generated_dir / f"pdk_{args.pdk.lower()}.fl"
base.extend(parse_filelists([pdk_filelist]))
base.deduplicate()
write_filelist(args.output.resolve(), base)
print(f"generated {args.mode} filelist: {args.output.resolve()}")
return 0
if __name__ == "__main__":
raise SystemExit(main())