Skip to content

Commit

Permalink
Pass ILM SDCs upwards through hierarchical flow (#796)
Browse files Browse the repository at this point in the history
* add ILM SDCs (hacked) to ILMStruct, read with create_constraint_mode -ilm_sdc_files

* no verbose_append

* need to retain update_constraint_mode

* jerry was right
  • Loading branch information
harrisonliew authored Sep 7, 2023
1 parent 46b4e75 commit b1f970a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 8 deletions.
13 changes: 10 additions & 3 deletions hammer/common/cadence/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from hammer.vlsi import HammerTool, HasSDCSupport, HasCPFSupport, HasUPFSupport, TCLTool, ILMStruct
from hammer.vlsi.constraints import MMMCCorner, MMMCCornerType
from hammer.utils import optional_map, add_dicts
from hammer.utils import optional_map, add_dicts, reduce_list_str, add_lists
import hammer.tech as hammer_tech


Expand Down Expand Up @@ -146,9 +146,16 @@ def append_mmmc(cmd: str) -> None:
blank_sdc = os.path.join(self.run_dir, "blank.sdc")
self.run_executable(["touch", blank_sdc])
sdc_files_arg = "-sdc_files {{ {} }}".format(blank_sdc)
append_mmmc("create_constraint_mode -name {name} {sdc_files_arg}".format(
if self.hierarchical_mode.is_nonleaf_hierarchical():
ilm_sdcs = reduce_list_str(add_lists, list(map(lambda ilm: ilm.sdcs, self.get_input_ilms()))) # type: List[str]
ilm_sdc_files_arg = "-ilm_sdc_files [list {sdc_files}]".format(
sdc_files=" ".join(ilm_sdcs))
else:
ilm_sdc_files_arg = ""
append_mmmc("create_constraint_mode -name {name} {sdc_files_arg} {ilm_sdc_files_arg}".format(
name=constraint_mode,
sdc_files_arg=sdc_files_arg
sdc_files_arg=sdc_files_arg,
ilm_sdc_files_arg=ilm_sdc_files_arg
))

corners = self.get_mmmc_corners() # type: List[MMMCCorner]
Expand Down
1 change: 1 addition & 0 deletions hammer/config/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ vlsi.inputs:
# gds (str) - path to the GDS file
# netlist (str) - path to the netlist file
# sim_netlist (str) - Optional. If specified, this netlist is appended for hierarchical simulation
# sdcs (List(str)) - paths to the SDC file(s) needed for parent constraints

mmmc_corners: [] # Multi-mode multi-corner setups, overrides supplies
# MMMC struct members:
Expand Down
18 changes: 17 additions & 1 deletion hammer/par/innovus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ def fill_outputs(self) -> bool:
lef=os.path.join(self.run_dir, "{top}ILM.lef".format(top=self.top_module)),
gds=self.output_gds_filename,
netlist=self.output_netlist_filename,
sim_netlist=self.output_sim_netlist_filename)
sim_netlist=self.output_sim_netlist_filename,
sdcs=self.output_ilm_sdcs)
]
else:
self.output_ilms = []
Expand Down Expand Up @@ -137,6 +138,17 @@ def output_spef_paths(self) -> List[str]:
else:
return [os.path.join(self.run_dir, "{top}.par.spef".format(top=self.top_module))]

@property
def output_ilm_sdcs(self) -> List[str]:
corners = self.get_mmmc_corners()
if corners:
filtered = list(filter(lambda c: c.type in [MMMCCornerType.Setup, MMMCCornerType.Hold], corners))
ctype_map = {MMMCCornerType.Setup: "setup", MMMCCornerType.Hold: "hold"}
return list(map(lambda c: os.path.join(self.run_dir, "{top}_postRoute_{corner_name}.{corner_type}_view.core.sdc".format(
top=self.top_module, corner_name=c.name, corner_type=ctype_map[c.type])), filtered))
else:
return [os.path.join(self.run_dir, "{top}_postRoute.core.sdc".format(top=self.top_module))]

@property
def env_vars(self) -> Dict[str, str]:
v = dict(super().env_vars)
Expand Down Expand Up @@ -824,6 +836,10 @@ def write_ilm(self) -> bool:
self.verbose_append("write_lef_abstract -5.8 {top}ILM.lef".format(top=self.top_module))
self.verbose_append("write_ilm -model_type all -to_dir {ilm_dir_name} -type_flex_ilm ilm".format(
ilm_dir_name=self.ilm_dir_name))
# Need to append -hierarchical after get_pins in SDCs for parent timing analysis
for sdc_out in self.output_ilm_sdcs:
self.append('gzip -d -c {ilm_dir_name}/mmmc/ilm_data/{top}/{sdc_in}.gz | sed "s/get_pins/get_pins -hierarchical/g" > {sdc_out}'.format(
ilm_dir_name=self.ilm_dir_name, top=self.top_module, sdc_in=os.path.basename(sdc_out), sdc_out=sdc_out))
self.ran_write_ilm = True
return True

Expand Down
3 changes: 2 additions & 1 deletion hammer/par/mockpar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,13 @@ def fill_outputs(self) -> bool:
self.output_gds = "/dev/null"
self.output_netlist = "/dev/null"
self.output_sim_netlist = "/dev/null"
self.output_ilm_sdcs = ["/dev/null"]
self.hcells_list = []
if self.hierarchical_mode in [HierarchicalMode.Leaf, HierarchicalMode.Hierarchical]:
self.output_ilms = [
ILMStruct(dir="/dev/null", data_dir="/dev/null", module=self.top_module,
lef="/dev/null", gds=self.output_gds, netlist=self.output_netlist,
sim_netlist=self.output_sim_netlist)
sim_netlist=self.output_sim_netlist, sdcs=self.output_ilm_sdcs)
]
else:
self.output_ilms = []
Expand Down
9 changes: 6 additions & 3 deletions hammer/vlsi/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class ILMStruct(NamedTuple('ILMStruct', [
('lef', str),
('gds', str),
('netlist', str),
('sim_netlist', Optional[str])
('sim_netlist', Optional[str]),
('sdcs', List[str])
])):
__slots__ = ()

Expand All @@ -36,7 +37,8 @@ def to_setting(self) -> dict:
"module": self.module,
"lef": self.lef,
"gds": self.gds,
"netlist": self.netlist
"netlist": self.netlist,
"sdcs": self.sdcs
}
if self.sim_netlist is not None:
output.update({"sim_netlist": self.sim_netlist})
Expand All @@ -51,7 +53,8 @@ def from_setting(ilm: dict) -> "ILMStruct":
lef=str(ilm["lef"]),
gds=str(ilm["gds"]),
netlist=str(ilm["netlist"]),
sim_netlist=ilm.get("sim_netlist")
sim_netlist=ilm.get("sim_netlist"),
sdcs=list(map(lambda x: str(x), ilm["sdcs"]))
)


Expand Down

0 comments on commit b1f970a

Please sign in to comment.