diff --git a/compiler/router/hanan_graph.py b/compiler/router/hanan_graph.py index b66e4943..04c4ab31 100644 --- a/compiler/router/hanan_graph.py +++ b/compiler/router/hanan_graph.py @@ -8,6 +8,7 @@ from copy import deepcopy from openram import debug from openram.base.vector import vector from openram.base.vector3d import vector3d +from openram.tech import drc from .direction import direction from .hanan_node import hanan_node from .hanan_probe import hanan_probe @@ -90,11 +91,12 @@ class hanan_graph: # Create a copy of blockages blockages = self.router.blockages[:] # Create a copy of pins with different name than the routed pins - for name, pins, in self.router.pins.items(): + 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)) + blockages.append(deepcopy(pin).inflated_pin(spacing=offset, multiple=1)) return blockages @@ -106,34 +108,26 @@ class hanan_graph: x_values = set() y_values = set() - offset = max(self.router.horiz_track_width, self.router.vert_track_width) / 2 # Add the source and target values for shape in [self.source, self.target]: aspect_ratio = shape.width() / shape.height() # If the pin is tall or fat, add two points on the ends if aspect_ratio <= 0.5: # Tall pin - uc = shape.uc() - bc = shape.bc() - points = [vector(uc.x, uc.y - offset), - vector(bc.x, bc.y + offset)] + points = [shape.uc(), shape.bc()] elif aspect_ratio >= 2: # Fat pin - lc = shape.lc() - rc = shape.rc() - points = [vector(lc.x + offset, lc.y), - vector(rc.x - offset, rc.y)] + points = [shape.lc(), shape.rc()] else: # Square-like pin - center = shape.center() - x_values.add(center.x) - y_values.add(center.y) - continue + points = [shape.center()] for p in points: x_values.add(p.x) y_values.add(p.y) # Add corners for blockages + offset = drc["grid"] for blockage in self.graph_blockages: ll, ur = blockage.rect + # Add minimum offset to the blockage corner nodes to prevent overlaps x_values.update([ll.x - offset, ur.x + offset]) y_values.update([ll.y - offset, ur.y + offset]) diff --git a/compiler/router/hanan_router.py b/compiler/router/hanan_router.py index 0b03b3fa..629a1dbd 100644 --- a/compiler/router/hanan_router.py +++ b/compiler/router/hanan_router.py @@ -109,6 +109,7 @@ class hanan_router(router_tech): """ """ debug.info(1, "Finding all blockages...") + blockages = [] for lpp in [self.vert_lpp, self.horiz_lpp]: shapes = self.layout.getAllShapes(lpp) for boundary in shapes: @@ -117,37 +118,31 @@ class hanan_router(router_tech): ll = vector(boundary[0], boundary[1]) ur = vector(boundary[2], boundary[3]) rect = [ll, ur] - new_shape = hanan_shape("blockage{}".format(len(self.blockages)), + new_shape = hanan_shape("blockage{}".format(len(blockages)), rect, lpp) # If there is a rectangle that is the same in the pins, # it isn't a blockage - if new_shape not in self.all_pins and not new_shape.contained_by_any(self.all_pins) and not self.blockage_contains(new_shape): - new_shape = new_shape.inflated_pin(multiple=1) - # Remove blockages contained by this new blockage - for i in range(len(self.blockages) - 1, -1, -1): - blockage = self.blockages[i] - # Remove the previous blockage contained by this new - # blockage - if new_shape.contains(blockage): - self.blockages.remove(blockage) - # Merge the previous blockage into this new blockage if - # they are aligning - elif new_shape.aligns(blockage): - new_shape.bbox([blockage]) - self.blockages.remove(blockage) - self.blockages.append(new_shape) + if new_shape.contained_by_any(self.all_pins) or new_shape.contained_by_any(blockages): + continue + # Remove blockages contained by this new blockage + for i in range(len(blockages) - 1, -1, -1): + blockage = blockages[i] + # Remove the previous blockage contained by this new + # blockage + if new_shape.contains(blockage): + blockages.remove(blockage) + # Merge the previous blockage into this new blockage if + # they are aligning + elif new_shape.aligns(blockage): + new_shape.bbox([blockage]) + blockages.remove(blockage) + blockages.append(new_shape) - - def blockage_contains(self, shape): - """ - Return if this shape is contained by a blockage. - """ - - for blockage in self.blockages: - if blockage.contains(shape): - return True - return False + # Inflate the shapes to prevent DRC errors + offset = self.layer_widths[0] / 2 + for blockage in blockages: + self.blockages.append(blockage.inflated_pin(spacing=offset, multiple=1)) def add_path(self, path): diff --git a/compiler/router/hanan_shape.py b/compiler/router/hanan_shape.py index 65dabe96..087ab02a 100644 --- a/compiler/router/hanan_shape.py +++ b/compiler/router/hanan_shape.py @@ -4,6 +4,8 @@ # All rights reserved. # from openram.base.pin_layout import pin_layout +from openram.base.vector import vector +from openram.tech import drc class hanan_shape(pin_layout): @@ -20,7 +22,14 @@ class hanan_shape(pin_layout): def inflated_pin(self, spacing=None, multiple=0.5): """ Override the default inflated_pin behavior. """ - inflated_area = self.inflate(spacing, multiple) + if not spacing: + spacing = 0 + drc_spacing = multiple * drc("{0}_to_{0}".format(self.layer)) + spacing = vector([spacing + drc_spacing] * 2) + (ll, ur) = self.rect + newll = ll - spacing + newur = ur + spacing + inflated_area = (newll, newur) return hanan_shape(self.name, inflated_area, self.layer)