Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pegasus DRC & LVS #797

Merged
merged 8 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/CAD-Tools/Pegasus.md
1 change: 1 addition & 0 deletions doc/CAD-Tools/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ The package should contain an class object named 'tool' to create an instance of
Tool-Plugin-Setup
OpenROAD
ICV
Pegasus
24 changes: 24 additions & 0 deletions e2e/pdks/sky130-bwrc.yml
Original file line number Diff line number Diff line change
@@ -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_091123"

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
30 changes: 30 additions & 0 deletions hammer/drc/pegasus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 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` 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`/`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/LVS results browser.

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/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/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.

Tested with:

* sky130
141 changes: 141 additions & 0 deletions hammer/drc/pegasus/__init__.py
Original file line number Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions hammer/drc/pegasus/defaults.yml
Original file line number Diff line number Diff line change
@@ -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"
6 changes: 6 additions & 0 deletions hammer/drc/pegasus/defaults_types.yml
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions hammer/lvs/pegasus/README.md
Loading