Added new enclosure connector algorithm using edge sorting.

This commit is contained in:
Matt Guthaus 2018-10-31 15:35:39 -07:00
parent fc45242ccb
commit c511d886bf
3 changed files with 171 additions and 21 deletions

View File

@ -118,6 +118,20 @@ class pin_layout:
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):
""" Check if a shape contains another rectangle """
# If it is the same shape entirely, it is contained!
@ -127,23 +141,13 @@ class pin_layout:
# Can only overlap on the same layer
if self.layer != other.layer:
return False
(ll,ur) = self.rect
(oll,our) = other.rect
# Check if the oll is inside the y range
if not (oll.y >= ll.y and oll.y <= ur.y):
if not self.xcontains(other):
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
# 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

View File

@ -114,10 +114,10 @@ class pin_group:
if index2 in remove_indices:
continue
if pin2.contains(pin1):
if pin1.contains(pin2):
if local_debug:
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
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)
pin_list.append(enclosure)
return self.remove_redundant_shapes(pin_list)
return pin_list
def compute_connector(self, pin, enclosure):
"""
@ -187,6 +187,138 @@ class pin_group:
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):
"""
Compute all of the connectors between the overlapping pins and enclosure shape list..
@ -313,16 +445,30 @@ class pin_group:
self.enclosed = True
# 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.
# 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):
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))
self.enclosures.append(connector)
debug.info(3,"Computed enclosure(s) {0}\n {1}\n {2}\n {3}".format(self.name,
self.pins,
self.grids,

View File

@ -707,7 +707,7 @@ class router(router_tech):
pg.enclose_pin()
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):
"""