mirror of https://github.com/VLSIDA/OpenRAM.git
Use grid furthest from blockages when blocked pin. Enclose multiple connectors.
This commit is contained in:
parent
20d4e390f6
commit
b8299565eb
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue