mirror of https://github.com/VLSIDA/OpenRAM.git
Include all blockages inside the routing region
This commit is contained in:
parent
4fe5aa49e4
commit
021da25cd6
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue