Merged in an old stash.

This commit is contained in:
Matt Guthaus 2018-10-29 11:18:12 -07:00
parent b7655eab10
commit f19bcace62
3 changed files with 83 additions and 23 deletions

View File

@ -16,7 +16,11 @@ class pin_group:
self.routed = False
# This is a list because we can have a pin group of disconnected sets of pins
# and these are represented by separate lists
self.pins = [pin_shapes]
if pin_shapes:
self.pins = [pin_shapes]
else:
self.pins = []
self.router = router
# These are the corresponding pin grids for each pin group.
self.grids = set()
@ -53,28 +57,37 @@ class pin_group:
"""
Remove any pin layout that is contained within another.
"""
local_debug = False
local_debug = True
if local_debug:
debug.info(0,"INITIAL: {}".format(pin_list))
# Make a copy of the list to start
new_pin_list = pin_list.copy()
remove_indices = set()
# This is n^2, but the number is small
for pin1 in pin_list:
for pin2 in pin_list:
for index1,pin1 in enumerate(pin_list):
if index1 in remove_indices:
continue
for index2,pin2 in enumerate(pin_list):
# Can't contain yourself
if pin1 == pin2:
continue
if index2 in remove_indices:
continue
if pin2.contains(pin1):
if local_debug:
debug.info(0,"{0} contains {1}".format(pin1,pin2))
# It may have already been removed by being enclosed in another pin
if pin1 in new_pin_list:
new_pin_list.remove(pin1)
remove_indices.add(index2)
# Remove them in decreasing order to not invalidate the indices
for i in sorted(remove_indices, reverse=True):
del new_pin_list[i]
if local_debug:
debug.info(0,"FINAL : {}".format(new_pin_list))
return new_pin_list
# FIXME: This relies on some technology parameters from router which is not clean.
@ -106,6 +119,7 @@ class pin_group:
ymax = max(plc.y,elc.y)
ll = vector(plc.x, ymin)
ur = vector(prc.x, ymax)
print(pin,enclosure,ll,ur)
p = pin_layout(pin.name, [ll, ur], pin.layer)
elif pin.yoverlaps(enclosure):
# Is it horizontal overlap, extend pin shape to enclosure
@ -248,13 +262,13 @@ class pin_group:
def enclose_pin(self):
"""
This will find the biggest rectangle enclosing some grid squares and
put a rectangle over it. It does not enclose grid squares that are blocked
by other shapes.
If there is one set of connected pin shapes,
this will find the smallest rectangle enclosure that overlaps with any pin.
If there is not, it simply returns all the enclosures.
"""
# Compute the enclosure pin_layout list of the set of tracks
enclosure_list = self.compute_enclosures()
# A single set of connected pins is easy, so use the optimized set
if len(self.pins)==1:
smallest = self.find_smallest_overlapping(self.pins[0],enclosure_list)
@ -268,7 +282,7 @@ class pin_group:
# debug.error("Unable to enclose pin {}".format(self.pins),-1)
else:
# Multiple pins is hard, so just use all of the enclosure shapes!
# FIXME: Find the minimum set of enclosures to reduce number of shapes.
# At least none of these are redundant shapes though.
self.enclosures = enclosure_list
debug.info(2,"Computed enclosure(s) {0}\n {1}\n {2}\n {3}".format(self.name, self.pins, self.grids, self.enclosures))
@ -305,6 +319,7 @@ class pin_group:
# Keep the same groups for each pin
pin_set = set()
blockage_set = set()
print("PINLIST:",self.pins)
for pin_list in self.pins:
for pin in pin_list:
debug.info(2," Converting {0}".format(pin))
@ -318,10 +333,10 @@ class pin_group:
# If we have a blockage, we must remove the grids
# Remember, this excludes the pin blockages already
shared_set = pin_set & router.blocked_grids
if shared_set:
if len(shared_set)>0:
debug.info(2,"Removing pins {}".format(shared_set))
shared_set = blockage_set & router.blocked_grids
if shared_set:
if len(shared_set)>0:
debug.info(2,"Removing blocks {}".format(shared_set))
pin_set.difference_update(router.blocked_grids)
blockage_set.difference_update(router.blocked_grids)

View File

@ -155,19 +155,27 @@ class router(router_tech):
for pin in pin_list:
self.combine_adjacent_pins(pin)
#self.write_debug_gds("debug_combine_pins.gds",stop_program=True)
# Separate any adjacent grids of differing net names to prevent wide metal DRC violations
self.separate_adjacent_pins(pin)
# Enclose the continguous grid units in a metal rectangle to fix some DRCs
self.enclose_pins()
def combine_adjacent_pins(self, pin_name):
def combine_adjacent_pins_pass(self, pin_name):
"""
This checks for simple cases where a pin component already overlaps a supply rail.
It will add an enclosure to ensure the overlap in wide DRC rule cases.
"""
# Make a copy since we are going to reduce this list
pin_groups = self.pin_groups[pin_name].copy()
Find pins that have adjacent routing tracks and merge them into a
single pin_group. The pins themselves may not be touching, but
enclose_pis in the next step will ensure they are touching.
"""
# Make a copy since we are going to add to (and then reduce) this list
pin_groups = self.pin_groups[pin_name].copy()
# Start as None to signal the first iteration
remove_indices = set()
for index1,pg1 in enumerate(self.pin_groups[pin_name]):
# Cannot combine more than once
if index1 in remove_indices:
@ -180,6 +188,7 @@ class router(router_tech):
if index2 in remove_indices:
continue
# Combine if at least 1 grid cell is adjacent
if pg1.adjacent(pg2):
combined = pin_group(pin_name, [], self)
combined.pins = [*pg1.pins, *pg2.pins]
@ -189,12 +198,48 @@ class router(router_tech):
remove_indices.update([index1,index2])
pin_groups.append(combined)
# Remove them in decreasing order to not invalidate the indices
debug.info(2,"Removing {}".format(sorted(remove_indices)))
for i in sorted(remove_indices, reverse=True):
del pin_groups[i]
# Use the new pin group!
self.pin_groups[pin_name] = pin_groups
removed_pairs = len(remove_indices)/2
debug.info(1, "Combined {0} pin pairs for {1}".format(removed_pairs,pin_name))
return(removed_pairs)
def combine_adjacent_pins(self, pin_name):
"""
Make multiple passes of the combine adjacent pins until we have no
more combinations or hit an iteration limit.
"""
# Start as None to signal the first iteration
num_removed_pairs = None
# Just used in case there's a circular combination or something weird
for iteration_count in range(10):
num_removed_pairs = self.combine_adjacent_pins_pass(pin_name)
if num_removed_pairs==0:
break
else:
debug.warning("Did not converge combining adjacent pins in supply router.")
def separate_adjacent_pins(self, pin_name, separation=1):
"""
This will try to separate all grid pins by the supplied number of separation
tracks (default is to prevent adjacency).
Go through all of the pin groups and check if any other pin group is
within a separation of it.
If so, reduce the pin group grid to not include the adjacent grid.
Try to do this intelligently to keep th pins enclosed.
"""
pass
def prepare_blockages(self, pin_name):
"""
Reset and add all of the blockages in the design.

View File

@ -71,7 +71,7 @@ class supply_router(router):
# Get the pin shapes
self.find_pins_and_blockages([self.vdd_name, self.gnd_name])
#self.write_debug_gds("pin_enclosures.gds",stop_program=True)
self.write_debug_gds("pin_enclosures.gds",stop_program=True)
# Add the supply rails in a mesh network and connect H/V with vias
# Block everything