Merge remote-tracking branch 'private/dev' into control-logic-pull

This commit is contained in:
mrg
2021-03-01 15:47:33 -08:00
7 changed files with 83 additions and 68 deletions
+2 -2
View File
@@ -146,10 +146,10 @@ class sense_amp_array(design.design):
inst = self.local_insts[i]
for gnd_pin in inst.get_pins("gnd"):
self.copy_power_pin(gnd_pin, directions=("V", "V"))
self.copy_power_pin(gnd_pin)
for vdd_pin in inst.get_pins("vdd"):
self.copy_power_pin(vdd_pin, directions=("V", "V"))
self.copy_power_pin(vdd_pin)
bl_pin = inst.get_pin(inst.mod.get_bl_names())
br_pin = inst.get_pin(inst.mod.get_br_names())
+14 -13
View File
@@ -7,6 +7,8 @@
#
from enum import Enum
from vector3d import vector3d
import debug
class direction(Enum):
NORTH = 1
@@ -20,31 +22,30 @@ class direction(Enum):
SOUTHEAST = 9
SOUTHWEST = 10
def get_offset(direct):
"""
Returns the vector offset for a given direction.
"""
if direct==direction.NORTH:
offset = vector3d(0,1,0)
offset = vector3d(0, 1, 0)
elif direct==direction.SOUTH:
offset = vector3d(0,-1,0)
offset = vector3d(0, -1 ,0)
elif direct==direction.EAST:
offset = vector3d(1,0,0)
offset = vector3d(1, 0, 0)
elif direct==direction.WEST:
offset = vector3d(-1,0,0)
offset = vector3d(-1, 0, 0)
elif direct==direction.UP:
offset = vector3d(0,0,1)
offset = vector3d(0, 0, 1)
elif direct==direction.DOWN:
offset = vector3d(0,0,-1)
offset = vector3d(0, 0, -1)
elif direct==direction.NORTHEAST:
offset = vector3d(1,1,0)
offset = vector3d(1, 1, 0)
elif direct==direction.NORTHWEST:
offset = vector3d(-1,1,0)
offset = vector3d(-1, 1, 0)
elif direct==direction.SOUTHEAST:
offset = vector3d(1,-1,0)
offset = vector3d(1, -1, 0)
elif direct==direction.SOUTHWEST:
offset = vector3d(-1,-1,0)
offset = vector3d(-1, -1, 0)
else:
debug.error("Invalid direction {}".format(direct))
@@ -67,8 +68,8 @@ class direction(Enum):
return [direction.get_offset(d) for d in direction.all_directions()]
def all_neighbors(cell):
return [cell+x for x in direction.all_offsets()]
return [cell + x for x in direction.all_offsets()]
def cardinal_neighbors(cell):
return [cell+x for x in direction.cardinal_offsets()]
return [cell + x for x in direction.cardinal_offsets()]
+16 -13
View File
@@ -34,7 +34,6 @@ class pin_group:
# Remove any redundant pins (i.e. contained in other pins)
self.remove_redundant_pins()
self.router = router
# These are the corresponding pin grids for each pin group.
self.grids = set()
@@ -101,13 +100,11 @@ class pin_group:
if local_debug:
debug.info(0, "INITIAL: {}".format(pin_list))
new_pin_list = pin_list.copy()
remove_indices = set()
add_indices = set(range(len(pin_list)))
# This is n^2, but the number is small
for index1, pin1 in enumerate(pin_list):
# If we remove this pin, it can't contain other pins
if index1 in remove_indices:
if index1 not in add_indices:
continue
for index2, pin2 in enumerate(pin_list):
@@ -117,17 +114,15 @@ class pin_group:
if index1 == index2:
continue
# If we already removed it, can't remove it again...
if index2 in remove_indices:
if index2 not in add_indices:
continue
if pin1.contains(pin2):
if local_debug:
debug.info(0, "{0} contains {1}".format(pin1, pin2))
remove_indices.add(index2)
add_indices.remove(index2)
# Remove them in decreasing order to not invalidate the indices
for i in sorted(remove_indices, reverse=True):
del new_pin_list[i]
new_pin_list = [pin_list[x] for x in add_indices]
if local_debug:
debug.info(0, "FINAL : {}".format(new_pin_list))
@@ -423,13 +418,15 @@ class pin_group:
# We may have started with an empty set
debug.check(len(self.grids) > 0, "Cannot seed an grid empty set.")
common_blockages = self.router.get_blocked_grids() & self.grids
# Start with the ll and make the widest row
row = [ll]
# Move in dir1 while we can
while True:
next_cell = row[-1] + offset1
# Can't move if not in the pin shape
if next_cell in self.grids and next_cell not in self.router.get_blocked_grids():
if next_cell in self.grids and next_cell not in common_blockages:
row.append(next_cell)
else:
break
@@ -438,7 +435,7 @@ class pin_group:
next_row = [x + offset2 for x in row]
for cell in next_row:
# Can't move if any cell is not in the pin shape
if cell not in self.grids or cell in self.router.get_blocked_grids():
if cell not in self.grids or cell in common_blockages:
break
else:
row = next_row
@@ -619,6 +616,11 @@ class pin_group:
# Set of track adjacent to or paritally overlap a pin (not full DRC connection)
partial_set = set()
# for pin in self.pins:
# lx = pin.lx()
# ly = pin.by()
# if lx > 87.9 and lx < 87.99 and ly > 18.56 and ly < 18.6:
# breakpoint()
for pin in self.pins:
debug.info(4, " Converting {0}".format(pin))
# Determine which tracks the pin overlaps
@@ -632,7 +634,8 @@ class pin_group:
blockage_in_tracks = self.router.convert_blockage(pin)
# Must include the pins here too because these are computed in a different
# way than blockages.
self.blockages.update(sufficient | insufficient | blockage_in_tracks)
blockages = sufficient | insufficient | blockage_in_tracks
self.blockages.update(blockages)
# If we have a blockage, we must remove the grids
# Remember, this excludes the pin blockages already
+13 -5
View File
@@ -504,14 +504,21 @@ class router(router_tech):
ll = vector(boundary[0], boundary[1])
ur = vector(boundary[2], boundary[3])
rect = [ll, ur]
new_pin = pin_layout("blockage{}".format(len(self.blockages)),
rect,
lpp)
new_shape = pin_layout("blockage{}".format(len(self.blockages)),
rect,
lpp)
# If there is a rectangle that is the same in the pins,
# it isn't a blockage!
if new_pin not in self.all_pins:
self.blockages.append(new_pin)
if new_shape not in self.all_pins and not self.pin_contains(new_shape):
self.blockages.append(new_shape)
def pin_contains(self, shape):
for pin in self.all_pins:
if pin.contains(shape):
return True
return False
def convert_point_to_units(self, p):
"""
Convert a path set of tracks to center line path.
@@ -1048,6 +1055,7 @@ class router(router_tech):
# Double check source and taget are not same node, if so, we are done!
for k, v in self.rg.map.items():
if v.source and v.target:
self.paths.append([k])
return True
# returns the path in tracks
+9 -8
View File
@@ -37,12 +37,12 @@ class supply_tree_router(router):
"""
Route the two nets in a single layer)
"""
debug.info(1,"Running supply router on {0} and {1}...".format(vdd_name, gnd_name))
debug.info(1, "Running supply router on {0} and {1}...".format(vdd_name, gnd_name))
self.vdd_name = vdd_name
self.gnd_name = gnd_name
# Clear the pins if we have previously routed
if (hasattr(self,'rg')):
if (hasattr(self, 'rg')):
self.clear_pins()
else:
# Creat a routing grid over the entire area
@@ -53,14 +53,14 @@ class supply_tree_router(router):
# Get the pin shapes
start_time = datetime.now()
self.find_pins_and_blockages([self.vdd_name, self.gnd_name])
print_time("Finding pins and blockages",datetime.now(), start_time, 3)
print_time("Finding pins and blockages", datetime.now(), start_time, 3)
# Route the supply pins to the supply rails
# Route vdd first since we want it to be shorter
start_time = datetime.now()
self.route_pins(vdd_name)
self.route_pins(gnd_name)
print_time("Maze routing supplies",datetime.now(), start_time, 3)
print_time("Maze routing supplies", datetime.now(), start_time, 3)
# self.write_debug_gds("final_tree_router.gds",False)
@@ -79,11 +79,11 @@ class supply_tree_router(router):
"""
remaining_components = sum(not x.is_routed() for x in self.pin_groups[pin_name])
debug.info(1,"Routing {0} with {1} pin components to connect.".format(pin_name,
remaining_components))
debug.info(1, "Routing {0} with {1} pin components to connect.".format(pin_name,
remaining_components))
# Create full graph
debug.info(2,"Creating adjacency matrix")
debug.info(2, "Creating adjacency matrix")
pin_size = len(self.pin_groups[pin_name])
adj_matrix = [[0] * pin_size for i in range(pin_size)]
@@ -95,7 +95,7 @@ class supply_tree_router(router):
adj_matrix[index1][index2] = dist
# Find MST
debug.info(2,"Finding MinimumSpanning Tree")
debug.info(2, "Finding MinimumSpanning Tree")
X = csr_matrix(adj_matrix)
Tcsr = minimum_spanning_tree(X)
mst = Tcsr.toarray().astype(int)
@@ -144,6 +144,7 @@ class supply_tree_router(router):
self.add_pin_component_source(pin_name, src_idx)
# Marks all pin components except index as target
# which unmarks it as a blockage too
self.add_pin_component_target(pin_name, dest_idx)
# Actually run the A* router
+4 -4
View File
@@ -325,13 +325,13 @@ class sram_1bank(sram_base):
# they might create some blockages
self.add_layout_pins()
# Route the supplies first since the MST is not blockage aware
# and signals can route to anywhere on sides (it is flexible)
self.route_supplies()
# Route the pins to the perimeter
if OPTS.perimeter_pins:
self.route_escape_pins()
# Route the supplies first since the MST is not blockage aware
# and signals can route to anywhere on sides (it is flexible)
self.route_supplies()
def route_dffs(self, add_routes=True):