mirror of https://github.com/VLSIDA/OpenRAM.git
Skywater changes.
Default 1 thread and no temp subdirectory. Add skywater setup/hold golden data Add CLI option for simulation threads (-m) Add compatibility mode option and nomodcheck for ngspice to speed up sky130 model loading. Make subdir when using default /tmp dir. Pass num_threads so temp subdirs are created.
This commit is contained in:
parent
b6f3fbdd1f
commit
671470f5f2
|
|
@ -19,7 +19,7 @@ jobs:
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: scn4me_subm Archives
|
name: scn4me_subm Archives
|
||||||
path: ${{ github.workspace }}/scn4me_subm_temp/*/*
|
path: $OPENRAM_HOME/*.zip
|
||||||
freepdk45:
|
freepdk45:
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -38,7 +38,7 @@ jobs:
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: FreePDK45 Archives
|
name: FreePDK45 Archives
|
||||||
path: ${{ github.workspace }}/freepdk45_temp/*/*
|
path: $OPENRAM_HOME/*.zip
|
||||||
# coverage_stats:
|
# coverage_stats:
|
||||||
# if: ${{ always() }}
|
# if: ${{ always() }}
|
||||||
# needs: [scn4me_subm, freepdk45]
|
# needs: [scn4me_subm, freepdk45]
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ def parse_spice_list(filename, key):
|
||||||
f = open(full_filename, "r")
|
f = open(full_filename, "r")
|
||||||
except IOError:
|
except IOError:
|
||||||
debug.error("Unable to open spice output file: {0}".format(full_filename),1)
|
debug.error("Unable to open spice output file: {0}".format(full_filename),1)
|
||||||
|
debug.archive()
|
||||||
|
|
||||||
contents = f.read()
|
contents = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
# val = re.search(r"{0}\s*=\s*(-?\d+.?\d*\S*)\s+.*".format(key), contents)
|
# val = re.search(r"{0}\s*=\s*(-?\d+.?\d*\S*)\s+.*".format(key), contents)
|
||||||
|
|
|
||||||
|
|
@ -360,6 +360,8 @@ class stimuli():
|
||||||
# -r {2}timing.raw
|
# -r {2}timing.raw
|
||||||
ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w")
|
ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w")
|
||||||
ng_cfg.write("set num_threads={}\n".format(OPTS.num_sim_threads))
|
ng_cfg.write("set num_threads={}\n".format(OPTS.num_sim_threads))
|
||||||
|
ng_cfg.write("set ngbehavior=hsa\n")
|
||||||
|
ng_cfg.write("set ng_nomodcheck\n")
|
||||||
ng_cfg.close()
|
ng_cfg.close()
|
||||||
|
|
||||||
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ def error(str, return_value=0):
|
||||||
|
|
||||||
if globals.OPTS.debug:
|
if globals.OPTS.debug:
|
||||||
pdb.set_trace()
|
pdb.set_trace()
|
||||||
|
|
||||||
assert return_value == 0
|
assert return_value == 0
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -108,7 +108,20 @@ def info(lev, str):
|
||||||
print_raw("[{0}/{1}]: {2}".format(class_name,
|
print_raw("[{0}/{1}]: {2}".format(class_name,
|
||||||
frm[0].f_code.co_name, str))
|
frm[0].f_code.co_name, str))
|
||||||
|
|
||||||
|
|
||||||
|
def archive():
|
||||||
|
from globals import OPTS
|
||||||
|
try:
|
||||||
|
OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME"))
|
||||||
|
except:
|
||||||
|
error("$OPENRAM_HOME is not properly defined.", 1)
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
zip_file = "{0}/{1}_{2}".format(OPENRAM_HOME, "fail_", os.getpid())
|
||||||
|
info(0, "Archiving failed files to {}.zip".format(zip_file))
|
||||||
|
shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
|
||||||
|
|
||||||
|
|
||||||
def bp():
|
def bp():
|
||||||
"""
|
"""
|
||||||
An empty function so you can set soft breakpoints in pdb.
|
An empty function so you can set soft breakpoints in pdb.
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,13 @@ def parse_args():
|
||||||
optparse.make_option("-j", "--threads",
|
optparse.make_option("-j", "--threads",
|
||||||
action="store",
|
action="store",
|
||||||
type="int",
|
type="int",
|
||||||
help="Specify the number of threads (default: 2)",
|
help="Specify the number of threads (default: 1)",
|
||||||
dest="num_threads"),
|
dest="num_threads"),
|
||||||
|
optparse.make_option("-m", "--sim_threads",
|
||||||
|
action="store",
|
||||||
|
type="int",
|
||||||
|
help="Specify the number of spice simulation threads (default: 2)",
|
||||||
|
dest="num_sim_threads"),
|
||||||
optparse.make_option("-v",
|
optparse.make_option("-v",
|
||||||
"--verbose",
|
"--verbose",
|
||||||
action="count",
|
action="count",
|
||||||
|
|
@ -381,6 +386,10 @@ def purge_temp():
|
||||||
""" Remove the temp directory. """
|
""" Remove the temp directory. """
|
||||||
debug.info(1,
|
debug.info(1,
|
||||||
"Purging temp directory: {}".format(OPTS.openram_temp))
|
"Purging temp directory: {}".format(OPTS.openram_temp))
|
||||||
|
#import inspect
|
||||||
|
#s = inspect.stack()
|
||||||
|
#print("Purge {0} in dir {1}".format(s[3].filename, OPTS.openram_temp))
|
||||||
|
|
||||||
# This annoyingly means you have to re-cd into
|
# This annoyingly means you have to re-cd into
|
||||||
# the directory each debug iteration
|
# the directory each debug iteration
|
||||||
# shutil.rmtree(OPTS.openram_temp, ignore_errors=True)
|
# shutil.rmtree(OPTS.openram_temp, ignore_errors=True)
|
||||||
|
|
@ -429,9 +438,15 @@ def setup_paths():
|
||||||
if "__pycache__" not in full_path:
|
if "__pycache__" not in full_path:
|
||||||
sys.path.append("{0}".format(full_path))
|
sys.path.append("{0}".format(full_path))
|
||||||
|
|
||||||
# Use a unique temp subdirectory
|
# Use a unique temp subdirectory if multithreaded
|
||||||
OPTS.openram_temp += "/openram_{0}_{1}_temp/".format(getpass.getuser(),
|
if OPTS.num_threads > 1 or OPTS.openram_temp == "/tmp":
|
||||||
os.getpid())
|
|
||||||
|
# Make a unique subdir
|
||||||
|
tempdir = "/openram_{0}_{1}_temp".format(getpass.getuser(),
|
||||||
|
os.getpid())
|
||||||
|
# Only add the unique subdir one time
|
||||||
|
if tempdir not in OPTS.openram_temp:
|
||||||
|
OPTS.openram_temp += tempdir
|
||||||
|
|
||||||
if not OPTS.openram_temp.endswith('/'):
|
if not OPTS.openram_temp.endswith('/'):
|
||||||
OPTS.openram_temp += "/"
|
OPTS.openram_temp += "/"
|
||||||
|
|
@ -470,6 +485,12 @@ def init_paths():
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.errno == 17: # errno.EEXIST
|
if e.errno == 17: # errno.EEXIST
|
||||||
os.chmod(OPTS.openram_temp, 0o750)
|
os.chmod(OPTS.openram_temp, 0o750)
|
||||||
|
#import inspect
|
||||||
|
#s = inspect.stack()
|
||||||
|
#from pprint import pprint
|
||||||
|
#pprint(s)
|
||||||
|
#print("Test {0} in dir {1}".format(s[2].filename, OPTS.openram_temp))
|
||||||
|
|
||||||
|
|
||||||
# Don't delete the output dir, it may have other files!
|
# Don't delete the output dir, it may have other files!
|
||||||
# make the directory if it doesn't exist
|
# make the directory if it doesn't exist
|
||||||
|
|
|
||||||
|
|
@ -526,13 +526,16 @@ class bank(design.design):
|
||||||
height=self.dff.height)
|
height=self.dff.height)
|
||||||
elif self.col_addr_size == 2:
|
elif self.col_addr_size == 2:
|
||||||
self.column_decoder = factory.create(module_type="hierarchical_predecode2x4",
|
self.column_decoder = factory.create(module_type="hierarchical_predecode2x4",
|
||||||
|
column_decoder=True,
|
||||||
height=self.dff.height)
|
height=self.dff.height)
|
||||||
|
|
||||||
elif self.col_addr_size == 3:
|
elif self.col_addr_size == 3:
|
||||||
self.column_decoder = factory.create(module_type="hierarchical_predecode3x8",
|
self.column_decoder = factory.create(module_type="hierarchical_predecode3x8",
|
||||||
|
column_decoder=True,
|
||||||
height=self.dff.height)
|
height=self.dff.height)
|
||||||
elif self.col_addr_size == 4:
|
elif self.col_addr_size == 4:
|
||||||
self.column_decoder = factory.create(module_type="hierarchical_predecode4x16",
|
self.column_decoder = factory.create(module_type="hierarchical_predecode4x16",
|
||||||
|
column_decoder=True,
|
||||||
height=self.dff.height)
|
height=self.dff.height)
|
||||||
else:
|
else:
|
||||||
# No error checking before?
|
# No error checking before?
|
||||||
|
|
|
||||||
|
|
@ -18,19 +18,17 @@ class hierarchical_predecode(design.design):
|
||||||
"""
|
"""
|
||||||
Pre 2x4 and 3x8 and TBD 4x16 decoder shared code.
|
Pre 2x4 and 3x8 and TBD 4x16 decoder shared code.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, input_number, height=None):
|
def __init__(self, name, input_number, column_decoder=False, height=None):
|
||||||
self.number_of_inputs = input_number
|
self.number_of_inputs = input_number
|
||||||
|
|
||||||
b = factory.create(module_type=OPTS.bitcell)
|
b = factory.create(module_type=OPTS.bitcell)
|
||||||
|
|
||||||
if not height:
|
if not height:
|
||||||
self.cell_height = b.height
|
self.cell_height = b.height
|
||||||
self.column_decoder = False
|
|
||||||
else:
|
else:
|
||||||
self.cell_height = height
|
self.cell_height = height
|
||||||
# If we are pitch matched to the bitcell, it's a predecoder
|
|
||||||
# otherwise it's a column decoder (out of pgates)
|
self.column_decoder = column_decoder
|
||||||
self.column_decoder = (height != b.height)
|
|
||||||
|
|
||||||
self.number_of_outputs = int(math.pow(2, self.number_of_inputs))
|
self.number_of_outputs = int(math.pow(2, self.number_of_inputs))
|
||||||
super().__init__(name)
|
super().__init__(name)
|
||||||
|
|
@ -87,8 +85,15 @@ class hierarchical_predecode(design.design):
|
||||||
|
|
||||||
self.bus_layer = layer_props.hierarchical_predecode.bus_layer
|
self.bus_layer = layer_props.hierarchical_predecode.bus_layer
|
||||||
self.bus_directions = layer_props.hierarchical_predecode.bus_directions
|
self.bus_directions = layer_props.hierarchical_predecode.bus_directions
|
||||||
self.bus_pitch = getattr(self, self.bus_layer + "_pitch")
|
|
||||||
self.bus_space = layer_props.hierarchical_predecode.bus_space_factor * getattr(self, self.bus_layer + "_space")
|
if self.column_decoder:
|
||||||
|
# Column decoders may be routed on M2/M3 if there's a write mask
|
||||||
|
self.bus_pitch = self.m3_pitch
|
||||||
|
self.bus_space = self.m3_space
|
||||||
|
else:
|
||||||
|
self.bus_pitch = getattr(self, self.bus_layer + "_pitch")
|
||||||
|
self.bus_space = getattr(self, self.bus_layer + "_space")
|
||||||
|
self.bus_space = layer_props.hierarchical_predecode.bus_space_factor * self.bus_space
|
||||||
self.input_layer = layer_props.hierarchical_predecode.input_layer
|
self.input_layer = layer_props.hierarchical_predecode.input_layer
|
||||||
self.output_layer = layer_props.hierarchical_predecode.output_layer
|
self.output_layer = layer_props.hierarchical_predecode.output_layer
|
||||||
self.output_layer_pitch = getattr(self, self.output_layer + "_pitch")
|
self.output_layer_pitch = getattr(self, self.output_layer + "_pitch")
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ class hierarchical_predecode2x4(hierarchical_predecode):
|
||||||
"""
|
"""
|
||||||
Pre 2x4 decoder used in hierarchical_decoder.
|
Pre 2x4 decoder used in hierarchical_decoder.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, height=None):
|
def __init__(self, name, column_decoder=False, height=None):
|
||||||
super().__init__( name, 2, height)
|
super().__init__(name, 2, column_decoder, height)
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
if not OPTS.netlist_only:
|
if not OPTS.netlist_only:
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ class hierarchical_predecode3x8(hierarchical_predecode):
|
||||||
"""
|
"""
|
||||||
Pre 3x8 decoder used in hierarchical_decoder.
|
Pre 3x8 decoder used in hierarchical_decoder.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, height=None):
|
def __init__(self, name, column_decoder=False, height=None):
|
||||||
super().__init__(name, 3, height)
|
super().__init__(name, 3, column_decoder, height)
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
if not OPTS.netlist_only:
|
if not OPTS.netlist_only:
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ class hierarchical_predecode4x16(hierarchical_predecode):
|
||||||
"""
|
"""
|
||||||
Pre 4x16 decoder used in hierarchical_decoder.
|
Pre 4x16 decoder used in hierarchical_decoder.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, height=None):
|
def __init__(self, name, column_decoder=False, height=None):
|
||||||
super().__init__(name, 4, height)
|
super().__init__(name, 4, column_decoder, height)
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
if not OPTS.netlist_only:
|
if not OPTS.netlist_only:
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ class options(optparse.Values):
|
||||||
magic_exe = None
|
magic_exe = None
|
||||||
|
|
||||||
# Number of threads to use
|
# Number of threads to use
|
||||||
num_threads = 2
|
num_threads = 1
|
||||||
# Number of threads to use in ngspice/hspice
|
# Number of threads to use in ngspice/hspice
|
||||||
num_sim_threads = 2
|
num_sim_threads = 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ import sys, os
|
||||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||||
import globals
|
import globals
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
from sram_factory import factory
|
|
||||||
import debug
|
|
||||||
|
|
||||||
class timing_setup_test(openram_test):
|
class timing_setup_test(openram_test):
|
||||||
|
|
||||||
|
|
@ -29,14 +28,12 @@ class timing_setup_test(openram_test):
|
||||||
import characterizer
|
import characterizer
|
||||||
reload(characterizer)
|
reload(characterizer)
|
||||||
from characterizer import setup_hold
|
from characterizer import setup_hold
|
||||||
import sram
|
|
||||||
import tech
|
import tech
|
||||||
slews = [tech.spice["rise_time"]*2]
|
slews = [tech.spice["rise_time"]*2]
|
||||||
|
|
||||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||||
sh = setup_hold(corner)
|
sh = setup_hold(corner)
|
||||||
data = sh.analyze(slews,slews)
|
data = sh.analyze(slews,slews)
|
||||||
#print data
|
|
||||||
if OPTS.tech_name == "freepdk45":
|
if OPTS.tech_name == "freepdk45":
|
||||||
golden_data = {'hold_times_HL': [-0.0158691],
|
golden_data = {'hold_times_HL': [-0.0158691],
|
||||||
'hold_times_LH': [-0.0158691],
|
'hold_times_LH': [-0.0158691],
|
||||||
|
|
@ -47,6 +44,11 @@ class timing_setup_test(openram_test):
|
||||||
'hold_times_LH': [-0.11718749999999999],
|
'hold_times_LH': [-0.11718749999999999],
|
||||||
'setup_times_HL': [0.16357419999999998],
|
'setup_times_HL': [0.16357419999999998],
|
||||||
'setup_times_LH': [0.1757812]}
|
'setup_times_LH': [0.1757812]}
|
||||||
|
elif OPTS.tech_name == "sky130":
|
||||||
|
golden_data = {'hold_times_HL': [-0.05615234],
|
||||||
|
'hold_times_LH': [-0.03173828],
|
||||||
|
'setup_times_HL': [0.078125],
|
||||||
|
'setup_times_LH': [0.1025391]}
|
||||||
else:
|
else:
|
||||||
self.assertTrue(False) # other techs fail
|
self.assertTrue(False) # other techs fail
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ import sys, os
|
||||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||||
import globals
|
import globals
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
from sram_factory import factory
|
|
||||||
import debug
|
|
||||||
|
|
||||||
class timing_setup_test(openram_test):
|
class timing_setup_test(openram_test):
|
||||||
|
|
||||||
|
|
@ -29,14 +28,12 @@ class timing_setup_test(openram_test):
|
||||||
import characterizer
|
import characterizer
|
||||||
reload(characterizer)
|
reload(characterizer)
|
||||||
from characterizer import setup_hold
|
from characterizer import setup_hold
|
||||||
import sram
|
|
||||||
import tech
|
import tech
|
||||||
slews = [tech.spice["rise_time"]*2]
|
slews = [tech.spice["rise_time"]*2]
|
||||||
|
|
||||||
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
|
||||||
sh = setup_hold(corner)
|
sh = setup_hold(corner)
|
||||||
data = sh.analyze(slews,slews)
|
data = sh.analyze(slews,slews)
|
||||||
#print data
|
|
||||||
if OPTS.tech_name == "freepdk45":
|
if OPTS.tech_name == "freepdk45":
|
||||||
golden_data = {'hold_times_HL': [-0.01586914],
|
golden_data = {'hold_times_HL': [-0.01586914],
|
||||||
'hold_times_LH': [-0.01586914],
|
'hold_times_LH': [-0.01586914],
|
||||||
|
|
@ -47,6 +44,11 @@ class timing_setup_test(openram_test):
|
||||||
'hold_times_LH': [-0.1293945],
|
'hold_times_LH': [-0.1293945],
|
||||||
'setup_times_HL': [0.1757812],
|
'setup_times_HL': [0.1757812],
|
||||||
'setup_times_LH': [0.1879883]}
|
'setup_times_LH': [0.1879883]}
|
||||||
|
elif OPTS.tech_name == "sky130":
|
||||||
|
golden_data = {'hold_times_HL': [-0.05615234],
|
||||||
|
'hold_times_LH': [-0.03173828],
|
||||||
|
'setup_times_HL': [0.078125],
|
||||||
|
'setup_times_LH': [0.1025391]}
|
||||||
else:
|
else:
|
||||||
self.assertTrue(False) # other techs fail
|
self.assertTrue(False) # other techs fail
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ class openram_back_end_test(openram_test):
|
||||||
if OPTS.tech_name:
|
if OPTS.tech_name:
|
||||||
options += " -t {}".format(OPTS.tech_name)
|
options += " -t {}".format(OPTS.tech_name)
|
||||||
|
|
||||||
|
if OPTS.num_threads:
|
||||||
|
options += " -j {}".format(OPTS.num_threads)
|
||||||
|
|
||||||
# Always perform code coverage
|
# Always perform code coverage
|
||||||
if OPTS.coverage == 0:
|
if OPTS.coverage == 0:
|
||||||
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
|
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ class openram_front_end_test(openram_test):
|
||||||
if OPTS.tech_name:
|
if OPTS.tech_name:
|
||||||
options += " -t {}".format(OPTS.tech_name)
|
options += " -t {}".format(OPTS.tech_name)
|
||||||
|
|
||||||
|
if OPTS.num_threads:
|
||||||
|
options += " -j {}".format(OPTS.num_threads)
|
||||||
|
|
||||||
# Always perform code coverage
|
# Always perform code coverage
|
||||||
if OPTS.coverage == 0:
|
if OPTS.coverage == 0:
|
||||||
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
|
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import sys, os
|
||||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||||
import globals
|
import globals
|
||||||
from subunit import ProtocolTestCase, TestProtocolClient
|
from subunit import ProtocolTestCase, TestProtocolClient
|
||||||
from subunit.test_results import AutoTimingTestResultDecorator
|
|
||||||
from testtools import ConcurrentTestSuite
|
from testtools import ConcurrentTestSuite
|
||||||
|
|
||||||
(OPTS, args) = globals.parse_args()
|
(OPTS, args) = globals.parse_args()
|
||||||
|
|
@ -71,7 +70,7 @@ def fork_tests(num_threads):
|
||||||
stream = os.fdopen(c2pwrite, 'wb', 0)
|
stream = os.fdopen(c2pwrite, 'wb', 0)
|
||||||
os.close(c2pread)
|
os.close(c2pread)
|
||||||
sys.stdin.close()
|
sys.stdin.close()
|
||||||
test_suite_result = AutoTimingTestResultDecorator(TestProtocolClient(stream))
|
test_suite_result = TestProtocolClient(stream)
|
||||||
test_suite.run(test_suite_result)
|
test_suite.run(test_suite_result)
|
||||||
except EBADF:
|
except EBADF:
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,9 @@ class openram_test(unittest.TestCase):
|
||||||
result=verify.run_drc(w.name, tempgds, None)
|
result=verify.run_drc(w.name, tempgds, None)
|
||||||
if result != 0:
|
if result != 0:
|
||||||
self.fail("DRC failed: {}".format(w.name))
|
self.fail("DRC failed: {}".format(w.name))
|
||||||
|
elif not OPTS.keep_temp:
|
||||||
if not OPTS.keep_temp:
|
|
||||||
self.cleanup()
|
self.cleanup()
|
||||||
|
|
||||||
def local_check(self, a, final_verification=False):
|
def local_check(self, a, final_verification=False):
|
||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
@ -74,10 +73,10 @@ class openram_test(unittest.TestCase):
|
||||||
# shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
|
# shutil.make_archive(zip_file, 'zip', OPTS.openram_temp)
|
||||||
self.fail("LVS mismatch: {}".format(a.name))
|
self.fail("LVS mismatch: {}".format(a.name))
|
||||||
|
|
||||||
|
if lvs_result == 0 and drc_result == 0 and not OPTS.keep_temp:
|
||||||
|
self.cleanup()
|
||||||
# For debug...
|
# For debug...
|
||||||
# import pdb; pdb.set_trace()
|
# import pdb; pdb.set_trace()
|
||||||
if not OPTS.keep_temp:
|
|
||||||
self.cleanup()
|
|
||||||
|
|
||||||
def run_pex(self, a, output=None):
|
def run_pex(self, a, output=None):
|
||||||
tempspice = "{}.sp".format(a.name)
|
tempspice = "{}.sp".format(a.name)
|
||||||
|
|
@ -104,6 +103,7 @@ class openram_test(unittest.TestCase):
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
""" Reset the duplicate checker and cleanup files. """
|
""" Reset the duplicate checker and cleanup files. """
|
||||||
|
|
||||||
files = glob.glob(OPTS.openram_temp + '*')
|
files = glob.glob(OPTS.openram_temp + '*')
|
||||||
for f in files:
|
for f in files:
|
||||||
# Only remove the files
|
# Only remove the files
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue