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
|
import heapq
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from openram import debug
|
from openram import debug
|
||||||
from openram.base.pin_layout import pin_layout
|
|
||||||
from openram.base.vector import vector
|
from openram.base.vector import vector
|
||||||
from openram.base.vector3d import vector3d
|
from openram.base.vector3d import vector3d
|
||||||
from .direction import direction
|
from .direction import direction
|
||||||
|
|
@ -61,12 +60,16 @@ class hanan_graph:
|
||||||
|
|
||||||
# Find the region to be routed and only include objects inside that region
|
# Find the region to be routed and only include objects inside that region
|
||||||
region = deepcopy(source)
|
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))
|
debug.info(0, "Routing region is {}".format(region.rect))
|
||||||
|
|
||||||
# Find the blockages that are in the routing area
|
# Find the blockages that are in the routing area
|
||||||
self.graph_blockages = []
|
self.graph_blockages = []
|
||||||
for blockage in self.router.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):
|
if region.overlaps(blockage):
|
||||||
self.graph_blockages.append(blockage)
|
self.graph_blockages.append(blockage)
|
||||||
debug.info(0, "Number of blockages detected in the routing region: {}".format(len(self.graph_blockages)))
|
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):
|
def generate_cartesian_values(self):
|
||||||
"""
|
"""
|
||||||
Generate x and y values from all the corners of the shapes in this
|
Generate x and y values from all the corners of the shapes in the
|
||||||
region.
|
routing region.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Obtain the x and y values for Hanan grid
|
|
||||||
x_values = set()
|
x_values = set()
|
||||||
y_values = set()
|
y_values = set()
|
||||||
offset = max(self.router.horiz_track_width, self.router.vert_track_width) / 2
|
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]:
|
for shape in [self.source, self.target]:
|
||||||
aspect_ratio = shape.width() / shape.height()
|
aspect_ratio = shape.width() / shape.height()
|
||||||
# If the pin is tall or fat, add two points on the ends
|
# If the pin is tall or fat, add two points on the ends
|
||||||
|
|
@ -133,8 +135,8 @@ class hanan_graph:
|
||||||
orthogonal neighbors.
|
orthogonal neighbors.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Generate Hanan points here (cartesian product of all x and y values)
|
|
||||||
y_len = len(y_values)
|
y_len = len(y_values)
|
||||||
|
left_offset = -(y_len * 2)
|
||||||
self.nodes = []
|
self.nodes = []
|
||||||
for x in x_values:
|
for x in x_values:
|
||||||
for y in y_values:
|
for y in y_values:
|
||||||
|
|
@ -144,7 +146,7 @@ class hanan_graph:
|
||||||
# Connect these two neighbors
|
# Connect these two neighbors
|
||||||
below_node.add_neighbor(above_node)
|
below_node.add_neighbor(above_node)
|
||||||
|
|
||||||
# Find potential neighbor nodes
|
# Find potential orthogonal neighbor nodes
|
||||||
belows = []
|
belows = []
|
||||||
aboves = []
|
aboves = []
|
||||||
count = len(self.nodes) // 2
|
count = len(self.nodes) // 2
|
||||||
|
|
@ -152,8 +154,8 @@ class hanan_graph:
|
||||||
belows.append(-2)
|
belows.append(-2)
|
||||||
aboves.append(-1)
|
aboves.append(-1)
|
||||||
if count >= y_len: # Left
|
if count >= y_len: # Left
|
||||||
belows.append(-(y_len * 2))
|
belows.append(left_offset)
|
||||||
aboves.append(-(y_len * 2) + 1)
|
aboves.append(left_offset + 1)
|
||||||
|
|
||||||
# Add these connections if not blocked by a blockage
|
# Add these connections if not blocked by a blockage
|
||||||
for i in belows:
|
for i in belows:
|
||||||
|
|
@ -179,7 +181,6 @@ class hanan_graph:
|
||||||
def remove_blocked_nodes(self):
|
def remove_blocked_nodes(self):
|
||||||
""" Remove the Hanan nodes that are blocked by a blockage. """
|
""" Remove the Hanan nodes that are blocked by a blockage. """
|
||||||
|
|
||||||
# Remove blocked points
|
|
||||||
for i in range(len(self.nodes) - 1, -1, -1):
|
for i in range(len(self.nodes) - 1, -1, -1):
|
||||||
node = self.nodes[i]
|
node = self.nodes[i]
|
||||||
point = node.center
|
point = node.center
|
||||||
|
|
@ -225,7 +226,7 @@ class hanan_graph:
|
||||||
# Get the closest node from the queue
|
# Get the closest node from the queue
|
||||||
current = heapq.heappop(queue)[2]
|
current = heapq.heappop(queue)[2]
|
||||||
|
|
||||||
# Continue if already discovered
|
# Skip this node if already discovered
|
||||||
if current in close_set:
|
if current in close_set:
|
||||||
continue
|
continue
|
||||||
close_set.add(current)
|
close_set.add(current)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
from openram import debug
|
from openram import debug
|
||||||
from openram.base.pin_layout import pin_layout
|
|
||||||
from openram.base.vector import vector
|
from openram.base.vector import vector
|
||||||
from openram.base.vector3d import vector3d
|
from openram.base.vector3d import vector3d
|
||||||
from openram.gdsMill import gdsMill
|
from openram.gdsMill import gdsMill
|
||||||
|
|
@ -13,6 +12,7 @@ from openram.tech import layer as tech_layer
|
||||||
from openram import OPTS
|
from openram import OPTS
|
||||||
from .router_tech import router_tech
|
from .router_tech import router_tech
|
||||||
from .hanan_graph import hanan_graph
|
from .hanan_graph import hanan_graph
|
||||||
|
from .hanan_shape import hanan_shape
|
||||||
|
|
||||||
|
|
||||||
class hanan_router(router_tech):
|
class hanan_router(router_tech):
|
||||||
|
|
@ -92,7 +92,7 @@ class hanan_router(router_tech):
|
||||||
ll = vector(boundary[0], boundary[1])
|
ll = vector(boundary[0], boundary[1])
|
||||||
ur = vector(boundary[2], boundary[3])
|
ur = vector(boundary[2], boundary[3])
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
pin = pin_layout(pin_name, rect, layer)
|
pin = hanan_shape(pin_name, rect, layer)
|
||||||
pin_set.add(pin)
|
pin_set.add(pin)
|
||||||
# Add these pins to the 'pins' dict
|
# Add these pins to the 'pins' dict
|
||||||
self.pins[pin_name] = pin_set
|
self.pins[pin_name] = pin_set
|
||||||
|
|
@ -111,7 +111,7 @@ class hanan_router(router_tech):
|
||||||
ll = vector(boundary[0], boundary[1])
|
ll = vector(boundary[0], boundary[1])
|
||||||
ur = vector(boundary[2], boundary[3])
|
ur = vector(boundary[2], boundary[3])
|
||||||
rect = [ll, ur]
|
rect = [ll, ur]
|
||||||
new_shape = pin_layout("blockage{}".format(len(self.blockages)),
|
new_shape = hanan_shape("blockage{}".format(len(self.blockages)),
|
||||||
rect,
|
rect,
|
||||||
lpp)
|
lpp)
|
||||||
# If there is a rectangle that is the same in the pins,
|
# 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
|
# Remove blockages contained by this new blockage
|
||||||
for i in range(len(self.blockages) - 1, -1, -1):
|
for i in range(len(self.blockages) - 1, -1, -1):
|
||||||
blockage = self.blockages[i]
|
blockage = self.blockages[i]
|
||||||
|
# Remove the previous blockage contained by this new
|
||||||
|
# blockage
|
||||||
if new_shape.contains(blockage):
|
if new_shape.contains(blockage):
|
||||||
self.blockages.remove(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)
|
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