Files
retroSoC/physical/librelane/mini/scripts/package.py
T
maksyuki c8187284d0 feat(tiny): add scripts for SDC generation and packaging
- Introduced  to create pad-aware timing constraints for the Tiny IHP130 chip flow.
- Added  to create a checksummed delivery archive for the Tiny LibreLane implementation.
- Created  for synthesis-only header of the locked IHP SRAM macro physical views.
- Implemented  to limit OpenSTA report enumeration for path counts.
- Updated  to include power pad definitions.
- Enhanced  to handle power pad counts and validation.
- Added tests for Tiny flow and pin map validation, including power pad overrides and constraints.
2026-09-27 08:48:12 +08:00

78 lines
3.0 KiB
Python
Executable File

#!/usr/bin/env python3
"""Create a checksummed LibreLane implementation delivery archive."""
from __future__ import annotations
import argparse
import hashlib
import shutil
import tarfile
import tempfile
from pathlib import Path
def hash_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as source:
while block := source.read(1024 * 1024):
digest.update(block)
return digest.hexdigest()
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, required=True)
parser.add_argument("--variant-root", type=Path, required=True)
parser.add_argument("--run-root", type=Path, required=True)
parser.add_argument("--target", choices=("chip", "core"), required=True)
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
root = args.root.resolve()
variant_root = args.variant_root.resolve()
run_root = args.run_root.resolve()
required = (
run_root / "config.json",
run_root / "result.json",
run_root / "final",
run_root / "runs/current",
variant_root / "meta/manifest.json",
variant_root / f"meta/librelane-{args.target}-doctor.json",
variant_root / f"meta/librelane-{args.target}.json",
root / "dependencies/dependencies.lock.json",
)
missing = [str(path) for path in required if not path.exists()]
if missing:
parser.error("missing LibreLane delivery input(s): " + ", ".join(missing))
args.output.parent.mkdir(parents=True, exist_ok=True)
with tempfile.TemporaryDirectory(prefix="retrosoc-librelane-package-") as temporary:
staging = Path(temporary) / f"retrosoc-ihp130-{args.target}"
shutil.copytree(run_root / "final", staging / "final")
shutil.copytree(run_root / "runs/current", staging / "evidence/run")
shutil.copy2(run_root / "config.json", staging / "evidence/config.json")
shutil.copy2(run_root / "result.json", staging / "evidence/result.json")
shutil.copy2(variant_root / "meta/manifest.json", staging / "evidence/manifest.json")
shutil.copy2(
variant_root / f"meta/librelane-{args.target}-doctor.json",
staging / "evidence/librelane-doctor.json",
)
shutil.copy2(
variant_root / f"meta/librelane-{args.target}.json",
staging / f"evidence/librelane-{args.target}.json",
)
shutil.copy2(
root / "dependencies/dependencies.lock.json",
staging / "evidence/dependencies.lock.json",
)
files = sorted(path for path in staging.rglob("*") if path.is_file())
sums = "\n".join(f"{hash_file(path)} {path.relative_to(staging)}" for path in files)
(staging / "SHA256SUMS").write_text(sums + "\n", encoding="utf-8")
with tarfile.open(args.output, "w:gz") as archive:
archive.add(staging, arcname=staging.name)
print(f"created LibreLane delivery: {args.output}")
return 0
if __name__ == "__main__":
raise SystemExit(main())