From cb7f557c475b60f6b01def112de0978782862573 Mon Sep 17 00:00:00 2001 From: Harrison Liew Date: Thu, 7 Sep 2023 22:01:12 -0700 Subject: [PATCH 1/8] Pegasus DRC & LVS successfully runs with Sky130 Cadence PDK --- hammer/drc/pegasus/README.md | 30 ++++ hammer/drc/pegasus/__init__.py | 141 +++++++++++++++ hammer/drc/pegasus/defaults.yml | 8 + hammer/drc/pegasus/defaults_types.yml | 6 + hammer/lvs/pegasus/README.md | 30 ++++ hammer/lvs/pegasus/__init__.py | 185 ++++++++++++++++++++ hammer/lvs/pegasus/defaults.yml | 8 + hammer/lvs/pegasus/defaults_types.yml | 6 + hammer/technology/sky130/defaults.yml | 3 + hammer/technology/sky130/defaults_types.yml | 6 +- hammer/technology/sky130/sky130.tech.json | 14 ++ 11 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 hammer/drc/pegasus/README.md create mode 100644 hammer/drc/pegasus/__init__.py create mode 100644 hammer/drc/pegasus/defaults.yml create mode 100644 hammer/drc/pegasus/defaults_types.yml create mode 100644 hammer/lvs/pegasus/README.md create mode 100644 hammer/lvs/pegasus/__init__.py create mode 100644 hammer/lvs/pegasus/defaults.yml create mode 100644 hammer/lvs/pegasus/defaults_types.yml diff --git a/hammer/drc/pegasus/README.md b/hammer/drc/pegasus/README.md new file mode 100644 index 000000000..10415ef9a --- /dev/null +++ b/hammer/drc/pegasus/README.md @@ -0,0 +1,30 @@ +# DRC with Pegasus + +## Pegasus usage notes + + Although batch Pegasus is primarily command-line option driven, the only way to override certain directives in the rule decks is to generate a control file called `pegasusdrcctl`. +* This file can also be used to fill in fields in the GUI version for debugging, and changes in the the GUI will then overwrite this file. +* This file is generated by the `generate_drc_ctl_file` step. Changes to what appears in this file must be done with either the key `drc.inputs.additional_drc_text` with each line terminated by a semicolon (appends to the end of the generated file), or with a replacement hook. + +## Pegasus Design Review usage notes + +Pegasus Design Review (DR) and Results Viewer (RV) together are the GUI DRC results browser. + +The first time you open DR with the `view_drc` script, you will get an error message: + +A Valid Technology File Path is Required? +"": Not Found? + +This is because you need to load the DRC deck as a technology. + +To import the technology, in the main Design Review windows, go to: + +Tools -> Technology Manager (window pops up) -> File -> Import -> PVL (tab) + +In this dialog window, enter the technology basename in the Hammer input key `vlsi.core.technology` (e.g. "sky130", not "hammer.technology.sky130") in the "Technology Name" field and browse to the DRC deck in the PVL Rule File dialog. Then hit Import, close the Technology Manager, close DR, and run the `view_drc` script again. + +Subsequent openings of databases anywhere will map to this technology and label layers properly because the technology information is stored your home directory. + +Tested with: + +* sky130 diff --git a/hammer/drc/pegasus/__init__.py b/hammer/drc/pegasus/__init__.py new file mode 100644 index 000000000..1f5b3509e --- /dev/null +++ b/hammer/drc/pegasus/__init__.py @@ -0,0 +1,141 @@ +# hammer-vlsi plugin for Cadence Pegasus. +# +# See LICENSE for licence details. + +from hammer.vlsi import HammerToolStep +from hammer.vlsi import HammerDRCTool +from hammer.common.cadence import CadenceTool +from hammer.logging import HammerVLSILogging + +from typing import Dict, List, Optional + +import os +import textwrap + + +class PegasusDRC(HammerDRCTool, CadenceTool): + + def tool_config_prefix(self) -> str: + return "drc.pegasus" + + def drc_results_pre_waived(self) -> Dict[str, int]: + return {} + + def fill_outputs(self) -> bool: + return True + + # TODO: placeholder empty step + def empty_step(self) -> bool: + return True + + @property + def steps(self) -> List[HammerToolStep]: + steps = [self.generate_drc_ctl_file] # TODO: DRC steps require multiple runs of the tool how do we support this? + return self.make_steps_from_methods(steps) + + def do_post_steps(self) -> bool: + assert super().do_post_steps() + return self.run_pegasus() + + def globally_waived_drc_rules(self) -> List[str]: + return [] + + def run_pegasus(self) -> bool: + self.create_enter_script() + + rules = list(map(lambda d: d.path, self.get_drc_decks())) + + # set the command arguments + pegasus_bin = self.get_setting("drc.pegasus.pegasus_bin") + args = [ + pegasus_bin, + "-drc", # DRC mode + "-dp", str(self.get_setting("vlsi.core.max_threads")), + "-license_dp_continue", # don't quit if requested dp license not available + "-control", self.drc_ctl_file, + "-log_dir", f"{self.top_module}_logs", + "-ui_data" # for results viewer + # TODO: -interactive for block level + ] + rules + + HammerVLSILogging.enable_colour = False + HammerVLSILogging.enable_tag = False + self.run_executable(args, cwd=self.run_dir) # TODO: check for errors and deal with them + HammerVLSILogging.enable_colour = True + HammerVLSILogging.enable_tag = True + + # TODO: check that drc run was successful + + # Create view_drc script & design review macro script file + # See the README for how this works + os.makedirs(self.generated_scripts_dir, exist_ok=True) + + technology = self.get_setting("vlsi.core.technology").split(".")[-1] + with open(self.view_drc_script, "w") as f: + f.write(textwrap.dedent(f""" + cd {self.run_dir} + source ./enter + {pegasus_bin}DesignReview -qrv -tech {technology} -data {self.layout_file} -post {self.dr_rv_macro} -verbose + """)) + os.chmod(self.view_drc_script, 0o755) + + with open(self.dr_rv_macro, "w") as f: + f.write(textwrap.dedent(f''' + PVS::invoke_pvsrv("{self.run_dir}"); + ''')) + + return True + + def generate_drc_ctl_file(self) -> bool: + """ Generate the DRC control file self.drc_ctl_file and fill its contents """ + with open(self.drc_ctl_file, "w") as f: + f.write(self.header.replace("#","//")) + f.write(textwrap.dedent(f''' + virtual_connect -report yes; + layout_path "{self.layout_file}"; + layout_primary {self.top_module}; + results_db -drc "{self.drc_results_db}" -ascii; + report_summary -drc "{self.drc_results_file}" -replace; + ''')) + f.write(self.get_additional_drc_text()) + return True + + @property + def generated_scripts_dir(self) -> str: + return os.path.join(self.run_dir, "generated-scripts") + + @property + def view_drc_script(self) -> str: + return os.path.join(self.generated_scripts_dir, "view_drc") + + @property + def dr_rv_macro(self) -> str: + return os.path.join(self.generated_scripts_dir, "dr.mac") + + @property + def drc_ctl_file(self) -> str: + return os.path.join(self.run_dir, "pegasusdrcctl") + + @property + def drc_results_db(self) -> str: + return os.path.join(self.run_dir, self.top_module + ".drc_errors.ascii") + + @property + def drc_results_file(self) -> str: + return os.path.join(self.run_dir, self.top_module + ".drc_results") + + @property + def env_vars(self) -> Dict[str, str]: + """ + Get the list of environment variables required for this tool. + Note to subclasses: remember to include variables from super().env_vars! + """ + v = dict(super().env_vars) + v["PEGASUS_BIN"] = self.get_setting("drc.pegasus.pegasus_bin") + return v + + @property + def post_synth_sdc(self) -> Optional[str]: + pass + +tool = PegasusDRC diff --git a/hammer/drc/pegasus/defaults.yml b/hammer/drc/pegasus/defaults.yml new file mode 100644 index 000000000..ec13b9196 --- /dev/null +++ b/hammer/drc/pegasus/defaults.yml @@ -0,0 +1,8 @@ +# Default settings for Pegasus DRC, for project/technology configuration and overriding. +drc.pegasus: + # Location of the binary + pegasus_bin: "${cadence.cadence_home}/PEGASUS/PEGASUS${drc.pegasus.version}/bin/pegasus" + pegasus_bin_meta: lazysubst + + # type: str + version: "231" diff --git a/hammer/drc/pegasus/defaults_types.yml b/hammer/drc/pegasus/defaults_types.yml new file mode 100644 index 000000000..9a74dd234 --- /dev/null +++ b/hammer/drc/pegasus/defaults_types.yml @@ -0,0 +1,6 @@ +# Default settings for Pegasus DRC, for project/technology configuration and overriding. +drc.pegasus: + # Location of the binary + pegasus_bin: str + + version: str diff --git a/hammer/lvs/pegasus/README.md b/hammer/lvs/pegasus/README.md new file mode 100644 index 000000000..c62010224 --- /dev/null +++ b/hammer/lvs/pegasus/README.md @@ -0,0 +1,30 @@ +# LVS with Pegasus + +## Pegasus usage notes + + Although batch Pegasus is primarily command-line option driven, the only way to override certain directives in the rule decks is to generate a control file called `pegasuslvsctl`. +* This file can also be used to fill in fields in the GUI version for debugging, and changes in the the GUI will then overwrite this file. +* This file is generated by the `generate_lvs_ctl_file` step. Changes to what appears in this file must be done with either the key `lvs.inputs.additional_lvs_text` with each line terminated by a semicolon (appends to the end of the generated file), or with a replacement hook. + +## Pegasus Design Review usage notes + +Pegasus Design Review (DR) and Results Viewer (RV) together are the GUI LVS results browser. + +The first time you open DR with the `view_lvs` script, you will get an error message: + +A Valid Technology File Path is Required? +"": Not Found? + +This is because you need to load the LVS deck as a technology. + +To import the technology, in the main Design Review windows, go to: + +Tools -> Technology Manager (window pops up) -> File -> Import -> PVL (tab) + +In this dialog window, enter the technology basename in the Hammer input key `vlsi.core.technology` (e.g. "sky130", not "hammer.technology.sky130") in the "Technology Name" field and browse to the LVS deck in the PVL Rule File dialog. Then hit Import, close the Technology Manager, close DR, and run the `view_lvs` script again. + +Subsequent openings of databases anywhere will map to this technology and label layers properly because the technology information is stored your home directory. + +Tested with: + +* sky130 diff --git a/hammer/lvs/pegasus/__init__.py b/hammer/lvs/pegasus/__init__.py new file mode 100644 index 000000000..140144c43 --- /dev/null +++ b/hammer/lvs/pegasus/__init__.py @@ -0,0 +1,185 @@ +# hammer-vlsi plugin for Cadence Pegasus. +# +# See LICENSE for licence details. + +from hammer.vlsi import HammerToolStep +from hammer.vlsi import HammerLVSTool +from hammer.common.cadence import CadenceTool +from hammer.logging import HammerVLSILogging +from hammer.utils import HammerFiletype, get_filetype +import hammer.tech as hammer_tech + +from typing import Dict, List, Optional + +import os +import textwrap + + +class PegasusLVS(HammerLVSTool, CadenceTool): + + def tool_config_prefix(self) -> str: + return "lvs.pegasus" + + def erc_results_pre_waived(self) -> Dict[str, int]: + return {} + + def lvs_results(self) -> List[str]: + return [] + + def fill_outputs(self) -> bool: + return True + + # TODO: placeholder empty step + def empty_step(self) -> bool: + return True + + @property + def steps(self) -> List[HammerToolStep]: + steps = [self.generate_lvs_ctl_file] # TODO: LVS steps require multiple runs of the tool how do we support this? + return self.make_steps_from_methods(steps) + + def do_post_steps(self) -> bool: + assert super().do_post_steps() + return self.run_pegasus() + + def globally_waived_erc_rules(self) -> List[str]: + return [] + + def run_pegasus(self) -> bool: + self.create_enter_script() + + rules = list(map(lambda d: d.path, self.get_lvs_decks())) + + # set the command arguments + pegasus_bin = self.get_setting("lvs.pegasus.pegasus_bin") + args = [ + pegasus_bin, + "-lvs", # LVS mode + "-dp", str(self.get_setting("vlsi.core.max_threads")), + "-license_dp_continue", # don't quit if requested dp license not available + "-automatch", # hierarchical correspondence + "-check_schematic", # check schematic integrity + "-control", self.lvs_ctl_file, + "-log_dir", f"{self.top_module}_logs", + "-ui_data" # for results viewer + ] + rules + + HammerVLSILogging.enable_colour = False + HammerVLSILogging.enable_tag = False + self.run_executable(args, cwd=self.run_dir) # TODO: check for errors and deal with them + HammerVLSILogging.enable_colour = True + HammerVLSILogging.enable_tag = True + + # TODO: check that lvs run was successful + + # Create view_lvs script & design review macro script file + # See the README for how this works + os.makedirs(self.generated_scripts_dir, exist_ok=True) + + technology = self.get_setting("vlsi.core.technology").split(".")[-1] + with open(self.view_lvs_script, "w") as f: + f.write(textwrap.dedent(f""" + cd {self.run_dir} + source ./enter + {pegasus_bin}DesignReview -qrv -tech {technology} -data {self.layout_file} -post {self.dr_rv_macro} -verbose + """)) + os.chmod(self.view_lvs_script, 0o755) + + with open(self.dr_rv_macro, "w") as f: + f.write(textwrap.dedent(f''' + PVS::invoke_pvsrv("{self.run_dir}"); + ''')) + + return True + + def generate_lvs_ctl_file(self) -> bool: + """ Generate the LVS control file self.lvs_ctl_file and fill its contents """ + library_spice_files = self.technology.read_libs([hammer_tech.filters.spice_filter], hammer_tech.HammerTechnologyUtils.to_plain_item) + ilms = list(map(lambda x: x.netlist, self.get_input_ilms())) # type: List[str] + + all_files = library_spice_files + self.schematic_files + ilms + spice_files = list(filter(lambda x: get_filetype(x) is HammerFiletype.SPICE, all_files)) + verilog_files = list(filter(lambda x: get_filetype(x) is HammerFiletype.VERILOG, all_files)) + unmatched = set(all_files).symmetric_difference(set(spice_files + verilog_files)) + if unmatched: + raise NotImplementedError("Unsupported netlist type for files: " + str(unmatched)) + + power_list="\n".join(map(lambda x: x.name, self.get_independent_power_nets())) + ground_list="\n".join(map(lambda x: x.name, self.get_independent_ground_nets())) + + with open(self.lvs_ctl_file, "w") as f: + f.write(self.header.replace("#","//") + "\n") + for sf in spice_files: + if os.path.basename(sf).split(".")[0] in ["cdl", "CDL"]: + f.write(f'schematic_path "{sf}" cdl;\n') + else: + f.write(f'schematic_path "{sf}" spice;\n') + for vf in verilog_files: + f.write(f'schematic_path "{vf}" verilog -keep_backslash -detect_buses -check_inconsistent_instances;\n') + f.write(textwrap.dedent(f''' + schematic_primary {self.top_module}; + layout_path "{self.layout_file}"; + layout_primary {self.top_module}; + lvs_power_name {power_list}; + lvs_ground_name {ground_list}; + lvs_find_shorts yes; + lvs_report_opt S; + results_db -erc "{self.erc_results_db}" -ascii; + report_summary -erc "{self.erc_results_file}" -replace; + lvs_report_file "{self.lvs_results_file}"; + ''')) + f.write(self.get_additional_lvs_text()) + return True + + @property + def hcells_file(self) -> str: + return os.path.join(self.run_dir, "hcells") + + def generate_hcells_file(self) -> None: + with open(self.hcells_file, "w") as f: + f.write("") + # TODO + + @property + def generated_scripts_dir(self) -> str: + return os.path.join(self.run_dir, "generated-scripts") + + @property + def view_lvs_script(self) -> str: + return os.path.join(self.generated_scripts_dir, "view_lvs") + + @property + def dr_rv_macro(self) -> str: + return os.path.join(self.generated_scripts_dir, "dr.mac") + + @property + def lvs_ctl_file(self) -> str: + return os.path.join(self.run_dir, "pegasuslvsctl") + + @property + def erc_results_db(self) -> str: + return os.path.join(self.run_dir, self.top_module + ".erc_errors.ascii") + + @property + def erc_results_file(self) -> str: + return os.path.join(self.run_dir, self.top_module + ".erc_results") + + @property + def lvs_results_file(self) -> str: + return os.path.join(self.run_dir, self.top_module + ".lvs_results") + + @property + def env_vars(self) -> Dict[str, str]: + """ + Get the list of environment variables required for this tool. + Note to subclasses: remember to include variables from super().env_vars! + """ + v = dict(super().env_vars) + v["PEGASUS_BIN"] = self.get_setting("lvs.pegasus.pegasus_bin") + return v + + @property + def post_synth_sdc(self) -> Optional[str]: + pass + +tool = PegasusLVS diff --git a/hammer/lvs/pegasus/defaults.yml b/hammer/lvs/pegasus/defaults.yml new file mode 100644 index 000000000..f9b7998d3 --- /dev/null +++ b/hammer/lvs/pegasus/defaults.yml @@ -0,0 +1,8 @@ +# Default settings for Pegasus LVS, for project/technology configuration and overriding. +lvs.pegasus: + # Location of the binary + pegasus_bin: "${cadence.cadence_home}/PEGASUS/PEGASUS${lvs.pegasus.version}/bin/pegasus" + pegasus_bin_meta: lazysubst + + # type: str + version: "231" diff --git a/hammer/lvs/pegasus/defaults_types.yml b/hammer/lvs/pegasus/defaults_types.yml new file mode 100644 index 000000000..6c728067b --- /dev/null +++ b/hammer/lvs/pegasus/defaults_types.yml @@ -0,0 +1,6 @@ +# Default settings for Pegasus LVS, for project/technology configuration and overriding. +lvs.pegasus: + # Location of the binary + pegasus_bin: str + + version: str diff --git a/hammer/technology/sky130/defaults.yml b/hammer/technology/sky130/defaults.yml index 7f6250683..48068af66 100644 --- a/hammer/technology/sky130/defaults.yml +++ b/hammer/technology/sky130/defaults.yml @@ -8,6 +8,9 @@ technology.sky130: # this key is OPTIONAL, no NDA files will be used if it does not point to a valid path # By default, this is used to populate pdk_home below. # It should contain s8/V2.0.1 + + sky130_cds: "/path/to/sky130_cds" # This contains the Cadence PDK + # this key is OPTIONAL, and is only required if you are running Pegasus DRC/LVS. sram22_sky130_macros: "/path/to/sram22_sky130_macros" # SRAM path # /path/to/sram22_sky130_macros diff --git a/hammer/technology/sky130/defaults_types.yml b/hammer/technology/sky130/defaults_types.yml index b43a22faa..f46c2e6f7 100644 --- a/hammer/technology/sky130/defaults_types.yml +++ b/hammer/technology/sky130/defaults_types.yml @@ -10,7 +10,11 @@ technology.sky130: # By default, this is used to populate pdk_home below. # It should contain s8/V2.0.1 sky130_nda: str - + + # This contains the Cadence PDK + # this key is OPTIONAL, and is only required if you are running Pegasus DRC/LVS. + sky130_cds: str + # RAM paths # OpenRAM openram_lib: str diff --git a/hammer/technology/sky130/sky130.tech.json b/hammer/technology/sky130/sky130.tech.json index bdd9fa099..273f06c67 100644 --- a/hammer/technology/sky130/sky130.tech.json +++ b/hammer/technology/sky130/sky130.tech.json @@ -9,6 +9,10 @@ { "id": "$SKY130A", "path": "technology.sky130.sky130A" + }, + { + "id": "$SKY130_CDS", + "path": "technology.sky130.sky130_cds" } ], "layer_map_file": "$SKY130_NDA/s8/V2.0.1/VirtuosoOA/libs/technology_library/technology_library.layermap", @@ -22,6 +26,11 @@ "tool_name": "klayout", "deck_name": "klayout_drc", "path": "$SKY130A/libs.tech/klayout/drc/sky130A.lydrc" + }, + { + "tool_name": "pegasus", + "deck_name": "pegasus_drc", + "path": "$SKY130_CDS/sky130_rev0006.drc.pvl" } ], "additional_drc_text": "", @@ -31,6 +40,11 @@ "deck_name": "calibre_lvs", "old_path": "$SKY130_NDA/s8/V2.0.1/LVS/Calibre/lvsRules_s8", "path": "cache/lvsControlFile_s8" + }, + { + "tool_name": "pegasus", + "deck_name": "pegasus_lvs", + "path": "$SKY130_CDS/sky130_rev0001.lvs.pvl" } ], "additional_lvs_text": "", From 2a17e69e18945ad1b6313225abc6e1dc1cf2af8b Mon Sep 17 00:00:00 2001 From: Harrison Liew Date: Thu, 7 Sep 2023 22:06:52 -0700 Subject: [PATCH 2/8] consolidate README and add to readthedocs --- doc/CAD-Tools/Pegasus.md | 1 + doc/CAD-Tools/index.rst | 1 + hammer/drc/pegasus/README.md | 14 +++++++------- hammer/lvs/pegasus/README.md | 31 +------------------------------ 4 files changed, 10 insertions(+), 37 deletions(-) create mode 120000 doc/CAD-Tools/Pegasus.md mode change 100644 => 120000 hammer/lvs/pegasus/README.md diff --git a/doc/CAD-Tools/Pegasus.md b/doc/CAD-Tools/Pegasus.md new file mode 120000 index 000000000..54ad788b4 --- /dev/null +++ b/doc/CAD-Tools/Pegasus.md @@ -0,0 +1 @@ +../../hammer/drc/pegasus/README.md \ No newline at end of file diff --git a/doc/CAD-Tools/index.rst b/doc/CAD-Tools/index.rst index 74991b7ee..e47dd1cd2 100644 --- a/doc/CAD-Tools/index.rst +++ b/doc/CAD-Tools/index.rst @@ -15,3 +15,4 @@ The package should contain an class object named 'tool' to create an instance of Tool-Plugin-Setup OpenROAD ICV + Pegasus diff --git a/hammer/drc/pegasus/README.md b/hammer/drc/pegasus/README.md index 10415ef9a..4cbb9f426 100644 --- a/hammer/drc/pegasus/README.md +++ b/hammer/drc/pegasus/README.md @@ -1,27 +1,27 @@ -# DRC with Pegasus +# DRC/LVS with Pegasus ## Pegasus usage notes - Although batch Pegasus is primarily command-line option driven, the only way to override certain directives in the rule decks is to generate a control file called `pegasusdrcctl`. + Although batch Pegasus is primarily command-line option driven, the only way to override certain directives in the rule decks is to generate a control file called `pegasusdrcctl` for DRC or `pegasuslvsctl` for LVS. * This file can also be used to fill in fields in the GUI version for debugging, and changes in the the GUI will then overwrite this file. -* This file is generated by the `generate_drc_ctl_file` step. Changes to what appears in this file must be done with either the key `drc.inputs.additional_drc_text` with each line terminated by a semicolon (appends to the end of the generated file), or with a replacement hook. +* This file is generated by the `generate_drc_ctl_file`/`generate_lvs_ctl_file` step. Changes to what appears in this file must be done with either the key `drc.inputs.additional_drc_text`/`lvs.inputs.additional_lvs_text` with each line terminated by a semicolon (appends to the end of the generated file), or with a replacement hook. ## Pegasus Design Review usage notes -Pegasus Design Review (DR) and Results Viewer (RV) together are the GUI DRC results browser. +Pegasus Design Review (DR) and Results Viewer (RV) together are the GUI DRC/LVS results browser. -The first time you open DR with the `view_drc` script, you will get an error message: +The first time you open DR with the `view_drc`/`view_lvs` script, you will get an error message: A Valid Technology File Path is Required? "": Not Found? -This is because you need to load the DRC deck as a technology. +This is because you need to load the DRC/LVS deck as a technology. To import the technology, in the main Design Review windows, go to: Tools -> Technology Manager (window pops up) -> File -> Import -> PVL (tab) -In this dialog window, enter the technology basename in the Hammer input key `vlsi.core.technology` (e.g. "sky130", not "hammer.technology.sky130") in the "Technology Name" field and browse to the DRC deck in the PVL Rule File dialog. Then hit Import, close the Technology Manager, close DR, and run the `view_drc` script again. +In this dialog window, enter the technology basename in the Hammer input key `vlsi.core.technology` (e.g. "sky130", not "hammer.technology.sky130") in the "Technology Name" field and browse to the DRC/LVS deck in the PVL Rule File dialog. Then hit Import, close the Technology Manager, close DR, and run the `view_drc`/`view_lvs` script again. Subsequent openings of databases anywhere will map to this technology and label layers properly because the technology information is stored your home directory. diff --git a/hammer/lvs/pegasus/README.md b/hammer/lvs/pegasus/README.md deleted file mode 100644 index c62010224..000000000 --- a/hammer/lvs/pegasus/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# LVS with Pegasus - -## Pegasus usage notes - - Although batch Pegasus is primarily command-line option driven, the only way to override certain directives in the rule decks is to generate a control file called `pegasuslvsctl`. -* This file can also be used to fill in fields in the GUI version for debugging, and changes in the the GUI will then overwrite this file. -* This file is generated by the `generate_lvs_ctl_file` step. Changes to what appears in this file must be done with either the key `lvs.inputs.additional_lvs_text` with each line terminated by a semicolon (appends to the end of the generated file), or with a replacement hook. - -## Pegasus Design Review usage notes - -Pegasus Design Review (DR) and Results Viewer (RV) together are the GUI LVS results browser. - -The first time you open DR with the `view_lvs` script, you will get an error message: - -A Valid Technology File Path is Required? -"": Not Found? - -This is because you need to load the LVS deck as a technology. - -To import the technology, in the main Design Review windows, go to: - -Tools -> Technology Manager (window pops up) -> File -> Import -> PVL (tab) - -In this dialog window, enter the technology basename in the Hammer input key `vlsi.core.technology` (e.g. "sky130", not "hammer.technology.sky130") in the "Technology Name" field and browse to the LVS deck in the PVL Rule File dialog. Then hit Import, close the Technology Manager, close DR, and run the `view_lvs` script again. - -Subsequent openings of databases anywhere will map to this technology and label layers properly because the technology information is stored your home directory. - -Tested with: - -* sky130 diff --git a/hammer/lvs/pegasus/README.md b/hammer/lvs/pegasus/README.md new file mode 120000 index 000000000..77db6a415 --- /dev/null +++ b/hammer/lvs/pegasus/README.md @@ -0,0 +1 @@ +../../drc/pegasus/README.md \ No newline at end of file From d7c8ddb82ddfc970577a8a8866cc66f3dd75dc39 Mon Sep 17 00:00:00 2001 From: Harrison Liew Date: Thu, 7 Sep 2023 22:09:13 -0700 Subject: [PATCH 3/8] add bwrc sky130_cds path --- e2e/pdks/sky130-bwrc.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 e2e/pdks/sky130-bwrc.yml diff --git a/e2e/pdks/sky130-bwrc.yml b/e2e/pdks/sky130-bwrc.yml new file mode 100644 index 000000000..e8c39b47f --- /dev/null +++ b/e2e/pdks/sky130-bwrc.yml @@ -0,0 +1,24 @@ +vlsi.core.technology: "hammer.technology.sky130" +technology.sky130: + sky130A: "/tools/commercial/skywater/local/chipyard-tutorial/.conda-sky130/share/pdk/sky130A" + sram22_sky130_macros: "/tools/commercial/skywater/local/chipyard-tutorial/sram22_sky130_macros" + openram_lib: "/tools/commercial/skywater/local/sky130_sram_macros" + sky130_nda: "/tools/commercial/skywater/swtech130/skywater-src-nda-20221031" + sky130_cds: "/tools/commercial/skywater/sky130_cds/sky130_prelim_release_080423" + +synthesis.genus.version: "211" +par.innovus.version: "211" + +sim.vcs.version: "S-2021.09-SP1-1" +sim.vcs.verdi_home: "/tools/synopsys/verdi/${sim.vcs.version}" +sim.vcs.verdi_home_meta: lazysubst + +synthesis.yosys.yosys_bin: "/tools/commercial/skywater/local/chipyard-tutorial/.conda-yosys/bin/yosys" +par.openroad.openroad_bin: "/tools/commercial/skywater/local/chipyard-tutorial/.conda-openroad/bin/openroad" +par.openroad.klayout_bin: "/tools/commercial/skywater/local/chipyard-tutorial/.conda-klayout/bin/klayout" +drc.magic.magic_bin: "/tools/commercial/skywater/local/chipyard-tutorial/.conda-signoff/bin/magic" +lvs.netgen.netgen_bin: "/tools/commercial/skywater/local/chipyard-tutorial/.conda-signoff/bin/netgen" + +# speed up tutorial runs & declutter log output +par.openroad.timing_driven: false +par.openroad.write_reports: false From 9cf7438a59c6eaa16391ab6fda8b929b47f875c4 Mon Sep 17 00:00:00 2001 From: Harrison Liew Date: Thu, 7 Sep 2023 22:47:31 -0700 Subject: [PATCH 4/8] PDK was updated --- e2e/pdks/sky130-bwrc.yml | 2 +- hammer/technology/sky130/sky130.tech.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/pdks/sky130-bwrc.yml b/e2e/pdks/sky130-bwrc.yml index e8c39b47f..c770e662b 100644 --- a/e2e/pdks/sky130-bwrc.yml +++ b/e2e/pdks/sky130-bwrc.yml @@ -4,7 +4,7 @@ technology.sky130: sram22_sky130_macros: "/tools/commercial/skywater/local/chipyard-tutorial/sram22_sky130_macros" openram_lib: "/tools/commercial/skywater/local/sky130_sram_macros" sky130_nda: "/tools/commercial/skywater/swtech130/skywater-src-nda-20221031" - sky130_cds: "/tools/commercial/skywater/sky130_cds/sky130_prelim_release_080423" + sky130_cds: "/tools/commercial/skywater/sky130_cds/PDK/20230830/sky130_pdk" synthesis.genus.version: "211" par.innovus.version: "211" diff --git a/hammer/technology/sky130/sky130.tech.json b/hammer/technology/sky130/sky130.tech.json index 273f06c67..f33941662 100644 --- a/hammer/technology/sky130/sky130.tech.json +++ b/hammer/technology/sky130/sky130.tech.json @@ -30,7 +30,7 @@ { "tool_name": "pegasus", "deck_name": "pegasus_drc", - "path": "$SKY130_CDS/sky130_rev0006.drc.pvl" + "path": "$SKY130_CDS/drc/sky130_rev0007.drc.pvl" } ], "additional_drc_text": "", @@ -44,7 +44,7 @@ { "tool_name": "pegasus", "deck_name": "pegasus_lvs", - "path": "$SKY130_CDS/sky130_rev0001.lvs.pvl" + "path": "$SKY130_CDS/lvs/sky130_rev0001.lvs.pvl" } ], "additional_lvs_text": "", From 052bf81fb04ea1955ed8fcaa2f0767dec3c22027 Mon Sep 17 00:00:00 2001 From: Nayiri K Date: Mon, 11 Sep 2023 14:49:56 -0700 Subject: [PATCH 5/8] moving calibre lvs deck hacking from pdk init to a calibre hook so that it doesn't run during pegasus lvs --- hammer/technology/sky130/__init__.py | 91 ++++++++++++++-------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/hammer/technology/sky130/__init__.py b/hammer/technology/sky130/__init__.py index 9587e2363..4c2201492 100644 --- a/hammer/technology/sky130/__init__.py +++ b/hammer/technology/sky130/__init__.py @@ -26,12 +26,10 @@ class SKY130Tech(HammerTechnology): def post_install_script(self) -> None: self.library_name = 'sky130_fd_sc_hd' # check whether variables were overriden to point to a valid path - self.use_nda_files = os.path.exists(self.get_setting("technology.sky130.sky130_nda")) self.use_sram22 = os.path.exists(self.get_setting("technology.sky130.sram22_sky130_macros")) self.setup_cdl() self.setup_verilog() self.setup_techlef() - self.setup_lvs_deck() self.setup_io_lefs() print('Loaded Sky130 Tech') @@ -134,34 +132,6 @@ def setup_techlef(self) -> None: if line.strip() == 'END pwell': df.write(_the_tlef_edit) - # Remove conflicting specification statements found in PDK LVS decks - def setup_lvs_deck(self) -> None: - if not self.use_nda_files: return - pattern = '.*({}).*\n'.format('|'.join(LVS_DECK_SCRUB_LINES)) - matcher = re.compile(pattern) - - source_paths = self.get_setting('technology.sky130.lvs_deck_sources') - lvs_decks = self.config.lvs_decks - if not lvs_decks: - return - for i in range(len(lvs_decks)): - deck = lvs_decks[i] - try: - source_path = Path(source_paths[i]) - except IndexError: - self.logger.error( - 'No corresponding source for LVS deck {}'.format(deck)) - if not source_path.exists(): - raise FileNotFoundError(f"LVS deck not found: {source_path}") - dest_path = self.expand_tech_cache_path(str(deck.path)) - self.ensure_dirs_exist(dest_path) - with open(source_path, 'r') as sf: - with open(dest_path, 'w') as df: - self.logger.info("Modifying LVS deck: {} -> {}".format - (source_path, dest_path)) - df.write(matcher.sub("", sf.read())) - df.write(LVS_DECK_INSERT_LINES) - # Power pins for clamps must be CLASS CORE # connect/disconnect spacers must be CLASS PAD SPACER, not AREAIO def setup_io_lefs(self) -> None: @@ -216,7 +186,7 @@ def get_tech_drc_hooks(self, tool_name: str) -> List[HammerToolHookAction]: return hooks.get(tool_name, []) def get_tech_lvs_hooks(self, tool_name: str) -> List[HammerToolHookAction]: - calibre_hooks = [] + calibre_hooks = [HammerTool.make_post_insertion_hook("generate_lvs_run_file", setup_calibre_lvs_deck)] if self.use_sram22: calibre_hooks.append(HammerTool.make_post_insertion_hook("generate_lvs_run_file", sram22_lvs_recognize_gates_all)) if self.get_setting("technology.sky130.lvs_blackbox_srams"): @@ -250,19 +220,6 @@ def sky130_sram_names() -> List[str]: END licon ''' -LVS_DECK_SCRUB_LINES = [ - "VIRTUAL CONNECT REPORT", - "SOURCE PRIMARY", - "SOURCE SYSTEM SPICE", - "SOURCE PATH", - "ERC", - "LVS REPORT" -] - -LVS_DECK_INSERT_LINES = ''' -LVS FILTER D OPEN SOURCE -LVS FILTER D OPEN LAYOUT -''' # various Innovus database settings def sky130_innovus_settings(ht: HammerTool) -> bool: @@ -434,4 +391,50 @@ def sram22_lvs_recognize_gates_all(ht: HammerTool) -> bool: f.write("LVS RECOGNIZE GATES ALL") return True + +LVS_DECK_SCRUB_LINES = [ + "VIRTUAL CONNECT REPORT", + "SOURCE PRIMARY", + "SOURCE SYSTEM SPICE", + "SOURCE PATH", + "ERC", + "LVS REPORT" +] + +LVS_DECK_INSERT_LINES = ''' +LVS FILTER D OPEN SOURCE +LVS FILTER D OPEN LAYOUT +''' + +def setup_calibre_lvs_deck(ht: HammerTool) -> bool: + assert isinstance(ht, HammerLVSTool), "Modify Calibre LVS deck for LVS only" + # Remove conflicting specification statements found in PDK LVS decks + pattern = '.*({}).*\n'.format('|'.join(LVS_DECK_SCRUB_LINES)) + matcher = re.compile(pattern) + + source_paths = ht.get_setting('technology.sky130.lvs_deck_sources') + lvs_decks = ht.technology.config.lvs_decks + if not lvs_decks: + return True + for i,deck in enumerate(lvs_decks): + if deck.tool_name != 'calibre': continue + try: + source_path = Path(source_paths[i]) + except IndexError: + ht.logger.error( + 'No corresponding source for LVS deck {}'.format(deck)) + continue + if not source_path.exists(): + raise FileNotFoundError(f"LVS deck not found: {source_path}") + dest_path = ht.technology.expand_tech_cache_path(str(deck.path)) + ht.technology.ensure_dirs_exist(dest_path) + with open(source_path, 'r') as sf: + with open(dest_path, 'w') as df: + ht.logger.info("Modifying LVS deck: {} -> {}".format + (source_path, dest_path)) + df.write(matcher.sub("", sf.read())) + df.write(LVS_DECK_INSERT_LINES) + return True + + tech = SKY130Tech() From d8b04fa318b98c360b02a6f6be16db2c8be8749b Mon Sep 17 00:00:00 2001 From: Nayiri K Date: Mon, 11 Sep 2023 15:12:01 -0700 Subject: [PATCH 6/8] changing path DNE print from error to warning, so this isn't mistaken for a real error by users when they don't specify some optional tech (usually NDA) paths --- hammer/tech/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hammer/tech/__init__.py b/hammer/tech/__init__.py index 3dc8beb32..35362c2c9 100644 --- a/hammer/tech/__init__.py +++ b/hammer/tech/__init__.py @@ -724,7 +724,7 @@ def check_installs(self) -> bool: path_key = install.path install_path = str(self.get_setting(path_key)) if not os.path.exists(install_path): - self.logger.error(f"The install path: {install_path} does not exist, looked at key {path_key}") + self.logger.warning(f"The install path: {install_path} does not exist, looked at key {path_key}") return False return True From 92a97493d2358333c4482c6592dca72eadd28283 Mon Sep 17 00:00:00 2001 From: ken_ho Date: Sun, 8 Oct 2023 17:10:40 -0700 Subject: [PATCH 7/8] distro directory changed again --- hammer/technology/sky130/sky130.tech.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hammer/technology/sky130/sky130.tech.json b/hammer/technology/sky130/sky130.tech.json index f33941662..bf07a5bd6 100644 --- a/hammer/technology/sky130/sky130.tech.json +++ b/hammer/technology/sky130/sky130.tech.json @@ -30,7 +30,7 @@ { "tool_name": "pegasus", "deck_name": "pegasus_drc", - "path": "$SKY130_CDS/drc/sky130_rev0007.drc.pvl" + "path": "$SKY130_CDS/pegasus/sky130_rev0006.drc.pvl" } ], "additional_drc_text": "", @@ -44,7 +44,7 @@ { "tool_name": "pegasus", "deck_name": "pegasus_lvs", - "path": "$SKY130_CDS/lvs/sky130_rev0001.lvs.pvl" + "path": "$SKY130_CDS/pegasus/sky130_rev0001.lvs.pvl" } ], "additional_lvs_text": "", @@ -2036,4 +2036,4 @@ "y": 5.44 } ] -} +} \ No newline at end of file From a6ee7dc8cbd741d1b33bc96e000f0c56be08ea01 Mon Sep 17 00:00:00 2001 From: ken_ho Date: Sun, 8 Oct 2023 17:15:28 -0700 Subject: [PATCH 8/8] Repoint the CDS to newest --- e2e/pdks/sky130-bwrc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/pdks/sky130-bwrc.yml b/e2e/pdks/sky130-bwrc.yml index c770e662b..e7feb9a04 100644 --- a/e2e/pdks/sky130-bwrc.yml +++ b/e2e/pdks/sky130-bwrc.yml @@ -4,7 +4,7 @@ technology.sky130: sram22_sky130_macros: "/tools/commercial/skywater/local/chipyard-tutorial/sram22_sky130_macros" openram_lib: "/tools/commercial/skywater/local/sky130_sram_macros" sky130_nda: "/tools/commercial/skywater/swtech130/skywater-src-nda-20221031" - sky130_cds: "/tools/commercial/skywater/sky130_cds/PDK/20230830/sky130_pdk" + sky130_cds: "/tools/commercial/skywater/sky130_cds/sky130_prelim_release_091123" synthesis.genus.version: "211" par.innovus.version: "211"