Refactor openram.py.

This commit is contained in:
Matt Guthaus 2018-02-08 12:47:19 -08:00
parent 54c21f6282
commit 6c89f7965d
3 changed files with 122 additions and 106 deletions

View File

@ -16,13 +16,7 @@ USAGE = "Usage: openram.py [options] <config file>\nUse -h for help.\n"
# Anonymous object that will be the options
OPTS = options.options()
# check that we are not using version 3 and at least 2.7
major_python_version = sys.version_info.major
minor_python_version = sys.version_info.minor
if not (major_python_version == 2 and minor_python_version >= 7):
debug.error("Python 2.7 is required.",-1)
def parse_args():
def parse_args(is_unit_test=True):
""" Parse the optional arguments for OpenRAM """
global OPTS
@ -36,8 +30,6 @@ def parse_args():
help="Output file(s) location"),
optparse.make_option("-n", "--nocheck", action="store_false",
help="Disable inline LVS/DRC checks", dest="check_lvsdrc"),
optparse.make_option("-q", "--quiet", action="store_false", dest="print_banner",
help="Don\'t display banner"),
optparse.make_option("-v", "--verbose", action="count", dest="debug_level",
help="Increase the verbosity level"),
optparse.make_option("-t", "--tech", dest="tech_name",
@ -66,13 +58,19 @@ def parse_args():
# Alias SCMOS to AMI 0.5um
if OPTS.tech_name == "scmos":
OPTS.tech_name = "scn3me_subm"
# Check that we have a single configuration file as argument.
OPTS.is_unit_test=is_unit_test
if not OPTS.is_unit_test and len(args) < 1:
print(USAGE)
sys.exit(2)
return (options, args)
def print_banner():
""" Conditionally print the banner to stdout """
global OPTS
if not OPTS.print_banner:
if OPTS.is_unit_test:
return
print("|==============================================================================|")
@ -89,8 +87,17 @@ def print_banner():
print("|==============================================================================|")
def check_versions():
""" check that we are not using version 3 and at least 2.7 """
major_python_version = sys.version_info.major
minor_python_version = sys.version_info.minor
if not (major_python_version == 2 and minor_python_version >= 7):
debug.error("Python 2.7 is required.",-1)
def init_openram(config_file):
"""Initialize the technology, paths, simulators, etc."""
check_versions()
debug.info(1,"Initializing OpenRAM...")
@ -100,6 +107,8 @@ def init_openram(config_file):
import_tech()
report_status()
def get_tool(tool_type, preferences):
"""
@ -173,6 +182,7 @@ def read_config(config_file):
def end_openram():
""" Clean up openram for a proper exit """
cleanup_paths()
@ -270,3 +280,39 @@ def import_tech():
debug.error("Nonexistent technology_setup_file: {0}.py".format(filename))
sys.exit(1)
def print_time(name, now_time, last_time=None):
if last_time:
time = round((now_time-last_time).total_seconds(),1)
else:
time = now_time
print("** {0}: {1} seconds".format(name,time))
return now_time
def report_status():
""" Check for valid arguments and report the info about the SRAM being generated """
# Check if all arguments are integers for bits, size, banks
if type(OPTS.word_size)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.word_size))
if type(OPTS.num_words)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.sram_size))
if type(OPTS.num_banks)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.num_banks))
if not OPTS.tech_name:
debug.error("Tech name must be specified in config file.")
if (OPTS.output_name == ""):
OPTS.output_name = "sram_{0}_{1}_{2}_{3}".format(OPTS.word_size,
OPTS.num_words,
OPTS.num_banks,
OPTS.OPTS.tech_name)
if not OPTS.is_unit_test:
print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
print("Technology: {0}".format(OPTS.tech_name))
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(OPTS.word_size,
OPTS.num_words,
OPTS.num_banks))
if not OPTS.check_lvsdrc:
print("DRC/LVS/PEX checking is disabled.")

View File

@ -14,116 +14,39 @@ import sys,os
import datetime
import re
import importlib
import globals
from globals import *
(OPTS, args) = globals.parse_args()
def print_time(name, now_time, last_time=None):
if last_time:
time = round((now_time-last_time).total_seconds(),1)
else:
time = now_time
print("** {0}: {1} seconds".format(name,time))
return now_time
(OPTS, args) = parse_args(is_unit_test=False)
# These depend on arguments, so don't load them until now.
import debug
# required positional args for using openram main exe
if len(args) < 1:
print(globals.USAGE)
sys.exit(2)
# Only print banner here so it's not in unit tests
print_banner()
globals.print_banner()
init_openram(args[0])
globals.init_openram(args[0])
# Check if all arguments are integers for bits, size, banks
if type(OPTS.word_size)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.word_size))
if type(OPTS.num_words)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.sram_size))
if type(OPTS.num_banks)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.num_banks))
if not OPTS.tech_name:
debug.error("Tech name must be specified in config file.")
word_size = OPTS.word_size
num_words = OPTS.num_words
num_banks = OPTS.num_banks
if (OPTS.output_name == ""):
OPTS.output_name = "sram_{0}_{1}_{2}_{3}".format(word_size,
num_words,
num_banks,
OPTS.tech_name)
print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
print("Technology: {0}".format(OPTS.tech_name))
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(word_size,num_words,num_banks))
# only start importing modules after we have the config file
# Start importing design modules after we have the config file
import verify
import sram
# Keep track of running stats
start_time = datetime.datetime.now()
last_time = start_time
print_time("Start",datetime.datetime.now())
if not OPTS.check_lvsdrc:
print("DRC/LVS/PEX checking is disabled.")
print_time("Start",last_time)
# import SRAM test generation
s = sram.sram(word_size=word_size,
num_words=num_words,
num_banks=num_banks,
s = sram.sram(word_size=OPTS.word_size,
num_words=OPTS.num_words,
num_banks=OPTS.num_banks,
name=OPTS.output_name)
last_time=print_time("SRAM creation", datetime.datetime.now(), last_time)
# Output the files for the resulting SRAM
s.save_output(last_time)
spname = OPTS.output_path + s.name + ".sp"
print("SP: Writing to {0}".format(spname))
s.sp_write(spname)
last_time=print_time("Spice writing", datetime.datetime.now(), last_time)
# Output the extracted design
sram_file = spname
if OPTS.use_pex:
sram_file = OPTS.output_path + "temp_pex.sp"
verify.run_pex(s.name, gdsname, spname, output=sram_file)
# Characterize the design
from characterizer import lib
libname = OPTS.output_path + s.name + ".lib"
print("LIB: Writing to {0}".format(libname))
if OPTS.analytical_delay:
print("Using analytical delay models (no characterization)")
else:
if OPTS.spice_name!="":
print("Performing simulation-based characterization with {}".format(OPTS.spice_name))
if OPTS.trim_netlist:
print("Trimming netlist to speed up characterization.")
lib.lib(libname,s,sram_file)
last_time=print_time("Characterization", datetime.datetime.now(), last_time)
# Write the layout
gdsname = OPTS.output_path + s.name + ".gds"
print("GDS: Writing to {0}".format(gdsname))
s.gds_write(gdsname)
last_time=print_time("GDS", datetime.datetime.now(), last_time)
# Create a LEF physical model
lefname = OPTS.output_path + s.name + ".lef"
print("LEF: Writing to {0}".format(lefname))
s.lef_write(lefname)
last_time=print_time("LEF", datetime.datetime.now(), last_time)
# Write a verilog model
vname = OPTS.output_path + s.name + ".v"
print("Verilog: Writing to {0}".format(vname))
s.verilog_write(vname)
last_time=print_time("Verilog", datetime.datetime.now(), last_time)
globals.end_openram()
# Delete temp files etc.
end_openram()
print_time("End",datetime.datetime.now(), start_time)

View File

@ -8,7 +8,7 @@ from bank import bank
import datetime
import getpass
from vector import vector
from globals import OPTS
from globals import OPTS, print_time
class sram(design.design):
@ -1009,3 +1009,50 @@ class sram(design.design):
def analytical_delay(self,slew,load):
""" LH and HL are the same in analytical model. """
return self.bank.analytical_delay(slew,load)
def save_output(self, last_time):
""" Save all the output files while reporting time to do it as well. """
spname = OPTS.output_path + self.name + ".sp"
print("SP: Writing to {0}".format(spname))
self.sp_write(spname)
last_time=print_time("Spice writing", datetime.datetime.now(), last_time)
# Output the extracted design
sram_file = spname
if OPTS.use_pex:
sram_file = OPTS.output_path + "temp_pex.sp"
verify.run_pex(self.name, gdsname, spname, output=sram_file)
# Characterize the design
from characterizer import lib
libname = OPTS.output_path + self.name + ".lib"
print("LIB: Writing to {0}".format(libname))
if OPTS.analytical_delay:
print("Using analytical delay models (no characterization)")
else:
if OPTS.spice_name!="":
print("Performing simulation-based characterization with {}".format(OPTS.spice_name))
if OPTS.trim_netlist:
print("Trimming netlist to speed up characterization.")
lib.lib(libname,self,sram_file)
last_time=print_time("Characterization", datetime.datetime.now(), last_time)
# Write the layout
gdsname = OPTS.output_path + self.name + ".gds"
print("GDS: Writing to {0}".format(gdsname))
self.gds_write(gdsname)
last_time=print_time("GDS", datetime.datetime.now(), last_time)
# Create a LEF physical model
lefname = OPTS.output_path + self.name + ".lef"
print("LEF: Writing to {0}".format(lefname))
self.lef_write(lefname)
last_time=print_time("LEF", datetime.datetime.now(), last_time)
# Write a verilog model
vname = OPTS.output_path + self.name + ".v"
print("Verilog: Writing to {0}".format(vname))
self.verilog_write(vname)
last_time=print_time("Verilog", datetime.datetime.now(), last_time)