diff --git a/compiler/characterizer/__init__.py b/compiler/characterizer/__init__.py index ab8f8126..b665f335 100644 --- a/compiler/characterizer/__init__.py +++ b/compiler/characterizer/__init__.py @@ -13,16 +13,16 @@ 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 OPTS.spice_name != "": + spice_exe=find_exe(OPTS.spice_name) if spice_exe=="": - debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_version),1) + debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_name),1) else: (choice,spice_exe) = get_tool("spice",["xa", "hspice", "ngspice", "ngspice.exe"]) - OPTS.spice_version = choice + OPTS.spice_name = choice # set the input dir for spice files if using ngspice - if OPTS.spice_version == "ngspice": + if OPTS.spice_name == "ngspice": os.environ["NGSPICE_INPUT_DIR"] = "{0}".format(OPTS.openram_temp) if spice_exe == "": diff --git a/compiler/characterizer/charutils.py b/compiler/characterizer/charutils.py index a763737c..386c3078 100644 --- a/compiler/characterizer/charutils.py +++ b/compiler/characterizer/charutils.py @@ -10,7 +10,7 @@ def relative_compare(value1,value2,error_tolerance=0.001): def parse_output(filename, key): """Parses a hspice output.lis file for a key value""" - if OPTS.spice_version == "xa" : + if OPTS.spice_name == "xa" : # customsim has a different output file name full_filename="{0}xa.meas".format(OPTS.openram_temp) else: @@ -26,7 +26,7 @@ def parse_output(filename, key): val = re.search(r"{0}\s*=\s*(-?\d+.?\d*[e]?[-+]?[0-9]*\S*)\s+.*".format(key), contents) if val != None: - debug.info(3, "Key = " + key + " Val = " + val.group(1)) + debug.info(4, "Key = " + key + " Val = " + val.group(1)) return val.group(1) else: return "Failed" diff --git a/compiler/characterizer/delay.py b/compiler/characterizer/delay.py index 03f0eda2..094d2e15 100644 --- a/compiler/characterizer/delay.py +++ b/compiler/characterizer/delay.py @@ -24,6 +24,7 @@ class delay(): self.vdd = tech.spice["supply_voltage"] self.gnd = tech.spice["gnd_voltage"] + def check_arguments(self): """Checks if arguments given for write_stimulus() meets requirements""" try: @@ -334,6 +335,17 @@ class delay(): self.set_probe(probe_address, probe_data) + # This is for debugging a full simulation + # debug.info(0,"Debug simulation running...") + # target_period=50.0 + # feasible_delay1=0.059083183 + # feasible_delay0=0.17953789 + # load=1.6728 + # slew=0.04 + # self.try_period(target_period, load, slew, feasible_delay1, feasible_delay0) + # sys.exit(1) + + (feasible_period, feasible_delay1, feasible_delay0) = self.find_feasible_period(max(loads), max(slews)) debug.check(feasible_delay1>0,"Negative delay may not be possible") debug.check(feasible_delay0>0,"Negative delay may not be possible") @@ -361,7 +373,7 @@ class delay(): # finds the minimum period without degrading the delays by X% min_period = self.find_min_period(feasible_period, max(loads), max(slews), feasible_delay1, feasible_delay0) debug.check(type(min_period)==float,"Couldn't find minimum period.") - debug.info(1, "Min Period: {0}n with a delay of {1}".format(min_period, feasible_delay1)) + debug.info(1, "Min Period: {0}n with a delay of {1} / {2}".format(min_period, feasible_delay1, feasible_delay0)) data = {"min_period": ch.round_time(min_period), diff --git a/compiler/characterizer/stimuli.py b/compiler/characterizer/stimuli.py index 8f3b71fb..d367b518 100644 --- a/compiler/characterizer/stimuli.py +++ b/compiler/characterizer/stimuli.py @@ -233,7 +233,7 @@ def gen_meas_delay(stim_file, meas_name, trig_name, targ_name, trig_val, targ_va def gen_meas_power(stim_file, meas_name, t_initial, t_final): """Creates the .meas statement for the measurement of avg power""" # power mea cmd is different in different spice: - if OPTS.spice_version == "hspice": + if OPTS.spice_name == "hspice": power_exp = "power" else: power_exp = "par('(-1*v(" + str(vdd_name) + ")*I(v" + str(vdd_name) + "))')" @@ -248,10 +248,16 @@ def write_control(stim_file, end_time): stim_file.write(".TRAN 5p {0}n UIC\n".format(end_time)) stim_file.write(".OPTIONS POST=1 RUNLVL=4 PROBE\n") # create plots for all signals - stim_file.write("* probe is used for hspice\n") - stim_file.write("*.probe V(*)\n") - stim_file.write("* plot is used for ngspice interactive mode \n") - stim_file.write("*.plot V(*)\n") + stim_file.write("* probe is used for hspice/xa, while plot is used in ngspice\n") + if OPTS.debug_level>0: + if OPTS.spice_name in ["hspice","xa"]: + stim_file.write(".probe V(*)\n") + else: + stim_file.write(".plot V(*)\n") + else: + stim_file.write("*.probe V(*)\n") + stim_file.write("*.plot V(*)\n") + # end the stimulus file stim_file.write(".end\n\n") @@ -278,12 +284,17 @@ def run_sim(): start_time = datetime.datetime.now() from characterizer import spice_exe - if OPTS.spice_version == "xa": - cmd = "{0} {1} -o {2}xa -mt 20".format(spice_exe, + if OPTS.spice_name == "xa": + # Output the xa configurations here. FIXME: Move this to write it once. + xa_cfg = open("{}xa.cfg".format(OPTS.openram_temp), "w") + xa_cfg.write("set_sim_level -level 7\n") + xa_cfg.write("set_powernet_level 7 -node vdd\n") + xa_cfg.close() + cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt 20".format(spice_exe, temp_stim, OPTS.openram_temp) valid_retcode=0 - elif OPTS.spice_version == "hspice": + elif OPTS.spice_name == "hspice": # TODO: Should make multithreading parameter a configuration option cmd = "{0} -mt 2 -i {1} -o {2}timing".format(spice_exe, temp_stim, diff --git a/compiler/globals.py b/compiler/globals.py index 06f848dc..10490fa4 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -45,12 +45,10 @@ def parse_args(): help="Increase the verbosity level"), optparse.make_option("-t", "--tech", dest="tech_name", help="Technology name"), - optparse.make_option("-s", "--spiceversion", dest="spice_version", - help="Spice simulator name"), + optparse.make_option("-s", "--spice", dest="spice_name", + help="Spice simulator executable name"), optparse.make_option("-r", "--remove_netlist_trimming", action="store_false", dest="trim_netlist", help="Disable removal of noncritical memory cells during characterization"), - optparse.make_option("-a", "--analytical", action="store_true", dest="analytical_delay", - help="Use analytical models to calculate delays (default)"), optparse.make_option("-c", "--characterize", action="store_false", dest="analytical_delay", help="Perform characterization to calculate delays (default is analytical models)") # -h --help is implicit. @@ -59,7 +57,7 @@ def parse_args(): parser = optparse.OptionParser(option_list=option_list, description="Compile and/or characterize an SRAM.", usage=USAGE, - version="sramc v" + VERSION) + version="OpenRAM v" + VERSION) (options, args) = parser.parse_args(values=OPTS) diff --git a/compiler/openram.py b/compiler/openram.py index d05cf764..df345c4d 100755 --- a/compiler/openram.py +++ b/compiler/openram.py @@ -55,9 +55,9 @@ num_banks = OPTS.config.num_banks if (OPTS.output_name == ""): OPTS.output_name = "sram_{0}_{1}_{2}_{3}".format(word_size, - num_words, - num_banks, - OPTS.tech_name) + num_words, + num_banks, + OPTS.tech_name) print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)") @@ -70,7 +70,7 @@ if not OPTS.check_lvsdrc: if OPTS.analytical_delay: print("Using analytical delay models (no characterization)") else: - print("Performing simulation-based characterization with {}".format(OPTS.spice_version)) + print("Performing simulation-based characterization with {}".format(OPTS.spice_name)) if OPTS.trim_netlist: print("Trimming netlist to speed up characterization (sacrificing some accuracy).") diff --git a/compiler/options.py b/compiler/options.py index d4ec0de5..a40558ad 100644 --- a/compiler/options.py +++ b/compiler/options.py @@ -19,7 +19,7 @@ class options(optparse.Values): # This determines whether LVS and DRC is checked for each submodule. check_lvsdrc = True # Variable to select the variant of spice - spice_version = "" + spice_name = "" # Should we print out the banner at startup print_banner = True # The DRC/LVS/PEX executable being used which is derived from the user PATH. diff --git a/compiler/sram.py b/compiler/sram.py index 3b236c1f..cc72ec08 100644 --- a/compiler/sram.py +++ b/compiler/sram.py @@ -108,6 +108,7 @@ class sram(design.design): self.bank_addr_size = self.col_addr_size + self.row_addr_size self.addr_size = self.bank_addr_size + int(log(self.num_banks, 2)) + debug.info(0,"Words per row: {}".format(self.words_per_row)) def estimate_words_per_row(self,tentative_num_cols, word_size): """This provides a heuristic rounded estimate for the number of words diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index 3b39d958..65ebe508 100644 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -21,7 +21,7 @@ class timing_sram_test(unittest.TestCase): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) # we will manually run lvs/drc OPTS.check_lvsdrc = False - OPTS.spice_version="hspice" + OPTS.spice_name="hspice" OPTS.analytical_delay = False # This is a hack to reload the characterizer __init__ with the spice version import characterizer diff --git a/compiler/tests/21_hspice_setuphold_test.py b/compiler/tests/21_hspice_setuphold_test.py index 9b40729c..d2ad0411 100644 --- a/compiler/tests/21_hspice_setuphold_test.py +++ b/compiler/tests/21_hspice_setuphold_test.py @@ -22,7 +22,7 @@ class timing_setup_test(unittest.TestCase): # we will manually run lvs/drc OPTS.check_lvsdrc = False - OPTS.spice_version="hspice" + OPTS.spice_name="hspice" OPTS.analytical_delay = False import characterizer reload(characterizer) diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 78bad910..2c333ad5 100644 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -19,7 +19,7 @@ class timing_sram_test(unittest.TestCase): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) # we will manually run lvs/drc OPTS.check_lvsdrc = False - OPTS.spice_version="ngspice" + OPTS.spice_name="ngspice" OPTS.analytical_delay = False # This is a hack to reload the characterizer __init__ with the spice version import characterizer @@ -82,7 +82,7 @@ class timing_sram_test(unittest.TestCase): # reset these options OPTS.check_lvsdrc = True - OPTS.spice_version="hspice" + OPTS.spice_name="hspice" OPTS.analytical_delay = True reload(characterizer) diff --git a/compiler/tests/21_ngspice_setuphold_test.py b/compiler/tests/21_ngspice_setuphold_test.py index bbf0f18a..f7b78515 100644 --- a/compiler/tests/21_ngspice_setuphold_test.py +++ b/compiler/tests/21_ngspice_setuphold_test.py @@ -22,7 +22,7 @@ class timing_setup_test(unittest.TestCase): # we will manually run lvs/drc OPTS.check_lvsdrc = False - OPTS.spice_version="ngspice" + OPTS.spice_name="ngspice" OPTS.analytical_delay = False # This is a hack to reload the characterizer __init__ with the spice version import characterizer @@ -61,7 +61,7 @@ class timing_setup_test(unittest.TestCase): # reset these options OPTS.check_lvsdrc = True - OPTS.spice_version="hspice" + OPTS.spice_name="hspice" OPTS.analytical_delay = True reload(characterizer) diff --git a/compiler/tests/22_pex_func_test_with_pinv.py b/compiler/tests/22_pex_func_test_with_pinv.py index 6e75e81b..025f6fe1 100644 --- a/compiler/tests/22_pex_func_test_with_pinv.py +++ b/compiler/tests/22_pex_func_test_with_pinv.py @@ -64,7 +64,7 @@ class sram_func_test(unittest.TestCase): import os - if OPTS.spice_version == "hspice": + if OPTS.spice_name == "hspice": cmd = "hspice -mt 2 -i {0} > {1} ".format( simulator_file, result_file) else: @@ -145,7 +145,7 @@ class sram_func_test(unittest.TestCase): 9.5 * tech.spice["clock_period"], 10 * tech.spice["clock_period"])) sim_file.write("\n") - if OPTS.spice_version == "hspice": + if OPTS.spice_name in ["hspice","xa"]: sim_file.write(".probe v(x*.*)\n") sim_file.write(".tran 0.1ns {0}ns\n".format( 10 * tech.spice["clock_period"])) diff --git a/compiler/tests/22_sram_func_test.py b/compiler/tests/22_sram_func_test.py index be5ce574..6ec0c546 100644 --- a/compiler/tests/22_sram_func_test.py +++ b/compiler/tests/22_sram_func_test.py @@ -22,7 +22,7 @@ class sram_func_test(unittest.TestCase): # we will manually run lvs/drc OPTS.check_lvsdrc = False - OPTS.spice_version="hspice" + OPTS.spice_name="hspice" OPTS.analytical_delay = False import characterizer reload(characterizer) diff --git a/compiler/tests/23_lib_sram_prune_test.py b/compiler/tests/23_lib_sram_prune_test.py index d975027b..87c4eb9e 100644 --- a/compiler/tests/23_lib_sram_prune_test.py +++ b/compiler/tests/23_lib_sram_prune_test.py @@ -18,7 +18,7 @@ class lib_test(unittest.TestCase): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) # we will manually run lvs/drc OPTS.check_lvsdrc = False - OPTS.spice_version="hspice" + OPTS.spice_name="hspice" OPTS.analytical_delay = False import characterizer reload(characterizer)