mirror of https://github.com/VLSIDA/OpenRAM.git
Expand blocked pins to neighbor grid cells.
This commit is contained in:
parent
11873c03cd
commit
de61630962
|
|
@ -316,7 +316,43 @@ class pin_layout:
|
|||
return [dx,dy]
|
||||
else:
|
||||
return [0,0]
|
||||
|
||||
def distance(self, other):
|
||||
"""
|
||||
Calculate the distance to another pin layout.
|
||||
"""
|
||||
(r1_ll,r1_ur) = self.rect
|
||||
(r2_ll,r2_ur) = other.rect
|
||||
|
||||
def dist(x1, y1, x2, y2):
|
||||
return sqrt((x2-x1)**2 + (y2-y1)**2)
|
||||
|
||||
left = r2_ur.x < r1_ll.x
|
||||
right = r1_ur.x < r2_ll.x
|
||||
bottom = r2_ur.y < r1_ll.y
|
||||
top = r1_ur.y < r2_ll.y
|
||||
|
||||
if top and left:
|
||||
return dist(r1_ll.x, r1_ur.y, r2_ur.x, r2_ll.y)
|
||||
elif left and bottom:
|
||||
return dist(r1_ll.x, r1_ll.y, r2_ur.x, r2_ur.y)
|
||||
elif bottom and right:
|
||||
return dist(r1_ur.x, r1_ll.y, r2_ll.x, r2_ur.y)
|
||||
elif right and top:
|
||||
return dist(r1_ur.x, r1_ur.y, r2_ll.x, r2_ll.y)
|
||||
elif left:
|
||||
return r1_ll.x - r2_ur.x
|
||||
elif right:
|
||||
return r2_ll.x - r1.ur.x
|
||||
elif bottom:
|
||||
return r1_ll.y - r2_ur.y
|
||||
elif top:
|
||||
return r2_ll.y - r1_ur.y
|
||||
else:
|
||||
# rectangles intersect
|
||||
return 0
|
||||
|
||||
|
||||
def overlap_length(self, other):
|
||||
"""
|
||||
Calculate the intersection segment and determine its length
|
||||
|
|
|
|||
|
|
@ -566,11 +566,10 @@ class pin_group:
|
|||
debug.info(2," Converting {0}".format(pin))
|
||||
# Determine which tracks the pin overlaps
|
||||
pin_in_tracks=self.router.convert_pin_to_tracks(self.name, pin)
|
||||
|
||||
pin_set.update(pin_in_tracks)
|
||||
|
||||
# Blockages will be a super-set of pins since it uses the inflated pin shape.
|
||||
blockage_in_tracks = self.router.convert_blockage(pin)
|
||||
|
||||
blockage_set.update(blockage_in_tracks)
|
||||
|
||||
# If we have a blockage, we must remove the grids
|
||||
|
|
@ -578,17 +577,26 @@ class pin_group:
|
|||
shared_set = pin_set & self.router.blocked_grids
|
||||
if len(shared_set)>0:
|
||||
debug.info(2,"Removing pins {}".format(shared_set))
|
||||
pin_set.difference_update(self.router.blocked_grids)
|
||||
|
||||
pin_set.difference_update(shared_set)
|
||||
shared_set = blockage_set & self.router.blocked_grids
|
||||
if len(shared_set)>0:
|
||||
debug.info(2,"Removing blocks {}".format(shared_set))
|
||||
blockage_set.difference_update(self.router.blocked_grids)
|
||||
blockage_set.difference_update(shared_set)
|
||||
|
||||
# At least one of the groups must have some valid tracks
|
||||
if (len(pin_set)==0 and len(blockage_set)==0):
|
||||
debug.error("Unable to find unblocked pin {} {}".format(self.name, self.pins))
|
||||
self.router.write_debug_gds("blocked_pin.gds")
|
||||
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:
|
||||
debug.info(2," Converting {0}".format(pin))
|
||||
# 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")
|
||||
|
||||
# We need to route each of the components, so don't combine the groups
|
||||
self.grids = pin_set | blockage_set
|
||||
|
|
|
|||
|
|
@ -495,10 +495,11 @@ class router(router_tech):
|
|||
# debug.info(0,"Pin {}".format(pin))
|
||||
return [ll,ur]
|
||||
|
||||
def convert_pin_to_tracks(self, pin_name, pin):
|
||||
def convert_pin_to_tracks(self, pin_name, pin, expansion=0):
|
||||
"""
|
||||
Convert a rectangular pin shape into a list of track locations,layers.
|
||||
If no pins are "on-grid" (i.e. sufficient overlap) it makes the one with most overlap if it is not blocked.
|
||||
If expansion>0, expamine areas beyond the current pin when it is blocked.
|
||||
"""
|
||||
(ll,ur) = pin.rect
|
||||
debug.info(3,"Converting pin [ {0} , {1} ]".format(ll,ur))
|
||||
|
|
@ -512,8 +513,8 @@ class router(router_tech):
|
|||
insufficient_list = set()
|
||||
|
||||
zindex=self.get_zindex(pin.layer_num)
|
||||
for x in range(int(ll[0]),int(ur[0])+1):
|
||||
for y in range(int(ll[1]),int(ur[1])+1):
|
||||
for x in range(int(ll[0])+expansion,int(ur[0])+1+expansion):
|
||||
for y in range(int(ll[1]+expansion),int(ur[1])+1+expansion):
|
||||
debug.info(4,"Converting [ {0} , {1} ]".format(x,y))
|
||||
(full_overlap,partial_overlap) = self.convert_pin_coord_to_tracks(pin, vector3d(x,y,zindex))
|
||||
if full_overlap:
|
||||
|
|
@ -523,9 +524,14 @@ class router(router_tech):
|
|||
|
||||
if len(sufficient_list)>0:
|
||||
return sufficient_list
|
||||
elif len(insufficient_list)>0:
|
||||
# If there wasn't a sufficient grid, find the best and patch it to be on grid.
|
||||
elif expansion==0 and len(insufficient_list)>0:
|
||||
#Remove blockages and return the best to be patched
|
||||
insufficient_list.difference_update(self.blocked_grids)
|
||||
return self.get_best_offgrid_pin(pin, insufficient_list)
|
||||
elif expansion>0:
|
||||
#Remove blockages and return the nearest
|
||||
insufficient_list.difference_update(self.blocked_grids)
|
||||
return self.get_nearest_offgrid_pin(pin, insufficient_list)
|
||||
else:
|
||||
debug.error("Unable to find any overlapping grids.", -1)
|
||||
|
||||
|
|
@ -555,6 +561,24 @@ class router(router_tech):
|
|||
|
||||
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),
|
||||
return the nearest grid cell (center to center).
|
||||
"""
|
||||
#print("INSUFFICIENT LIST",insufficient_list)
|
||||
# Find the coordinate with the most overlap
|
||||
best_coord = None
|
||||
best_dist = math.inf
|
||||
for coord in insufficient_list:
|
||||
track_pin = self.convert_track_to_pin(coord)
|
||||
min_dist = pin.distance(track_pin)
|
||||
if min_dist<best_dist:
|
||||
best_dist=min_dist
|
||||
best_coord=coord
|
||||
|
||||
return set([best_coord])
|
||||
|
||||
|
||||
def convert_pin_coord_to_tracks(self, pin, coord):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue