Try routing in larger regions if no path is found

This commit is contained in:
Eren Dogan 2023-07-25 18:40:07 -07:00
parent ed404a3ad2
commit 6cda5415a4
3 changed files with 45 additions and 15 deletions

View File

@ -111,7 +111,7 @@ class graph:
return False
def create_graph(self, source, target):
def create_graph(self, source, target, scale=1):
""" Create the graph to run routing on later. """
debug.info(2, "Creating the graph for source '{}' and target'{}'.".format(source, target))
@ -122,6 +122,7 @@ class graph:
# Find the region to be routed and only include objects inside that region
region = deepcopy(source)
region.bbox([target])
region.multiply(scale)
region = region.inflated_pin(spacing=self.router.track_space)
debug.info(3, "Routing region is {}".format(region.rect))
@ -147,6 +148,9 @@ class graph:
debug.info(3, "Number of vias detected in the routing region: {}".format(len(self.graph_vias)))
debug.info(3, "Number of nodes in the routing graph: {}".format(len(self.nodes)))
# Return the region to scale later if no path is found
return region.rect
def find_graph_blockages(self, region):
""" Find blockages that overlap the routing region. """

View File

@ -96,20 +96,35 @@ class graph_router(router_tech):
pins = self.pins[pin_name]
# Route closest pins according to the minimum spanning tree
for source, target in self.get_mst_pairs(list(pins)):
# Create the graph
g = graph(self)
g.create_graph(source, target)
# Find the shortest path from source to target
path = g.find_shortest_path()
# TODO: Exponentially increase the routing area and retry if no
# path was found
debug.check(path is not None, "Couldn't route from {} to {}".format(source, target))
# Create the path shapes on layout
self.add_path(path)
# Find the recently added shapes
self.prepare_gds_reader()
self.find_blockages(pin_name)
self.find_vias()
# This is the routing region scale
scale = 1
while True:
# Create the graph
g = graph(self)
region = g.create_graph(source, target, scale)
# Find the shortest path from source to target
path = g.find_shortest_path()
# If there is no path found, exponentially try again with a
# larger routing region
if path is None:
rll, rur = region
bll, bur = self.ring_bbox
# Stop scaling the region and throw an error
if rll.x < bll.x and rll.y < bll.y and \
rur.x > bur.x and rur.y > bur.y:
self.write_debug_gds(gds_name="{}error.gds".format(OPTS.openram_temp), g=g, source=source, target=target)
debug.error("Couldn't route from {} to {}.".format(source, target), -1)
# Exponentially scale the region
scale *= 2
debug.info(0, "Retry routing in larger routing region with scale {}".format(scale))
continue
# Create the path shapes on layout
self.add_path(path)
# Find the recently added shapes
self.prepare_gds_reader()
self.find_blockages(pin_name)
self.find_vias()
break
def prepare_gds_reader(self):

View File

@ -65,6 +65,17 @@ class graph_shape(pin_layout):
return graph_shape(self.name, inflated_area, self.layer, self)
def multiply(self, scale):
""" Multiply the width and height with the scale value. """
width = (self.width() * (scale - 1)) / 2
height = (self.height() * (scale - 1)) / 2
ll, ur = self.rect
newll = vector(ll.x - width, ll.y - height)
newur = vector(ur.x + width, ur.y + height)
self.rect = [snap(newll), snap(newur)]
def aligns(self, other):
""" Return if the other shape aligns with this shape. """