From 2eb9f5c6bc24b811d19dce7df02da9d77638cd38 Mon Sep 17 00:00:00 2001 From: mguthaus Date: Wed, 15 Nov 2017 17:02:53 -0800 Subject: [PATCH] Move verify into a module. Make characterizer a module. Move exe searching to modules. --- compiler/characterizer/__init__.py | 31 +++++++ compiler/characterizer/stimuli.py | 11 +-- compiler/globals.py | 92 ++++++--------------- compiler/openram.py | 2 +- compiler/tests/21_hspice_delay_test.py | 9 +- compiler/tests/21_hspice_setuphold_test.py | 3 +- compiler/tests/21_ngspice_delay_test.py | 11 +-- compiler/tests/21_ngspice_setuphold_test.py | 11 ++- compiler/{verify.py => verify/__init__.py} | 38 ++++++--- compiler/{ => verify}/assura.py | 0 compiler/{ => verify}/calibre.py | 21 ++--- compiler/{ => verify}/magic.py | 0 12 files changed, 119 insertions(+), 110 deletions(-) create mode 100644 compiler/characterizer/__init__.py rename compiler/{verify.py => verify/__init__.py} (57%) rename compiler/{ => verify}/assura.py (100%) rename compiler/{ => verify}/calibre.py (94%) rename compiler/{ => verify}/magic.py (100%) diff --git a/compiler/characterizer/__init__.py b/compiler/characterizer/__init__.py new file mode 100644 index 00000000..ab8f8126 --- /dev/null +++ b/compiler/characterizer/__init__.py @@ -0,0 +1,31 @@ +import os +import debug +from globals import OPTS,find_exe,get_tool +import lib +import delay +import setup_hold + + +debug.info(2,"Initializing characterizer...") + +spice_exe = "" + +if OPTS.analytical_delay: + debug.info(1,"Using analytical delay models (no characterization)") +else: + if OPTS.spice_version != "": + spice_exe=find_exe(OPTS.spice_version) + if spice_exe=="": + debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_version),1) + else: + (choice,spice_exe) = get_tool("spice",["xa", "hspice", "ngspice", "ngspice.exe"]) + OPTS.spice_version = choice + + # set the input dir for spice files if using ngspice + if OPTS.spice_version == "ngspice": + os.environ["NGSPICE_INPUT_DIR"] = "{0}".format(OPTS.openram_temp) + + if spice_exe == "": + debug.error("No recognizable spice version found. Unable to perform characterization.",1) + + diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index 13c9bb06..ec6c00f0 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -278,21 +278,22 @@ def run_sim(): temp_stim = "{0}stim.sp".format(OPTS.openram_temp) + from characterizer import spice_exe if OPTS.spice_version == "xa": - cmd = "{0} {1} -o {2}xa -mt 20".format(OPTS.spice_exe, + cmd = "{0} {1} -o {2}xa -mt 20".format(spice_exe, temp_stim, OPTS.openram_temp) valid_retcode=0 elif OPTS.spice_version == "hspice": # TODO: Should make multithreading parameter a configuration option - cmd = "{0} -mt 2 -i {1} -o {2}timing".format(OPTS.spice_exe, + cmd = "{0} -mt 2 -i {1} -o {2}timing".format(spice_exe, temp_stim, OPTS.openram_temp) valid_retcode=0 else: - cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe, - temp_stim, - OPTS.openram_temp) + cmd = "{0} -b -o {2}timing.lis {1}".format(spice_exe, + temp_stim, + OPTS.openram_temp) # for some reason, ngspice-25 returns 1 when it only has acceptable warnings valid_retcode=1 diff --git a/compiler/globals.py b/compiler/globals.py index a2931c4b..d169c496 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -25,9 +25,6 @@ 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 is_exe(fpath): - return os.path.exists(fpath) and os.access(fpath, os.X_OK) - # parse the optional arguments # this only does the optional arguments @@ -113,15 +110,23 @@ def init_openram(config_file): import_tech() - set_spice() - +def get_tool(tool_type, preferences): + """ + Find which tool we have from a list of preferences and return the full path. + """ + debug.info(2,"Finding {} tool...".format(tool_type)) global OPTS - OPTS.drc_exe = get_tool("DRC",["calibre","assura","magic"]) - OPTS.lvs_exe = get_tool("LVS",["calibre","assura","netgen"]) - OPTS.pex_exe = get_tool("PEX",["calibre","magic"]) - #set_drc() - #set_lvs() - #set_pex() + + for name in preferences: + exe_name = find_exe(name) + if exe_name!="": + debug.info(1, "Using {0}: {1}".format(tool_type,exe_name)) + return(name,exe_name) + else: + debug.info(1, "Could not find {0}, trying next {1} tool.".format(name,tool_type)) + else: + return(None,"") + def read_config(config_file): @@ -160,36 +165,6 @@ def read_config(config_file): debug.error("Unable to make output directory.",-1) -def find_exe(check_exe): - """ Check if the binary exists in the path and return the full path. """ - # Check if the preferred spice option exists in the path - for path in os.environ["PATH"].split(os.pathsep): - exe = os.path.join(path, check_exe) - # if it is found, then break and use first version - if is_exe(exe): - return exe - return "" - -def get_tool(tool_type, preferences): - """ - Find which tool we have from a list of preferences and return the full path. - """ - debug.info(2,"Finding {} tool...".format(tool_type)) - global OPTS - - if not OPTS.check_lvsdrc: - debug.info(1,"LVS/DRC/PEX disabled.") - return None - else: - for name in preferences: - exe_name = find_exe(name) - if exe_name!="": - debug.info(1, "Using {0}: {1}".format(tool_type,exe_name)) - return(exe_name) - else: - debug.info(1, "Could not find {0}, trying next {1} tool.".format(name,tool_type)) - else: - return("") def end_openram(): """ Clean up openram for a proper exit """ @@ -245,31 +220,18 @@ def setup_paths(): os.chmod(OPTS.openram_temp, 0o750) - - -def set_spice(): - debug.info(2,"Finding spice...") - global OPTS - - if OPTS.analytical_delay: - debug.info(1,"Using analytical delay models (no characterization)") - return - else: - if OPTS.spice_version != "": - OPTS.spice_exe=find_exe(OPTS.spice_version) - if OPTS.spice_exe=="": - debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_version),1) - else: - OPTS.spice_exe = get_tool("spice",["xa", "hspice", "ngspice", "ngspice.exe"]) - - # set the input dir for spice files if using ngspice - if OPTS.spice_version == "ngspice": - os.environ["NGSPICE_INPUT_DIR"] = "{0}".format(OPTS.openram_temp) - - if OPTS.spice_exe == "": - debug.error("No recognizable spice version found. Unable to perform characterization.",1) - +def is_exe(fpath): + return os.path.exists(fpath) and os.access(fpath, os.X_OK) +def find_exe(check_exe): + """ Check if the binary exists in the path and return the full path. """ + # Check if the preferred spice option exists in the path + for path in os.environ["PATH"].split(os.pathsep): + exe = os.path.join(path, check_exe) + # if it is found, then break and use first version + if is_exe(exe): + return exe + return "" # imports correct technology directories for testing def import_tech(): diff --git a/compiler/openram.py b/compiler/openram.py index 13f9f2cf..d05cf764 100755 --- a/compiler/openram.py +++ b/compiler/openram.py @@ -107,7 +107,7 @@ if OPTS.use_pex: verify.run_pex(s.name, gdsname, spname, output=sram_file) # Characterize the design -import lib +from characterizer import lib libname = OPTS.output_path + s.name + ".lib" print("LIB: Writing to {0}".format(libname)) lib.lib(libname,s,sram_file) diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index 545a2250..d86f53dc 100644 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -24,8 +24,11 @@ class timing_sram_test(unittest.TestCase): OPTS.check_lvsdrc = False OPTS.spice_version="hspice" OPTS.analytical_delay = False - globals.set_spice() - + # This is a hack to reload the characterizer __init__ with the spice version + import characterizer + reload(characterizer) + from characterizer import delay + import sram debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank") @@ -36,8 +39,6 @@ class timing_sram_test(unittest.TestCase): OPTS.check_lvsdrc = True - import delay - tempspice = OPTS.openram_temp + "temp.sp" s.sp_write(tempspice) diff --git a/compiler/tests/21_hspice_setuphold_test.py b/compiler/tests/21_hspice_setuphold_test.py index 9a6518e1..2d49f4d1 100644 --- a/compiler/tests/21_hspice_setuphold_test.py +++ b/compiler/tests/21_hspice_setuphold_test.py @@ -23,8 +23,7 @@ class timing_setup_test(unittest.TestCase): # we will manually run lvs/drc OPTS.check_lvsdrc = False - OPTS.spice_version="hspice" - globals.set_spice() + from characterizer import delay import sram import tech diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 3459acf0..12daa90b 100644 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -22,8 +22,11 @@ class timing_sram_test(unittest.TestCase): OPTS.check_lvsdrc = False OPTS.spice_version="ngspice" OPTS.analytical_delay = False - globals.set_spice() - + # This is a hack to reload the characterizer __init__ with the spice version + import characterizer + reload(characterizer) + from characterizer import delay + import sram debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank") @@ -32,8 +35,6 @@ class timing_sram_test(unittest.TestCase): num_banks=OPTS.config.num_banks, name="sram1") - import delay - tempspice = OPTS.openram_temp + "temp.sp" s.sp_write(tempspice) @@ -84,7 +85,7 @@ class timing_sram_test(unittest.TestCase): OPTS.check_lvsdrc = True OPTS.spice_version="hspice" OPTS.analytical_delay = True - globals.set_spice() + reload(characterizer) os.remove(tempspice) diff --git a/compiler/tests/21_ngspice_setuphold_test.py b/compiler/tests/21_ngspice_setuphold_test.py index 77fc9b40..23620028 100644 --- a/compiler/tests/21_ngspice_setuphold_test.py +++ b/compiler/tests/21_ngspice_setuphold_test.py @@ -23,14 +23,15 @@ class timing_setup_test(unittest.TestCase): # we will manually run lvs/drc OPTS.check_lvsdrc = False OPTS.spice_version="ngspice" - globals.set_spice() + # This is a hack to reload the characterizer __init__ with the spice version + import characterizer + reload(characterizer) + from characterizer import setup_hold import sram import tech slews = [tech.spice["rise_time"]*2] - import setup_hold - sh = setup_hold.setup_hold() data = sh.analyze(slews,slews) @@ -60,7 +61,9 @@ class timing_setup_test(unittest.TestCase): # reset these options OPTS.check_lvsdrc = True OPTS.spice_version="hspice" - globals.set_spice() + + reload(characterizer) + globals.end_openram() # instantiate a copdsay of the class to actually run the test diff --git a/compiler/verify.py b/compiler/verify/__init__.py similarity index 57% rename from compiler/verify.py rename to compiler/verify/__init__.py index 7f930ce4..7eb38277 100644 --- a/compiler/verify.py +++ b/compiler/verify/__init__.py @@ -8,38 +8,52 @@ run_pex, repsectively. If there is an error, they should abort and report the er If not, OpenRAM will continue as if nothing happened! """ +import os import debug -from globals import OPTS +from globals import OPTS,find_exe,get_tool -if OPTS.drc_exe == None: +debug.info(2,"Initializing verify...") + +if not OPTS.check_lvsdrc: + debug.info(1,"LVS/DRC/PEX disabled.") + drc_exe = None + lvs_exe = None + pex_exe = None +else: + drc_exe = get_tool("DRC",["calibre","assura","magic"]) + lvs_exe = get_tool("LVS",["calibre","assura","netgen"]) + pex_exe = get_tool("PEX",["calibre","magic"]) + + +if drc_exe == None: pass -elif "calibre" in OPTS.drc_exe: +elif "calibre" in drc_exe: from calibre import run_drc -elif "assura" in OPTS.drc_exe: +elif "assura" in drc_exe: from assura import run_drc -elif "magic" in OPTS.drc_exe: +elif "magic" in drc_exe: from magic import run_drc else: debug.warning("Did not find a supported DRC tool.") -if OPTS.lvs_exe == None: +if lvs_exe == None: pass -elif "calibre" in OPTS.lvs_exe: +elif "calibre" in lvs_exe: from calibre import run_lvs -elif "assura" in OPTS.lvs_exe: +elif "assura" in lvs_exe: from assura import run_lvs -elif "netgen" in OPTS.lvs_exe: +elif "netgen" in lvs_exe: from magic import run_lvs else: debug.warning("Did not find a supported LVS tool.") -if OPTS.pex_exe == None: +if pex_exe == None: pass -elif "calibre" in OPTS.pex_exe: +elif "calibre" in pex_exe: from calibre import run_pex -elif "magic" in OPTS.pex_exe: +elif "magic" in pex_exe: from magic import run_pex else: debug.warning("Did not find a supported PEX tool.") diff --git a/compiler/assura.py b/compiler/verify/assura.py similarity index 100% rename from compiler/assura.py rename to compiler/verify/assura.py diff --git a/compiler/calibre.py b/compiler/verify/calibre.py similarity index 94% rename from compiler/calibre.py rename to compiler/verify/calibre.py index 806ad521..2565dbfe 100644 --- a/compiler/calibre.py +++ b/compiler/verify/calibre.py @@ -100,10 +100,9 @@ def run_drc(name, gds_name): errfile = "{0}{1}.drc.err".format(OPTS.openram_temp, name) outfile = "{0}{1}.drc.out".format(OPTS.openram_temp, name) - cmd = "{0} -gui -drc {1}drc_runset -batch 2> {2} 1> {3}".format(OPTS.drc_exe, - OPTS.openram_temp, - errfile, - outfile) + cmd = "calibre -gui -drc {0}drc_runset -batch 2> {1} 1> {2}".format(OPTS.openram_temp, + errfile, + outfile) debug.info(1, cmd) os.system(cmd) os.chdir(cwd) @@ -177,10 +176,9 @@ def run_lvs(name, gds_name, sp_name): errfile = "{0}{1}.lvs.err".format(OPTS.openram_temp, name) outfile = "{0}{1}.lvs.out".format(OPTS.openram_temp, name) - cmd = "{0} -gui -lvs {1}lvs_runset -batch 2> {2} 1> {3}".format(OPTS.lvs_exe, - OPTS.openram_temp, - errfile, - outfile) + cmd = "calibre -gui -lvs {0}lvs_runset -batch 2> {1} 1> {2}".format(OPTS.openram_temp, + errfile, + outfile) debug.info(1, cmd) os.system(cmd) os.chdir(cwd) @@ -287,10 +285,9 @@ def run_pex(name, gds_name, sp_name, output=None): errfile = "{0}{1}.pex.err".format(OPTS.openram_temp, name) outfile = "{0}{1}.pex.out".format(OPTS.openram_temp, name) - cmd = "{0} -gui -pex {1}pex_runset -batch 2> {2} 1> {3}".format(OPTS.pex_exe, - OPTS.openram_temp, - errfile, - outfile) + cmd = "calibre -gui -pex {0}pex_runset -batch 2> {1} 1> {2}".format(OPTS.openram_temp, + errfile, + outfile) debug.info(2, cmd) os.system(cmd) os.chdir(cwd) diff --git a/compiler/magic.py b/compiler/verify/magic.py similarity index 100% rename from compiler/magic.py rename to compiler/verify/magic.py