Merge branch 'dev' into char

This commit is contained in:
Bugra Onal
2022-11-29 14:50:00 -08:00
99 changed files with 1862 additions and 336 deletions
+1 -1
View File
@@ -95,7 +95,7 @@ model: $(STAMPS)
$(eval bname=$(basename $(notdir $@)))
$(eval config_path=$(CONFIG_DIR)/$(addsuffix .py, $(notdir $(basename $@))))
mkdir -p $(SIM_DIR)/$(bname)
-python3 $(OPENRAM_HOME)/openram.py $(OPTS) -p $(SIM_DIR)/$(bname) -o $(bname) -t $(TECH) $(config_path) 2>&1 > /dev/null
-python3 $(OPENRAM_HOME)/../sram_compiler.py $(OPTS) -p $(SIM_DIR)/$(bname) -o $(bname) -t $(TECH) $(config_path) 2>&1 > /dev/null
touch $@
clean_model:
+1 -1
View File
@@ -131,7 +131,7 @@ def bp():
An empty function so you can set soft breakpoints in pdb.
Usage:
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 sram_compiler.py config.py" or "python3 -m pdb 05_bitcell_array.test" (for example)
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.
5) You can now set additional breakpoints or display commands
+9
View File
@@ -186,12 +186,15 @@ class cell_properties():
self.names["col_cap_bitcell_2port"] = "col_cap_cell_2rw"
self.names["row_cap_bitcell_1port"] = "row_cap_cell_1rw"
self.names["row_cap_bitcell_2port"] = "row_cap_cell_2rw"
self.names["internal"] = "internal"
self.use_strap = False
self._ptx = _ptx(model_is_subckt=False,
bin_spice_models=False)
self._pgate = _pgate(add_implants=False)
self._inv_dec = cell(["A", "Z", "vdd", "gnd"],
["INPUT", "OUTPUT", "POWER", "GROUND"])
@@ -231,6 +234,12 @@ class cell_properties():
self._row_cap_2port = bitcell(["wl0", "wl1", "gnd"],
["INPUT", "INPUT", "POWER", "GROUND"])
self._internal = cell([],[])
@property
def internal(self):
return self._internal
@property
def ptx(self):
return self._ptx
+31 -8
View File
@@ -24,7 +24,7 @@ import subprocess
VERSION = "1.2.0"
NAME = "OpenRAM v{}".format(VERSION)
USAGE = "openram.py [options] <config file>\nUse -h for help.\n"
USAGE = "sram_compiler.py [options] <config file>\nUse -h for help.\n"
OPTS = options.options()
CHECKPOINT_OPTS = None
@@ -141,9 +141,6 @@ def print_banner():
debug.print_raw("|=========" + user_info.center(60) + "=========|")
dev_info = "Development help: [email protected]"
debug.print_raw("|=========" + dev_info.center(60) + "=========|")
if OPTS.openram_temp:
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("|==============================================================================|")
@@ -432,16 +429,23 @@ def setup_paths():
global OPTS
# If $OPENRAM_HOME is defined, use that path for the source code.
# Otherwise, use the openram package.
try:
OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME"))
except:
debug.error("$OPENRAM_HOME is not properly defined.", 1)
import openram
OPENRAM_HOME = os.path.dirname(openram.__file__) + "/compiler"
# Add this directory to os.environ here
os.environ["OPENRAM_HOME"] = OPENRAM_HOME
debug.check(os.path.isdir(OPENRAM_HOME),
"$OPENRAM_HOME does not exist: {0}".format(OPENRAM_HOME))
debug.info(1, "OpenRAM source code found in {}".format(OPENRAM_HOME))
if OPENRAM_HOME not in sys.path:
debug.error("Please add OPENRAM_HOME to the PYTHONPATH.", -1)
sys.path.insert(0, OPENRAM_HOME)
debug.info(2, "Adding source code to PYTHONPATH.")
# Use a unique temp subdirectory if multithreaded
if OPTS.num_threads > 1 or OPTS.openram_temp == "/tmp":
@@ -547,11 +551,30 @@ def import_tech():
debug.info(2,
"Importing technology: " + OPTS.tech_name)
# environment variable should point to the technology dir
OPENRAM_TECH = ""
# Check if $OPENRAM_TECH is defined
try:
OPENRAM_TECH = os.path.abspath(os.environ.get("OPENRAM_TECH"))
except:
debug.error("$OPENRAM_TECH environment variable is not defined.", 1)
debug.info(2,
"$OPENRAM_TECH environment variable is not defined. "
"Only the default technology modules will be considered if installed.")
# Point to the default technology modules that are part of the openram package
try:
import openram
if OPENRAM_TECH != "":
OPENRAM_TECH += ":"
OPENRAM_TECH += os.path.dirname(openram.__file__) + "/technology"
except:
if OPENRAM_TECH == "":
debug.warning("Couldn't find a tech directory. "
"Install openram library or set $OPENRAM_TECH.")
debug.info(1, "Tech directory found in {}".format(OPENRAM_TECH))
# Add this environment variable to os.environ
os.environ["OPENRAM_TECH"] = OPENRAM_TECH
# Add all of the paths
for tech_path in OPENRAM_TECH.split(":"):
Regular → Executable
+1
View File
@@ -80,3 +80,4 @@ from .write_mask_and_array import *
from .sram_1bank import *
from .sram_config import *
from .sram import *
from .internal_base import *
-4
View File
@@ -29,7 +29,3 @@ class bitcell_1port(bitcell_base):
"""
self.add_graph_edges(graph, port_nets)
def is_non_inverting(self):
"""Return input to output polarity for module"""
return False
-5
View File
@@ -99,8 +99,3 @@ class bitcell_2port(bitcell_base):
# Port 1 edges
graph.add_edge(pin_dict["wl1"], pin_dict["bl1"], self)
graph.add_edge(pin_dict["wl1"], pin_dict["br1"], self)
def is_non_inverting(self):
"""Return input to output polarity for module"""
return False
+12
View File
@@ -265,3 +265,15 @@ class bitcell_base(design):
delay = math.sqrt(2*tstep*(vdd-spice["nom_threshold"])/m)
return delay
def build_graph(self, graph, inst_name, port_nets):
"""
Adds edges based on inputs/outputs.
Overrides base class function.
"""
debug.error("Must override build_graph function in bitcell base class.")
def is_non_inverting(self):
"""Return input to output polarity for module"""
return False
+14
View File
@@ -0,0 +1,14 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2021 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 base import design
class internal_base(design):
def __init__(self, name, cell_name=None, prop=None):
design.__init__(self, name, cell_name, prop)
-85
View File
@@ -1,85 +0,0 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2021 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.
#
"""
SRAM Compiler
The output files append the given suffixes to the output name:
a spice (.sp) file for circuit simulation
a GDS2 (.gds) file containing the layout
a LEF (.lef) file for preliminary P&R (real one should be from layout)
a Liberty (.lib) file for timing analysis/optimization
"""
import sys
import datetime
import globals as g
(OPTS, args) = g.parse_args()
# Check that we are left with a single configuration file as argument.
if len(args) != 1:
print(g.USAGE)
sys.exit(2)
# Set top process to openram
OPTS.top_process = 'openram'
# These depend on arguments, so don't load them until now.
import debug
# Parse config file and set up all the options
g.init_openram(config_file=args[0], is_unit_test=False)
# Ensure that the right bitcell exists or use the parameterised one
g.setup_bitcell()
# Only print banner here so it's not in unit tests
g.print_banner()
# Keep track of running stats
start_time = datetime.datetime.now()
g.print_time("Start", start_time)
# Output info about this run
g.report_status()
from modules import sram_config
# Configure the SRAM organization
c = sram_config(word_size=OPTS.word_size,
num_words=OPTS.num_words,
write_size=OPTS.write_size,
num_banks=OPTS.num_banks,
words_per_row=OPTS.words_per_row,
num_spare_rows=OPTS.num_spare_rows,
num_spare_cols=OPTS.num_spare_cols)
debug.print_raw("Words per row: {}".format(c.words_per_row))
output_extensions = ["lvs", "sp", "v", "lib", "py", "html", "log"]
# Only output lef/gds if back-end
if not OPTS.netlist_only:
output_extensions.extend(["lef", "gds"])
output_files = ["{0}{1}.{2}".format(OPTS.output_path,
OPTS.output_name, x)
for x in output_extensions]
debug.print_raw("Output files are: ")
for path in output_files:
debug.print_raw(path)
from modules import sram
s = sram(name=OPTS.output_name,
sram_config=c)
# Output the files for the resulting SRAM
s.save()
# Delete temp files etc.
g.end_openram()
g.print_time("End", datetime.datetime.now(), start_time)
+1 -1
View File
@@ -13,7 +13,7 @@ class options(optparse.Values):
"""
Class for holding all of the OpenRAM options. All
of these options can be over-riden in a configuration file
that is the sole required command-line positional argument for openram.py.
that is the sole required command-line positional argument for sram_compiler.py.
"""
###################
+1 -1
View File
@@ -35,7 +35,7 @@ class code_format_test(openram_test):
continue
if re.search("debug.py$", code):
continue
if re.search("openram.py$", code):
if re.search("sram_compiler.py$", code):
continue
if re.search("testutils.py$", code):
continue
+3 -3
View File
@@ -23,7 +23,7 @@ class openram_back_end_test(openram_test):
config_file = "{}/tests/configs/config_back_end".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file)
debug.info(1, "Testing top-level back-end openram.py with 2-bit, 16 word SRAM.")
debug.info(1, "Testing top-level back-end sram_compiler.py with 2-bit, 16 word SRAM.")
out_file = "testsram"
out_path = "/tmp/testsram_{0}_{1}_{2}/".format(OPTS.tech_name, getpass.getuser(), os.getpid())
@@ -54,9 +54,9 @@ class openram_back_end_test(openram_test):
# Always perform code coverage
if OPTS.coverage == 0:
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
exe_name = "{0}/openram.py ".format(OPENRAM_HOME)
exe_name = "{0}/../sram_compiler.py ".format(OPENRAM_HOME)
else:
exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
exe_name = "{0}{1}/../sram_compiler.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
config_name = "{0}/tests/configs/config_back_end.py".format(OPENRAM_HOME)
cmd = "{0} -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name,
out_file,
+3 -3
View File
@@ -23,7 +23,7 @@ class openram_front_end_test(openram_test):
config_file = "{}/tests/configs/config_front_end".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file)
debug.info(1, "Testing top-level front-end openram.py with 2-bit, 16 word SRAM.")
debug.info(1, "Testing top-level front-end sram_compiler.py with 2-bit, 16 word SRAM.")
out_file = "testsram"
out_path = "/tmp/testsram_{0}_{1}_{2}".format(OPTS.tech_name, getpass.getuser(), os.getpid())
@@ -54,9 +54,9 @@ class openram_front_end_test(openram_test):
# Always perform code coverage
if OPTS.coverage == 0:
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
exe_name = "{0}/openram.py ".format(OPENRAM_HOME)
exe_name = "{0}/../sram_compiler.py ".format(OPENRAM_HOME)
else:
exe_name = "{0}{1}/openram.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
exe_name = "{0}{1}/../sram_compiler.py ".format(OPTS.coverage_exe, OPENRAM_HOME)
config_name = "{0}/tests/configs/config_front_end.py".format(OPENRAM_HOME)
cmd = "{0} -n -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name,
out_file,
+5 -2
View File
@@ -121,8 +121,11 @@ $(TEST_BASES):
@mkdir -p results/$*/tmp
@$(DOCKER_CMD) sh -c ". /home/cad-user/.bashrc && sleep 1 && python3 -u $(OPENRAM_DIR)/$(getfile).py \
-t $(gettech) -k -v $(ARGS) -p $(OPENRAM_DIR)/results/$* > $(OPENRAM_DIR)/results/$*.out 2>&1 && touch $(OPENRAM_DIR)/results/$*.ok || touch $(OPENRAM_DIR)/results/$*.bad"
@test -f $(TOP_DIR)/compiler/tests/results/$*.ok && echo "$* ... PASS!" && \
rm -rf $(TOP_DIR)/compiler/tests/results/$* || echo "$* ... FAIL!"
ifdef KEEP
@test -f $(TOP_DIR)/compiler/tests/results/$*.ok && echo "$* ... PASS!" || echo "$* ... FAIL!"
else
@test -f $(TOP_DIR)/compiler/tests/results/$*.ok && echo "$* ... PASS!" && rm -rf $(TOP_DIR)/compiler/tests/results/$* || echo "$* ... FAIL!"
endif
.DELETE_ON_ERROR: $(TEST_STAMPS)
.PHONY: docker-pull