diff --git a/compiler/router/pin_group.py b/compiler/router/pin_group.py index cb55f193..4458fdfd 100644 --- a/compiler/router/pin_group.py +++ b/compiler/router/pin_group.py @@ -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)) diff --git a/compiler/router/router.py b/compiler/router/router.py index 0e77f939..ce0a739a 100644 --- a/compiler/router/router.py +++ b/compiler/router/router.py @@ -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 diff --git a/compiler/router/supply_tree_router.py b/compiler/router/supply_tree_router.py index a433271e..31311550 100644 --- a/compiler/router/supply_tree_router.py +++ b/compiler/router/supply_tree_router.py @@ -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=""):