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 (r2_ll,r2_ur) = other.rect
def dist(x1, y1, x2, y2): 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 left = r2_ur.x < r1_ll.x
right = r1_ur.x < r2_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 debug
import math
from direction import direction from direction import direction
from vector3d import vector3d from vector3d import vector3d
@ -139,3 +140,16 @@ def flatten_set(curset):
else: else:
newset.update(flatten_set(c)) newset.update(flatten_set(c))
return newset 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): if pin.contained_by_any(self.enclosures):
continue 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) left_connector = self.find_left_connector(pin, self.enclosures)
right_connector = self.find_right_connector(pin, self.enclosures) right_connector = self.find_right_connector(pin, self.enclosures)
above_connector = self.find_above_connector(pin, self.enclosures) above_connector = self.find_above_connector(pin, self.enclosures)
below_connector = self.find_below_connector(pin, self.enclosures) below_connector = self.find_below_connector(pin, self.enclosures)
import copy connector_list = [left_connector, right_connector, above_connector, below_connector]
bbox_connector = copy.copy(pin) filtered_list = list(filter(lambda x: x!=None, connector_list))
bbox_connector.bbox([left_connector, right_connector, above_connector, below_connector]) if (len(filtered_list)>0):
self.enclosures.append(bbox_connector) 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 # This could only happen when there was no enclosure in any cardinal direction from a pin
for pin_list in self.pins: for pin_list in self.pins:
if not self.overlap_any_shape(pin_list, self.enclosures): 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 # At least one of the groups must have some valid tracks
if (len(pin_set)==0 and len(blockage_set)==0): 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_list in self.pins:
for pin in pin_list: for pin in pin_list:
@ -604,7 +610,7 @@ class pin_group:
# Determine which tracks the pin overlaps # Determine which tracks the pin overlaps
pin_in_tracks=self.router.convert_pin_to_tracks(self.name, pin, expansion=1) pin_in_tracks=self.router.convert_pin_to_tracks(self.name, pin, expansion=1)
pin_set.update(pin_in_tracks) pin_set.update(pin_in_tracks)
if len(pin_set)==0: if len(pin_set)==0:
debug.error("Unable to find unblocked pin {} {}".format(self.name, self.pins)) debug.error("Unable to find unblocked pin {} {}".format(self.name, self.pins))
self.router.write_debug_gds("blocked_pin.gds") self.router.write_debug_gds("blocked_pin.gds")
@ -650,7 +656,6 @@ class pin_group:
that is ensured to overlap the supply rail wire. that is ensured to overlap the supply rail wire.
It then adds rectangle(s) for the enclosure. It then adds rectangle(s) for the enclosure.
""" """
additional_set = set() additional_set = set()
# Check the layer of any element in the pin to determine which direction to route it # Check the layer of any element in the pin to determine which direction to route it
e = next(iter(start_set)) e = next(iter(start_set))
@ -674,3 +679,6 @@ class pin_group:
self.set_routed() self.set_routed()
self.enclosures = self.compute_enclosures() self.enclosures = self.compute_enclosures()

View File

@ -515,7 +515,7 @@ class router(router_tech):
# scale the size bigger to include neaby tracks # scale the size bigger to include neaby tracks
ll=ll.scale(self.track_factor).floor() ll=ll.scale(self.track_factor).floor()
ur=ur.scale(self.track_factor).ceil() ur=ur.scale(self.track_factor).ceil()
#print(pin)
# Keep tabs on tracks with sufficient and insufficient overlap # Keep tabs on tracks with sufficient and insufficient overlap
sufficient_list = set() sufficient_list = set()
insufficient_list = set() insufficient_list = set()
@ -529,23 +529,22 @@ class router(router_tech):
if partial_overlap: if partial_overlap:
insufficient_list.update([partial_overlap]) insufficient_list.update([partial_overlap])
debug.info(4,"Converting [ {0} , {1} ] full={2} partial={3}".format(x,y, full_overlap, 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: if len(sufficient_list)>0:
return sufficient_list return sufficient_list
elif expansion==0 and len(insufficient_list)>0: 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) best_pin = self.get_all_offgrid_pin(pin, insufficient_list)
#print(best_pin)
return best_pin return best_pin
elif expansion>0: elif expansion>0:
#Remove blockages and return the nearest nearest_pin = self.get_furthest_offgrid_pin(pin, insufficient_list)
insufficient_list.difference_update(self.blocked_grids)
nearest_pin = self.get_nearest_offgrid_pin(pin, insufficient_list)
return nearest_pin return nearest_pin
else: else:
debug.error("Unable to find any overlapping grids.", -1) return set()
def get_all_offgrid_pin(self, pin, insufficient_list): def get_all_offgrid_pin(self, pin, insufficient_list):
""" """
@ -585,6 +584,23 @@ class router(router_tech):
return set([best_coord]) 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): def get_nearest_offgrid_pin(self, pin, insufficient_list):
""" """
Given a pin and a list of grid cells (probably non-overlapping), 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)) return vector3d(min(self.x,other.x),min(self.y,other.y),min(self.z,other.z))
def distance(self, other): 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) 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): def adjacent(self, other):