diff --git a/compiler/characterizer/__init__.py b/compiler/characterizer/__init__.py index 53155e09..4f32beb3 100644 --- a/compiler/characterizer/__init__.py +++ b/compiler/characterizer/__init__.py @@ -18,7 +18,7 @@ if not OPTS.analytical_delay: if OPTS.spice_name != "": OPTS.spice_exe=find_exe(OPTS.spice_name) - if OPTS.spice_exe=="": + if OPTS.spice_exe=="" or OPTS.spice_exe==None: debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_name),1) else: (OPTS.spice_name,OPTS.spice_exe) = get_tool("spice",["xa", "hspice", "ngspice", "ngspice.exe"]) diff --git a/compiler/characterizer/functional.py b/compiler/characterizer/functional.py index 34df6efb..d6579ab5 100644 --- a/compiler/characterizer/functional.py +++ b/compiler/characterizer/functional.py @@ -52,18 +52,18 @@ class functional(simulation): rw_ops = ["noop", "write", "read"] w_ops = ["noop", "write"] r_ops = ["noop", "read"] - rw_read_data = "0"*self.word_size + rw_read_din_data = "0"*self.word_size check = 0 # First cycle idle - debug_comment = self.cycle_comment("noop", "0"*self.word_size, "0"*self.addr_size, 0, self.t_current) - self.add_noop_all_ports(debug_comment, "0"*self.addr_size, "0"*self.word_size) + comment = self.gen_cycle_comment("noop", "0"*self.word_size, "0"*self.addr_size, 0, self.t_current) + self.add_noop_all_ports(comment, "0"*self.addr_size, "0"*self.word_size) # Write at least once addr = self.gen_addr() word = self.gen_data() - debug_comment = self.cycle_comment("write", word, addr, 0, self.t_current) - self.add_write(debug_comment, addr, word, 0) + comment = self.gen_cycle_comment("write", word, addr, 0, self.t_current) + self.add_write(comment, addr, word, 0) self.stored_words[addr] = word # Read at least once. For multiport, it is important that one read cycle uses all RW and R port to read from the same address simultaniously. @@ -72,8 +72,8 @@ class functional(simulation): if self.port_id[port] == "w": self.add_noop_one_port("0"*self.addr_size, "0"*self.word_size, port) else: - debug_comment = self.cycle_comment("read", word, addr, port, self.t_current) - self.add_read_one_port(debug_comment, addr, rw_read_data, port) + comment = self.gen_cycle_comment("read", word, addr, port, self.t_current) + self.add_read_one_port(comment, addr, rw_read_din_data, port) self.write_check.append([word, "{0}{1}".format(self.dout_name,port), self.t_current+self.period, check]) check += 1 self.cycle_times.append(self.t_current) @@ -101,8 +101,8 @@ class functional(simulation): if addr in w_addrs: self.add_noop_one_port("0"*self.addr_size, "0"*self.word_size, port) else: - debug_comment = self.cycle_comment("write", word, addr, port, self.t_current) - self.add_write_one_port(debug_comment, addr, word, port) + comment = self.gen_cycle_comment("write", word, addr, port, self.t_current) + self.add_write_one_port(comment, addr, word, port) self.stored_words[addr] = word w_addrs.append(addr) else: @@ -111,8 +111,8 @@ class functional(simulation): if addr in w_addrs: self.add_noop_one_port("0"*self.addr_size, "0"*self.word_size, port) else: - debug_comment = self.cycle_comment("read", word, addr, port, self.t_current) - self.add_read_one_port(debug_comment, addr, rw_read_data, port) + comment = self.gen_cycle_comment("read", word, addr, port, self.t_current) + self.add_read_one_port(comment, addr, rw_read_din_data, port) self.write_check.append([word, "{0}{1}".format(self.dout_name,port), self.t_current+self.period, check]) check += 1 @@ -120,8 +120,8 @@ class functional(simulation): self.t_current += self.period # Last cycle idle needed to correctly measure the value on the second to last clock edge - debug_comment = self.cycle_comment("noop", "0"*self.word_size, "0"*self.addr_size, 0, self.t_current) - self.add_noop_all_ports(debug_comment, "0"*self.addr_size, "0"*self.word_size) + comment = self.gen_cycle_comment("noop", "0"*self.word_size, "0"*self.addr_size, 0, self.t_current) + self.add_noop_all_ports(comment, "0"*self.addr_size, "0"*self.word_size) def read_stim_results(self): # Extrat DOUT values from spice timing.lis @@ -129,17 +129,17 @@ class functional(simulation): sp_read_value = "" for bit in range(self.word_size): value = parse_spice_list("timing", "v{0}.{1}ck{2}".format(dout_port.lower(),bit,check)) - if value > 0.9 * self.vdd_voltage: + if value > 0.88 * self.vdd_voltage: sp_read_value = "1" + sp_read_value - elif value < 0.1 * self.vdd_voltage: + elif value < 0.12 * self.vdd_voltage: sp_read_value = "0" + sp_read_value else: error ="FAILED: {0}_{1} value {2} at time {3}n does not fall within noise margins <{4} or >{5}.".format(dout_port, bit, value, eo_period, - 0.1*self.vdd_voltage, - 0.9*self.vdd_voltage) + 0.12*self.vdd_voltage, + 0.88*self.vdd_voltage) return (0, error) self.read_check.append([sp_read_value, dout_port, eo_period, check]) @@ -225,6 +225,11 @@ class functional(simulation): sig_name="{0}{1}_{2} ".format(self.dout_name, self.read_index[port], bit) self.sf.write("CD{0}{1} {2} 0 {3}f\n".format(self.read_index[port], bit, sig_name, self.load)) + # Write debug comments to stim file + self.sf.write("\n\n * Sequence of operations\n") + for comment in self.fn_cycle_comments: + self.sf.write("*{}\n".format(comment)) + # Generate data input bits self.sf.write("\n* Generation of data and address signals\n") for port in range(self.total_write): @@ -267,7 +272,7 @@ class functional(simulation): t_intital=t_intital, t_final=t_final) - self.stim.write_control(self.cycle_times[-1] + self.period, runlvl=1) + self.stim.write_control(self.cycle_times[-1] + self.period) self.sf.close() diff --git a/compiler/characterizer/simulation.py b/compiler/characterizer/simulation.py index f56b1e39..3d156d2d 100644 --- a/compiler/characterizer/simulation.py +++ b/compiler/characterizer/simulation.py @@ -58,6 +58,7 @@ class simulation(): # For generating comments in SPICE stimulus self.cycle_comments = [] + self.fn_cycle_comments = [] def add_control_one_port(self, port, op): """Appends control signals for operation to a given port""" @@ -108,9 +109,11 @@ class simulation(): def add_write(self, comment, address, data, port): """ Add the control values for a write cycle. """ - debug.info(2, comment) debug.check(port in self.write_index, "Cannot add write cycle to a read port. Port {0}, Write Ports {1}".format(port, self.write_index)) + debug.info(2, comment) + self.fn_cycle_comments.append(comment) self.append_cycle_comment(port, comment) + self.cycle_times.append(self.t_current) self.t_current += self.period @@ -125,18 +128,20 @@ class simulation(): if unselected_port != port: self.add_noop_one_port(address, noop_data, unselected_port) - def add_read(self, comment, address, data, port): + def add_read(self, comment, address, din_data, port): """ Add the control values for a read cycle. """ - debug.info(2, comment) debug.check(port in self.read_index, "Cannot add read cycle to a write port. Port {0}, Read Ports {1}".format(port, self.read_index)) + debug.info(2, comment) + self.fn_cycle_comments.append(comment) self.append_cycle_comment(port, comment) + self.cycle_times.append(self.t_current) self.t_current += self.period self.add_control_one_port(port, "read") #If the port is also a readwrite then add data. if port in self.write_index: - self.add_data(data,port) + self.add_data(din_data,port) self.add_address(address, port) #This value is hard coded here. Possibly change to member variable or set in add_noop_one_port @@ -145,7 +150,48 @@ class simulation(): for unselected_port in range(self.total_ports): if unselected_port != port: self.add_noop_one_port(address, noop_data, unselected_port) - + + def add_noop_all_ports(self, comment, address, data): + """ Add the control values for a noop to all ports. """ + debug.info(2, comment) + self.fn_cycle_comments.append(comment) + self.append_cycle_comment("All", comment) + + self.cycle_times.append(self.t_current) + self.t_current += self.period + + for port in range(self.total_ports): + self.add_noop_one_port(address, data, port) + + def add_write_one_port(self, comment, address, data, port): + """ Add the control values for a write cycle. Does not increment the period. """ + debug.check(port in self.write_index, "Cannot add write cycle to a read port. Port {0}, Write Ports {1}".format(port, self.write_index)) + debug.info(2, comment) + self.fn_cycle_comments.append(comment) + + self.add_control_one_port(port, "write") + self.add_data(data,port) + self.add_address(address,port) + + def add_read_one_port(self, comment, address, din_data, port): + """ Add the control values for a read cycle. Does not increment the period. """ + debug.check(port in self.read_index, "Cannot add read cycle to a write port. Port {0}, Read Ports {1}".format(port, self.read_index)) + debug.info(2, comment) + self.fn_cycle_comments.append(comment) + + self.add_control_one_port(port, "read") + #If the port is also a readwrite then add data. + if port in self.write_index: + self.add_data(din_data,port) + self.add_address(address, port) + + def add_noop_one_port(self, address, data, port): + """ Add the control values for a noop to a single port. Does not increment the period. """ + self.add_control_one_port(port, "noop") + if port in self.write_index: + self.add_data(data,port) + self.add_address(address, port) + def append_cycle_comment(self, port, comment): """Add comment to list to be printed in stimulus file""" #Clean up time before appending. Make spacing dynamic as well. @@ -156,51 +202,8 @@ class simulation(): time, time_spacing, comment)) - - def add_noop_all_ports(self, comment, address, data): - """ Add the control values for a noop to all ports. """ - debug.info(2, comment) - self.append_cycle_comment("All", comment) - self.cycle_times.append(self.t_current) - self.t_current += self.period - - for port in range(self.total_ports): - self.add_noop_one_port(address, data, port) - - def add_write_one_port(self, comment, address, data, port): - """ Add the control values for a write cycle. Does not increment the period. """ - debug.check(port in self.write_index, "Cannot add write cycle to a read port. Port {0}, Write Ports {1}".format(port, self.write_index)) - debug.info(1, comment) - self.cycle_comments.append("Cycle {0:2d}\tPort {3}\t{1:5.2f}ns:\t{2}".format(len(self.cycle_comments), - self.t_current, - comment, - port)) - self.add_control_one_port(port, "write") - self.add_data(data,port) - self.add_address(address,port) - - def add_read_one_port(self, comment, address, data, port): - """ Add the control values for a read cycle. Does not increment the period. """ - debug.check(port in self.read_index, "Cannot add read cycle to a write port. Port {0}, Read Ports {1}".format(port, self.read_index)) - debug.info(1, comment) - self.cycle_comments.append("Cycle {0:2d}\tPort {3}\t{1:5.2f}ns:\t{2}".format(len(self.cycle_comments), - self.t_current, - comment, - port)) - self.add_control_one_port(port, "read") - #If the port is also a readwrite then add data. - if port in self.write_index: - self.add_data(data,port) - self.add_address(address, port) - - def add_noop_one_port(self, address, data, port): - """ Add the control values for a noop to a single port. Does not increment the period. """ - self.add_control_one_port(port, "noop") - if port in self.write_index: - self.add_data(data,port) - self.add_address(address, port) - def cycle_comment(self, op, word, addr, port, t_current): + def gen_cycle_comment(self, op, word, addr, port, t_current): if op == "noop": comment = "\tIdle during cycle {0} ({1}ns - {2}ns)".format(int(t_current/self.period), t_current, diff --git a/compiler/tests/21_hspice_delay_test.py b/compiler/tests/21_hspice_delay_test.py index 62352b69..a5aca3e8 100755 --- a/compiler/tests/21_hspice_delay_test.py +++ b/compiler/tests/21_hspice_delay_test.py @@ -17,16 +17,13 @@ class timing_sram_test(openram_test): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) OPTS.spice_name="hspice" OPTS.analytical_delay = False - + OPTS.netlist_only = True # This is a hack to reload the characterizer __init__ with the spice version from importlib import reload import characterizer reload(characterizer) from characterizer import delay - if not OPTS.spice_exe: - debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) - from sram import sram from sram_config import sram_config c = sram_config(word_size=1, diff --git a/compiler/tests/21_hspice_setuphold_test.py b/compiler/tests/21_hspice_setuphold_test.py index 2969f95e..9bfdb24b 100755 --- a/compiler/tests/21_hspice_setuphold_test.py +++ b/compiler/tests/21_hspice_setuphold_test.py @@ -17,15 +17,13 @@ class timing_setup_test(openram_test): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) OPTS.spice_name="hspice" OPTS.analytical_delay = False - + OPTS.netlist_only = True + # This is a hack to reload the characterizer __init__ with the spice version from importlib import reload import characterizer reload(characterizer) from characterizer import setup_hold - if not OPTS.spice_exe: - debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) - import sram import tech slews = [tech.spice["rise_time"]*2] diff --git a/compiler/tests/21_ngspice_delay_test.py b/compiler/tests/21_ngspice_delay_test.py index 37572318..45a9b7f6 100755 --- a/compiler/tests/21_ngspice_delay_test.py +++ b/compiler/tests/21_ngspice_delay_test.py @@ -24,9 +24,6 @@ class timing_sram_test(openram_test): import characterizer reload(characterizer) from characterizer import delay - if not OPTS.spice_exe: - debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) - from sram import sram from sram_config import sram_config c = sram_config(word_size=1, diff --git a/compiler/tests/21_ngspice_setuphold_test.py b/compiler/tests/21_ngspice_setuphold_test.py index d86fcb23..d58bfc50 100755 --- a/compiler/tests/21_ngspice_setuphold_test.py +++ b/compiler/tests/21_ngspice_setuphold_test.py @@ -17,15 +17,13 @@ class timing_setup_test(openram_test): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) OPTS.spice_name="ngspice" OPTS.analytical_delay = False - + OPTS.netlist_only = True + # This is a hack to reload the characterizer __init__ with the spice version from importlib import reload import characterizer reload(characterizer) from characterizer import setup_hold - if not OPTS.spice_exe: - debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) - import sram import tech slews = [tech.spice["rise_time"]*2] diff --git a/compiler/tests/22_psram_func_test.py b/compiler/tests/22_psram_1bank_2mux_func_test.py similarity index 66% rename from compiler/tests/22_psram_func_test.py rename to compiler/tests/22_psram_1bank_2mux_func_test.py index 6a527754..d8233d08 100755 --- a/compiler/tests/22_psram_func_test.py +++ b/compiler/tests/22_psram_1bank_2mux_func_test.py @@ -11,8 +11,8 @@ import globals from globals import OPTS import debug -#@unittest.skip("SKIPPING 22_psram_func_test") -class psram_func_test(openram_test): +#@unittest.skip("SKIPPING 22_psram_1bank_2mux_func_test") +class psram_1bank_2mux_func_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) @@ -26,33 +26,27 @@ class psram_func_test(openram_test): import characterizer reload(characterizer) from characterizer import functional - if not OPTS.spice_exe: - debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) - from sram import sram from sram_config import sram_config c = sram_config(word_size=4, num_words=64, num_banks=1) c.words_per_row=2 - - OPTS.num_rw_ports = 1 - OPTS.num_w_ports = 1 - OPTS.num_r_ports = 1 - - debug.info(1, "Functional test for 1bit, 16word SRAM, with 1 bank. Multiport with {}RW {}W {}R.".format(OPTS.num_rw_ports, OPTS.num_w_ports, OPTS.num_r_ports)) - s = sram(c, name="sram1") - - tempspice = OPTS.openram_temp + "temp.sp" + debug.info(1, "Functional test for psram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + tempspice = OPTS.openram_temp + "temp.sp" s.sp_write(tempspice) - + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, tempspice, corner) f.num_cycles = 10 - (fail,error) = f.run() - + (fail, error) = f.run() self.assertTrue(fail,error) - + globals.end_openram() # instantiate a copdsay of the class to actually run the test diff --git a/compiler/tests/22_psram_1bank_4mux_func_test.py b/compiler/tests/22_psram_1bank_4mux_func_test.py new file mode 100755 index 00000000..1ae684d9 --- /dev/null +++ b/compiler/tests/22_psram_1bank_4mux_func_test.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +""" +Run a regression test on various srams +""" + +import unittest +from testutils import header,openram_test +import sys,os +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +import debug + +@unittest.skip("SKIPPING 22_psram_1bank_4mux_func_test") +class psram_1bank_4mux_func_test(openram_test): + + def runTest(self): + globals.init_openram("config_20_{0}".format(OPTS.tech_name)) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.bitcell = "pbitcell" + OPTS.replica_bitcell="replica_pbitcell" + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram import sram + from sram_config import sram_config + c = sram_config(word_size=4, + num_words=256, + num_banks=1) + c.words_per_row=4 + debug.info(1, "Functional test for psram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + tempspice = OPTS.openram_temp + "temp.sp" + s.sp_write(tempspice) + + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + + f = functional(s.s, tempspice, corner) + f.num_cycles = 10 + (fail, error) = f.run() + self.assertTrue(fail,error) + + globals.end_openram() + +# instantiate a copdsay of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/compiler/tests/22_psram_1bank_8mux_func_test.py b/compiler/tests/22_psram_1bank_8mux_func_test.py new file mode 100755 index 00000000..d81e76f9 --- /dev/null +++ b/compiler/tests/22_psram_1bank_8mux_func_test.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Run a regression test on various srams +""" + +import unittest +from testutils import header,openram_test +import sys,os +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +import debug + +@unittest.skip("SKIPPING 22_psram_1bank_8mux_func_test") +class psram_1bank_8mux_func_test(openram_test): + + def runTest(self): + globals.init_openram("config_20_{0}".format(OPTS.tech_name)) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.bitcell = "pbitcell" + OPTS.replica_bitcell="replica_pbitcell" + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram import sram + from sram_config import sram_config + c = sram_config(word_size=4, + num_words=512, + num_banks=1) + c.words_per_row=8 + debug.info(1, "Functional test for psram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + s.sp_write(tempspice) + + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + + f = functional(s.s, tempspice, corner) + f.num_cycles = 10 + (fail, error) = f.run() + self.assertTrue(fail,error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/compiler/tests/22_psram_1bank_nomux_func_test.py b/compiler/tests/22_psram_1bank_nomux_func_test.py new file mode 100755 index 00000000..681e24d5 --- /dev/null +++ b/compiler/tests/22_psram_1bank_nomux_func_test.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +""" +Run a functioal test on 1 bank SRAM +""" + +import unittest +from testutils import header,openram_test +import sys,os +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +import debug + +#@unittest.skip("SKIPPING 22_psram_1bank_nomux_func_test") +class psram_1bank_nomux_func_test(openram_test): + + def runTest(self): + globals.init_openram("config_20_{0}".format(OPTS.tech_name)) + OPTS.analytical_delay = False + OPTS.netlist_only = True + OPTS.bitcell = "pbitcell" + OPTS.replica_bitcell="replica_pbitcell" + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram import sram + from sram_config import sram_config + c = sram_config(word_size=4, + num_words=32, + num_banks=1) + c.words_per_row=1 + debug.info(1, "Functional test for psram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + tempspice = OPTS.openram_temp + "temp.sp" + s.sp_write(tempspice) + + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + + f = functional(s.s, tempspice, corner) + f.num_cycles = 10 + (fail, error) = f.run() + self.assertTrue(fail,error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/compiler/tests/22_sram_func_test.py b/compiler/tests/22_sram_1bank_2mux_func_test.py similarity index 65% rename from compiler/tests/22_sram_func_test.py rename to compiler/tests/22_sram_1bank_2mux_func_test.py index de55c2ce..7779ed4f 100755 --- a/compiler/tests/22_sram_func_test.py +++ b/compiler/tests/22_sram_1bank_2mux_func_test.py @@ -11,8 +11,8 @@ import globals from globals import OPTS import debug -#@unittest.skip("SKIPPING 22_sram_func_test") -class sram_func_test(openram_test): +#@unittest.skip("SKIPPING 22_sram_1bank_2mux_func_test") +class sram_1bank_2mux_func_test(openram_test): def runTest(self): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) @@ -24,28 +24,27 @@ class sram_func_test(openram_test): import characterizer reload(characterizer) from characterizer import functional - if not OPTS.spice_exe: - debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) - from sram import sram from sram_config import sram_config c = sram_config(word_size=4, num_words=64, num_banks=1) c.words_per_row=2 - debug.info(1, "Functional test for 1bit, 16word SRAM, with 1 bank") - s = sram(c, name="sram1") - - tempspice = OPTS.openram_temp + "temp.sp" + debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + tempspice = OPTS.openram_temp + "temp.sp" s.sp_write(tempspice) - + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + f = functional(s.s, tempspice, corner) f.num_cycles = 10 (fail, error) = f.run() - self.assertTrue(fail,error) - + globals.end_openram() # instantiate a copdsay of the class to actually run the test diff --git a/compiler/tests/22_sram_1bank_4mux_func_test.py b/compiler/tests/22_sram_1bank_4mux_func_test.py new file mode 100755 index 00000000..c16b86fe --- /dev/null +++ b/compiler/tests/22_sram_1bank_4mux_func_test.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +""" +Run a regression test on various srams +""" + +import unittest +from testutils import header,openram_test +import sys,os +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +import debug + +@unittest.skip("SKIPPING 22_sram_1bank_4mux_func_test") +class sram_1bank_4mux_func_test(openram_test): + + def runTest(self): + globals.init_openram("config_20_{0}".format(OPTS.tech_name)) + OPTS.analytical_delay = False + OPTS.netlist_only = True + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram import sram + from sram_config import sram_config + c = sram_config(word_size=4, + num_words=256, + num_banks=1) + c.words_per_row=4 + debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + tempspice = OPTS.openram_temp + "temp.sp" + s.sp_write(tempspice) + + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + + f = functional(s.s, tempspice, corner) + f.num_cycles = 10 + (fail, error) = f.run() + self.assertTrue(fail,error) + + globals.end_openram() + +# instantiate a copdsay of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/compiler/tests/22_sram_1bank_8mux_func_test.py b/compiler/tests/22_sram_1bank_8mux_func_test.py new file mode 100755 index 00000000..be8e538f --- /dev/null +++ b/compiler/tests/22_sram_1bank_8mux_func_test.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +""" +Run a regression test on various srams +""" + +import unittest +from testutils import header,openram_test +import sys,os +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +import debug + +@unittest.skip("SKIPPING 22_sram_1bank_8mux_func_test") +class sram_1bank_8mux_func_test(openram_test): + + def runTest(self): + globals.init_openram("config_20_{0}".format(OPTS.tech_name)) + OPTS.analytical_delay = False + OPTS.netlist_only = True + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + if not OPTS.spice_exe: + debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) + + from sram import sram + from sram_config import sram_config + c = sram_config(word_size=4, + num_words=512, + num_banks=1) + c.words_per_row=8 + debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + s.sp_write(tempspice) + + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + + f = functional(s.s, tempspice, corner) + f.num_cycles = 10 + (fail, error) = f.run() + self.assertTrue(fail,error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/compiler/tests/22_sram_1bank_nomux_func_test.py b/compiler/tests/22_sram_1bank_nomux_func_test.py new file mode 100755 index 00000000..52d63f4a --- /dev/null +++ b/compiler/tests/22_sram_1bank_nomux_func_test.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +""" +Run a functioal test on 1 bank SRAM +""" + +import unittest +from testutils import header,openram_test +import sys,os +sys.path.append(os.path.join(sys.path[0],"..")) +import globals +from globals import OPTS +import debug + +#@unittest.skip("SKIPPING 22_sram_func_test") +class sram_1bank_nomux_func_test(openram_test): + + def runTest(self): + globals.init_openram("config_20_{0}".format(OPTS.tech_name)) + OPTS.analytical_delay = False + OPTS.netlist_only = True + + # This is a hack to reload the characterizer __init__ with the spice version + from importlib import reload + import characterizer + reload(characterizer) + from characterizer import functional + from sram import sram + from sram_config import sram_config + c = sram_config(word_size=4, + num_words=32, + num_banks=1) + c.words_per_row=1 + debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, + c.num_words, + c.words_per_row, + c.num_banks)) + s = sram(c, name="sram") + tempspice = OPTS.openram_temp + "temp.sp" + s.sp_write(tempspice) + + corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) + + f = functional(s.s, tempspice, corner) + f.num_cycles = 10 + (fail, error) = f.run() + self.assertTrue(fail,error) + + globals.end_openram() + +# instantiate a copy of the class to actually run the test +if __name__ == "__main__": + (OPTS, args) = globals.parse_args() + del sys.argv[1:] + header(__file__, OPTS.tech_name) + unittest.main() diff --git a/compiler/tests/27_worst_case_delay_test.py b/compiler/tests/27_worst_case_delay_test.py index cf999e45..42a07bef 100755 --- a/compiler/tests/27_worst_case_delay_test.py +++ b/compiler/tests/27_worst_case_delay_test.py @@ -19,6 +19,7 @@ class worst_case_timing_sram_test(openram_test): globals.init_openram("config_20_{0}".format(OPTS.tech_name)) OPTS.spice_name="hspice" OPTS.analytical_delay = False + OPTS.netlist_only = True OPTS.trim_netlist = False OPTS.check_lvsdrc = True