mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-08-30 01:48:33 +02:00
Merge branch 'dev' into char
This commit is contained in:
+1
-1
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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 *
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
+14
@@ -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)
|
||||
@@ -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
@@ -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.
|
||||
"""
|
||||
|
||||
###################
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user