mirror of https://github.com/VLSIDA/OpenRAM.git
Merged in an old stash.
This commit is contained in:
parent
b7655eab10
commit
f19bcace62
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue