Include all blockages inside the routing region

This commit is contained in:
Eren Dogan 2023-06-04 08:46:59 -07:00
parent 4fe5aa49e4
commit 021da25cd6
3 changed files with 62 additions and 15 deletions

View File

@ -6,7 +6,6 @@
import heapq
from copy import deepcopy
from openram import debug
from openram.base.pin_layout import pin_layout
from openram.base.vector import vector
from openram.base.vector3d import vector3d
from .direction import direction
@ -61,12 +60,16 @@ class hanan_graph:
# Find the region to be routed and only include objects inside that region
region = deepcopy(source)
region.bbox([source, target])
region.bbox([target])
region = region.inflated_pin(multiple=1)
debug.info(0, "Routing region is {}".format(region.rect))
# Find the blockages that are in the routing area
self.graph_blockages = []
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
if region.overlaps(blockage):
self.graph_blockages.append(blockage)
debug.info(0, "Number of blockages detected in the routing region: {}".format(len(self.graph_blockages)))
@ -80,16 +83,15 @@ class hanan_graph:
def generate_cartesian_values(self):
"""
Generate x and y values from all the corners of the shapes in this
region.
Generate x and y values from all the corners of the shapes in the
routing region.
"""
# Obtain the x and y values for Hanan grid
x_values = set()
y_values = set()
offset = max(self.router.horiz_track_width, self.router.vert_track_width) / 2
# Add the source and target pins first
# 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
@ -133,8 +135,8 @@ class hanan_graph:
orthogonal neighbors.
"""
# Generate Hanan points here (cartesian product of all x and y values)
y_len = len(y_values)
left_offset = -(y_len * 2)
self.nodes = []
for x in x_values:
for y in y_values:
@ -144,7 +146,7 @@ class hanan_graph:
# Connect these two neighbors
below_node.add_neighbor(above_node)
# Find potential neighbor nodes
# Find potential orthogonal neighbor nodes
belows = []
aboves = []
count = len(self.nodes) // 2
@ -152,8 +154,8 @@ class hanan_graph:
belows.append(-2)
aboves.append(-1)
if count >= y_len: # Left
belows.append(-(y_len * 2))
aboves.append(-(y_len * 2) + 1)
belows.append(left_offset)
aboves.append(left_offset + 1)
# Add these connections if not blocked by a blockage
for i in belows:
@ -179,7 +181,6 @@ class hanan_graph:
def remove_blocked_nodes(self):
""" Remove the Hanan nodes that are blocked by a blockage. """
# Remove blocked points
for i in range(len(self.nodes) - 1, -1, -1):
node = self.nodes[i]
point = node.center
@ -225,7 +226,7 @@ class hanan_graph:
# Get the closest node from the queue
current = heapq.heappop(queue)[2]
# Continue if already discovered
# Skip this node if already discovered
if current in close_set:
continue
close_set.add(current)

View File

@ -4,7 +4,6 @@
# All rights reserved.
#
from openram import debug
from openram.base.pin_layout import pin_layout
from openram.base.vector import vector
from openram.base.vector3d import vector3d
from openram.gdsMill import gdsMill
@ -13,6 +12,7 @@ from openram.tech import layer as tech_layer
from openram import OPTS
from .router_tech import router_tech
from .hanan_graph import hanan_graph
from .hanan_shape import hanan_shape
class hanan_router(router_tech):
@ -92,7 +92,7 @@ class hanan_router(router_tech):
ll = vector(boundary[0], boundary[1])
ur = vector(boundary[2], boundary[3])
rect = [ll, ur]
pin = pin_layout(pin_name, rect, layer)
pin = hanan_shape(pin_name, rect, layer)
pin_set.add(pin)
# Add these pins to the 'pins' dict
self.pins[pin_name] = pin_set
@ -111,7 +111,7 @@ class hanan_router(router_tech):
ll = vector(boundary[0], boundary[1])
ur = vector(boundary[2], boundary[3])
rect = [ll, ur]
new_shape = pin_layout("blockage{}".format(len(self.blockages)),
new_shape = hanan_shape("blockage{}".format(len(self.blockages)),
rect,
lpp)
# If there is a rectangle that is the same in the pins,
@ -121,8 +121,15 @@ class hanan_router(router_tech):
# 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)

View File

@ -0,0 +1,39 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz
# All rights reserved.
#
from openram.base.pin_layout import pin_layout
class hanan_shape(pin_layout):
"""
This class inherits the pin_layout class to change some of its behavior for
the Hanan router.
"""
def __init__(self, name, rect, layer_name_pp):
pin_layout.__init__(self, name, rect, layer_name_pp)
def inflated_pin(self, spacing=None, multiple=0.5):
""" Override the default inflated_pin behavior. """
inflated_area = self.inflate(spacing, multiple)
return hanan_shape(self.name, inflated_area, self.layer)
def aligns(self, other):
""" Return if the other shape aligns with this shape. """
# Shapes must overlap to be able to align
if not self.overlaps(other):
return False
ll, ur = self.rect
oll, our = other.rect
if ll.x == oll.x and ur.x == our.x:
return True
if ll.y == oll.y and ur.y == our.y:
return True
return False