diff --git a/patches/fakeram/0001-Add-ORFS-ASAP7-backend.patch b/patches/fakeram/0001-Add-ORFS-ASAP7-backend.patch deleted file mode 100644 index d2ae3cd83a..0000000000 --- a/patches/fakeram/0001-Add-ORFS-ASAP7-backend.patch +++ /dev/null @@ -1,169 +0,0 @@ -diff --git a/BUILD.bazel b/BUILD.bazel -new file mode 100644 -index 0000000..16e9be4 ---- /dev/null -+++ b/BUILD.bazel -@@ -0,0 +1,5 @@ -+filegroup( -+ name = "all_files", -+ srcs = glob(["**/*"]), -+ visibility = ["//visibility:public"], -+) -diff --git a/MODULE.bazel b/MODULE.bazel -new file mode 100644 -index 0000000..f12bf1f ---- /dev/null -+++ b/MODULE.bazel -@@ -0,0 +1,4 @@ -+module( -+ name = "fakeram", -+ version = "2.0.0", -+) -diff --git a/orfs_asap7/__init__.py b/orfs_asap7/__init__.py -new file mode 100644 -index 0000000..edcf578 ---- /dev/null -+++ b/orfs_asap7/__init__.py -@@ -0,0 +1 @@ -+# ORFS ASAP7 package -diff --git a/orfs_asap7/generate.py b/orfs_asap7/generate.py -new file mode 100644 -index 0000000..58fef20 ---- /dev/null -+++ b/orfs_asap7/generate.py -@@ -0,0 +1,83 @@ -+import json -+import sys -+from pathlib import Path -+ -+from utils.class_process import Process -+from utils.memory_config import MemoryConfig -+from utils.memory_factory import MemoryFactory -+from utils.timing_data import TimingData -+from utils.ram_liberty_exporter import RAMLibertyExporter -+from utils.lef_exporter import LefExporter -+ -+ASAP7_PROCESS_CONFIG = { -+ "tech_nm": 7, -+ "voltage": 0.7, -+ "metal_prefix": "M", -+ "metal_layer": "M4", -+ "pin_width_nm": 24, -+ "pin_pitch_nm": 48, -+ "metal_track_pitch_nm": 48, -+ "manufacturing_grid_nm": 1, -+ "contacted_poly_pitch_nm": 54, -+ "fin_pitch_nm": 27, -+ "column_mux_factor": 1, -+ "snap_width_nm": 190, -+ "snap_height_nm": 1400, -+} -+ -+ASAP7_TIMING_CONFIG = { -+ "cycle_time": 1.0, -+ "access_time": 0.5, -+ "setup_time": 0.1, -+ "hold_time": 0.05, -+ "leakage": 0.001, -+} -+ -+def run_orfs_asap7(platform: str, out_dir: Path, json_path: Path): -+ if platform != "asap7": -+ sys.stderr.write(f"FakeRAM2.0 orfs_asap7: unsupported platform {platform}\n") -+ return 1 -+ -+ try: -+ data = json.loads(json_path.read_text()) -+ memories = data.get("memories", []) -+ except Exception as e: -+ sys.stderr.write(f"FakeRAM2.0 orfs_asap7: failed to read {json_path}: {e}\n") -+ return 1 -+ -+ out_dir.mkdir(parents=True, exist_ok=True) -+ converted = sorted((m for m in memories if m.get("idiomatic")), key=lambda m: m["name"]) -+ -+ process = Process(ASAP7_PROCESS_CONFIG) -+ timing_data = TimingData(ASAP7_TIMING_CONFIG) -+ -+ for m in converted: -+ name = m["name"] -+ bits = m.get("bits", 32) -+ rows = m.get("rows", 128) -+ -+ sram_dict = { -+ "name": name, -+ "width": bits, -+ "depth": rows, -+ "banks": 1, -+ } -+ mem_config = MemoryConfig.from_json(sram_dict) -+ ram = MemoryFactory.create(mem_config, "RAM", "SP", process, timing_data) -+ -+ # Export Liberty -+ lib_path = out_dir / f"{name}.lib" -+ with open(lib_path, "w") as f: -+ RAMLibertyExporter(ram).export(f) -+ -+ pre_lib_path = out_dir / f"{name}_pre_layout.lib" -+ with open(pre_lib_path, "w") as f: -+ RAMLibertyExporter(ram).export(f) -+ -+ # Export LEF -+ lef_path = out_dir / f"{name}.lef" -+ with open(lef_path, "w") as f: -+ LefExporter(ram).export(f) -+ -+ (out_dir / "blackboxes.txt").write_text("".join(f"{m['name']}\n" for m in converted)) -+ return 0 -diff --git a/run.py b/run.py -index f525c5f..06ae626 100755 ---- a/run.py -+++ b/run.py -@@ -8,6 +8,7 @@ from utils.class_process import Process - from utils.memory_config import MemoryConfig - from utils.memory_factory import MemoryFactory - from utils.timing_data import TimingData -+from orfs_asap7.generate import run_orfs_asap7 - - - def get_args() -> argparse.Namespace: -@@ -28,10 +29,19 @@ def get_args() -> argparse.Namespace: - required=False, - default="results", - ) -+ parser.add_argument( -+ "--orfs_asap7_backend", -+ action="store_true", -+ help="Use ORFS ASAP7 backend (expects JSON in memories.json format)", -+ ) - return parser.parse_args() - - - def main(args: argparse.Namespace): -+ if args.orfs_asap7_backend: -+ from pathlib import Path -+ return run_orfs_asap7(platform="asap7", out_dir=Path(args.output_dir), json_path=Path(args.config)) -+ - json_data = RunUtils.get_config(args.config) - # Create a process object (shared by all srams) - process = Process(json_data) -@@ -52,4 +62,4 @@ def main(args: argparse.Namespace): - ### Entry point - if __name__ == "__main__": - args = get_args() -- main(args) -+ sys.exit(main(args)) -diff --git a/utils/class_process.py b/utils/class_process.py -index e1cfac3..745285c 100644 ---- a/utils/class_process.py -+++ b/utils/class_process.py -@@ -119,6 +119,9 @@ class Process: - - total_height += additional_height - -+ min_height = max(3.5, self.snap_height_nm / 1000.0 if self.snap_height_nm else 0) -+ total_height = max(total_height, min_height) -+ - return (total_width, total_height) - - def get_tech_nm(self): diff --git a/tools/FakeRAM2.0/orfs_asap7/__init__.py b/tools/FakeRAM2.0/orfs_asap7/__init__.py new file mode 100644 index 0000000000..edcf5785fb --- /dev/null +++ b/tools/FakeRAM2.0/orfs_asap7/__init__.py @@ -0,0 +1 @@ +# ORFS ASAP7 package diff --git a/tools/FakeRAM2.0/orfs_asap7/generate.py b/tools/FakeRAM2.0/orfs_asap7/generate.py new file mode 100644 index 0000000000..be30f8f927 --- /dev/null +++ b/tools/FakeRAM2.0/orfs_asap7/generate.py @@ -0,0 +1,88 @@ +import json +import sys +from pathlib import Path + +from utils.class_process import Process +from utils.memory_config import MemoryConfig +from utils.memory_factory import MemoryFactory +from utils.timing_data import TimingData +from utils.ram_liberty_exporter import RAMLibertyExporter +from utils.lef_exporter import LefExporter + +ASAP7_PROCESS_CONFIG = { + "tech_nm": 7, + "voltage": 0.7, + "metal_prefix": "M", + "metal_layer": "M4", + "pin_width_nm": 24, + "pin_pitch_nm": 48, + "metal_track_pitch_nm": 48, + "manufacturing_grid_nm": 1, + "contacted_poly_pitch_nm": 54, + "fin_pitch_nm": 27, + "column_mux_factor": 1, + "snap_width_nm": 190, + "snap_height_nm": 1400, +} + +ASAP7_TIMING_CONFIG = { + "cycle_time": 1.0, + "access_time": 0.5, + "setup_time": 0.1, + "hold_time": 0.05, + "leakage": 0.001, +} + + +def run_orfs_asap7(platform: str, out_dir: Path, json_path: Path): + if platform != "asap7": + sys.stderr.write(f"FakeRAM2.0 orfs_asap7: unsupported platform {platform}\n") + return 1 + + try: + data = json.loads(json_path.read_text()) + memories = data.get("memories", []) + except Exception as e: + sys.stderr.write(f"FakeRAM2.0 orfs_asap7: failed to read {json_path}: {e}\n") + return 1 + + out_dir.mkdir(parents=True, exist_ok=True) + converted = sorted( + (m for m in memories if m.get("idiomatic")), key=lambda m: m["name"] + ) + + process = Process(ASAP7_PROCESS_CONFIG) + timing_data = TimingData(ASAP7_TIMING_CONFIG) + + for m in converted: + name = m["name"] + bits = m.get("bits", 32) + rows = m.get("rows", 128) + + sram_dict = { + "name": name, + "width": bits, + "depth": rows, + "banks": 1, + } + mem_config = MemoryConfig.from_json(sram_dict) + ram = MemoryFactory.create(mem_config, "RAM", "SP", process, timing_data) + + # Export Liberty + lib_path = out_dir / f"{name}.lib" + with open(lib_path, "w") as f: + RAMLibertyExporter(ram).export(f) + + pre_lib_path = out_dir / f"{name}_pre_layout.lib" + with open(pre_lib_path, "w") as f: + RAMLibertyExporter(ram).export(f) + + # Export LEF + lef_path = out_dir / f"{name}.lef" + with open(lef_path, "w") as f: + LefExporter(ram).export(f) + + (out_dir / "blackboxes.txt").write_text( + "".join(f"{m['name']}\n" for m in converted) + ) + return 0 diff --git a/tools/FakeRAM2.0/run.py b/tools/FakeRAM2.0/run.py index a89ce07234..3e10151b7f 100755 --- a/tools/FakeRAM2.0/run.py +++ b/tools/FakeRAM2.0/run.py @@ -8,6 +8,7 @@ from utils.memory_config import MemoryConfig from utils.memory_factory import MemoryFactory from utils.timing_data import TimingData +from orfs_asap7.generate import run_orfs_asap7 def get_args() -> argparse.Namespace: @@ -26,10 +27,22 @@ def get_args() -> argparse.Namespace: required=False, default="results", ) + parser.add_argument( + "--orfs_asap7_backend", + action="store_true", + help="Use ORFS ASAP7 backend (expects JSON in memories.json format)", + ) return parser.parse_args() def main(args: argparse.Namespace): + if args.orfs_asap7_backend: + from pathlib import Path + + return run_orfs_asap7( + platform="asap7", out_dir=Path(args.output_dir), json_path=Path(args.config) + ) + json_data = RunUtils.get_config(args.config) # Create a process object (shared by all srams) process = Process(json_data) @@ -50,4 +63,4 @@ def main(args: argparse.Namespace): ### Entry point if __name__ == "__main__": args = get_args() - main(args) + sys.exit(main(args)) diff --git a/tools/FakeRAM2.0/utils/class_process.py b/tools/FakeRAM2.0/utils/class_process.py index 487a853e6a..c11dae3d6a 100644 --- a/tools/FakeRAM2.0/utils/class_process.py +++ b/tools/FakeRAM2.0/utils/class_process.py @@ -119,6 +119,11 @@ def get_macro_dimensions(self, width_in_bits, depth, num_banks, additional_heigh total_height += additional_height + min_height = max( + 3.5, self.snap_height_nm / 1000.0 if self.snap_height_nm else 0 + ) + total_height = max(total_height, min_height) + return (total_width, total_height) def get_tech_nm(self):