Remove blocked Hanan node connections

This commit is contained in:
Eren Dogan 2023-05-30 20:09:10 -07:00
parent 2799c106bd
commit e3d8ad13b2
3 changed files with 60 additions and 36 deletions

View File

@ -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)

View File

@ -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:

View File

@ -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. """