From 5e5d3b97c549c090f680e63e3c56da9a37738b22 Mon Sep 17 00:00:00 2001 From: harrisonliew Date: Wed, 18 Oct 2023 14:25:55 -0700 Subject: [PATCH 1/3] add cover power blockage up to top_layer for hardmacros --- hammer/par/innovus/__init__.py | 4 ++++ hammer/tech/stackup.py | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/hammer/par/innovus/__init__.py b/hammer/par/innovus/__init__.py index bac2987d1..a902ec096 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_up_to_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: diff --git a/hammer/tech/stackup.py b/hammer/tech/stackup.py index 66a3f351d..7ba9ecbe7 100644 --- a/hammer/tech/stackup.py +++ b/hammer/tech/stackup.py @@ -390,6 +390,19 @@ 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_up_to_layer(self, name: str) -> List[Metal]: + """ + Get all the metals below and including 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) + return list(filter(lambda m: m.index in range(1, index), self.metals)) + 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. From d0204f0e87ce6470962aa9dec395a46e5c6e8539 Mon Sep 17 00:00:00 2001 From: harrisonliew Date: Wed, 18 Oct 2023 14:30:35 -0700 Subject: [PATCH 2/3] cover should not be inclusive of top layer --- hammer/par/innovus/__init__.py | 2 +- hammer/tech/stackup.py | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/hammer/par/innovus/__init__.py b/hammer/par/innovus/__init__.py index a902ec096..dc12ce6ad 100644 --- a/hammer/par/innovus/__init__.py +++ b/hammer/par/innovus/__init__.py @@ -1047,7 +1047,7 @@ 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_up_to_layer(current_top_layer))) + 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( diff --git a/hammer/tech/stackup.py b/hammer/tech/stackup.py index 7ba9ecbe7..a3eafb09a 100644 --- a/hammer/tech/stackup.py +++ b/hammer/tech/stackup.py @@ -390,16 +390,19 @@ 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_up_to_layer(self, name: str) -> List[Metal]: + def get_metals_below_layer(self, name: str) -> List[Metal]: """ - Get all the metals below and including the specified metal layer. + 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) - return list(filter(lambda m: m.index in range(1, index), self.metals)) + 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)) From f4ae116afe5f538a04e4e1f4999366e694963283 Mon Sep 17 00:00:00 2001 From: harrisonliew Date: Wed, 18 Oct 2023 14:59:44 -0700 Subject: [PATCH 3/3] remove reset_db, antenna trim --- hammer/par/innovus/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/hammer/par/innovus/__init__.py b/hammer/par/innovus/__init__.py index dc12ce6ad..d0e755f8a 100644 --- a/hammer/par/innovus/__init__.py +++ b/hammer/par/innovus/__init__.py @@ -1100,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) @@ -1148,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)