|
1 | 1 | import os |
2 | | -import subprocess |
3 | 2 | from core.pdk_defines import DEFINES_BY_PDK, SUPPORTED_PDKS |
| 3 | +from core.log import print_blue, print_red, print_yellow, print_green |
| 4 | +from core import run_cmd, write_template_to_file |
| 5 | +from jinja2 import Environment, FileSystemLoader |
| 6 | +from core import ImplementationFlow |
| 7 | +from typing import Any, Dict |
| 8 | +from core import TEMPLATES_DIR, CONSTRAINTS_DIR |
4 | 9 |
|
5 | 10 |
|
6 | | -def run_asic_flow(pdk_name: str, project_files: list[str]) -> None: |
7 | | - pdk_name = pdk_name.lower() |
| 11 | +TOOLCHAINS_INSTALL_PATH = { |
| 12 | + 'openroad': os.getenv('OPENROAD_INSTALL_PATH', '/eda/asic/OpenROAD-flow-scripts/'), |
| 13 | +} |
| 14 | + |
| 15 | + |
| 16 | +# ------------------------- |
| 17 | +# OpenRoad Flow |
| 18 | +# ------------------------- |
| 19 | +class OpenRoadFlow(ImplementationFlow): |
| 20 | + def generate_project(self) -> None: |
| 21 | + print_blue(f"Running OpenRoad flow for PDK: '{self.technology}'") |
| 22 | + |
| 23 | + constraints: str = ( |
| 24 | + f'{CONSTRAINTS_DIR}/openroad.sdc' |
| 25 | + if self.constraint_file == 'default' |
| 26 | + else self.constraint_file |
| 27 | + ) |
| 28 | + |
| 29 | + context: Dict[str, Any] = { |
| 30 | + 'design_name': self.top_module, |
| 31 | + 'verilog_files': self.project_files, |
| 32 | + 'sdc_file': constraints, |
| 33 | + 'design_nickname': self.top_module, |
| 34 | + 'platform': self.technology, |
| 35 | + 'core_utilization': 5, |
| 36 | + 'place_density': 0.10, |
| 37 | + 'synth_hdl_frontend': 'slang', |
| 38 | + 'synth_hierarchical': False, |
| 39 | + 'synth_min_keep_size': 0, |
| 40 | + 'additional_lefs': False, |
| 41 | + 'additional_lef_files': DEFINES_BY_PDK[self.technology].get( |
| 42 | + 'additional_lef_files', [] |
| 43 | + ), |
| 44 | + 'additional_libs': False, |
| 45 | + 'additional_lib_files': DEFINES_BY_PDK[self.technology].get( |
| 46 | + 'additional_lib_files', [] |
| 47 | + ), |
| 48 | + } |
| 49 | + |
| 50 | + write_template_to_file(self.env, 'openroad.j2', context, 'openroad.mk') |
| 51 | + print_green( |
| 52 | + f"OpenRoad project files generated for '{self.technology}' PDK." |
| 53 | + ) |
| 54 | + |
| 55 | + def run_tool(self) -> None: |
| 56 | + openroad_path = TOOLCHAINS_INSTALL_PATH.get('openroad', '') |
| 57 | + if not openroad_path or not os.path.exists(openroad_path): |
| 58 | + raise EnvironmentError( |
| 59 | + 'OpenRoad toolchain path is not set or does not exist.' |
| 60 | + ) |
| 61 | + |
| 62 | + openroad_makefile_path = os.path.join(openroad_path, 'flow/Makefile') |
| 63 | + |
| 64 | + run_cmd( |
| 65 | + [ |
| 66 | + 'make', |
| 67 | + f'--file={openroad_makefile_path}', |
| 68 | + 'DESIGN_CONFIG=openroad.mk', |
| 69 | + ] |
| 70 | + ) |
| 71 | + |
| 72 | + def clean(self) -> None: |
| 73 | + run_cmd(['rm', '-rf', 'build', 'reports', '*.jou', '*.log', '*.bit']) |
8 | 74 |
|
| 75 | + def report(self, report_path: str = 'reports') -> None: |
| 76 | + pass |
| 77 | + |
| 78 | + |
| 79 | +def run_asic_flow( |
| 80 | + pdk_name: str, |
| 81 | + project_files: list[str], |
| 82 | + constraint_file: str = 'default', |
| 83 | + top_module: str = 'processorci_top', |
| 84 | + get_reports: bool = False, |
| 85 | + clean: bool = False, |
| 86 | + report_path: str = 'reports', |
| 87 | +) -> None: |
| 88 | + |
| 89 | + pdk_name = pdk_name.lower() |
9 | 90 | if pdk_name not in SUPPORTED_PDKS: |
10 | | - raise ValueError(f"PDK '{pdk_name}' is not supported.") |
| 91 | + raise ValueError( |
| 92 | + f"PDK '{pdk_name}' is not supported. Supported PDKs: {SUPPORTED_PDKS}" |
| 93 | + ) |
| 94 | + |
| 95 | + env: Environment = Environment( |
| 96 | + loader=FileSystemLoader(TEMPLATES_DIR), |
| 97 | + trim_blocks=True, |
| 98 | + lstrip_blocks=True, |
| 99 | + ) |
| 100 | + |
| 101 | + flow = OpenRoadFlow( |
| 102 | + technology=pdk_name, |
| 103 | + project_files=project_files, |
| 104 | + constraint_file=constraint_file, |
| 105 | + top_module=top_module, |
| 106 | + env=env, |
| 107 | + ) |
| 108 | + |
| 109 | + flow.run() |
| 110 | + |
| 111 | + if get_reports: |
| 112 | + flow.report(report_path=report_path) |
| 113 | + |
| 114 | + if clean: |
| 115 | + flow.clean() |
0 commit comments