-
Notifications
You must be signed in to change notification settings - Fork 305
Expand file tree
/
Copy pathorfs_config_gen.py
More file actions
73 lines (70 loc) · 3.26 KB
/
orfs_config_gen.py
File metadata and controls
73 lines (70 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import sys
from pathlib import Path
from datetime import datetime
from pdk_validator import validate_netlist, PDKValidator
PDK_DEFAULTS = {
"sky130": {
"PLATFORM": "sky130hd",
"SCL": "sky130_fd_sc_hd",
"TARGET_DENSITY": "0.65",
"CLOCK_PERIOD": "10.0",
"CORE_UTILIZATION": "40",
"CORE_ASPECT_RATIO": "1",
"CORE_MARGIN": "2",
}
}
def generate_config(cir_out_path, design_name=None, pdk="sky130",
clock_port="clk", clock_period_ns=None, output_dir="."):
print(f"[orfs_config_gen] Validating {cir_out_path} against {pdk} PDK...")
report = validate_netlist(cir_out_path, pdk)
PDKValidator.print_report(report)
if report["summary"] == "FAIL":
raise RuntimeError(f"Validation FAILED - {len(report['unmappable'])} unmappable primitive(s).")
if design_name is None:
design_name = Path(cir_out_path).stem.replace(".cir", "").replace(".", "_")
defaults = PDK_DEFAULTS.get(pdk, PDK_DEFAULTS["sky130"])
clk_period = str(clock_period_ns) if clock_period_ns else defaults["CLOCK_PERIOD"]
lines = [
f"# ORFS config.mk - auto-generated by eSim-ORFS integration",
f"# Source : {Path(cir_out_path).resolve()}",
f"# Generated : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
f"# PDK : {pdk}", f"",
f"export DESIGN_NAME = {design_name}",
f"export PLATFORM = {defaults['PLATFORM']}", f"",
f"export VERILOG_FILES = $(DESIGN_HOME)/src/$(DESIGN_NAME)/$(DESIGN_NAME).v",
f"export SDC_FILE = $(DESIGN_HOME)/src/$(DESIGN_NAME)/constraint.sdc",
f"export ABC_AREA = 0", f"",
f"export CORE_UTILIZATION = {defaults['CORE_UTILIZATION']}",
f"export CORE_ASPECT_RATIO = {defaults['CORE_ASPECT_RATIO']}",
f"export CORE_MARGIN = {defaults['CORE_MARGIN']}", f"",
f"export CLOCK_PORT = {clock_port}",
f"export CLOCK_PERIOD = {clk_period}", f"",
f"export TARGET_DENSITY = {defaults['TARGET_DENSITY']}", f"",
f"# Mapped cells ({len(report['valid_cells'])}):",
]
for cell in report["valid_cells"]:
lines.append(f"# {cell['name']} -> {cell['cell']}")
if report["analog_primitives"]:
lines.append(f"# Skipped analog ({len(report['analog_primitives'])}):")
for a in report["analog_primitives"]:
lines.append(f"# {a['name']} ({a['type'].upper()})")
out_path = Path(output_dir) / "config.mk"
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_text("\n".join(lines) + "\n")
print(f"[orfs_config_gen] config.mk written to: {out_path.resolve()}")
return str(out_path)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("netlist")
parser.add_argument("--design")
parser.add_argument("--pdk", default="sky130")
parser.add_argument("--clock-port", default="clk")
parser.add_argument("--clock-period", type=float)
parser.add_argument("--output-dir", default=".")
args = parser.parse_args()
try:
generate_config(args.netlist, args.design, args.pdk, args.clock_port, args.clock_period, args.output_dir)
except RuntimeError as e:
print(f"\n[ERROR] {e}")
sys.exit(1)