Prevent via DRC errors

This commit is contained in:
Eren Dogan 2023-07-17 16:30:19 -07:00
parent 6e051e7f06
commit b5983fbfd6
2 changed files with 56 additions and 3 deletions

View File

@ -83,6 +83,18 @@ class graph:
return False
def is_via_blocked(self, point):
""" Return if a via on the given point is blocked by another via. """
for via in self.graph_vias:
ll, ur = via.rect
center = via.center()
if via.on_segment(ll, point, ur) and \
(center.x != point.x or center.y != point.y):
return True
return False
def create_graph(self, source, target):
""" Create the graph to run routing on later. """
debug.info(2, "Creating the graph for source '{}' and target'{}'.".format(source, target))
@ -109,7 +121,17 @@ class graph:
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)
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)))
# Create the graph
x_values, y_values = self.generate_cartesian_values()
@ -197,9 +219,9 @@ class graph:
for i in range(0, len(self.nodes), 2):
search(i, lambda count: (count / 2) % y_len, 2) # Down
search(i, lambda count: (count / 2) >= y_len, y_len * 2) # Left
# FIXME: Avoid vias for inter-layer edges
if not hasattr(self.nodes[i], "remove") and \
not hasattr(self.nodes[i + 1], "remove"):
not hasattr(self.nodes[i + 1], "remove") and \
not self.is_via_blocked(self.nodes[i].center):
self.nodes[i].add_neighbor(self.nodes[i + 1])
# Remove marked nodes

View File

@ -42,6 +42,8 @@ class graph_router(router_tech):
# This is all the blockages including the pins. The graph class handles
# pins as blockages while considering their routability
self.blockages = []
# This is all the vias between routing layers
self.vias = []
# New pins are the side supply pins
self.new_pins = {}
# Fake pins are imaginary pins on the side supply pins to route other
@ -69,8 +71,9 @@ class graph_router(router_tech):
self.find_pins(vdd_name)
self.find_pins(gnd_name)
# Find blockages
# Find blockages and vias
self.find_blockages()
self.find_vias()
# Add side pins
if self.pin_type in ["top", "bottom", "right", "left"]:
@ -106,6 +109,7 @@ class graph_router(router_tech):
# Find the recently added shapes
self.prepare_gds_reader()
self.find_blockages(pin_name)
self.find_vias()
# FIXME: Comment-out later
self.write_debug_gds(gds_name="after.gds")
@ -214,6 +218,33 @@ class graph_router(router_tech):
self.blockages.remove(prev_blockage)
def find_vias(self):
""" """
debug.info(2, "Finding vias...")
# Prepare lpp values here
from openram.tech import layer
via_lpp = layer[self.via_layer_name]
valid_lpp = self.horiz_lpp
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]
new_shape = graph_shape("via", rect, valid_lpp)
# If there is a rectangle that is the same in the pins,
# it isn't a blockage
# Also ignore the new pins
if new_shape.contained_by_any(self.vias):
continue
self.vias.append(new_shape.inflated_pin(spacing=self.track_space,
multiple=1,
extra_spacing=self.offset))
def add_side_pin(self, pin_name, side, width=3, num_connects=4, bbox=None):
""" Add supply pin to one side of the layout. """