remove debug lines and merge

This commit is contained in:
jcirimel 2021-02-09 20:53:23 -08:00
commit b18e2eae8d
368 changed files with 5943 additions and 940 deletions

View File

@ -10,7 +10,7 @@ stages:
freepdk45: freepdk45:
stage: test stage: test
script: script:
- coverage run -p $OPENRAM_HOME/tests/regress.py -t freepdk45 - coverage run -p $OPENRAM_HOME/tests/regress.py -j 6 -t freepdk45
artifacts: artifacts:
paths: paths:
- .coverage.* - .coverage.*
@ -19,7 +19,7 @@ freepdk45:
scn4m_subm: scn4m_subm:
stage: test stage: test
script: script:
- coverage run -p $OPENRAM_HOME/tests/regress.py -t scn4m_subm - coverage run -p $OPENRAM_HOME/tests/regress.py -j 6 -t scn4m_subm
artifacts: artifacts:
paths: paths:
- .coverage.* - .coverage.*

View File

@ -43,12 +43,12 @@ The OpenRAM compiler has very few dependencies:
If you want to perform DRC and LVS, you will need either: If you want to perform DRC and LVS, you will need either:
+ Calibre (for [FreePDK45]) + Calibre (for [FreePDK45])
+ [Magic] 8.3.27 or higher (for [SCMOS]) + [Magic] 8.3.130 or newer
+ [Netgen] 1.5 (for [SCMOS]) + [Netgen] 1.5.164 or newer
You must set two environment variables: You must set two environment variables:
+ OPENRAM\_HOME should point to the compiler source directory. + OPENRAM\_HOME should point to the compiler source directory.
+ OPENERAM\_TECH should point to a root technology directory. + OPENERAM\_TECH should point to one or more root technology directories (colon separated).
## Environment ## Environment
@ -65,11 +65,11 @@ You may also wish to add OPENRAM\_HOME to your PYTHONPATH:
export PYTHONPATH="$PYTHONPATH:$OPENRAM_HOME" export PYTHONPATH="$PYTHONPATH:$OPENRAM_HOME"
``` ```
We include the tech files necessary for [SCMOS] We include the tech files necessary for [SCMOS] SCN4M_SUBM. The
SCN4M_SUBM. The [SCMOS] spice models, however, are generic and should [SCMOS] spice models, however, are generic and should be replaced with
be replaced with foundry models. If you are using [FreePDK45], you foundry models. If you are using [FreePDK45], you should also have
should also have that set up and have the environment variable point that set up and have the environment variable point to the PDK. For
to the PDK. For example add this to your .bashrc: example add this to your .bashrc:
``` ```
export FREEPDK45="/bsoe/software/design-kits/FreePDK45" export FREEPDK45="/bsoe/software/design-kits/FreePDK45"
@ -160,9 +160,9 @@ specific technology (e.g., [FreePDK45]) should be a subdirectory
* dff.gds * dff.gds
* sense_amp.gds * sense_amp.gds
* write_driver.gds * write_driver.gds
* cell_6t.gds * cell_1rw.gds
* replica\_cell\_6t.gds * replica\_cell\_1rw.gds
* dummy\_cell\_6t.gds * dummy\_cell\_1rw.gds
* sp_lib folder with all the .sp (premade) library netlists for the above cells. * sp_lib folder with all the .sp (premade) library netlists for the above cells.
* layers.map * layers.map
* A valid tech Python module (tech directory with \_\_init\_\_.py and tech.py) with: * A valid tech Python module (tech directory with \_\_init\_\_.py and tech.py) with:

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -49,8 +49,6 @@ class design(hierarchy_design):
self.add_pin_names(prop.port_map) self.add_pin_names(prop.port_map)
self.add_pin_types(prop.port_types) self.add_pin_types(prop.port_types)
def debug_writer(self):
self.gds_write("/home/jesse/output/direct_rw.gds")
(width, height) = utils.get_libcell_size(self.cell_name, (width, height) = utils.get_libcell_size(self.cell_name,
GDS["unit"], GDS["unit"],
@ -59,12 +57,13 @@ class design(hierarchy_design):
self.pin_map = utils.get_libcell_pins(self.pins, self.pin_map = utils.get_libcell_pins(self.pins,
self.cell_name, self.cell_name,
GDS["unit"]) GDS["unit"])
import gdsMill
reader = self.gds
writer = gdsMill.Gds2writer(reader)
writer.writeToFile('/home/jesse/output/direct_rw.gds')
self.gds_write("/home/jesse/output/direct_rw.gds") # Convert names back to the original names
# so that copying will use the new names
for pin_name in self.pin_map:
for index1, pin in enumerate(self.pin_map[pin_name]):
self.pin_map[pin_name][index1].name = self.get_original_pin_name(pin.name)
self.width = width self.width = width
self.height = height self.height = height

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -1220,49 +1220,88 @@ class layout():
pin.height()) pin.height())
elif add_vias: elif add_vias:
self.add_power_pin(name, pin.center(), start_layer=pin.layer) self.copy_power_pin(pin)
def add_io_pin(self, instance, pin_name, new_name="", start_layer=None): def add_io_pin(self, instance, pin_name, new_name, start_layer=None):
""" """
Add a signle input or output pin up to metal 3. Add a signle input or output pin up to metal 3.
""" """
pin = instance.get_pin(pin_name) pin = instance.get_pin(pin_name)
if new_name == "":
new_name = pin_name
if not start_layer: if not start_layer:
start_layer = pin.layer start_layer = pin.layer
# Just use the power pin function for now to save code
self.add_power_pin(name=new_name, loc=pin.center(), start_layer=start_layer)
def add_power_pin(self, name, loc, size=[1, 1], directions=None, start_layer="m1"): # Just use the power pin function for now to save code
self.add_power_pin(new_name, pin.center(), start_layer=start_layer)
def add_power_pin(self, name, loc, directions=None, start_layer="m1"):
# Hack for min area
if OPTS.tech_name == "sky130":
min_area = drc["minarea_{}".format(self.pwr_grid_layer)]
width = round_to_grid(sqrt(min_area))
height = round_to_grid(min_area / width)
else:
width = None
height = None
if start_layer == self.pwr_grid_layer:
self.add_layout_pin_rect_center(text=name,
layer=self.pwr_grid_layer,
offset=loc,
width=width,
height=height)
else:
via = self.add_via_stack_center(from_layer=start_layer,
to_layer=self.pwr_grid_layer,
offset=loc,
directions=directions)
if not width:
width = via.width
if not height:
height = via.height
self.add_layout_pin_rect_center(text=name,
layer=self.pwr_grid_layer,
offset=loc,
width=width,
height=height)
def copy_power_pin(self, pin, loc=None, directions=None):
""" """
Add a single power pin from the lowest power_grid layer down to M1 (or li) at Add a single power pin from the lowest power_grid layer down to M1 (or li) at
the given center location. The starting layer is specified to determine the given center location. The starting layer is specified to determine
which vias are needed. which vias are needed.
""" """
if start_layer == self.pwr_grid_layer: if not loc:
self.add_layout_pin_rect_center(text=name, loc = pin.center()
layer=self.pwr_grid_layer,
offset=loc) # Hack for min area
if OPTS.tech_name == "sky130":
min_area = drc["minarea_{}".format(self.pwr_grid_layer)]
width = round_to_grid(sqrt(min_area))
height = round_to_grid(min_area / width)
else: else:
via = self.add_via_stack_center(from_layer=start_layer, width = None
height = None
if pin.layer == self.pwr_grid_layer:
self.add_layout_pin_rect_center(text=pin.name,
layer=self.pwr_grid_layer,
offset=loc,
width=width,
height=height)
else:
via = self.add_via_stack_center(from_layer=pin.layer,
to_layer=self.pwr_grid_layer, to_layer=self.pwr_grid_layer,
size=size,
offset=loc, offset=loc,
directions=directions) directions=directions)
# Hack for min area if not width:
if OPTS.tech_name == "sky130":
width = round_to_grid(sqrt(drc["minarea_m3"]))
height = round_to_grid(drc["minarea_m3"] / width)
else:
width = via.width width = via.width
if not height:
height = via.height height = via.height
self.add_layout_pin_rect_center(text=name, self.add_layout_pin_rect_center(text=pin.name,
layer=self.pwr_grid_layer, layer=self.pwr_grid_layer,
offset=loc, offset=loc,
width=width, width=width,

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -11,11 +11,15 @@ import globals
from globals import OPTS,find_exe,get_tool from globals import OPTS,find_exe,get_tool
from .lib import * from .lib import *
from .delay import * from .delay import *
from .elmore import *
from .linear_regression import *
from .setup_hold import * from .setup_hold import *
from .functional import * from .functional import *
from .simulation import * from .simulation import *
from .measurements import * from .measurements import *
from .model_check import * from .model_check import *
from .analytical_util import *
from .regression_model import *
debug.info(1,"Initializing characterizer...") debug.info(1,"Initializing characterizer...")
OPTS.spice_exe = "" OPTS.spice_exe = ""

View File

@ -0,0 +1,310 @@
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import debug
import csv
import math
import numpy as np
import os
process_transform = {'SS':0.0, 'TT': 0.5, 'FF':1.0}
def get_data_names(file_name):
"""
Returns just the data names in the first row of the CSV
"""
with open(file_name, newline='') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
row_iter = 0
# reader is iterable not a list, probably a better way to do this
for row in csv_reader:
# Return names from first row
return row[0].split(',')
def get_data(file_name):
"""
Returns data in CSV as lists of features
"""
with open(file_name, newline='') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
row_iter = 0
for row in csv_reader:
row_iter += 1
if row_iter == 1:
feature_names = row[0].split(',')
input_list = [[] for _ in feature_names]
scaled_list = [[] for _ in feature_names]
try:
process_ind = feature_names.index('process')
except:
debug.error('Process not included as a feature.')
continue
data = []
split_str = row[0].split(',')
for i in range(len(split_str)):
if i == process_ind:
data.append(process_transform[split_str[i]])
else:
data.append(float(split_str[i]))
data[0] = math.log(data[0], 2)
for i in range(len(data)):
input_list[i].append(data[i])
return input_list
def apply_samples_to_data(all_data, algo_samples):
# Take samples from algorithm and match them to samples in data
data_samples, unused_data = [], []
sample_positions = set()
for sample in algo_samples:
sample_positions.add(find_sample_position_with_min_error(all_data, sample))
for i in range(len(all_data)):
if i in sample_positions:
data_samples.append(all_data[i])
else:
unused_data.append(all_data[i])
return data_samples, unused_data
def find_sample_position_with_min_error(data, sampled_vals):
min_error = 0
sample_pos = 0
count = 0
for data_slice in data:
error = squared_error(data_slice, sampled_vals)
if min_error == 0 or error < min_error:
min_error = error
sample_pos = count
count += 1
return sample_pos
def squared_error(list_a, list_b):
error_sum = 0;
for a,b in zip(list_a, list_b):
error_sum+=(a-b)**2
return error_sum
def get_max_min_from_datasets(dir):
if not os.path.isdir(dir):
debug.warning("Input Directory not found:{}".format(dir))
return [], [], []
# Assuming all files are CSV
data_files = [f for f in os.listdir(dir) if os.path.isfile(os.path.join(dir, f))]
maxs,mins,sums,total_count = [],[],[],0
for file in data_files:
data = get_data(os.path.join(dir, file))
# Get max, min, sum, and count from every file
data_max, data_min, data_sum, count = [],[],[], 0
for feature_list in data:
data_max.append(max(feature_list))
data_min.append(min(feature_list))
data_sum.append(sum(feature_list))
count = len(feature_list)
# Aggregate the data
if not maxs or not mins or not sums:
maxs,mins,sums,total_count = data_max,data_min,data_sum,count
else:
for i in range(len(maxs)):
maxs[i] = max(data_max[i], maxs[i])
mins[i] = min(data_min[i], mins[i])
sums[i] = data_sum[i]+sums[i]
total_count+=count
avgs = [s/total_count for s in sums]
return maxs,mins,avgs
def get_max_min_from_file(path):
if not os.path.isfile(path):
debug.warning("Input file not found: {}".format(path))
return [], [], []
data = get_data(path)
# Get max, min, sum, and count from every file
data_max, data_min, data_sum, count = [],[],[], 0
for feature_list in data:
data_max.append(max(feature_list))
data_min.append(min(feature_list))
data_sum.append(sum(feature_list))
count = len(feature_list)
avgs = [s/count for s in data_sum]
return data_max, data_min, avgs
def get_data_and_scale(file_name, sample_dir):
maxs,mins,avgs = get_max_min_from_datasets(sample_dir)
# Get data
all_data = get_data(file_name)
# Scale data from file
self_scaled_data = [[] for _ in range(len(all_data[0]))]
self_maxs,self_mins = [],[]
for feature_list, cur_max, cur_min in zip(all_data,maxs, mins):
for i in range(len(feature_list)):
self_scaled_data[i].append((feature_list[i]-cur_min)/(cur_max-cur_min))
return np.asarray(self_scaled_data)
def rescale_data(data, old_maxs, old_mins, new_maxs, new_mins):
# unscale from old values, rescale by new values
data_new_scaling = []
for data_row in data:
scaled_row = []
for val, old_max,old_min, cur_max, cur_min in zip(data_row, old_maxs,old_mins, new_maxs, new_mins):
unscaled_data = val*(old_max-old_min) + old_min
scaled_row.append((unscaled_data-cur_min)/(cur_max-cur_min))
data_new_scaling.append(scaled_row)
return data_new_scaling
def sample_from_file(num_samples, file_name, sample_dir=None):
"""
Get a portion of the data from CSV file and scale it based on max/min of dataset.
Duplicate samples are trimmed.
"""
if sample_dir:
maxs,mins,avgs = get_max_min_from_datasets(sample_dir)
else:
maxs,mins,avgs = [], [], []
# Get data
all_data = get_data(file_name)
# Get algorithms sample points, assuming hypercube for now
num_labels = 1
inp_dims = len(all_data) - num_labels
samples = np.random.rand(num_samples, inp_dims)
# Scale data from file
self_scaled_data = [[] for _ in range(len(all_data[0]))]
self_maxs,self_mins = [],[]
for feature_list in all_data:
max_val = max(feature_list)
self_maxs.append(max_val)
min_val = min(feature_list)
self_mins.append(min_val)
for i in range(len(feature_list)):
self_scaled_data[i].append((feature_list[i]-min_val)/(max_val-min_val))
# Apply algorithm sampling points to available data
sampled_data, unused_data = apply_samples_to_data(self_scaled_data,samples)
#unscale values and rescale using all available data (both sampled and unused points rescaled)
if len(maxs)!=0 and len(mins)!=0:
sampled_data = rescale_data(sampled_data, self_maxs,self_mins, maxs, mins)
unused_new_scaling = rescale_data(unused_data, self_maxs,self_mins, maxs, mins)
return np.asarray(sampled_data), np.asarray(unused_new_scaling)
def get_scaled_data(file_name):
"""Get data from CSV file and scale it based on max/min of dataset"""
if file_name:
maxs,mins,avgs = get_max_min_from_file(file_name)
else:
maxs,mins,avgs = [], [], []
# Get data
all_data = get_data(file_name)
# Data is scaled by max/min and data format is changed to points vs feature lists
self_scaled_data = scale_data_and_transform(all_data)
samples = np.asarray(self_scaled_data)
features, labels = samples[:, :-1], samples[:,-1:]
return features, labels
def scale_data_and_transform(data):
"""
Assume data is a list of features, change to a list of points and max/min scale
"""
scaled_data = [[] for _ in range(len(data[0]))]
for feature_list in data:
max_val = max(feature_list)
min_val = min(feature_list)
for i in range(len(feature_list)):
if max_val == min_val:
scaled_data[i].append(0.0)
else:
scaled_data[i].append((feature_list[i]-min_val)/(max_val-min_val))
return scaled_data
def scale_input_datapoint(point, file_path):
"""
Input data has no output and needs to be scaled like the model inputs during
training.
"""
maxs, mins, avgs = get_max_min_from_file(file_path)
debug.info(3, "maxs={}".format(maxs))
debug.info(3, "mins={}".format(mins))
debug.info(3, "point={}".format(point))
scaled_point = []
for feature, mx, mn in zip(point, maxs, mins):
if mx == mn:
scaled_point.append(0.0)
else:
scaled_point.append((feature-mn)/(mx-mn))
return scaled_point
def unscale_data(data, file_path, pos=None):
if file_path:
maxs,mins,avgs = get_max_min_from_file(file_path)
else:
debug.error("Must provide reference data to unscale")
return None
# Hard coded to only convert the last max/min (i.e. the label of the data)
if pos == None:
maxs,mins,avgs = [maxs[-1]],[mins[-1]],[avgs[-1]]
else:
maxs,mins,avgs = [maxs[pos]],[mins[pos]],[avgs[pos]]
unscaled_data = []
for data_row in data:
unscaled_row = []
for val, cur_max, cur_min in zip(data_row, maxs, mins):
unscaled_val = val*(cur_max-cur_min) + cur_min
unscaled_row.append(unscaled_val)
unscaled_data.append(unscaled_row)
return unscaled_data
def abs_error(labels, preds):
total_error = 0
for label_i, pred_i in zip(labels, preds):
cur_error = abs(label_i[0]-pred_i[0])/label_i[0]
total_error += cur_error
return total_error/len(labels)
def max_error(labels, preds):
mx_error = 0
for label_i, pred_i in zip(labels, preds):
cur_error = abs(label_i[0]-pred_i[0])/label_i[0]
mx_error = max(cur_error, mx_error)
return mx_error
def min_error(labels, preds):
mn_error = 1
for label_i, pred_i in zip(labels, preds):
cur_error = abs(label_i[0]-pred_i[0])/label_i[0]
mn_error = min(cur_error, mn_error)
return mn_error

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -52,21 +52,6 @@ class delay(simulation):
self.create_signal_names() self.create_signal_names()
self.add_graph_exclusions() self.add_graph_exclusions()
def create_measurement_names(self):
""" Create measurement names. The names themselves currently define the type of measurement """
self.delay_meas_names = ["delay_lh", "delay_hl", "slew_lh", "slew_hl"]
self.power_meas_names = ["read0_power",
"read1_power",
"write0_power",
"write1_power",
"disabled_read0_power",
"disabled_read1_power",
"disabled_write0_power",
"disabled_write1_power"]
# self.voltage_when_names = ["volt_bl", "volt_br"]
# self.bitline_delay_names = ["delay_bl", "delay_br"]
def create_measurement_objects(self): def create_measurement_objects(self):
""" Create the measurements used for read and write ports """ """ Create the measurements used for read and write ports """
@ -525,7 +510,7 @@ class delay(simulation):
elif delay_obj.meta_str == sram_op.READ_ONE: elif delay_obj.meta_str == sram_op.READ_ONE:
meas_cycle_delay = self.cycle_times[self.measure_cycles[port][delay_obj.meta_str]] meas_cycle_delay = self.cycle_times[self.measure_cycles[port][delay_obj.meta_str]]
else: else:
debug.error("Unrecognised delay Index={}".format(delay_obj.meta_str),1) debug.error("Unrecognized delay Index={}".format(delay_obj.meta_str),1)
# These measurements have there time further delayed to the neg. edge of the clock. # These measurements have there time further delayed to the neg. edge of the clock.
if delay_obj.meta_add_delay: if delay_obj.meta_add_delay:
@ -1037,29 +1022,11 @@ class delay(simulation):
""" """
Probe address and data can be set separately to utilize other Probe address and data can be set separately to utilize other
functions in this characterizer besides analyze. functions in this characterizer besides analyze.
Netlist reduced for simulation.
""" """
super().set_probe(probe_address, probe_data)
self.probe_address = probe_address
self.probe_data = probe_data
self.bitline_column = self.get_data_bit_column_number(probe_address, probe_data)
self.wordline_row = self.get_address_row_number(probe_address)
self.prepare_netlist() self.prepare_netlist()
def get_data_bit_column_number(self, probe_address, probe_data):
"""Calculates bitline column number of data bit under test using bit position and mux size"""
if self.sram.col_addr_size>0:
col_address = int(probe_address[0:self.sram.col_addr_size], 2)
else:
col_address = 0
bl_column = int(self.sram.words_per_row * probe_data + col_address)
return bl_column
def get_address_row_number(self, probe_address):
"""Calculates wordline row number of data bit under test using address and column mux size"""
return int(probe_address[self.sram.col_addr_size:], 2)
def prepare_netlist(self): def prepare_netlist(self):
""" Prepare a trimmed netlist and regular netlist. """ """ Prepare a trimmed netlist and regular netlist. """
@ -1303,89 +1270,6 @@ class delay(simulation):
# Add test cycle of read/write port pair. One port could have been used already, but the other has not. # Add test cycle of read/write port pair. One port could have been used already, but the other has not.
self.gen_test_cycles_one_port(cur_read_port, cur_write_port) self.gen_test_cycles_one_port(cur_read_port, cur_write_port)
def sum_delays(self, delays):
"""Adds the delays (delay_data objects) so the correct slew is maintained"""
delay = delays[0]
for i in range(1, len(delays)):
delay+=delays[i]
return delay
def analytical_delay(self, slews, loads):
"""
Return the analytical model results for the SRAM.
"""
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
debug.warning("In analytical mode, all ports have the timing of the first read port.")
# Probe set to 0th bit, does not matter for analytical delay.
self.set_probe('0' * self.addr_size, 0)
self.create_graph()
self.set_internal_spice_names()
self.create_measurement_names()
port = self.read_ports[0]
self.graph.get_all_paths('{}{}'.format("clk", port),
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
# Select the path with the bitline (bl)
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
# Set delay/power for slews and loads
port_data = self.get_empty_measure_data_dict()
power = self.analytical_power(slews, loads)
debug.info(1, 'Slew, Load, Delay(ns), Slew(ns)')
max_delay = 0.0
for slew in slews:
for load in loads:
# Calculate delay based on slew and load
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load)
total_delay = self.sum_delays(path_delays)
max_delay = max(max_delay, total_delay.delay)
debug.info(1,
'{}, {}, {}, {}'.format(slew,
load,
total_delay.delay / 1e3,
total_delay.slew / 1e3))
# Delay is only calculated on a single port and replicated for now.
for port in self.all_ports:
for mname in self.delay_meas_names + self.power_meas_names:
if "power" in mname:
port_data[port][mname].append(power.dynamic)
elif "delay" in mname and port in self.read_ports:
port_data[port][mname].append(total_delay.delay / 1e3)
elif "slew" in mname and port in self.read_ports:
port_data[port][mname].append(total_delay.slew / 1e3)
else:
debug.error("Measurement name not recognized: {}".format(mname), 1)
# Margin for error in period. Calculated by averaging required margin for a small and large
# memory. FIXME: margin is quite large, should be looked into.
period_margin = 1.85
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
"leakage_power": power.leakage}
debug.info(2, "SRAM Data:\n{}".format(sram_data))
debug.info(2, "Port Data:\n{}".format(port_data))
return (sram_data, port_data)
def analytical_power(self, slews, loads):
"""Get the dynamic and leakage power from the SRAM"""
# slews unused, only last load is used
load = loads[-1]
power = self.sram.analytical_power(self.corner, load)
# convert from nW to mW
power.dynamic /= 1e6
power.leakage /= 1e6
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
return power
def gen_data(self): def gen_data(self):
""" Generates the PWL data inputs for a simulation timing test. """ """ Generates the PWL data inputs for a simulation timing test. """
@ -1412,11 +1296,3 @@ class delay(simulation):
self.stim.gen_pwl("CSB{0}".format(port), self.cycle_times, self.csb_values[port], self.period, self.slew, 0.05) self.stim.gen_pwl("CSB{0}".format(port), self.cycle_times, self.csb_values[port], self.period, self.slew, 0.05)
if port in self.readwrite_ports: if port in self.readwrite_ports:
self.stim.gen_pwl("WEB{0}".format(port), self.cycle_times, self.web_values[port], self.period, self.slew, 0.05) self.stim.gen_pwl("WEB{0}".format(port), self.cycle_times, self.web_values[port], self.period, self.slew, 0.05)
def get_empty_measure_data_dict(self):
"""Make a dict of lists for each type of delay and power measurement to append results to"""
measure_names = self.delay_meas_names + self.power_meas_names
# Create list of dicts. List lengths is # of ports. Each dict maps the measurement names to lists.
measure_data = [{mname: [] for mname in measure_names} for i in self.all_ports]
return measure_data

View File

@ -0,0 +1,106 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
from .simulation import simulation
from globals import OPTS
import debug
class elmore(simulation):
"""
Delay model for the SRAM which calculates Elmore delays along the SRAM critical path.
"""
def __init__(self, sram, spfile, corner):
super().__init__(sram, spfile, corner)
# self.targ_read_ports = []
# self.targ_write_ports = []
# self.period = 0
# if self.write_size:
# self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
# else:
# self.num_wmasks = 0
#self.set_load_slew(0, 0)
self.set_corner(corner)
self.create_signal_names()
self.add_graph_exclusions()
def get_lib_values(self, slews, loads):
"""
Return the analytical model results for the SRAM.
"""
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
debug.warning("In analytical mode, all ports have the timing of the first read port.")
# Probe set to 0th bit, does not matter for analytical delay.
self.set_probe('0' * self.addr_size, 0)
self.create_graph()
self.set_internal_spice_names()
self.create_measurement_names()
port = self.read_ports[0]
self.graph.get_all_paths('{}{}'.format("clk", port),
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
# Select the path with the bitline (bl)
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
# Set delay/power for slews and loads
port_data = self.get_empty_measure_data_dict()
power = self.analytical_power(slews, loads)
debug.info(1, 'Slew, Load, Delay(ns), Slew(ns)')
max_delay = 0.0
for slew in slews:
for load in loads:
# Calculate delay based on slew and load
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load)
total_delay = self.sum_delays(path_delays)
max_delay = max(max_delay, total_delay.delay)
debug.info(1,
'{}, {}, {}, {}'.format(slew,
load,
total_delay.delay / 1e3,
total_delay.slew / 1e3))
# Delay is only calculated on a single port and replicated for now.
for port in self.all_ports:
for mname in self.delay_meas_names + self.power_meas_names:
if "power" in mname:
port_data[port][mname].append(power.dynamic)
elif "delay" in mname and port in self.read_ports:
port_data[port][mname].append(total_delay.delay / 1e3)
elif "slew" in mname and port in self.read_ports:
port_data[port][mname].append(total_delay.slew / 1e3)
else:
debug.error("Measurement name not recognized: {}".format(mname), 1)
# Margin for error in period. Calculated by averaging required margin for a small and large
# memory. FIXME: margin is quite large, should be looked into.
period_margin = 1.85
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
"leakage_power": power.leakage}
debug.info(2, "SRAM Data:\n{}".format(sram_data))
debug.info(2, "Port Data:\n{}".format(port_data))
return (sram_data, port_data)
def analytical_power(self, slews, loads):
"""Get the dynamic and leakage power from the SRAM"""
# slews unused, only last load is used
load = loads[-1]
power = self.sram.analytical_power(self.corner, load)
# convert from nW to mW
power.dynamic /= 1e6
power.leakage /= 1e6
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
return power

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -74,26 +74,38 @@ class lib:
self.corners = [] self.corners = []
self.lib_files = [] self.lib_files = []
# Nominal corner if OPTS.use_specified_corners == None:
corner_set = set() # Nominal corner
nom_corner = (nom_process, nom_supply, nom_temperature) corner_tuples = set()
corner_set.add(nom_corner) if OPTS.only_use_config_corners:
if not OPTS.nominal_corner_only: if OPTS.nominal_corner_only:
# Temperature corners debug.warning("Nominal corner only option ignored if use only config corners is set.")
corner_set.add((nom_process, nom_supply, min_temperature)) # Generate a powerset of input PVT lists
corner_set.add((nom_process, nom_supply, max_temperature)) for p in self.process_corners:
# Supply corners for v in self.supply_voltages:
corner_set.add((nom_process, min_supply, nom_temperature)) for t in self.temperatures:
corner_set.add((nom_process, max_supply, nom_temperature)) corner_tuples.add((p, v, t))
# Process corners else:
corner_set.add((min_process, nom_supply, nom_temperature)) nom_corner = (nom_process, nom_supply, nom_temperature)
corner_set.add((max_process, nom_supply, nom_temperature)) corner_tuples.add(nom_corner)
if not OPTS.nominal_corner_only:
# Enforce that nominal corner is the first to be characterized # Temperature corners
self.add_corner(*nom_corner) corner_tuples.add((nom_process, nom_supply, min_temperature))
corner_set.remove(nom_corner) corner_tuples.add((nom_process, nom_supply, max_temperature))
for corner_tuple in corner_set: # Supply corners
corner_tuples.add((nom_process, min_supply, nom_temperature))
corner_tuples.add((nom_process, max_supply, nom_temperature))
# Process corners
corner_tuples.add((min_process, nom_supply, nom_temperature))
corner_tuples.add((max_process, nom_supply, nom_temperature))
# Enforce that nominal corner is the first to be characterized
self.add_corner(*nom_corner)
corner_tuples.remove(nom_corner)
else:
corner_tuples = OPTS.use_specified_corners
for corner_tuple in corner_tuples:
self.add_corner(*corner_tuple) self.add_corner(*corner_tuple)
def add_corner(self, proc, volt, temp): def add_corner(self, proc, volt, temp):
@ -582,18 +594,28 @@ class lib:
def compute_delay(self): def compute_delay(self):
"""Compute SRAM delays for current corner""" """Compute SRAM delays for current corner"""
self.d = delay(self.sram, self.sp_file, self.corner)
if self.use_model: if self.use_model:
char_results = self.d.analytical_delay(self.slews,self.loads) model_name_lc = OPTS.model_name.lower()
self.char_sram_results, self.char_port_results = char_results if model_name_lc == "linear_regression":
from .linear_regression import linear_regression as model
elif model_name_lc == "elmore":
from .elmore import elmore as model
else:
debug.error("{} model not recognized. See options.py for available models.".format(OPTS.model_name))
import math
m = model(self.sram, self.sp_file, self.corner)
char_results = m.get_lib_values(self.slews,self.loads)
else: else:
self.d = delay(self.sram, self.sp_file, self.corner)
if (self.sram.num_spare_rows == 0): if (self.sram.num_spare_rows == 0):
probe_address = "1" * self.sram.addr_size probe_address = "1" * self.sram.addr_size
else: else:
probe_address = "0" + "1" * (self.sram.addr_size - 1) probe_address = "0" + "1" * (self.sram.addr_size - 1)
probe_data = self.sram.word_size - 1 probe_data = self.sram.word_size - 1
char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads) char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
self.char_sram_results, self.char_port_results = char_results self.char_sram_results, self.char_port_results = char_results
def compute_setup_hold(self): def compute_setup_hold(self):
""" Do the analysis if we haven't characterized a FF yet """ """ Do the analysis if we haven't characterized a FF yet """
@ -608,6 +630,79 @@ class lib:
def parse_info(self,corner,lib_name): def parse_info(self,corner,lib_name):
""" Copies important characterization data to datasheet.info to be added to datasheet """ """ Copies important characterization data to datasheet.info to be added to datasheet """
if OPTS.output_datasheet_info:
datasheet_path = OPTS.output_path
else:
datasheet_path = OPTS.openram_temp
datasheet = open(datasheet_path +'/datasheet.info', 'a+')
self.write_inp_params_datasheet(datasheet, corner, lib_name)
self.write_signal_from_ports(datasheet,
"din{1}[{0}:0]".format(self.sram.word_size - 1, '{}'),
self.write_ports,
"setup_times_LH",
"setup_times_HL",
"hold_times_LH",
"hold_times_HL")
# self.write_signal_from_ports(datasheet,
# "dout{1}[{0}:0]".format(self.sram.word_size - 1, '{}'),
# self.read_ports,
# "delay_lh",
# "delay_hl",
# "slew_lh",
# "slew_hl")
for port in self.all_ports:
#dout timing
if port in self.read_ports:
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"dout{1}[{0}:0]".format(self.sram.word_size - 1, port),
min(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
max(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
min(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
max(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
min(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
max(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
min(list(map(round_time,self.char_port_results[port]["slew_hl"]))),
max(list(map(round_time,self.char_port_results[port]["slew_hl"])))
))
self.write_signal_from_ports(datasheet,
"csb{}",
self.all_ports,
"setup_times_LH",
"setup_times_HL",
"hold_times_LH",
"hold_times_HL")
self.write_signal_from_ports(datasheet,
"addr{1}[{0}:0]".format(self.sram.addr_size - 1, '{}'),
self.all_ports,
"setup_times_LH",
"setup_times_HL",
"hold_times_LH",
"hold_times_HL")
self.write_signal_from_ports(datasheet,
"web{}",
self.readwrite_ports,
"setup_times_LH",
"setup_times_HL",
"hold_times_LH",
"hold_times_HL")
self.write_power_datasheet(datasheet)
self.write_model_params(datasheet)
datasheet.write("END\n")
datasheet.close()
def write_inp_params_datasheet(self, datasheet, corner, lib_name):
if OPTS.is_unit_test: if OPTS.is_unit_test:
git_id = 'FFFFFFFFFFFFFFFFFFFF' git_id = 'FFFFFFFFFFFFFFFFFFFF'
@ -625,11 +720,9 @@ class lib:
# check if git id is valid # check if git id is valid
if len(git_id) != 40: if len(git_id) != 40:
debug.warning("Failed to retrieve git id") debug.warning("Failed to retrieve git id")
git_id = 'Failed to retruieve' git_id = 'Failed to retrieve'
datasheet = open(OPTS.openram_temp +'/datasheet.info', 'a+')
current_time = datetime.date.today() current_time = datetime.date.today()
# write static information to be parser later # write static information to be parser later
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},".format( datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},".format(
OPTS.output_name, OPTS.output_name,
@ -657,104 +750,26 @@ class lib:
# write area # write area
datasheet.write(str(self.sram.width * self.sram.height) + ',') datasheet.write(str(self.sram.width * self.sram.height) + ',')
# write timing information for all ports def write_signal_from_ports(self, datasheet, signal, ports, time_pos_1, time_pos_2, time_pos_3, time_pos_4):
for port in self.all_ports: for port in ports:
#din timings
if port in self.write_ports:
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"din{1}[{0}:0]".format(self.sram.word_size - 1, port),
min(list(map(round_time,self.times["setup_times_LH"]))),
max(list(map(round_time,self.times["setup_times_LH"]))),
min(list(map(round_time,self.times["setup_times_HL"]))),
max(list(map(round_time,self.times["setup_times_HL"]))),
min(list(map(round_time,self.times["hold_times_LH"]))),
max(list(map(round_time,self.times["hold_times_LH"]))),
min(list(map(round_time,self.times["hold_times_HL"]))),
max(list(map(round_time,self.times["hold_times_HL"])))
))
for port in self.all_ports:
#dout timing
if port in self.read_ports:
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"dout{1}[{0}:0]".format(self.sram.word_size - 1, port),
min(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
max(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
min(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
max(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
min(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
max(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
min(list(map(round_time,self.char_port_results[port]["slew_hl"]))),
max(list(map(round_time,self.char_port_results[port]["slew_hl"])))
))
for port in self.all_ports:
#csb timings
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format( datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"csb{0}".format(port), signal.format(port),
min(list(map(round_time,self.times["setup_times_LH"]))), min(list(map(round_time,self.times[time_pos_1]))),
max(list(map(round_time,self.times["setup_times_LH"]))), max(list(map(round_time,self.times[time_pos_1]))),
min(list(map(round_time,self.times["setup_times_HL"]))), min(list(map(round_time,self.times[time_pos_2]))),
max(list(map(round_time,self.times["setup_times_HL"]))), max(list(map(round_time,self.times[time_pos_2]))),
min(list(map(round_time,self.times["hold_times_LH"]))), min(list(map(round_time,self.times[time_pos_3]))),
max(list(map(round_time,self.times["hold_times_LH"]))), max(list(map(round_time,self.times[time_pos_3]))),
min(list(map(round_time,self.times["hold_times_HL"]))), min(list(map(round_time,self.times[time_pos_4]))),
max(list(map(round_time,self.times["hold_times_HL"]))) max(list(map(round_time,self.times[time_pos_4])))
)) ))
for port in self.all_ports: def write_power_datasheet(self, datasheet):
#addr timings
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"addr{1}[{0}:0]".format(self.sram.addr_size - 1, port),
min(list(map(round_time,self.times["setup_times_LH"]))),
max(list(map(round_time,self.times["setup_times_LH"]))),
min(list(map(round_time,self.times["setup_times_HL"]))),
max(list(map(round_time,self.times["setup_times_HL"]))),
min(list(map(round_time,self.times["hold_times_LH"]))),
max(list(map(round_time,self.times["hold_times_LH"]))),
min(list(map(round_time,self.times["hold_times_HL"]))),
max(list(map(round_time,self.times["hold_times_HL"])))
))
for port in self.all_ports:
if port in self.readwrite_ports:
#web timings
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
"web{0}".format(port),
min(list(map(round_time,self.times["setup_times_LH"]))),
max(list(map(round_time,self.times["setup_times_LH"]))),
min(list(map(round_time,self.times["setup_times_HL"]))),
max(list(map(round_time,self.times["setup_times_HL"]))),
min(list(map(round_time,self.times["hold_times_LH"]))),
max(list(map(round_time,self.times["hold_times_LH"]))),
min(list(map(round_time,self.times["hold_times_HL"]))),
max(list(map(round_time,self.times["hold_times_HL"])))
))
# write power information # write power information
for port in self.all_ports: for port in self.all_ports:
name = '' name = ''
@ -793,7 +808,31 @@ class lib:
control_str += ' & csb{0}'.format(i) control_str += ' & csb{0}'.format(i)
datasheet.write("{0},{1},{2},".format('leak', control_str, self.char_sram_results["leakage_power"])) datasheet.write("{0},{1},{2},".format('leak', control_str, self.char_sram_results["leakage_power"]))
def write_model_params(self, datasheet):
datasheet.write("END\n") """Write values which will be used in the analytical model as inputs"""
datasheet.close() datasheet.write("{0},{1},".format('words_per_row', OPTS.words_per_row))
datasheet.write("{0},{1},".format('slews', list(self.slews)))
datasheet.write("{0},{1},".format('loads', list(self.loads)))
for port in self.read_ports:
datasheet.write("{0},{1},".format('cell_rise_{}'.format(port), self.char_port_results[port]["delay_lh"]))
datasheet.write("{0},{1},".format('cell_fall_{}'.format(port), self.char_port_results[port]["delay_hl"]))
datasheet.write("{0},{1},".format('rise_transition_{}'.format(port), self.char_port_results[port]["slew_lh"]))
datasheet.write("{0},{1},".format('fall_transition_{}'.format(port), self.char_port_results[port]["slew_hl"]))
for port in self.write_ports:
write1_power = np.mean(self.char_port_results[port]["write1_power"])
write0_power = np.mean(self.char_port_results[port]["write0_power"])
datasheet.write("{0},{1},".format('write_rise_power_{}'.format(port), write1_power))
#FIXME: should be write_fall_power
datasheet.write("{0},{1},".format('read_fall_power_{}'.format(port), write0_power))
for port in self.read_ports:
read1_power = np.mean(self.char_port_results[port]["read1_power"])
read0_power = np.mean(self.char_port_results[port]["read0_power"])
datasheet.write("{0},{1},".format('read_rise_power_{}'.format(port), read1_power))
#FIXME: should be read_fall_power
datasheet.write("{0},{1},".format('write_fall_power_{}'.format(port), read0_power))

View File

@ -0,0 +1,38 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
from .regression_model import regression_model
from globals import OPTS
import debug
from sklearn.linear_model import LinearRegression
class linear_regression(regression_model):
def __init__(self, sram, spfile, corner):
super().__init__(sram, spfile, corner)
def generate_model(self, features, labels):
"""
Supervised training of model.
"""
model = LinearRegression()
model.fit(features, labels)
return model
def model_prediction(self, model, features):
"""
Have the model perform a prediction and unscale the prediction
as the model is trained with scaled values.
"""
pred = model.predict(features)
return pred

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -0,0 +1,48 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
from .regression_model import regression_model
from globals import OPTS
import debug
from tensorflow import keras
from tensorflow.keras import layers
import tensorflow as tf
class neural_network(regression_model):
def __init__(self, sram, spfile, corner):
super().__init__(sram, spfile, corner)
def generate_model(self, features, labels):
"""
Supervised training of model.
"""
model = keras.Sequential([
layers.Dense(32, activation=tf.nn.relu, input_shape=[features.shape[1]]),
layers.Dense(32, activation=tf.nn.relu),
layers.Dense(32, activation=tf.nn.relu),
layers.Dense(1)
])
optimizer = keras.optimizers.RMSprop(0.0099)
model.compile(loss='mean_squared_error', optimizer=optimizer)
model.fit(features, labels, epochs=100, verbose=0)
return model
def model_prediction(self, model, features):
"""
Have the model perform a prediction and unscale the prediction
as the model is trained with scaled values.
"""
pred = model.predict(features)
return pred

View File

@ -0,0 +1,140 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
from .analytical_util import *
from .simulation import simulation
from globals import OPTS
import debug
import math
relative_data_path = "/sim_data"
data_fnames = ["rise_delay.csv",
"fall_delay.csv",
"rise_slew.csv",
"fall_slew.csv",
"write1_power.csv",
"write0_power.csv",
"read1_power.csv",
"read0_power.csv",
"leakage_data.csv"]
# Positions must correspond to data_fname list
lib_dnames = ["delay_lh",
"delay_hl",
"slew_lh",
"slew_hl",
"write1_power",
"write0_power",
"read1_power",
"read0_power",
"leakage_power"]
# Check if another data dir was specified
if OPTS.sim_data_path == None:
data_dir = OPTS.openram_tech+relative_data_path
else:
data_dir = OPTS.sim_data_path
data_paths = {dname:data_dir +'/'+fname for dname, fname in zip(lib_dnames, data_fnames)}
class regression_model(simulation):
def __init__(self, sram, spfile, corner):
super().__init__(sram, spfile, corner)
self.set_corner(corner)
def get_lib_values(self, slews, loads):
"""
A model and prediction is created for each output needed for the LIB
"""
debug.info(1, "Characterizing SRAM using linear regression models.")
log_num_words = math.log(OPTS.num_words, 2)
model_inputs = [log_num_words,
OPTS.word_size,
OPTS.words_per_row,
self.sram.width * self.sram.height,
process_transform[self.process],
self.vdd_voltage,
self.temperature]
self.create_measurement_names()
models = self.train_models()
# Set delay/power for slews and loads
port_data = self.get_empty_measure_data_dict()
debug.info(1, 'Slew, Load, Port, Delay(ns), Slew(ns)')
max_delay = 0.0
for slew in slews:
for load in loads:
# List returned with value order being delay, power, leakage, slew
sram_vals = self.get_predictions(model_inputs+[slew, load], models)
# Delay is only calculated on a single port and replicated for now.
for port in self.all_ports:
port_data[port]['delay_lh'].append(sram_vals['delay_lh'])
port_data[port]['delay_hl'].append(sram_vals['delay_hl'])
port_data[port]['slew_lh'].append(sram_vals['slew_lh'])
port_data[port]['slew_hl'].append(sram_vals['slew_hl'])
port_data[port]['write1_power'].append(sram_vals['write1_power'])
port_data[port]['write0_power'].append(sram_vals['write0_power'])
port_data[port]['read1_power'].append(sram_vals['read1_power'])
port_data[port]['read0_power'].append(sram_vals['read0_power'])
# Disabled power not modeled. Copied from other power predictions
port_data[port]['disabled_write1_power'].append(sram_vals['write1_power'])
port_data[port]['disabled_write0_power'].append(sram_vals['write0_power'])
port_data[port]['disabled_read1_power'].append(sram_vals['read1_power'])
port_data[port]['disabled_read0_power'].append(sram_vals['read0_power'])
debug.info(1, '{}, {}, {}, {}, {}'.format(slew,
load,
port,
sram_vals['delay_lh'],
sram_vals['slew_lh']))
# Estimate the period as double the delay with margin
period_margin = 0.1
sram_data = {"min_period": sram_vals['delay_lh'] * 2,
"leakage_power": sram_vals["leakage_power"]}
debug.info(2, "SRAM Data:\n{}".format(sram_data))
debug.info(2, "Port Data:\n{}".format(port_data))
return (sram_data, port_data)
def get_predictions(self, model_inputs, models):
"""
Generate a model and prediction for LIB output
"""
#Scaled the inputs using first data file as a reference
data_name = lib_dnames[0]
scaled_inputs = np.asarray([scale_input_datapoint(model_inputs, data_paths[data_name])])
predictions = {}
for dname in data_paths.keys():
path = data_paths[dname]
m = models[dname]
features, labels = get_scaled_data(path)
scaled_pred = self.model_prediction(m, scaled_inputs)
pred = unscale_data(scaled_pred.tolist(), path)
debug.info(2,"Unscaled Prediction = {}".format(pred))
predictions[dname] = pred[0][0]
return predictions
def train_models(self):
"""
Generate and return models
"""
models = {}
for dname, dpath in data_paths.items():
features, labels = get_scaled_data(dpath)
model = self.generate_model(features, labels)
models[dname] = model
return models

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -39,6 +39,21 @@ class simulation():
else: else:
self.num_wmasks = 0 self.num_wmasks = 0
def create_measurement_names(self):
""" Create measurement names. The names themselves currently define the type of measurement """
self.delay_meas_names = ["delay_lh", "delay_hl", "slew_lh", "slew_hl"]
self.power_meas_names = ["read0_power",
"read1_power",
"write0_power",
"write1_power",
"disabled_read0_power",
"disabled_read1_power",
"disabled_write0_power",
"disabled_write1_power"]
# self.voltage_when_names = ["volt_bl", "volt_br"]
# self.bitline_delay_names = ["delay_bl", "delay_br"]
def set_corner(self, corner): def set_corner(self, corner):
""" Set the corner values """ """ Set the corner values """
self.corner = corner self.corner = corner
@ -92,6 +107,32 @@ class simulation():
self.cycle_comments = [] self.cycle_comments = []
self.fn_cycle_comments = [] self.fn_cycle_comments = []
def set_probe(self, probe_address, probe_data):
"""
Probe address and data can be set separately to utilize other
functions in this characterizer besides analyze.
"""
self.probe_address = probe_address
self.probe_data = probe_data
self.bitline_column = self.get_data_bit_column_number(probe_address, probe_data)
self.wordline_row = self.get_address_row_number(probe_address)
def get_data_bit_column_number(self, probe_address, probe_data):
"""Calculates bitline column number of data bit under test using bit position and mux size"""
if self.sram.col_addr_size>0:
col_address = int(probe_address[0:self.sram.col_addr_size], 2)
else:
col_address = 0
bl_column = int(self.sram.words_per_row * probe_data + col_address)
return bl_column
def get_address_row_number(self, probe_address):
"""Calculates wordline row number of data bit under test using address and column mux size"""
return int(probe_address[self.sram.col_addr_size:], 2)
def add_control_one_port(self, port, op): def add_control_one_port(self, port, op):
"""Appends control signals for operation to a given port""" """Appends control signals for operation to a given port"""
# Determine values to write to port # Determine values to write to port
@ -544,6 +585,21 @@ class simulation():
for i in range(len(bl_names)): for i in range(len(bl_names)):
bl_names[i] = bl_names[i].split('.')[-1] bl_names[i] = bl_names[i].split('.')[-1]
return bl_names[0], bl_names[1] return bl_names[0], bl_names[1]
def get_empty_measure_data_dict(self):
"""Make a dict of lists for each type of delay and power measurement to append results to"""
measure_names = self.delay_meas_names + self.power_meas_names
# Create list of dicts. List lengths is # of ports. Each dict maps the measurement names to lists.
measure_data = [{mname: [] for mname in measure_names} for i in self.all_ports]
return measure_data
def sum_delays(self, delays):
"""Adds the delays (delay_data objects) so the correct slew is maintained"""
delay = delays[0]
for i in range(1, len(delays)):
delay+=delays[i]
return delay

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -312,12 +312,12 @@ class stimuli():
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt {3}".format(OPTS.spice_exe, cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt {3}".format(OPTS.spice_exe,
temp_stim, temp_stim,
OPTS.openram_temp, OPTS.openram_temp,
OPTS.num_threads) OPTS.num_sim_threads)
valid_retcode=0 valid_retcode=0
elif OPTS.spice_name == "hspice": elif OPTS.spice_name == "hspice":
# TODO: Should make multithreading parameter a configuration option # TODO: Should make multithreading parameter a configuration option
cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe, cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe,
OPTS.num_threads, OPTS.num_sim_threads,
temp_stim, temp_stim,
OPTS.openram_temp) OPTS.openram_temp)
valid_retcode=0 valid_retcode=0
@ -326,7 +326,7 @@ class stimuli():
# Measurements can't be made with a raw file set in ngspice # Measurements can't be made with a raw file set in ngspice
# -r {2}timing.raw # -r {2}timing.raw
ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w") ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w")
ng_cfg.write("set num_threads={}\n".format(OPTS.num_threads)) ng_cfg.write("set num_threads={}\n".format(OPTS.num_sim_threads))
ng_cfg.close() ng_cfg.close()
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe, cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -28,7 +28,11 @@ class datasheet():
# css styling is kept in a seperate file # css styling is kept in a seperate file
self.html += datasheet_css.read() self.html += datasheet_css.read()
with open(OPTS.openram_temp + "/datasheet.info") as info: if OPTS.output_datasheet_info:
datasheet_path = OPTS.output_path
else:
datasheet_path = OPTS.openram_temp
with open(datasheet_path + "/datasheet.info") as info:
self.html += '<!--' self.html += '<!--'
for row in info: for row in info:
self.html += row self.html += row

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -633,13 +633,16 @@ def parse_characterizer_csv(f, pages):
class datasheet_gen(): class datasheet_gen():
def datasheet_write(name): def datasheet_write(name):
"""writes the datasheet to a file""" """writes the datasheet to a file"""
in_dir = OPTS.openram_temp if OPTS.output_datasheet_info:
datasheet_path = OPTS.output_path
else:
datasheet_path = OPTS.openram_temp
if not (os.path.isdir(in_dir)): if not (os.path.isdir(datasheet_path)):
os.mkdir(in_dir) os.mkdir(datasheet_path)
datasheets = [] datasheets = []
parse_characterizer_csv(in_dir + "/datasheet.info", datasheets) parse_characterizer_csv(datasheet_path + "/datasheet.info", datasheets)
for sheets in datasheets: for sheets in datasheets:
with open(name, 'w+') as f: with open(name, 'w+') as f:

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -115,7 +115,7 @@ def bp():
Usage: Usage:
1) Add a breakpoint anywhere in your code with "import debug; debug.bp()". 1) Add a breakpoint anywhere in your code with "import debug; debug.bp()".
2) Run "python3 -m pdb openram.py config.py" or "python3 -m pdb 05_bitcell_array.test" (for example) 2) Run "python3 -m pdb openram.py config.py" or "python3 -m pdb 05_bitcell_array.test" (for example)
3) When pdb starts, run "break debug.py" to set a SOFT breakpoint. (Or you can add this to your ~/.pdbrc) 3) When pdb starts, run "break debug.bp" to set a SOFT breakpoint. (Or you can add this to your ~/.pdbrc)
4) Then run "cont" to continue. 4) Then run "cont" to continue.
5) You can now set additional breakpoints or display commands 5) You can now set additional breakpoints or display commands
and whenever you encounter the debug.bp() they won't be "reset". and whenever you encounter the debug.bp() they won't be "reset".

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -18,6 +18,8 @@ import sys
import re import re
import copy import copy
import importlib import importlib
import getpass
VERSION = "1.1.9" VERSION = "1.1.9"
NAME = "OpenRAM v{}".format(VERSION) NAME = "OpenRAM v{}".format(VERSION)
@ -113,6 +115,10 @@ def parse_args():
if OPTS.tech_name == "s8": if OPTS.tech_name == "s8":
OPTS.tech_name = "sky130" OPTS.tech_name = "sky130"
if OPTS.openram_temp:
# If they define the temp directory, we can only use one thread at a time!
OPTS.num_threads = 1
return (options, args) return (options, args)
@ -133,8 +139,9 @@ def print_banner():
debug.print_raw("|=========" + user_info.center(60) + "=========|") debug.print_raw("|=========" + user_info.center(60) + "=========|")
dev_info = "Development help: openram-dev-group@ucsc.edu" dev_info = "Development help: openram-dev-group@ucsc.edu"
debug.print_raw("|=========" + dev_info.center(60) + "=========|") debug.print_raw("|=========" + dev_info.center(60) + "=========|")
temp_info = "Temp dir: {}".format(OPTS.openram_temp) if OPTS.openram_temp:
debug.print_raw("|=========" + temp_info.center(60) + "=========|") temp_info = "Temp dir: {}".format(OPTS.openram_temp)
debug.print_raw("|=========" + temp_info.center(60) + "=========|")
debug.print_raw("|=========" + "See LICENSE for license info".center(60) + "=========|") debug.print_raw("|=========" + "See LICENSE for license info".center(60) + "=========|")
debug.print_raw("|==============================================================================|") debug.print_raw("|==============================================================================|")
@ -414,6 +421,10 @@ def setup_paths():
if "__pycache__" not in full_path: if "__pycache__" not in full_path:
sys.path.append("{0}".format(full_path)) sys.path.append("{0}".format(full_path))
# Use a unique temp directory
if not OPTS.openram_temp:
OPTS.openram_temp = "/tmp/openram_{0}_{1}_temp/".format(getpass.getuser(),
os.getpid())
if not OPTS.openram_temp.endswith('/'): if not OPTS.openram_temp.endswith('/'):
OPTS.openram_temp += "/" OPTS.openram_temp += "/"
debug.info(1, "Temporary files saved in " + OPTS.openram_temp) debug.info(1, "Temporary files saved in " + OPTS.openram_temp)

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -615,9 +615,7 @@ class bank(design.design):
for pin_name in ["vdd", "gnd"]: for pin_name in ["vdd", "gnd"]:
pin_list = inst.get_pins(pin_name) pin_list = inst.get_pins(pin_name)
for pin in pin_list: for pin in pin_list:
self.add_power_pin(pin_name, self.copy_power_pin(pin, pin.center())
pin.center(),
start_layer=pin.layer)
def route_bank_select(self, port): def route_bank_select(self, port):
""" Route the bank select logic. """ """ Route the bank select logic. """

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California # Copyright (c) 2016-2021 Regents of the University of California
# All rights reserved. # All rights reserved.
# #
from bitcell_base_array import bitcell_base_array from bitcell_base_array import bitcell_base_array
@ -100,7 +100,5 @@ class col_cap_array(bitcell_base_array):
inst = self.cell_inst[row, col] inst = self.cell_inst[row, col]
for pin_name in ["vdd", "gnd"]: for pin_name in ["vdd", "gnd"]:
for pin in inst.get_pins(pin_name): for pin in inst.get_pins(pin_name):
self.add_power_pin(name=pin_name, self.copy_power_pin(pin)
loc=pin.center(),
start_layer=pin.layer)

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -177,14 +177,10 @@ class delay_chain(design.design):
load_list = self.load_inst_map[inst] load_list = self.load_inst_map[inst]
for pin_name in ["vdd", "gnd"]: for pin_name in ["vdd", "gnd"]:
pin = load_list[0].get_pin(pin_name) pin = load_list[0].get_pin(pin_name)
self.add_power_pin(pin_name, self.copy_power_pin(pin, loc=pin.rc() - vector(self.m1_pitch, 0))
pin.rc() - vector(self.m1_pitch, 0),
start_layer=pin.layer)
pin = load_list[-2].get_pin(pin_name) pin = load_list[-2].get_pin(pin_name)
self.add_power_pin(pin_name, self.copy_power_pin(pin, loc=pin.rc() - vector(self.m1_pitch, 0))
pin.rc() - vector(self.m1_pitch, 0),
start_layer=pin.layer)
def add_layout_pins(self): def add_layout_pins(self):

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -112,11 +112,11 @@ class dff_array(design.design):
for col in range(self.columns): for col in range(self.columns):
# Continous vdd rail along with label. # Continous vdd rail along with label.
vdd_pin=self.dff_insts[row, col].get_pin("vdd") vdd_pin=self.dff_insts[row, col].get_pin("vdd")
self.add_power_pin("vdd", vdd_pin.center(), start_layer=vdd_pin.layer) self.copy_power_pin(vdd_pin)
# Continous gnd rail along with label. # Continous gnd rail along with label.
gnd_pin=self.dff_insts[row, col].get_pin("gnd") gnd_pin=self.dff_insts[row, col].get_pin("gnd")
self.add_power_pin("gnd", gnd_pin.center(), start_layer=gnd_pin.layer) self.copy_power_pin(gnd_pin)
for row in range(self.rows): for row in range(self.rows):
for col in range(self.columns): for col in range(self.columns):

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -159,11 +159,11 @@ class dff_buf_array(design.design):
for col in range(self.columns): for col in range(self.columns):
# Continous vdd rail along with label. # Continous vdd rail along with label.
vdd_pin=self.dff_insts[row, col].get_pin("vdd") vdd_pin=self.dff_insts[row, col].get_pin("vdd")
self.add_power_pin("vdd", vdd_pin.lc(), start_layer=vdd_pin.layer) self.copy_power_pin(vdd_pin, loc=vdd_pin.lc())
# Continous gnd rail along with label. # Continous gnd rail along with label.
gnd_pin=self.dff_insts[row, col].get_pin("gnd") gnd_pin=self.dff_insts[row, col].get_pin("gnd")
self.add_power_pin("gnd", gnd_pin.lc(), start_layer=gnd_pin.layer) self.copy_power_pin(gnd_pin, loc=gnd_pin.lc())
def add_layout_pins(self): def add_layout_pins(self):

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,17 +1,16 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
# #
import debug import debug
import design import design
from tech import drc
from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
import dff_inv from sram_factory import factory
class dff_inv_array(design.design): class dff_inv_array(design.design):
""" """
@ -130,12 +129,11 @@ class dff_inv_array(design.design):
for col in range(self.columns): for col in range(self.columns):
# Adds power pin on left of row # Adds power pin on left of row
vdd_pin=self.dff_insts[row,col].get_pin("vdd") vdd_pin=self.dff_insts[row,col].get_pin("vdd")
self.add_power_pin("vdd", vdd_pin.lc()) self.add_power_pin(vdd_pin, loc=vdd_pin.lc())
# Adds gnd pin on left of row # Adds gnd pin on left of row
gnd_pin=self.dff_insts[row,col].get_pin("gnd") gnd_pin=self.dff_insts[row,col].get_pin("gnd")
self.add_power_pin("gnd", gnd_pin.lc()) self.add_power_pin(gnd_pin, loc=gnd_pin.lc())
for row in range(self.rows): for row in range(self.rows):
for col in range(self.columns): for col in range(self.columns):

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California # Copyright (c) 2016-2021 Regents of the University of California
# All rights reserved. # All rights reserved.
# #
from bitcell_base_array import bitcell_base_array from bitcell_base_array import bitcell_base_array

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -611,12 +611,7 @@ class hierarchical_decoder(design.design):
for i in self.and_inst[:-1]: for i in self.and_inst[:-1]:
pins = i.get_pins(n) pins = i.get_pins(n)
for pin in pins: for pin in pins:
self.add_power_pin(name=n, self.copy_power_pin(pin, loc=pin.uc())
loc=pin.uc(),
start_layer=pin.layer)
self.add_power_pin(name=n,
loc=pin.uc(),
start_layer=pin.layer)
for i in self.pre2x4_inst + self.pre3x8_inst: for i in self.pre2x4_inst + self.pre3x8_inst:
self.copy_layout_pin(i, n) self.copy_layout_pin(i, n)
@ -628,9 +623,7 @@ class hierarchical_decoder(design.design):
# The nand and inv are the same height rows... # The nand and inv are the same height rows...
supply_pin = self.and_inst[row].get_pin(pin_name) supply_pin = self.and_inst[row].get_pin(pin_name)
pin_pos = vector(xoffset, supply_pin.cy()) pin_pos = vector(xoffset, supply_pin.cy())
self.add_power_pin(name=pin_name, self.copy_power_pin(supply_pin, loc=pin_pos)
loc=pin_pos,
start_layer=supply_pin.layer)
# Copy the pins from the predecoders # Copy the pins from the predecoders
for pre in self.pre2x4_inst + self.pre3x8_inst + self.pre4x16_inst: for pre in self.pre2x4_inst + self.pre3x8_inst + self.pre4x16_inst:

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -330,12 +330,7 @@ class hierarchical_predecode(design.design):
for i in self.inv_inst[:-1:2] + self.and_inst[:-1:2]: for i in self.inv_inst[:-1:2] + self.and_inst[:-1:2]:
pins = i.get_pins(n) pins = i.get_pins(n)
for pin in pins: for pin in pins:
self.add_power_pin(name=n, self.copy_power_pin(pin, loc=pin.uc())
loc=pin.uc(),
start_layer=pin.layer)
self.add_power_pin(name=n,
loc=pin.uc(),
start_layer=pin.layer)
# In other techs, we are using standard cell decoder cells with horizontal power # In other techs, we are using standard cell decoder cells with horizontal power
else: else:
@ -353,9 +348,7 @@ class hierarchical_predecode(design.design):
for xoffset in [self.inv_inst[0].lx() - self.bus_space, for xoffset in [self.inv_inst[0].lx() - self.bus_space,
self.and_inst[0].lx() - self.bus_space]: self.and_inst[0].lx() - self.bus_space]:
pin_pos = vector(xoffset, and_pin.cy()) pin_pos = vector(xoffset, and_pin.cy())
self.add_power_pin(name=n, self.copy_power_pin(and_pin, loc=pin_pos)
loc=pin_pos,
start_layer=and_pin.layer)

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
@ -186,9 +186,7 @@ class local_bitcell_array(bitcell_base_array.bitcell_base_array):
for inst in supply_insts: for inst in supply_insts:
pin_list = inst.get_pins(pin_name) pin_list = inst.get_pins(pin_name)
for pin in pin_list: for pin in pin_list:
self.add_power_pin(name=pin_name, self.copy_power_pin(pin)
loc=pin.center(),
start_layer=pin.layer)
def route(self): def route(self):

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California and The Board # Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College # of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California # Copyright (c) 2016-2021 Regents of the University of California
# All rights reserved. # All rights reserved.
# #
from math import log, ceil from math import log, ceil
@ -82,9 +82,9 @@ class port_address(design.design):
for rbl_vdd_pin in self.rbl_driver_inst.get_pins("vdd"): for rbl_vdd_pin in self.rbl_driver_inst.get_pins("vdd"):
if layer_props.port_address.supply_offset: if layer_props.port_address.supply_offset:
self.add_power_pin("vdd", rbl_vdd_pin.center()) self.copy_power_pin(rbl_vdd_pin)
else: else:
self.add_power_pin("vdd", rbl_vdd_pin.lc()) self.copy_power_pin(rbl_vdd_pin, loc=rbl_vdd_pin.lc())
# Also connect the B input of the RBL and_dec to vdd # Also connect the B input of the RBL and_dec to vdd
if OPTS.local_array_size == 0: if OPTS.local_array_size == 0:

View File

@ -1,6 +1,6 @@
# See LICENSE for licensing information. # See LICENSE for licensing information.
# #
# Copyright (c) 2016-2019 Regents of the University of California # Copyright (c) 2016-2021 Regents of the University of California
# All rights reserved. # All rights reserved.
# #
from tech import drc from tech import drc

Some files were not shown because too many files have changed in this diff Show More