mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
- Introduced a new ECC directory containing scripts and Makefile for the padless ICS55 core hardening flow. - Updated the main Makefile to include the new ECC Makefile and added relevant help commands. - Added dependencies for the ECC CLI in the dependencies.lock.json file. - Created README documentation for the ECC flow detailing usage and requirements. - Implemented various scripts for configuration generation, validation, output checking, and packaging of ECC results. - Added unit tests to validate the ECC configuration and flow behavior.
108 lines
3.6 KiB
Python
108 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate a padless ICS55 ECC project configuration from canonical inputs."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
from pathlib import Path
|
|
|
|
|
|
EXPECTED_CLOCKS = (
|
|
"clk_external",
|
|
"clk_system",
|
|
"clk_audio",
|
|
"clk_jtag",
|
|
"clk_dvp",
|
|
"clk_usb2_ulpi",
|
|
)
|
|
|
|
|
|
def relative(path: Path, base: Path) -> str:
|
|
return os.path.relpath(path.resolve(), base.resolve())
|
|
|
|
|
|
def render(args: argparse.Namespace) -> str:
|
|
project_dir = args.output.resolve().parent
|
|
pdk_root = args.pdk_root.resolve()
|
|
sdc = args.sdc.resolve()
|
|
liberty = args.h7cr_liberty.resolve()
|
|
tech = pdk_root / "prtech/techLEF/N551P6M_ecos.lef"
|
|
lef = (
|
|
pdk_root
|
|
/ "IP/STD_cell/ics55_LLSC_H7C_V1p10C100/ics55_LLSC_H7CR/lef/"
|
|
"ics55_LLSC_H7CR_ecos.lef"
|
|
)
|
|
required = (args.rtl.resolve(), sdc, pdk_root, tech, lef, liberty)
|
|
missing = [str(path) for path in required if not path.exists()]
|
|
if missing:
|
|
raise FileNotFoundError("missing ECC configuration input(s): " + ", ".join(missing))
|
|
sdc_text = sdc.read_text(encoding="utf-8")
|
|
missing_clocks = [clock for clock in EXPECTED_CLOCKS if f"-name {clock}" not in sdc_text]
|
|
if missing_clocks:
|
|
raise ValueError("ECC SDC is missing clock(s): " + ", ".join(missing_clocks))
|
|
|
|
return "\n".join(
|
|
(
|
|
"# Generated by physical/ecc/scripts/generate_config.py; do not edit.",
|
|
"[design]",
|
|
'name = "retrosoc_core"',
|
|
'top = "retrosoc_core"',
|
|
f'rtl = ["{relative(args.rtl, project_dir)}"]',
|
|
'clock_port = "extclk_i_pad"',
|
|
f"frequency_mhz = {args.ext_clk_hz / 1_000_000:.9g}",
|
|
"",
|
|
"[pdk]",
|
|
'name = "ics55"',
|
|
f'root = "{relative(pdk_root, project_dir)}"',
|
|
"",
|
|
"# ECC v0.1.0-alpha.10 resolves PDK content paths relative to pdk.root.",
|
|
"# Supply only the padless H7CR core library and the generated multi-clock SDC.",
|
|
"[pdk.overrides]",
|
|
f'tech = "{relative(tech, pdk_root)}"',
|
|
f'lefs = ["{relative(lef, pdk_root)}"]',
|
|
f'libs = ["{relative(liberty, pdk_root)}"]',
|
|
f'sdc = "{relative(sdc, project_dir)}"',
|
|
'site_core = "core7"',
|
|
'tap_cell = "FILLTAPH7R"',
|
|
'end_cap = "FILLTAPH7R"',
|
|
'fillers = ["FILLER64H7R", "FILLER32H7R", "FILLER16H7R", "FILLER8H7R", "FILLER4H7R", "FILLER2H7R", "FILLER1H7R"]',
|
|
"",
|
|
"[flow]",
|
|
'preset = "harden"',
|
|
'run = "default"',
|
|
"",
|
|
"[params.floorplan]",
|
|
"core_util = 0.60",
|
|
"aspect_ratio = 1.0",
|
|
"",
|
|
"[params.place]",
|
|
"target_density = 0.55",
|
|
"",
|
|
)
|
|
)
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--rtl", type=Path, required=True)
|
|
parser.add_argument("--sdc", type=Path, required=True)
|
|
parser.add_argument("--pdk-root", type=Path, required=True)
|
|
parser.add_argument("--h7cr-liberty", type=Path, required=True)
|
|
parser.add_argument("--ext-clk-hz", type=int, required=True)
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
if args.ext_clk_hz <= 0:
|
|
parser.error("--ext-clk-hz must be positive")
|
|
try:
|
|
content = render(args)
|
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
|
args.output.write_text(content, encoding="utf-8")
|
|
except (OSError, ValueError) as error:
|
|
parser.error(str(error))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|