Skip to content

Commit

Permalink
Added simple PLE flow and progress on iSpatial flow. (#829)
Browse files Browse the repository at this point in the history
* Added simple PLE flow and progress on iSpatial flow.

* Removed hard-coded floorplan generation, now reads in def.

* Updated comments describing physical flow effort levels.

* Moved syn_opt step into syn_map because it is entirely conditional.

* ispatial and ple

* removed qrc bug fix

---------

Co-authored-by: Cade Richard <[email protected]>
Co-authored-by: Class Account <[email protected]>
Co-authored-by: Evan Li <[email protected]>
  • Loading branch information
4 people authored May 13, 2024
1 parent 5e3cfb3 commit 5277152
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
57 changes: 55 additions & 2 deletions hammer/synthesis/genus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def get_tool_hooks(self) -> List[HammerToolHookAction]:
def steps(self) -> List[HammerToolStep]:
steps_methods = [
self.init_environment,
self.predict_floorplan,
self.syn_generic,
self.syn_map,
self.add_tieoffs,
Expand Down Expand Up @@ -223,6 +224,19 @@ def init_environment(self) -> bool:
files=" ".join(lef_files)
))

# Read qrc tech files for physical synthesis.
qrc_files = self.technology.read_libs([
hammer_tech.filters.qrc_tech_filter
], hammer_tech.HammerTechnologyUtils.to_plain_item)
verbose_append("set_db qrc_tech_file {{ {files} }}".format(
files=" ".join(qrc_files)
))

# Quit when ispatial is used with sky130
if(not qrc_files and self.get_setting("synthesis.genus.phys_flow_effort").lower() == "high"):
self.logger.warning("Sky130 does not support ISpatial due to missing of qrc tech files.")
verbose_append("quit")

# Load input files and check that they are all Verilog.
if not self.check_input_files([".v", ".sv", "vh"]):
return False
Expand Down Expand Up @@ -264,6 +278,12 @@ def init_environment(self) -> bool:
# TODO: is there a way to track instance paths through the synthesis process?
verbose_append("set_db root: .auto_ungroup none")

# Set design effort.
verbose_append(f"set_db phys_flow_effort {self.get_setting('synthesis.genus.phys_flow_effort')}")

if self.get_setting("synthesis.genus.phys_flow_effort").lower() == "high":
self.verbose_append("set_db opt_spatial_effort extreme")

# Set "don't use" cells.
for l in self.generate_dont_use_commands():
self.append(l)
Expand Down Expand Up @@ -325,21 +345,48 @@ def syn_generic(self) -> bool:
if len(inverter_cells) > 0 and len(logic_cells) > 0:
# Clock mapping needs at least the attributes cts_inverter_cells and cts_logic_cells to be set
self.append("set_db map_clock_tree true")
self.verbose_append("syn_generic")

if self.get_setting("synthesis.genus.phys_flow_effort").lower() == "none":
self.verbose_append("syn_generic")
else:
self.verbose_append("syn_generic -physical")

self.dedup_ilms()

return True

def syn_map(self) -> bool:
self.verbose_append("syn_map")
if self.get_setting("synthesis.genus.phys_flow_effort").lower() == "none":
self.verbose_append("syn_map")
else:
self.verbose_append("syn_map -physical")

# High QoR optimization.
if self.get_setting("synthesis.genus.phys_flow_effort").lower() == "medium":
self.verbose_append("syn_opt")
elif self.get_setting("synthesis.genus.phys_flow_effort").lower() == "high":
self.verbose_append("syn_opt -spatial")

# Need to suffix modules for hierarchical simulation if not top
if self.hierarchical_mode not in [HierarchicalMode.Flat, HierarchicalMode.Top]:
self.verbose_append("update_names -module -log hier_updated_names.log -suffix _{MODULE}".format(MODULE=self.top_module))

self.dedup_ilms()

return True

def predict_floorplan(self) -> bool:
if self.get_setting("synthesis.genus.phys_flow_effort").lower() == "none":
self.verbose_append("set_db predict_floorplan_enable_during_generic false")
self.verbose_append("set_db physical_force_predict_floorplan false")
else:
self.verbose_append("set_db invs_temp_dir temp_invs")
self.verbose_append(f"set_db innovus_executable {self.get_setting('par.innovus.innovus_bin')}")
self.verbose_append("set_db predict_floorplan_enable_during_generic true")
self.verbose_append("set_db physical_force_predict_floorplan true")
self.verbose_append(f"set_db predict_floorplan_use_innovus true")
self.verbose_append("predict_floorplan")
return True

def add_tieoffs(self) -> bool:
tie_hi_cells = self.technology.get_special_cell_by_type(CellType.TieHiCell)
Expand Down Expand Up @@ -376,8 +423,13 @@ def generate_reports(self) -> bool:
"""Generate reports."""
# TODO: extend report generation capabilities
self.verbose_append("write_reports -directory reports -tag final")
if self.get_setting("synthesis.genus.phys_flow_effort").lower() != "none":
self.verbose_append("report_ple > reports/final_ple.rpt")
#qor done by write_reports

# Write reports does not normally report unconstrained paths
self.verbose_append("report_timing -unconstrained -max_paths 50 > reports/final_unconstrained.rpt")

return True

def write_regs(self) -> bool:
Expand Down Expand Up @@ -420,6 +472,7 @@ def write_outputs(self) -> bool:
verbose_append("write_design -innovus {hier_flag} -gzip_files {top}".format(
hier_flag="-hierarchical" if is_hier else "", top=top))

verbose_append("write_db -common")
self.ran_write_outputs = True

return True
Expand Down
7 changes: 7 additions & 0 deletions hammer/synthesis/genus/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,12 @@ synthesis.genus:
# Used to locate the binary - e.g. the '221' in ${cadence.cadence_home}/DDI/DDI221/GENUS221/bin/genus
version: "231"

# Physical flow effort.
# Valid options: high, medium, and none. Requires Genus Physical Option (GEN40) license and access to the Innovus System.
# High effort: Provides the best QoR at the cost of runtime. Requires Genus_Physical_Opt license.
# Medium effort: Offers the best trade-off between the runtime and QoR and turns legalization off by default.
# None: Will result in the best runtime. Works with all base Genus products.
phys_flow_effort: "medium"

# Generate the TCL file but do not run it yet.
generate_only: false
1 change: 1 addition & 0 deletions hammer/tech/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ class Library(BaseModel):
spice_model_file: Optional[SpiceModelFile] = None
power_grid_library: Optional[str] = None
extra_prefixes: Optional[List[PathPrefix]] = None
def_file: Optional[str] = None


PathsFunctionType = Callable[[Library], List[str]]
Expand Down
4 changes: 2 additions & 2 deletions hammer/technology/sky130/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ def post_install_script(self) -> None:
# check whether variables were overriden to point to a valid path
self.use_sram22 = os.path.exists(self.get_setting("technology.sky130.sram22_sky130_macros"))
self.setup_cdl()
self.setup_verilog()
# self.setup_verilog()
self.setup_techlef()
self.setup_io_lefs()
# self.setup_io_lefs()
self.logger.info('Loaded Sky130 Tech')


Expand Down
1 change: 0 additions & 1 deletion hammer/vlsi/cli_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ def __init__(self) -> None:
self.formal_rundir = "" # type: Optional[str]
self.timing_rundir = "" # type: Optional[str]
self.pcb_rundir = "" # type: Optional[str]

self.synthesis_action: CLIActionConfigType
# If a subclass has defined these, don't clobber them in init
# since the subclass still uses this init function.
Expand Down

0 comments on commit 5277152

Please sign in to comment.