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]
|
return [dx,dy]
|
||||||
else:
|
else:
|
||||||
return [0,0]
|
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):
|
def overlap_length(self, other):
|
||||||
"""
|
"""
|
||||||
Calculate the intersection segment and determine its length
|
Calculate the intersection segment and determine its length
|
||||||
|
|
|
||||||
|
|
@ -566,11 +566,10 @@ class pin_group:
|
||||||
debug.info(2," Converting {0}".format(pin))
|
debug.info(2," Converting {0}".format(pin))
|
||||||
# Determine which tracks the pin overlaps
|
# Determine which tracks the pin overlaps
|
||||||
pin_in_tracks=self.router.convert_pin_to_tracks(self.name, pin)
|
pin_in_tracks=self.router.convert_pin_to_tracks(self.name, pin)
|
||||||
|
|
||||||
pin_set.update(pin_in_tracks)
|
pin_set.update(pin_in_tracks)
|
||||||
|
|
||||||
# Blockages will be a super-set of pins since it uses the inflated pin shape.
|
# Blockages will be a super-set of pins since it uses the inflated pin shape.
|
||||||
blockage_in_tracks = self.router.convert_blockage(pin)
|
blockage_in_tracks = self.router.convert_blockage(pin)
|
||||||
|
|
||||||
blockage_set.update(blockage_in_tracks)
|
blockage_set.update(blockage_in_tracks)
|
||||||
|
|
||||||
# If we have a blockage, we must remove the grids
|
# 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
|
shared_set = pin_set & self.router.blocked_grids
|
||||||
if len(shared_set)>0:
|
if len(shared_set)>0:
|
||||||
debug.info(2,"Removing pins {}".format(shared_set))
|
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
|
shared_set = blockage_set & self.router.blocked_grids
|
||||||
if len(shared_set)>0:
|
if len(shared_set)>0:
|
||||||
debug.info(2,"Removing blocks {}".format(shared_set))
|
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
|
# 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.error("Unable to find unblocked pin {} {}".format(self.name, self.pins))
|
debug.warning("Pin is very close to metal blockage.\nAttempting to expand blocked pin {}".format(self.pins))
|
||||||
self.router.write_debug_gds("blocked_pin.gds")
|
|
||||||
|
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
|
# We need to route each of the components, so don't combine the groups
|
||||||
self.grids = pin_set | blockage_set
|
self.grids = pin_set | blockage_set
|
||||||
|
|
|
||||||
|
|
@ -495,10 +495,11 @@ class router(router_tech):
|
||||||
# debug.info(0,"Pin {}".format(pin))
|
# debug.info(0,"Pin {}".format(pin))
|
||||||
return [ll,ur]
|
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.
|
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 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
|
(ll,ur) = pin.rect
|
||||||
debug.info(3,"Converting pin [ {0} , {1} ]".format(ll,ur))
|
debug.info(3,"Converting pin [ {0} , {1} ]".format(ll,ur))
|
||||||
|
|
@ -512,8 +513,8 @@ class router(router_tech):
|
||||||
insufficient_list = set()
|
insufficient_list = set()
|
||||||
|
|
||||||
zindex=self.get_zindex(pin.layer_num)
|
zindex=self.get_zindex(pin.layer_num)
|
||||||
for x in range(int(ll[0]),int(ur[0])+1):
|
for x in range(int(ll[0])+expansion,int(ur[0])+1+expansion):
|
||||||
for y in range(int(ll[1]),int(ur[1])+1):
|
for y in range(int(ll[1]+expansion),int(ur[1])+1+expansion):
|
||||||
debug.info(4,"Converting [ {0} , {1} ]".format(x,y))
|
debug.info(4,"Converting [ {0} , {1} ]".format(x,y))
|
||||||
(full_overlap,partial_overlap) = self.convert_pin_coord_to_tracks(pin, vector3d(x,y,zindex))
|
(full_overlap,partial_overlap) = self.convert_pin_coord_to_tracks(pin, vector3d(x,y,zindex))
|
||||||
if full_overlap:
|
if full_overlap:
|
||||||
|
|
@ -523,9 +524,14 @@ class router(router_tech):
|
||||||
|
|
||||||
if len(sufficient_list)>0:
|
if len(sufficient_list)>0:
|
||||||
return sufficient_list
|
return sufficient_list
|
||||||
elif len(insufficient_list)>0:
|
elif expansion==0 and len(insufficient_list)>0:
|
||||||
# If there wasn't a sufficient grid, find the best and patch it to be on grid.
|
#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)
|
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:
|
else:
|
||||||
debug.error("Unable to find any overlapping grids.", -1)
|
debug.error("Unable to find any overlapping grids.", -1)
|
||||||
|
|
||||||
|
|
@ -555,6 +561,24 @@ class router(router_tech):
|
||||||
|
|
||||||
return set([best_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),
|
||||||
|
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):
|
def convert_pin_coord_to_tracks(self, pin, coord):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue