From 5bf629f3e5854b3408afa7f2dccf4f8d41abc020 Mon Sep 17 00:00:00 2001 From: Eren Dogan Date: Wed, 28 Jun 2023 20:55:49 -0700 Subject: [PATCH] Prevent DRC violations for vdd and gnd pins --- compiler/router/hanan_graph.py | 27 ++++++--------------------- compiler/router/hanan_router.py | 5 +++++ compiler/router/hanan_shape.py | 8 +++++--- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/compiler/router/hanan_graph.py b/compiler/router/hanan_graph.py index d1bd5974..fa92e4bf 100644 --- a/compiler/router/hanan_graph.py +++ b/compiler/router/hanan_graph.py @@ -47,7 +47,8 @@ class hanan_graph: # Check if any blockage blocks this probe for blockage in self.graph_blockages: # Check if two shapes overlap - if blockage.overlaps(probe_shape): + # Inflated blockages of pins don't block probes + if blockage.overlaps(probe_shape) and blockage.name != self.source.name: return True return False @@ -67,7 +68,7 @@ class hanan_graph: # Find the blockages that are in the routing area self.graph_blockages = [] - for blockage in self.get_blockages(source.name): + for blockage in self.router.blockages: # Set the region's lpp to current blockage's lpp so that the # overlaps method works region.lpp = blockage.lpp @@ -82,24 +83,6 @@ class hanan_graph: debug.info(0, "Number of nodes in the routing graph: {}".format(len(self.nodes))) - def get_blockages(self, pin_name): - """ - Return all blockages for this routing region, including pins with - different name. - """ - - # Create a copy of blockages - blockages = self.router.blockages[:] - # Create a copy of pins with different name than the routed pins - offset = self.router.layer_widths[0] / 2 - for name, pins in self.router.pins.items(): - if name == pin_name: - continue - for pin in pins: - blockages.append(deepcopy(pin).inflated_pin(multiple=1, extra_spacing=offset)) - return blockages - - def generate_cartesian_values(self): """ Generate x and y values from all the corners of the shapes in the @@ -200,7 +183,9 @@ class hanan_graph: point = node.center for blockage in self.graph_blockages: # Remove if the node is inside a blockage - if self.inside_shape(point, blockage): + # If the blockage is an inflated routable, remove if outside + # the routable shape + if self.inside_shape(point, blockage) and (blockage.name != self.source.name or not self.inside_shape(point, blockage.inflated_from)): node.remove_all_neighbors() self.nodes.remove(node) break diff --git a/compiler/router/hanan_router.py b/compiler/router/hanan_router.py index 10d27042..14ecb92e 100644 --- a/compiler/router/hanan_router.py +++ b/compiler/router/hanan_router.py @@ -144,6 +144,11 @@ class hanan_router(router_tech): for blockage in blockages: self.blockages.append(blockage.inflated_pin(multiple=1, extra_spacing=offset)) + # Add vdd and gnd pins as blockages as well + # NOTE: This is done to make vdd and gnd pins DRC-safe + for pin in self.all_pins: + self.blockages.append(pin.inflated_pin(multiple=1, extra_spacing=offset, keep_link=True)) + def add_path(self, path): """ Add the route path to the layout. """ diff --git a/compiler/router/hanan_shape.py b/compiler/router/hanan_shape.py index c76f61dc..39af5bbf 100644 --- a/compiler/router/hanan_shape.py +++ b/compiler/router/hanan_shape.py @@ -14,12 +14,14 @@ class hanan_shape(pin_layout): the Hanan router. """ - def __init__(self, name, rect, layer_name_pp): + def __init__(self, name, rect, layer_name_pp, inflated_from=None): pin_layout.__init__(self, name, rect, layer_name_pp) + self.inflated_from = inflated_from - def inflated_pin(self, spacing=None, multiple=0.5, extra_spacing=0): + + def inflated_pin(self, spacing=None, multiple=0.5, extra_spacing=0, keep_link=False): """ Override the default inflated_pin behavior. """ ll, ur = self.inflate(spacing, multiple) @@ -27,7 +29,7 @@ class hanan_shape(pin_layout): newll = ll - extra newur = ur + extra inflated_area = (newll, newur) - return hanan_shape(self.name, inflated_area, self.layer) + return hanan_shape(self.name, inflated_area, self.layer, self if keep_link else None) def aligns(self, other):