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
|
min_neighbor = None
|
||||||
for j in range(i + 1, len(self.nodes)):
|
for j in range(i + 1, len(self.nodes)):
|
||||||
neighbor = self.nodes[j]
|
neighbor = self.nodes[j]
|
||||||
|
# Skip if not on the same layer
|
||||||
if node.center.z != neighbor.center.z:
|
if node.center.z != neighbor.center.z:
|
||||||
continue
|
continue
|
||||||
|
# Calculate the distance vector and distance value
|
||||||
distance_vector = neighbor.center - node.center
|
distance_vector = neighbor.center - node.center
|
||||||
distance = node.center.distance(neighbor.center)
|
distance = node.center.distance(neighbor.center)
|
||||||
|
# Skip if not connected rectilinearly
|
||||||
if (distance_vector.x or (distance_vector.y * d.y <= 0)) and \
|
if (distance_vector.x or (distance_vector.y * d.y <= 0)) and \
|
||||||
(distance_vector.y or (distance_vector.x * d.x <= 0)):
|
(distance_vector.y or (distance_vector.x * d.x <= 0)):
|
||||||
continue
|
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:
|
if distance < min_dist:
|
||||||
min_dist = distance
|
min_dist = distance
|
||||||
min_neighbor = neighbor
|
min_neighbor = neighbor
|
||||||
|
|
@ -156,7 +162,7 @@ class navigation_graph:
|
||||||
|
|
||||||
# Update neighbor scores
|
# Update neighbor scores
|
||||||
for node in current.neighbors:
|
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]:
|
if node.id not in g_scores or tentative_score < g_scores[node.id]:
|
||||||
came_from[node.id] = current
|
came_from[node.id] = current
|
||||||
g_scores[node.id] = tentative_score
|
g_scores[node.id] = tentative_score
|
||||||
|
|
@ -165,16 +171,3 @@ class navigation_graph:
|
||||||
|
|
||||||
# Return None if not connected
|
# Return None if not connected
|
||||||
return None
|
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)
|
node.neighbors.remove(self)
|
||||||
|
|
||||||
|
|
||||||
def get_edge_cost(self, node):
|
def get_edge_cost(self, other):
|
||||||
""" Return the cost of going to node. """
|
""" Get the cost of going from this node to the other node. """
|
||||||
|
|
||||||
if node in self.neighbors:
|
if other in self.neighbors:
|
||||||
return self.center.distance(node.center) + abs(self.center.z - node.center.z)
|
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")
|
return float("inf")
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ class navigation_router(router_tech):
|
||||||
|
|
||||||
def route(self, vdd_name="vdd", gnd_name="gnd"):
|
def route(self, vdd_name="vdd", gnd_name="gnd"):
|
||||||
""" Route the given pins in the given order. """
|
""" 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
|
# Prepare gdsMill to find pins and blockages
|
||||||
self.design.gds_write(self.gds_filename)
|
self.design.gds_write(self.gds_filename)
|
||||||
|
|
@ -63,7 +64,7 @@ class navigation_router(router_tech):
|
||||||
# Create the path shapes on layout
|
# Create the path shapes on layout
|
||||||
self.add_path(path)
|
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):
|
def find_pins(self, pin_name):
|
||||||
|
|
@ -142,13 +143,14 @@ class navigation_router(router_tech):
|
||||||
""" """
|
""" """
|
||||||
|
|
||||||
# Display the inflated blockage
|
# Display the inflated blockage
|
||||||
for blockage in self.nav.graph_blockages:
|
if "nav" in self.__dict__:
|
||||||
self.add_object_info(blockage, "blockage")
|
for blockage in self.nav.graph_blockages:
|
||||||
for node in self.nav.nodes:
|
self.add_object_info(blockage, "blockage")
|
||||||
offset = (node.center.x, node.center.y)
|
for node in self.nav.nodes:
|
||||||
self.design.add_label(text="O",
|
offset = (node.center.x, node.center.y)
|
||||||
layer="text",
|
self.design.add_label(text="O",
|
||||||
offset=offset)
|
layer="text",
|
||||||
|
offset=offset)
|
||||||
if source:
|
if source:
|
||||||
self.add_object_info(source, "source")
|
self.add_object_info(source, "source")
|
||||||
if target:
|
if target:
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,29 @@
|
||||||
Utility functions for navigation router.
|
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):
|
def is_in_region(point, region):
|
||||||
""""""
|
""""""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue