mirror of https://github.com/VLSIDA/OpenRAM.git
Added new enclosure connector algorithm using edge sorting.
This commit is contained in:
parent
fc45242ccb
commit
c511d886bf
|
|
@ -118,6 +118,20 @@ class pin_layout:
|
||||||
|
|
||||||
return y_overlaps
|
return y_overlaps
|
||||||
|
|
||||||
|
def xcontains(self, other):
|
||||||
|
""" Check if shape contains the x overlap """
|
||||||
|
(ll,ur) = self.rect
|
||||||
|
(oll,our) = other.rect
|
||||||
|
|
||||||
|
return (oll.x >= ll.x and our.x <= ur.x)
|
||||||
|
|
||||||
|
def ycontains(self, other):
|
||||||
|
""" Check if shape contains the y overlap """
|
||||||
|
(ll,ur) = self.rect
|
||||||
|
(oll,our) = other.rect
|
||||||
|
|
||||||
|
return (oll.y >= ll.y and our.y <= ur.y)
|
||||||
|
|
||||||
def contains(self, other):
|
def contains(self, other):
|
||||||
""" Check if a shape contains another rectangle """
|
""" Check if a shape contains another rectangle """
|
||||||
# If it is the same shape entirely, it is contained!
|
# If it is the same shape entirely, it is contained!
|
||||||
|
|
@ -127,23 +141,13 @@ class pin_layout:
|
||||||
# Can only overlap on the same layer
|
# Can only overlap on the same layer
|
||||||
if self.layer != other.layer:
|
if self.layer != other.layer:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
(ll,ur) = self.rect
|
if not self.xcontains(other):
|
||||||
(oll,our) = other.rect
|
|
||||||
|
|
||||||
# Check if the oll is inside the y range
|
|
||||||
if not (oll.y >= ll.y and oll.y <= ur.y):
|
|
||||||
return False
|
return False
|
||||||
# Check if the oll is inside the x range
|
|
||||||
if not (oll.x >= ll.x and oll.x <= ur.x):
|
if not self.ycontains(other):
|
||||||
return False
|
return False
|
||||||
# Check if the our is inside the y range
|
|
||||||
if not (our.y >= ll.y and our.y <= ur.y):
|
|
||||||
return False
|
|
||||||
# Check if the our is inside the x range
|
|
||||||
if not (our.x >= ll.x and our.x <= ur.x):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,10 +114,10 @@ class pin_group:
|
||||||
if index2 in remove_indices:
|
if index2 in remove_indices:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if pin2.contains(pin1):
|
if pin1.contains(pin2):
|
||||||
if local_debug:
|
if local_debug:
|
||||||
debug.info(0,"{0} contains {1}".format(pin1,pin2))
|
debug.info(0,"{0} contains {1}".format(pin1,pin2))
|
||||||
remove_indices.add(index2)
|
remove_indices.add(index2)
|
||||||
|
|
||||||
# Remove them in decreasing order to not invalidate the indices
|
# Remove them in decreasing order to not invalidate the indices
|
||||||
for i in sorted(remove_indices, reverse=True):
|
for i in sorted(remove_indices, reverse=True):
|
||||||
|
|
@ -144,7 +144,7 @@ class pin_group:
|
||||||
enclosure = self.router.compute_pin_enclosure(ll, ur, ll.z)
|
enclosure = self.router.compute_pin_enclosure(ll, ur, ll.z)
|
||||||
pin_list.append(enclosure)
|
pin_list.append(enclosure)
|
||||||
|
|
||||||
return self.remove_redundant_shapes(pin_list)
|
return pin_list
|
||||||
|
|
||||||
def compute_connector(self, pin, enclosure):
|
def compute_connector(self, pin, enclosure):
|
||||||
"""
|
"""
|
||||||
|
|
@ -187,6 +187,138 @@ class pin_group:
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
def find_above_connector(self, pin, enclosures):
|
||||||
|
"""
|
||||||
|
Find the enclosure that is to above the pin
|
||||||
|
and make a connector to it's upper edge.
|
||||||
|
"""
|
||||||
|
# Create the list of shapes that contain the pin edge
|
||||||
|
edge_list = []
|
||||||
|
for shape in enclosures:
|
||||||
|
if shape.xcontains(pin):
|
||||||
|
edge_list.append(shape)
|
||||||
|
|
||||||
|
# Sort them by their bottom edge
|
||||||
|
edge_list.sort(key=lambda x: x.by(), reverse=True)
|
||||||
|
|
||||||
|
# Find the bottom edge that is next to the pin's top edge
|
||||||
|
above_item = None
|
||||||
|
for item in edge_list:
|
||||||
|
if item.by()>=pin.uy():
|
||||||
|
above_item = item
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# There was nothing
|
||||||
|
if above_item==None:
|
||||||
|
return None
|
||||||
|
# If it already overlaps, no connector needed
|
||||||
|
if above_item.overlaps(pin):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Otherwise, make a connector to the item
|
||||||
|
p = self.compute_connector(pin, above_item)
|
||||||
|
return p
|
||||||
|
|
||||||
|
def find_below_connector(self, pin, enclosures):
|
||||||
|
"""
|
||||||
|
Find the enclosure that is below the pin
|
||||||
|
and make a connector to it's upper edge.
|
||||||
|
"""
|
||||||
|
# Create the list of shapes that contain the pin edge
|
||||||
|
edge_list = []
|
||||||
|
for shape in enclosures:
|
||||||
|
if shape.xcontains(pin):
|
||||||
|
edge_list.append(shape)
|
||||||
|
|
||||||
|
# Sort them by their upper edge
|
||||||
|
edge_list.sort(key=lambda x: x.uy())
|
||||||
|
|
||||||
|
# Find the upper edge that is next to the pin's bottom edge
|
||||||
|
bottom_item = None
|
||||||
|
for item in edge_list:
|
||||||
|
if item.uy()<=pin.by():
|
||||||
|
bottom_item = item
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# There was nothing to the left
|
||||||
|
if bottom_item==None:
|
||||||
|
return None
|
||||||
|
# If it already overlaps, no connector needed
|
||||||
|
if bottom_item.overlaps(pin):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Otherwise, make a connector to the item
|
||||||
|
p = self.compute_connector(pin, bottom_item)
|
||||||
|
return p
|
||||||
|
|
||||||
|
def find_left_connector(self, pin, enclosures):
|
||||||
|
"""
|
||||||
|
Find the enclosure that is to the left of the pin
|
||||||
|
and make a connector to it's right edge.
|
||||||
|
"""
|
||||||
|
# Create the list of shapes that contain the pin edge
|
||||||
|
edge_list = []
|
||||||
|
for shape in enclosures:
|
||||||
|
if shape.ycontains(pin):
|
||||||
|
edge_list.append(shape)
|
||||||
|
|
||||||
|
# Sort them by their right edge
|
||||||
|
edge_list.sort(key=lambda x: x.rx())
|
||||||
|
|
||||||
|
# Find the right edge that is to the pin's left edge
|
||||||
|
left_item = None
|
||||||
|
for item in edge_list:
|
||||||
|
if item.rx()<=pin.lx():
|
||||||
|
left_item = item
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# There was nothing to the left
|
||||||
|
if left_item==None:
|
||||||
|
return None
|
||||||
|
# If it already overlaps, no connector needed
|
||||||
|
if left_item.overlaps(pin):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Otherwise, make a connector to the item
|
||||||
|
p = self.compute_connector(pin, left_item)
|
||||||
|
return p
|
||||||
|
|
||||||
|
def find_right_connector(self, pin, enclosures):
|
||||||
|
"""
|
||||||
|
Find the enclosure that is to the right of the pin
|
||||||
|
and make a connector to it's left edge.
|
||||||
|
"""
|
||||||
|
# Create the list of shapes that contain the pin edge
|
||||||
|
edge_list = []
|
||||||
|
for shape in enclosures:
|
||||||
|
if shape.ycontains(pin):
|
||||||
|
edge_list.append(shape)
|
||||||
|
|
||||||
|
# Sort them by their right edge
|
||||||
|
edge_list.sort(key=lambda x: x.lx(), reverse=True)
|
||||||
|
|
||||||
|
# Find the left edge that is next to the pin's right edge
|
||||||
|
right_item = None
|
||||||
|
for item in edge_list:
|
||||||
|
if item.lx()>=pin.rx():
|
||||||
|
right_item = item
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
# There was nothing to the right
|
||||||
|
if right_item==None:
|
||||||
|
return None
|
||||||
|
# If it already overlaps, no connector needed
|
||||||
|
if right_item.overlaps(pin):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Otherwise, make a connector to the item
|
||||||
|
p = self.compute_connector(pin, right_item)
|
||||||
|
return p
|
||||||
|
|
||||||
def find_smallest_connector(self, pin_list, shape_list):
|
def find_smallest_connector(self, pin_list, shape_list):
|
||||||
"""
|
"""
|
||||||
Compute all of the connectors between the overlapping pins and enclosure shape list..
|
Compute all of the connectors between the overlapping pins and enclosure shape list..
|
||||||
|
|
@ -313,16 +445,30 @@ class pin_group:
|
||||||
self.enclosed = True
|
self.enclosed = True
|
||||||
|
|
||||||
# Compute the enclosure pin_layout list of the set of tracks
|
# Compute the enclosure pin_layout list of the set of tracks
|
||||||
self.enclosures = self.compute_enclosures()
|
redundant_enclosures = self.compute_enclosures()
|
||||||
|
|
||||||
|
# Now simplify the enclosure list
|
||||||
|
self.enclosures = self.remove_redundant_shapes(redundant_enclosures)
|
||||||
|
|
||||||
|
for pin_list in self.pins:
|
||||||
|
for pin in pin_list:
|
||||||
|
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)
|
||||||
|
for connector in [left_connector, right_connector, above_connector, below_connector]:
|
||||||
|
if connector:
|
||||||
|
self.enclosures.append(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 a connector.
|
||||||
|
# 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):
|
||||||
connector = self.find_smallest_connector(pin_list, self.enclosures)
|
connector = self.find_smallest_connector(pin_list, self.enclosures)
|
||||||
debug.check(connector!=None, "Could not find a connector for {} with {}".format(pin_list, self.enclosures))
|
debug.check(connector!=None, "Could not find a connector for {} with {}".format(pin_list, self.enclosures))
|
||||||
self.enclosures.append(connector)
|
self.enclosures.append(connector)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
debug.info(3,"Computed enclosure(s) {0}\n {1}\n {2}\n {3}".format(self.name,
|
debug.info(3,"Computed enclosure(s) {0}\n {1}\n {2}\n {3}".format(self.name,
|
||||||
self.pins,
|
self.pins,
|
||||||
self.grids,
|
self.grids,
|
||||||
|
|
|
||||||
|
|
@ -707,7 +707,7 @@ class router(router_tech):
|
||||||
pg.enclose_pin()
|
pg.enclose_pin()
|
||||||
pg.add_enclosure(self.cell)
|
pg.add_enclosure(self.cell)
|
||||||
|
|
||||||
#self.write_debug_gds("pin_debug.gds", True)
|
#self.write_debug_gds("pin_debug.gds", False)
|
||||||
|
|
||||||
def add_source(self, pin_name):
|
def add_source(self, pin_name):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue