blob: 2657d67ab07693042c5c554c1ea900c8be7eabc6 [file] [log] [blame]
#!/usr/bin/env python3
import json
import os
import pathlib
import pprint
import subprocess
import sys
__dir__ = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.abspath(os.path.join(__dir__, "..")))
def main(pdk_path, version):
pr_path = pathlib.Path(os.path.join(pdk_path, "libraries", "sky130_fd_pr", version))
devices = []
with open(os.path.join(__dir__, 'devices.txt')) as f:
for l in f:
if '#' in l:
l = l[:l.index('#')]
l = l.strip()
if not l:
continue
bits = l.split()
devices.append(bits[0])
print()
print("Devices:")
print('-'*75)
pprint.pprint(devices)
print('-'*75)
print()
print("Removing previous runs:")
print('-'*75)
for f in pr_path.rglob("*_results.json"):
f = os.path.abspath(f)
print(str(f))
os.unlink(f)
print('-'*75)
with subprocess.Popen([
'parallel', '-v',
os.path.join(__dir__, 'run_spice_tests_new.py'),
pdk_path,
version,
'{}',
], stdin=subprocess.PIPE, stderr=subprocess.STDOUT) as p:
p.communicate('\n'.join(devices).encode('utf-8'))
retcode = p.wait()
passes = []
fails = []
ignores = []
baseline_entries = []
reasons = {}
print()
print("Loading results from:")
print('-'*75)
for f in sorted(pr_path.rglob("*_results.json")):
f = os.path.abspath(f)
print(str(f))
with open(f) as f:
data = json.load(f)
assert isinstance(data, dict), data
passes.extend(data.pop('passes'))
fails.extend(data.pop('fails'))
ignores.extend(data.pop('ignores'))
baseline_entries.extend(data.pop('baseline_entries'))
reasons.update(data.pop('reasons'))
print('-'*75)
print()
output = os.path.join(pr_path, 'simulation_run.log')
with open(output, 'w') as of:
print(file=of)
print('Simulation summary', file=of)
print('='*75, file=of)
print(file=of)
print('Passing devices', file=of)
print('-'*75, file=of)
for passing in passes:
print(passing, file=of)
print('-'*75, file=of)
print(file=of)
print('Ignored (unusable) devices', file=of)
print('-'*75, file=of)
for ignored in ignores:
print(ignored, file=of)
print('-'*75, file=of)
print(file=of)
print('Failing devices', file=of)
print('-'*75, file=of)
for failing in fails:
print(failing, file=of)
print(' Reason: ' + reasons[failing], file=of)
print('-'*75, file=of)
# Output pass / fail / ignore summary
print(file=of)
print('Final results', file=of)
print('#'*75, file=of)
print('Passes: ' + str(len(passes)), file=of)
print('Fails: ' + str(len(fails)), file=of)
print('Ignores: ' + str(len(ignores)), file=of)
print()
print()
print()
with open(output) as f:
print(f.read())
return retcode
if __name__ == "__main__":
args = list(sys.argv)
args.pop(0)
pdk_path = args.pop(0)
if args and args[0] and args[0][0] == 'v':
version = args.pop(0)
else:
version = 'v0.20.1'
sys.exit(main(pdk_path, version))