Differentiate pin and other blockages for easier to understand blockage processing.

This commit is contained in:
mrg 2021-01-14 15:58:37 -08:00
parent e3a888e0f7
commit 683f4214b2
3 changed files with 37 additions and 27 deletions

View File

@ -8,6 +8,7 @@
from direction import direction
from pin_layout import pin_layout
from vector import vector
from vector3d import vector3d
import debug
@ -619,18 +620,16 @@ class pin_group:
# Blockages will be a super-set of pins since
# it uses the inflated pin shape.
blockage_in_tracks = self.router.convert_blockage(pin)
self.blockages.update(blockage_in_tracks)
# Must include the pins here too because these are computed in a different
# way than blockages.
self.blockages.update(sufficient | insufficient | blockage_in_tracks)
# If we have a blockage, we must remove the grids
# Remember, this excludes the pin blockages already
shared_set = pin_set & self.router.get_blocked_grids()
if len(shared_set) > 0:
debug.info(4, "Removing pins {}".format(shared_set))
pin_set.difference_update(shared_set)
shared_set = partial_set & self.router.get_blocked_grids()
if len(shared_set) > 0:
debug.info(4, "Removing pins {}".format(shared_set))
blocked_grids = self.router.get_blocked_grids()
pin_set.difference_update(blocked_grids)
partial_set.difference_update(blocked_grids)
# At least one of the groups must have some valid tracks
if (len(pin_set) == 0 and len(partial_set) == 0):
# debug.warning("Pin is very close to metal blockage.\nAttempting to expand blocked pin {}".format(self.pins))
@ -641,9 +640,13 @@ class pin_group:
(sufficient, insufficient) = self.router.convert_pin_to_tracks(self.name,
pin,
expansion=1)
# This time, don't remove blockages in the hopes that it might be ok.
# Could cause DRC problems!
pin_set.update(sufficient)
partial_set.update(insufficient)
# If it's still empty, we must bail.
if len(pin_set) == 0 and len(partial_set) == 0:
debug.error("Unable to find unblocked pin {} {}".format(self.name,
self.pins))

View File

@ -356,7 +356,9 @@ class router(router_tech):
# Start fresh. Not the best for run-time, but simpler.
self.clear_all_blockages()
# This adds the initial blockges of the design
# which includes all blockages due to non-pin shapes
# print("BLOCKING:", self.blocked_grids)
self.set_blockages(self.blocked_grids, True)
@ -368,19 +370,16 @@ class router(router_tech):
# If function doesn't exist, it isn't a supply router
pass
# Block all of the pin components
# (some will be unblocked if they're a source/target)
# Also block the previous routes
# Now go and block all of the blockages due to pin shapes.
# Some of these will get unblocked later if they are the source/target.
for name in self.pin_groups:
# This should be a superset of the grids...
blockage_grids = {y for x in self.pin_groups[name] for y in x.blockages}
self.set_blockages(blockage_grids, True)
# But do the grids just in case
blockage_grids = {y for x in self.pin_groups[name] for y in x.grids}
self.set_blockages(blockage_grids, True)
# FIXME: These duplicate a bit of work
# These are the paths that have already been routed.
# If we have paths that were recently routed, add them as blockages as well.
# We might later do rip-up and reroute so they might not be metal shapes in the design yet.
# Also, this prevents having to reload an entire GDS and find the blockage shapes.
self.set_blockages(self.path_blockages)
def convert_shape_to_units(self, shape):
@ -468,7 +467,9 @@ class router(router_tech):
"""
Return the blocked grids with their flag set
"""
return set([x for x in self.blocked_grids if self.rg.is_blocked(x)])
#return set([x for x in self.blocked_grids if self.rg.is_blocked(x)])
# These are all the non-pin blockages
return self.blocked_grids
def retrieve_blockages(self, lpp):
"""
@ -483,7 +484,10 @@ class router(router_tech):
new_pin = pin_layout("blockage{}".format(len(self.blockages)),
rect,
lpp)
self.blockages.append(new_pin)
# If there is a rectangle that is the same in the pins,
# it isn't a blockage!
if new_pin not in self.all_pins:
self.blockages.append(new_pin)
def convert_point_to_units(self, p):
"""
@ -1031,7 +1035,6 @@ class router(router_tech):
self.paths.append(grid_utils.flatten_set(path))
self.add_route(path)
self.path_blockages.append(self.paths[-1])
return True
else:
@ -1120,7 +1123,7 @@ class router(router_tech):
"""
Erase all of the comments on the current level.
"""
debug.info(0, "Erasing router info")
debug.info(2, "Erasing router info")
lpp = techlayer["text"]
self.cell.objs = [x for x in self.cell.objs if x.lpp != lpp]
@ -1130,7 +1133,7 @@ class router(router_tech):
the boundary layer for debugging purposes. This can only be
called once or the labels will overlap.
"""
debug.info(0, "Adding router info")
debug.info(2, "Adding router info")
show_blockages = False
show_blockage_grids = False

View File

@ -13,7 +13,7 @@ import grid_utils
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import minimum_spanning_tree
from signal_grid import signal_grid
from vector3d import vector3d
class supply_tree_router(router):
"""
@ -116,6 +116,10 @@ class supply_tree_router(router):
# Route MST components
for (src, dest) in connections:
self.route_signal(pin_name, src, dest)
# if pin_name == "gnd":
# print("\nSRC {}: ".format(src) + str(self.pin_groups[pin_name][src].grids) + str(self.pin_groups[pin_name][src].blockages))
# print("DST {}: ".format(dest) + str(self.pin_groups[pin_name][dest].grids) + str(self.pin_groups[pin_name][dest].blockages))
# self.write_debug_gds("post_{0}_{1}.gds".format(src, dest), False)
#self.write_debug_gds("final.gds", True)
#return
@ -136,6 +140,9 @@ class supply_tree_router(router):
# easier to debug.
self.prepare_blockages()
if unblock_routes:
msg = "Unblocking supply self blockages to improve access (may cause DRC errors):\n{0}\n{1})"
debug.warning(msg.format(pin_name,
self.pin_groups[pin_name][src_idx].pins))
self.set_blockages(self.path_blockages, False)
# Add the single component of the pin as the source
@ -149,9 +156,6 @@ class supply_tree_router(router):
if self.run_router(detour_scale=detour_scale):
return
debug.warning("Unblocking supply self blockages to improve access (may cause DRC errors):\n{0}\n{1})".format(pin_name,
self.pin_groups[pin_name][src_idx].pins))
self.write_debug_gds("debug_route.gds", True)
def add_io_pin(self, instance, pin_name, new_name=""):