mirror of https://github.com/VLSIDA/OpenRAM.git
Avoid blockages when connecting Hanan points
This commit is contained in:
parent
648a631a28
commit
33f1b924a4
|
|
@ -78,13 +78,19 @@ class navigation_graph:
|
|||
min_neighbor = None
|
||||
for j in range(i + 1, len(self.nodes)):
|
||||
neighbor = self.nodes[j]
|
||||
# Skip if not on the same layer
|
||||
if node.center.z != neighbor.center.z:
|
||||
continue
|
||||
# Calculate the distance vector and distance value
|
||||
distance_vector = neighbor.center - node.center
|
||||
distance = node.center.distance(neighbor.center)
|
||||
# Skip if not connected rectilinearly
|
||||
if (distance_vector.x or (distance_vector.y * d.y <= 0)) and \
|
||||
(distance_vector.y or (distance_vector.x * d.x <= 0)):
|
||||
continue
|
||||
# Skip if this connection is blocked by a blockage
|
||||
if is_probe_blocked(node.center, neighbor.center, self.graph_blockages):
|
||||
continue
|
||||
if distance < min_dist:
|
||||
min_dist = distance
|
||||
min_neighbor = neighbor
|
||||
|
|
@ -156,7 +162,7 @@ class navigation_graph:
|
|||
|
||||
# Update neighbor scores
|
||||
for node in current.neighbors:
|
||||
tentative_score = self.get_edge_cost(current, node) + g_scores[current.id]
|
||||
tentative_score = current.get_edge_cost(node) + g_scores[current.id]
|
||||
if node.id not in g_scores or tentative_score < g_scores[node.id]:
|
||||
came_from[node.id] = current
|
||||
g_scores[node.id] = tentative_score
|
||||
|
|
@ -165,16 +171,3 @@ class navigation_graph:
|
|||
|
||||
# Return None if not connected
|
||||
return None
|
||||
|
||||
|
||||
def get_edge_cost(self, source, target):
|
||||
""" """
|
||||
|
||||
if target in source.neighbors:
|
||||
is_vertical = source.center.x == target.center.x
|
||||
layer_dist = source.center.distance(target.center)
|
||||
if is_vertical != bool(source.center.z):
|
||||
layer_dist *= 2
|
||||
via_dist = abs(source.center.z - target.center.z) * 2
|
||||
return layer_dist + via_dist
|
||||
return float("inf")
|
||||
|
|
|
|||
|
|
@ -40,9 +40,14 @@ class navigation_node:
|
|||
node.neighbors.remove(self)
|
||||
|
||||
|
||||
def get_edge_cost(self, node):
|
||||
""" Return the cost of going to node. """
|
||||
def get_edge_cost(self, other):
|
||||
""" Get the cost of going from this node to the other node. """
|
||||
|
||||
if node in self.neighbors:
|
||||
return self.center.distance(node.center) + abs(self.center.z - node.center.z)
|
||||
if other in self.neighbors:
|
||||
is_vertical = self.center.x == other.center.x
|
||||
layer_dist = self.center.distance(other.center)
|
||||
if is_vertical != bool(self.center.z):
|
||||
layer_dist *= 2
|
||||
via_dist = abs(self.center.z - other.center.z) * 2
|
||||
return layer_dist + via_dist
|
||||
return float("inf")
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ class navigation_router(router_tech):
|
|||
|
||||
def route(self, vdd_name="vdd", gnd_name="gnd"):
|
||||
""" Route the given pins in the given order. """
|
||||
debug.info(1, "Running router for {}...".format(pins))
|
||||
#debug.info(1, "Running router for {}...".format(pins))
|
||||
self.write_debug_gds(gds_name="before.gds")
|
||||
|
||||
# Prepare gdsMill to find pins and blockages
|
||||
self.design.gds_write(self.gds_filename)
|
||||
|
|
@ -63,7 +64,7 @@ class navigation_router(router_tech):
|
|||
# Create the path shapes on layout
|
||||
self.add_path(path)
|
||||
|
||||
self.write_debug_gds(source=vdd_0, target=vdd_1)
|
||||
self.write_debug_gds(gds_name="after.gds", source=vdd_0, target=vdd_1)
|
||||
|
||||
|
||||
def find_pins(self, pin_name):
|
||||
|
|
@ -142,13 +143,14 @@ class navigation_router(router_tech):
|
|||
""" """
|
||||
|
||||
# Display the inflated blockage
|
||||
for blockage in self.nav.graph_blockages:
|
||||
self.add_object_info(blockage, "blockage")
|
||||
for node in self.nav.nodes:
|
||||
offset = (node.center.x, node.center.y)
|
||||
self.design.add_label(text="O",
|
||||
layer="text",
|
||||
offset=offset)
|
||||
if "nav" in self.__dict__:
|
||||
for blockage in self.nav.graph_blockages:
|
||||
self.add_object_info(blockage, "blockage")
|
||||
for node in self.nav.nodes:
|
||||
offset = (node.center.x, node.center.y)
|
||||
self.design.add_label(text="O",
|
||||
layer="text",
|
||||
offset=offset)
|
||||
if source:
|
||||
self.add_object_info(source, "source")
|
||||
if target:
|
||||
|
|
|
|||
|
|
@ -7,6 +7,29 @@
|
|||
Utility functions for navigation 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):
|
||||
""""""
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue