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
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
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([left_connector, right_connector, above_connector, below_connector])
|
||||
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:
|
||||
|
|
@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -530,22 +530,21 @@ class router(router_tech):
|
|||
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),
|
||||
|
|
|
|||
|
|
@ -164,9 +164,13 @@ 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):
|
||||
""" Is the one grid adjacent in any planar direction to the other """
|
||||
|
|
|
|||
Loading…
Reference in New Issue