mirror of https://github.com/VLSIDA/OpenRAM.git
Remove blocked Hanan node connections
This commit is contained in:
parent
2799c106bd
commit
e3d8ad13b2
|
|
@ -29,6 +29,32 @@ class hanan_graph:
|
|||
return point.z == self.router.get_zindex(shape.lpp)
|
||||
|
||||
|
||||
def is_probe_blocked(self, p1, p2):
|
||||
"""
|
||||
Return if a probe sent from p1 to p2 encounters a blockage.
|
||||
The probe must be sent vertically or horizontally.
|
||||
This function assumes that p1 and p2 are on the same layer.
|
||||
This function assumes that blockages are rectangular.
|
||||
"""
|
||||
|
||||
# Check if any blockage blocks this probe
|
||||
for blockage in self.graph_blockages:
|
||||
if not self.is_on_same_layer(p1, blockage):
|
||||
continue
|
||||
ll, ur = blockage.rect
|
||||
right_x = ur[0]
|
||||
upper_y = ur[1]
|
||||
left_x = ll[0]
|
||||
lower_y = ll[1]
|
||||
# Check if blocked vertically
|
||||
if is_between(left_x, right_x, p1.x) and (is_between(p1.y, p2.y, upper_y) or is_between(p1.y, p2.y, lower_y)):
|
||||
return True
|
||||
# Check if blocked horizontally
|
||||
if is_between(upper_y, lower_y, p1.y) and (is_between(p1.x, p2.x, left_x) or is_between(p1.x, p2.x, right_x)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def create_graph(self, source, target):
|
||||
""" Create the Hanan graph to run routing on later. """
|
||||
debug.info(0, "Creating the Hanan graph for source '{0}' and target'{1}'.".format(source, target))
|
||||
|
|
@ -114,16 +140,31 @@ class hanan_graph:
|
|||
for y in y_values:
|
||||
below_node = hanan_node([x, y, 0])
|
||||
above_node = hanan_node([x, y, 1])
|
||||
|
||||
# Connect these two neighbors
|
||||
below_node.add_neighbor(above_node)
|
||||
# Connect down and left nodes
|
||||
|
||||
# Find potential neighbor nodes
|
||||
belows = []
|
||||
aboves = []
|
||||
count = len(self.nodes) // 2
|
||||
if count % y_len: # Down
|
||||
below_node.add_neighbor(self.nodes[-2])
|
||||
above_node.add_neighbor(self.nodes[-1])
|
||||
belows.append(-2)
|
||||
aboves.append(-1)
|
||||
if count >= y_len: # Left
|
||||
below_node.add_neighbor(self.nodes[-(y_len * 2)])
|
||||
above_node.add_neighbor(self.nodes[-(y_len * 2) + 1])
|
||||
belows.append(-(y_len * 2))
|
||||
aboves.append(-(y_len * 2) + 1)
|
||||
|
||||
# Add these connections if not blocked by a blockage
|
||||
for i in belows:
|
||||
node = self.nodes[i]
|
||||
if not self.is_probe_blocked(below_node.center, node.center):
|
||||
below_node.add_neighbor(node)
|
||||
for i in aboves:
|
||||
node = self.nodes[i]
|
||||
if not self.is_probe_blocked(above_node.center, node.center):
|
||||
above_node.add_neighbor(node)
|
||||
|
||||
self.nodes.append(below_node)
|
||||
self.nodes.append(above_node)
|
||||
|
||||
|
|
@ -136,6 +177,7 @@ class hanan_graph:
|
|||
node = self.nodes[i]
|
||||
point = node.center
|
||||
for blockage in self.graph_blockages:
|
||||
# Remove if the node is inside a blockage
|
||||
if self.is_on_same_layer(point, blockage) and is_in_region(point, blockage):
|
||||
node.remove_all_neighbors()
|
||||
self.nodes.remove(node)
|
||||
|
|
|
|||
|
|
@ -116,18 +116,23 @@ class hanan_router(router_tech):
|
|||
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 self.pin_contains(new_shape):
|
||||
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]
|
||||
if new_shape.contains(blockage):
|
||||
self.blockages.remove(blockage)
|
||||
self.blockages.append(new_shape)
|
||||
|
||||
|
||||
def pin_contains(self, shape):
|
||||
def blockage_contains(self, shape):
|
||||
"""
|
||||
Return if this pin contains another pin or is contained by another pin.
|
||||
Return if this shape is contained by a blockage.
|
||||
"""
|
||||
|
||||
for pin in self.all_pins:
|
||||
if pin.contains(shape) or shape.contains(pin):
|
||||
for blockage in self.blockages:
|
||||
if blockage.contains(shape):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
|
@ -153,12 +158,12 @@ class hanan_router(router_tech):
|
|||
""" """
|
||||
|
||||
# Display the inflated blockage
|
||||
if "nav" in self.__dict__:
|
||||
if "hg" in self.__dict__:
|
||||
for blockage in self.hg.graph_blockages:
|
||||
self.add_object_info(blockage, "blockage")
|
||||
self.add_object_info(blockage, "blockage{}".format(self.get_zindex(blockage.lpp)))
|
||||
for node in self.hg.nodes:
|
||||
offset = (node.center.x, node.center.y)
|
||||
self.design.add_label(text="O",
|
||||
self.design.add_label(text="n{}".format(node.center.z),
|
||||
layer="text",
|
||||
offset=offset)
|
||||
if source:
|
||||
|
|
|
|||
|
|
@ -7,29 +7,6 @@
|
|||
Utility functions for Hanan router.
|
||||
"""
|
||||
|
||||
def is_probe_blocked(p1, p2, blockages):
|
||||
"""
|
||||
Return if a probe sent from p1 to p2 encounters a blockage.
|
||||
The probe must be sent vertically or horizontally.
|
||||
This method assumes that blockages are rectangular.
|
||||
"""
|
||||
|
||||
# Check if any blockage blocks this probe
|
||||
for blockage in blockages:
|
||||
ll, ur = blockage.rect
|
||||
right_x = ur[0]
|
||||
upper_y = ur[1]
|
||||
left_x = ll[0]
|
||||
lower_y = ll[1]
|
||||
# Check if blocked vertically
|
||||
if is_between(left_x, right_x, p1.x) and (is_between(p1.y, p2.y, upper_y) or is_between(p1.y, p2.y, lower_y)):
|
||||
return True
|
||||
# Check if blocked horizontally
|
||||
if is_between(upper_y, lower_y, p1.y) and (is_between(p1.x, p2.x, left_x) or is_between(p1.x, p2.x, right_x)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def is_in_region(point, region):
|
||||
""" Return if a point is in the given region. """
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue