Cleanup graph router

This commit is contained in:
Eren Dogan 2023-07-24 08:03:08 -07:00
parent 54f2e73214
commit 947e94323d
3 changed files with 46 additions and 31 deletions

View File

@ -128,24 +128,20 @@ class graph:
# Find the blockages that are in the routing area
self.graph_blockages = []
self.find_graph_blockages(region)
for shape in [source, target]:
if shape not in self.graph_blockages:
self.graph_blockages.append(shape)
# Find the vias that are in the routing area
self.graph_vias = []
for via in self.router.vias:
# Set the regions's lpp to current via's lpp so that the
# overlaps method works
region.lpp = via.lpp
if region.overlaps(via):
self.graph_vias.append(via)
self.find_graph_vias(region)
# Create the graph
# Generate the cartesian values from shapes in the area
x_values, y_values = self.generate_cartesian_values()
# Adjust the routing region to include "edge" shapes
region.bbox(self.graph_blockages)
# Find and include edge shapes to prevent DRC errors
self.find_graph_blockages(region)
# Generate the graph nodes from cartesian values
self.generate_graph_nodes(x_values, y_values)
# Save the graph nodes that lie in source and target shapes
self.save_end_nodes()
debug.info(3, "Number of blockages detected in the routing region: {}".format(len(self.graph_blockages)))
debug.info(3, "Number of vias detected in the routing region: {}".format(len(self.graph_vias)))
@ -156,13 +152,33 @@ class graph:
""" Find blockages that overlap the routing region. """
for blockage in self.router.blockages:
# Set the region's lpp to current blockage's lpp so that the
# overlaps method works
# Skip if already included
if blockage in self.graph_blockages:
continue
# Set the region's lpp to current blockage's lpp so that the
# overlaps method works
region.lpp = blockage.lpp
if region.overlaps(blockage):
self.graph_blockages.append(blockage)
# FIXME: Don't include source and target if they're already included
# in inflated form
for shape in [self.source, self.target]:
if shape not in self.graph_blockages:
self.graph_blockages.append(shape)
def find_graph_vias(self, region):
""" Find vias that overlap the routing region. """
for via in self.router.vias:
# Skip if already included
if via in self.graph_vias:
continue
# Set the regions's lpp to current via's lpp so that the
# overlaps method works
region.lpp = via.lpp
if region.overlaps(via):
self.graph_vias.append(via)
def generate_cartesian_values(self):

View File

@ -97,10 +97,10 @@ class graph_router(router_tech):
# Route closest pins according to the minimum spanning tree
for source, target in self.get_mst_pairs(list(pins)):
# Create the graph
hg = graph(self)
hg.create_graph(source, target)
g = graph(self)
g.create_graph(source, target)
# Find the shortest path from source to target
path = hg.find_shortest_path()
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))
@ -130,7 +130,6 @@ class graph_router(router_tech):
for shape in shape_list:
layer, boundary = shape
# gdsMill boundaries are in (left, bottom, right, top) order
# so repack and snap to the grid
ll = vector(boundary[0], boundary[1])
ur = vector(boundary[2], boundary[3])
rect = [ll, ur]
@ -163,7 +162,6 @@ class graph_router(router_tech):
shapes = self.layout.getAllShapes(lpp)
for boundary in shapes:
# gdsMill boundaries are in (left, bottom, right, top) order
# so repack and snap to the grid
ll = vector(boundary[0], boundary[1])
ur = vector(boundary[2], boundary[3])
rect = [ll, ur]
@ -224,7 +222,6 @@ class graph_router(router_tech):
shapes = self.layout.getAllShapes(via_lpp)
for boundary in shapes:
# gdsMill boundaries are in (left, bottom, right, top) order
# so repack and snap to the grid
ll = vector(boundary[0], boundary[1])
ur = vector(boundary[2], boundary[3])
rect = [ll, ur]
@ -486,30 +483,32 @@ class graph_router(router_tech):
def get_new_pins(self, name):
""" """
""" Return the new supply pins added by this router. """
return self.new_pins[name]
def write_debug_gds(self, gds_name="debug_route.gds", hg=None, source=None, target=None):
""" """
def write_debug_gds(self, gds_name="debug_route.gds", g=None, source=None, target=None):
""" Write the debug GDSII file for the router. """
self.add_router_info(hg, source, target)
self.add_router_info(g, source, target)
self.design.gds_write(gds_name)
self.del_router_info()
def add_router_info(self, hg=None, source=None, target=None):
""" """
def add_router_info(self, g=None, source=None, target=None):
"""
Add debug information to the text layer about the graph and router.
"""
# Display the inflated blockage
if hg:
if g:
for blockage in self.blockages:
if blockage in hg.graph_blockages:
if blockage in g.graph_blockages:
self.add_object_info(blockage, "blockage{}++[{}]".format(self.get_zindex(blockage.lpp), blockage.name))
else:
self.add_object_info(blockage, "blockage{}[{}]".format(self.get_zindex(blockage.lpp), blockage.name))
for node in hg.nodes:
for node in g.nodes:
offset = (node.center.x, node.center.y)
self.design.add_label(text="n{}".format(node.center.z),
layer="text",
@ -526,14 +525,14 @@ class graph_router(router_tech):
def del_router_info(self):
""" """
""" Delete router information from the text layer. """
lpp = tech_layer["text"]
self.design.objs = [x for x in self.design.objs if x.lpp != lpp]
def add_object_info(self, obj, label):
""" """
""" Add debug information to the text layer about an object. """
ll, ur = obj.rect
self.design.add_rect(layer="text",

View File

@ -124,14 +124,14 @@ class router_tech:
return (min_width, min_spacing)
def get_layer_width(self, zindex):
""" """
""" Return the minimum width of a layer. """
layer_name = self.get_layer(zindex)
min_wire_width = drc("minwidth_{0}".format(layer_name), 0, math.inf)
min_width = self.route_track_width * drc("minwidth_{0}".format(layer_name), self.route_track_width * min_wire_width, math.inf)
return min_width
def get_layer_space(self, zindex, width):
""" """
""" Return the minimum spacing of a layer given wire width. """
if width is None:
width = self.get_layer_width(zindex)
layer_name = self.get_layer(zindex)