From 51f91e6d0aef5e8d636be7ec3711461038bd9103 Mon Sep 17 00:00:00 2001 From: Harrison Liew Date: Thu, 19 Oct 2023 13:21:52 -0700 Subject: [PATCH] Power straps updates (#808) * add cover power blockage up to top_layer for hardmacros * cover should not be inclusive of top layer * remove reset_db, antenna trim --- hammer/par/innovus/__init__.py | 7 ++++--- hammer/tech/stackup.py | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hammer/par/innovus/__init__.py b/hammer/par/innovus/__init__.py index bac2987d1..d0e755f8a 100644 --- a/hammer/par/innovus/__init__.py +++ b/hammer/par/innovus/__init__.py @@ -1047,10 +1047,14 @@ def generate_floorplan_tcl(self) -> List[str]: current_top_layer = None if current_top_layer is not None: bot_layer = self.get_stackup().get_metal_by_index(1).name + cover_layers = list(map(lambda m: m.name, self.get_stackup().get_metals_below_layer(current_top_layer))) output.append("create_place_halo -insts {inst} -halo_deltas {{{s} {s} {s} {s}}} -snap_to_site".format( inst=new_path, s=spacing)) output.append("create_route_halo -bottom_layer {b} -space {s} -top_layer {t} -inst {inst}".format( inst=new_path, b=bot_layer, t=current_top_layer, s=spacing)) + output.append("create_route_blockage -pg_nets -inst {inst} -layers {{{layers}}} -cover".format( + inst=new_path, layers=" ".join(cover_layers))) + elif constraint.type == PlacementConstraintType.Obstruction: obs_types = get_or_else(constraint.obs_types, []) # type: List[ObstructionType] if ObstructionType.Place in obs_types: @@ -1096,7 +1100,6 @@ def specify_std_cell_power_straps(self, blockage_spacing: Decimal, bbox: Optiona layer = self.get_stackup().get_metal(layer_name) results = [ "# Power strap definition for layer {} (rails):\n".format(layer_name), - "reset_db -category add_stripes", "set_db add_stripes_stacked_via_bottom_layer {}".format(layer_name), "set_db add_stripes_stacked_via_top_layer {}".format(layer_name), "set_db add_stripes_spacing_from_block {}".format(blockage_spacing) @@ -1144,10 +1147,8 @@ def specify_power_straps(self, layer_name: str, bottom_via_layer_name: str, bloc # TODO warn if the straps are off-pitch results = ["# Power strap definition for layer %s:\n" % layer_name] results.extend([ - "reset_db -category add_stripes", "set_db add_stripes_stacked_via_top_layer {}".format(layer_name), "set_db add_stripes_stacked_via_bottom_layer {}".format(bottom_via_layer_name), - "set_db add_stripes_trim_antenna_back_to_shape {stripe}", "set_db add_stripes_spacing_from_block {}".format(blockage_spacing) ]) layer = self.get_stackup().get_metal(layer_name) diff --git a/hammer/tech/stackup.py b/hammer/tech/stackup.py index 66a3f351d..a3eafb09a 100644 --- a/hammer/tech/stackup.py +++ b/hammer/tech/stackup.py @@ -390,6 +390,22 @@ def get_metal(self, name: str) -> Metal: return m raise ValueError("Metal named %s is not defined in stackup %s" % (name, self.name)) + def get_metals_below_layer(self, name: str) -> List[Metal]: + """ + Get all the metals below the specified metal layer. + + :param index: Index of the metal layer + :return: A list of metal layer objects + """ + try: + index = next(m.index for m in self.metals if m.name == name) + if index > 1: + return list(filter(lambda m: m.index in range(1, index), self.metals)) + else: + raise ValueError("There are no metals below layer %s in stackup %s" % (name, self.name)) + except StopIteration: + raise ValueError("Metal named %s is not defined in stackup %s" % (name, self.name)) + def get_metal_by_index(self, index: int) -> Metal: """ Get a given metal layer by index.