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)
|
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):
|
def create_graph(self, source, target):
|
||||||
""" Create the Hanan graph to run routing on later. """
|
""" 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))
|
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:
|
for y in y_values:
|
||||||
below_node = hanan_node([x, y, 0])
|
below_node = hanan_node([x, y, 0])
|
||||||
above_node = hanan_node([x, y, 1])
|
above_node = hanan_node([x, y, 1])
|
||||||
|
|
||||||
# Connect these two neighbors
|
# Connect these two neighbors
|
||||||
below_node.add_neighbor(above_node)
|
below_node.add_neighbor(above_node)
|
||||||
# Connect down and left nodes
|
|
||||||
|
# Find potential neighbor nodes
|
||||||
|
belows = []
|
||||||
|
aboves = []
|
||||||
count = len(self.nodes) // 2
|
count = len(self.nodes) // 2
|
||||||
if count % y_len: # Down
|
if count % y_len: # Down
|
||||||
below_node.add_neighbor(self.nodes[-2])
|
belows.append(-2)
|
||||||
above_node.add_neighbor(self.nodes[-1])
|
aboves.append(-1)
|
||||||
if count >= y_len: # Left
|
if count >= y_len: # Left
|
||||||
below_node.add_neighbor(self.nodes[-(y_len * 2)])
|
belows.append(-(y_len * 2))
|
||||||
above_node.add_neighbor(self.nodes[-(y_len * 2) + 1])
|
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(below_node)
|
||||||
self.nodes.append(above_node)
|
self.nodes.append(above_node)
|
||||||
|
|
||||||
|
|
@ -136,6 +177,7 @@ class hanan_graph:
|
||||||
node = self.nodes[i]
|
node = self.nodes[i]
|
||||||
point = node.center
|
point = node.center
|
||||||
for blockage in self.graph_blockages:
|
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):
|
if self.is_on_same_layer(point, blockage) and is_in_region(point, blockage):
|
||||||
node.remove_all_neighbors()
|
node.remove_all_neighbors()
|
||||||
self.nodes.remove(node)
|
self.nodes.remove(node)
|
||||||
|
|
|
||||||
|
|
@ -116,18 +116,23 @@ class hanan_router(router_tech):
|
||||||
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,
|
||||||
# it isn't a blockage
|
# 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)
|
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)
|
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:
|
for blockage in self.blockages:
|
||||||
if pin.contains(shape) or shape.contains(pin):
|
if blockage.contains(shape):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -153,12 +158,12 @@ class hanan_router(router_tech):
|
||||||
""" """
|
""" """
|
||||||
|
|
||||||
# Display the inflated blockage
|
# Display the inflated blockage
|
||||||
if "nav" in self.__dict__:
|
if "hg" in self.__dict__:
|
||||||
for blockage in self.hg.graph_blockages:
|
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:
|
for node in self.hg.nodes:
|
||||||
offset = (node.center.x, node.center.y)
|
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",
|
layer="text",
|
||||||
offset=offset)
|
offset=offset)
|
||||||
if source:
|
if source:
|
||||||
|
|
|
||||||
|
|
@ -7,29 +7,6 @@
|
||||||
Utility functions for Hanan router.
|
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):
|
def is_in_region(point, region):
|
||||||
""" Return if a point is in the given region. """
|
""" Return if a point is in the given region. """
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue