Use grid furthest from blockages when blocked pin. Enclose multiple connectors.

This commit is contained in:
Matt Guthaus 2018-11-19 17:32:55 -08:00
parent 20d4e390f6
commit b8299565eb
5 changed files with 61 additions and 19 deletions

View File

@ -343,7 +343,7 @@ class pin_layout:
(r2_ll,r2_ur) = other.rect
def dist(x1, y1, x2, y2):
return sqrt((x2-x1)**2 + (y2-y1)**2)
return math.sqrt((x2-x1)**2 + (y2-y1)**2)
left = r2_ur.x < r1_ll.x
right = r1_ur.x < r2_ll.x

View File

@ -3,6 +3,7 @@ Some utility functions for sets of grid cells.
"""
import debug
import math
from direction import direction
from vector3d import vector3d
@ -139,3 +140,16 @@ def flatten_set(curset):
else:
newset.update(flatten_set(c))
return newset
def distance_set(coord, curset):
"""
Return the distance from a coordinate to any item in the set
"""
min_dist = math.inf
for c in curset:
min_dist = min(coord.euclidean_distance(c), min_dist)
return min_dist

View File

@ -465,16 +465,22 @@ class pin_group:
if pin.contained_by_any(self.enclosures):
continue
# Find a connector in the cardinal directions
# If there is overlap, but it isn't contained, these could all be None
# These could also be none if the pin is diagonal from the enclosure
left_connector = self.find_left_connector(pin, self.enclosures)
right_connector = self.find_right_connector(pin, self.enclosures)
above_connector = self.find_above_connector(pin, self.enclosures)
below_connector = self.find_below_connector(pin, self.enclosures)
import copy
bbox_connector = copy.copy(pin)
bbox_connector.bbox([left_connector, right_connector, above_connector, below_connector])
self.enclosures.append(bbox_connector)
connector_list = [left_connector, right_connector, above_connector, below_connector]
filtered_list = list(filter(lambda x: x!=None, connector_list))
if (len(filtered_list)>0):
import copy
bbox_connector = copy.copy(pin)
bbox_connector.bbox(filtered_list)
self.enclosures.append(bbox_connector)
# Now, make sure each pin touches an enclosure. If not, add a connector.
# Now, make sure each pin touches an enclosure. If not, add another (diagonal) connector.
# This could only happen when there was no enclosure in any cardinal direction from a pin
for pin_list in self.pins:
if not self.overlap_any_shape(pin_list, self.enclosures):
@ -596,7 +602,7 @@ class pin_group:
# At least one of the groups must have some valid tracks
if (len(pin_set)==0 and len(blockage_set)==0):
debug.warning("Pin is very close to metal blockage.\nAttempting to expand blocked pin {}".format(self.pins))
#debug.warning("Pin is very close to metal blockage.\nAttempting to expand blocked pin {}".format(self.pins))
for pin_list in self.pins:
for pin in pin_list:
@ -604,7 +610,7 @@ class pin_group:
# Determine which tracks the pin overlaps
pin_in_tracks=self.router.convert_pin_to_tracks(self.name, pin, expansion=1)
pin_set.update(pin_in_tracks)
if len(pin_set)==0:
debug.error("Unable to find unblocked pin {} {}".format(self.name, self.pins))
self.router.write_debug_gds("blocked_pin.gds")
@ -650,7 +656,6 @@ class pin_group:
that is ensured to overlap the supply rail wire.
It then adds rectangle(s) for the enclosure.
"""
additional_set = set()
# Check the layer of any element in the pin to determine which direction to route it
e = next(iter(start_set))
@ -674,3 +679,6 @@ class pin_group:
self.set_routed()
self.enclosures = self.compute_enclosures()

View File

@ -515,7 +515,7 @@ class router(router_tech):
# scale the size bigger to include neaby tracks
ll=ll.scale(self.track_factor).floor()
ur=ur.scale(self.track_factor).ceil()
#print(pin)
# Keep tabs on tracks with sufficient and insufficient overlap
sufficient_list = set()
insufficient_list = set()
@ -529,23 +529,22 @@ class router(router_tech):
if partial_overlap:
insufficient_list.update([partial_overlap])
debug.info(4,"Converting [ {0} , {1} ] full={2} partial={3}".format(x,y, full_overlap, partial_overlap))
# Remove the blocked grids
sufficient_list.difference_update(self.blocked_grids)
insufficient_list.difference_update(self.blocked_grids)
if len(sufficient_list)>0:
return sufficient_list
elif expansion==0 and len(insufficient_list)>0:
#Remove blockages and return any overlap
insufficient_list.difference_update(self.blocked_grids)
best_pin = self.get_all_offgrid_pin(pin, insufficient_list)
#print(best_pin)
return best_pin
elif expansion>0:
#Remove blockages and return the nearest
insufficient_list.difference_update(self.blocked_grids)
nearest_pin = self.get_nearest_offgrid_pin(pin, insufficient_list)
nearest_pin = self.get_furthest_offgrid_pin(pin, insufficient_list)
return nearest_pin
else:
debug.error("Unable to find any overlapping grids.", -1)
return set()
def get_all_offgrid_pin(self, pin, insufficient_list):
"""
@ -585,6 +584,23 @@ class router(router_tech):
return set([best_coord])
def get_furthest_offgrid_pin(self, pin, insufficient_list):
"""
Get a grid cell that is the furthest from the blocked grids.
"""
#print("INSUFFICIENT LIST",insufficient_list)
# Find the coordinate with the most overlap
best_coord = None
best_dist = math.inf
for coord in insufficient_list:
min_dist = grid_utils.distance_set(coord, self.blocked_grids)
if min_dist<best_dist:
best_dist=min_dist
best_coord=coord
return set([best_coord])
def get_nearest_offgrid_pin(self, pin, insufficient_list):
"""
Given a pin and a list of grid cells (probably non-overlapping),

View File

@ -164,8 +164,12 @@ class vector3d():
return vector3d(min(self.x,other.x),min(self.y,other.y),min(self.z,other.z))
def distance(self, other):
""" Return the planar distance between two values """
""" Return the manhattan distance between two values """
return abs(self.x-other.x)+abs(self.y-other.y)
def euclidean_distance(self, other):
""" Return the euclidean distance between two values """
return math.sqrt((self.x-other.x)**2+(self.y-other.y)**2)
def adjacent(self, other):