Add both ngspice and hspice timing tests. Add hidden option to force to a version. Otherwise, default to either version if found.

This commit is contained in:
Matt Guthaus 2016-11-10 11:33:10 -08:00
parent b7b3a796f5
commit f3f2171f89
8 changed files with 240 additions and 27 deletions

View File

@ -185,37 +185,48 @@ def set_spice():
debug.info(2,"Finding spice...")
global OPTS
# set the input dir for spice files if using ngspice (not needed for
# hspice)
OPTS.spice_exe = ""
# Check if the preferred spice option exists in the path
for path in os.environ["PATH"].split(os.pathsep):
spice_exe = os.path.join(path, OPTS.spice_version)
# if it is found, then break and use first version
if is_exe(spice_exe):
debug.info(1, "Using spice: " + spice_exe)
OPTS.spice_exe = spice_exe
break
if not OPTS.force_spice:
# if we didn't find the preferred version, try the other version and warn
prev_version=OPTS.spice_version
if OPTS.spice_version == "hspice":
OPTS.spice_version = "ngspice"
else:
OPTS.spice_version = "hspice"
debug.warning("Unable to find {0} so trying {1}".format(prev_version,OPTS.spice_version))
for path in os.environ["PATH"].split(os.pathsep):
spice_exe = os.path.join(path, OPTS.spice_version)
# if it is found, then break and use first version
if is_exe(spice_exe):
found_spice = True
debug.info(1, "Using spice: " + spice_exe)
OPTS.spice_exe = spice_exe
break
# 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)
for path in os.environ["PATH"].split(os.pathsep):
OPTS.spice_exe = os.path.join(path, OPTS.spice_version)
# if it is found, then break and use first version
if is_exe(OPTS.spice_exe):
debug.info(1, "Using spice: " + OPTS.spice_exe)
return
# if we didn't find the previous version, try the other version
if OPTS.spice_version == "hspice":
OPTS.spice_version = "ngspice"
else:
OPTS.spice_version = "hspice"
debug.warning("Unable to find spice so trying other: " + OPTS.spice_version)
for path in os.environ["PATH"].split(os.pathsep):
OPTS.spice_exe = os.path.join(path, OPTS.spice_version)
# if it is found, then break and use first version
if is_exe(OPTS.spice_exe):
found_spice = True
debug.info(1, "Using spice: " + OPTS.spice_exe)
break
else:
if OPTS.spice_exe == "":
# otherwise, give warning and procede
debug.warning("Spice not found. Unable to perform characterization.")
if OPTS.force_spice:
debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_version),1)
else:
debug.error("Neither hspice/ngspice not found. Unable to perform characterization.",1)
# imports correct technology directories for testing
def import_tech():
global OPTS

View File

@ -18,6 +18,8 @@ class options(optparse.Values):
check_lvsdrc = True
# Variable to select the variant of spice (hspice or ngspice right now)
spice_version = "hspice"
# Should we fall back if we can't find our preferred spice?
force_spice = False
# Should we print out the banner at startup
print_banner = True
# The Calibre executable being used which is derived from the user PATH.

View File

@ -23,7 +23,10 @@ class timing_sram_test(unittest.TestCase):
# we will manually run lvs/drc
OPTS.check_lvsdrc = False
OPTS.use_pex = False
OPTS.spice_version="hspice"
OPTS.force_spice = True
globals.set_spice()
import sram
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")

View File

@ -23,6 +23,9 @@ class timing_setup_test(unittest.TestCase):
# we will manually run lvs/drc
OPTS.check_lvsdrc = False
OPTS.use_pex = False
OPTS.spice_version="hspice"
OPTS.force_spice = True
globals.set_spice()
import sram
import setup_hold

View File

@ -20,9 +20,13 @@ class timing_setup_test(unittest.TestCase):
def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
# we will manually run lvs/drc
OPTS.check_lvsdrc = False
OPTS.use_pex = False
OPTS.spice_version="hspice"
OPTS.force_spice = True
globals.set_spice()
import sram
import setup_hold

View File

@ -0,0 +1,77 @@
#!/usr/bin/env python2.7
"""
Run a regresion test on various srams
"""
import unittest
from header import header
import sys,os
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.get_opts()
#@unittest.skip("SKIPPING 21_timing_sram_test")
class timing_sram_test(unittest.TestCase):
def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
# we will manually run lvs/drc
OPTS.check_lvsdrc = False
OPTS.use_pex = False
OPTS.spice_version="ngspice"
OPTS.force_spice = True
globals.set_spice()
import sram
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
s = sram.sram(word_size=OPTS.config.word_size,
num_words=OPTS.config.num_words,
num_banks=OPTS.config.num_banks,
name="test_sram1")
OPTS.check_lvsdrc = True
import delay
tempspice = OPTS.openram_temp + "temp.sp"
s.sp_write(tempspice)
probe_address = "1" * s.addr_size
probe_data = s.word_size - 1
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
d = delay.delay(s,tempspice)
data = d.analyze(probe_address, probe_data)
if OPTS.tech_name == "freepdk45":
self.assertTrue(isclose(data['delay1'],0.013649))
self.assertTrue(isclose(data['delay0'],0.22893))
self.assertTrue(isclose(data['min_period1'],0.078582763671875))
self.assertTrue(isclose(data['min_period0'],0.25543212890625))
elif OPTS.tech_name == "scn3me_subm":
self.assertTrue(isclose(data['delay1'],1.5335))
self.assertTrue(isclose(data['delay0'],2.2635000000000005))
self.assertTrue(isclose(data['min_period1'],1.53564453125))
self.assertTrue(isclose(data['min_period0'],2.998046875))
else:
self.assertTrue(False) # other techs fail
os.remove(tempspice)
def isclose(value1,value2):
""" This is used to compare relative values for convergence. """
return (abs(value1 - value2) / max(value1,value2) <= 1e-2)
# 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()

View File

@ -0,0 +1,57 @@
#!/usr/bin/env python2.7
"""
Run a regresion test on various srams
"""
import unittest
from header import header
import sys,os
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.get_opts()
#@unittest.skip("SKIPPING 21_timing_sram_test")
class timing_setup_test(unittest.TestCase):
def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
# we will manually run lvs/drc
OPTS.check_lvsdrc = False
OPTS.use_pex = False
OPTS.spice_version="ngspice"
OPTS.force_spice = True
globals.set_spice()
import sram
import setup_hold
sh = setup_hold.setup_hold()
[one_setup_time, zero_setup_time] = sh.hold_time()
OPTS.check_lvsdrc = True
if OPTS.tech_name == "freepdk45":
self.assertTrue(isclose(one_setup_time,-0.0048828125))
self.assertTrue(isclose(zero_setup_time,-0.010986328125))
elif OPTS.tech_name == "scn3me_subm":
self.assertTrue(isclose(one_setup_time,0.04638671875))
self.assertTrue(isclose(zero_setup_time,-0.0830078125))
else:
self.assertTrue(False) # other techs fail
def isclose(value1,value2):
""" This is used to compare relative values for convergence. """
return (abs(value1 - value2) / max(value1,value2) <= 1e-2)
# 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()

View File

@ -0,0 +1,56 @@
#!/usr/bin/env python2.7
"""
Run a regresion test on various srams
"""
import unittest
from header import header
import sys,os
sys.path.append(os.path.join(sys.path[0],".."))
import globals
import debug
import calibre
OPTS = globals.get_opts()
#@unittest.skip("SKIPPING 21_timing_sram_test")
class timing_setup_test(unittest.TestCase):
def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
# we will manually run lvs/drc
OPTS.check_lvsdrc = False
OPTS.use_pex = False
OPTS.spice_version="ngspice"
OPTS.force_spice = True
globals.set_spice()
import sram
import setup_hold
sh = setup_hold.setup_hold()
[one_setup_time, zero_setup_time] = sh.setup_time()
OPTS.check_lvsdrc = True
if OPTS.tech_name == "freepdk45":
self.assertTrue(isclose(one_setup_time,0.0146484375))
self.assertTrue(isclose(zero_setup_time,0.008544921875))
elif OPTS.tech_name == "scn3me_subm":
self.assertTrue(isclose(one_setup_time,0.0927734375))
self.assertTrue(isclose(zero_setup_time,-0.0244140625))
else:
self.assertTrue(False) # other techs fail
def isclose(value1,value2):
""" This is used to compare relative values for convergence. """
return (abs(value1 - value2) / max(value1,value2) <= 1e-2)
# 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()