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

This commit is contained in:
mrg 2021-03-01 15:47:33 -08:00
commit 13bdae2e30
7 changed files with 83 additions and 68 deletions

View File

@ -4,52 +4,54 @@ jobs:
scn4me_subm:
runs-on: self-hosted
steps:
- name: Check out repository
- name: Checkout code
uses: actions/checkout@v1
- name: SCMOS test
run: |
. /home/github-runner/setup-paths.sh
export OPENRAM_HOME="`pwd`/compiler"
export OPENRAM_TECH="`pwd`/technology:/software/PDKs/skywater-tech"
export OPENRAM_TMP="`pwd`/scn4me_subm"
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 48 -t scn4m_subm
export OPENRAM_TMP="${{ github.workspace }}/scn4me_subm_temp"
#python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 12 -t scn4m_subm
$OPENRAM_HOME/tests/regress.py -j 12 -t scn4m_subm
- name: Archive
if: ${{ failure() }}
uses: actions/upload-artifact@v2
with:
name: scn4me_subm Archives
path: $OPENRAM_TMP/
path: ${{ github.workspace }}/scn4me_subm_temp/*/
freepdk45:
runs-on: self-hosted
steps:
- name: Check out repository
- name: Checkout code
uses: actions/checkout@v1
- name: FreePDK45 test
run: |
. /home/github-runner/setup-paths.sh
export OPENRAM_HOME="`pwd`/compiler"
export OPENRAM_TECH="`pwd`/technology:/software/PDKs/skywater-tech"
export OPENRAM_TMP="`pwd`/freepdk45"
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 48 -t freepdk45
export OPENRAM_TMP="${{ github.workspace }}/freepdk45_temp"
#python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 12 -t freepdk45
$OPENRAM_HOME/tests/regress.py -j 12 -t freepdk45
- name: Archive
if: ${{ failure() }}
uses: actions/upload-artifact@v2
with:
name: FreePDK45 Archives
path: $OPENRAM_TMP/
coverage:
if: ${{ always() }}
needs: [scn4me_subm, freepdk45]
runs-on: self-hosted
steps:
- name: Coverage stats
run: |
python3-coverage combine
python3-coverage report
python3-coverage html -d coverage_html
- name: Archive coverage
uses: actions/upload-artifact@v2
with:
name: code-coverage-report
path: coverage_html/
path: ${{ github.workspace }}/freepdk45_temp/*/
# coverage_stats:
# if: ${{ always() }}
# needs: [scn4me_subm, freepdk45]
# runs-on: self-hosted
# steps:
# - name: Coverage stats
# run: |
# python3-coverage combine
# python3-coverage report
# python3-coverage html -d ${{ github.workspace }}/coverage_html
# - name: Archive coverage
# uses: actions/upload-artifact@v2
# with:
# name: code-coverage-report
# path: ${{ github.workspace }}/coverage_html/

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())

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()]

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

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

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

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):